Mats Erik Andersson <g...@gisladisker.se> writes: > In order to enhance my credibility, let me produce > a test case for getsubopt() that illuminates the > failure of the present implementation of shishi_cfg().
Thank you! I believe you have identified a difference between GNU and POSIX getsubopt. Possibly gnulib should work around this problem. I'm redirecting this to the gnulib list for further discussion by the experts. Gnulib's getsubopt portability issues are documented here: http://www.gnu.org/software/gnulib/manual/html_node/getsubopt.html It only says the function is missing on some platforms, not any other portability concerns. The POSIX spec is here: http://pubs.opengroup.org/onlinepubs/009695399/functions/getsubopt.html Note: If the string at *optionp contains only one suboption argument (equivalently, no commas), getsubopt() shall update *optionp to point to the null character at the end of the string. Otherwise, it shall isolate the suboption argument by replacing the comma separator with a null character, and shall update *optionp to point to the start of the next suboption argument. If the suboption argument has an associated value (equivalently, contains an equal sign), getsubopt() shall update *valuep to point to the value's first character. Otherwise, it shall set *valuep to a null pointer. The calling application may use this information to determine whether the presence or absence of a value for the suboption is an error. Additionally, when getsubopt() fails to match the suboption argument with a token in the keylistp array, the calling application should decide if this is an error, or if the unrecognized option should be processed in another way. Alas the final paragraph doesn't demand any specific behaviour of getsubopt when there is no match, however the paragraph begins with "Additionaly" so presumably (*) whatever is done when there is no match is done on top of what is normally done, which is covered by the previous paragraph. (*) This is debatable, but was my initial reading. The GNU libc documentation is here: http://www.gnu.org/software/libc/manual/html_node/Suboptions.html#Suboptions Note: In case the suboption has an associated value introduced by a `=' character, a pointer to the value is returned in VALUEP. The string is `\0' terminated. If no argument is available VALUEP is set to the null pointer. By doing this the caller can check whether a necessary value is given or whether no unexpected value is present. In case the next suboption in the string is not mentioned in the TOKENS array the starting address of the suboption including a possible value is returned in VALUEP and the return value of the function is `-1'. I'm not sure the final paragraph is POSIX compliant. The first paragraph in the POSIX spec quoted above says VALUEP should be NULL if there is no argument, and presumably that applies even if there is no token match. GNU behaves different when there is no token match. The glibc implemtation is here: http://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/getsubopt.c;h=e770c2d8471f348b083b3a92ee87b74395bf0a9b;hb=HEAD#l32 Note: /* Parse comma separated suboption from *OPTIONP and match against strings in TOKENS. If found return index and set *VALUEP to optional value introduced by an equal sign. If the suboption is not part of TOKENS return in *VALUEP beginning of unknown suboption. On exit *OPTIONP is set to the beginning of the next token or at the terminating NUL character. */ int getsubopt (char **optionp, char *const *tokens, char **valuep) So I think a portable program that uses getsubopt needs to save a copy of optionp before passing it to getsubopt, and then if getsubopt returns -1 it needs to look at that copy instead of value. If the application is interested in what the unknown suboption was, that is. > The test program "test_subopt.c", contained in the present > message, produces the following output at execution time. > > GNU libc, OpenSolaris: > > INPUT: name=this,that,those > > NAME: value = 'this', tail = 'that,those' > default: value = 'that', tail = 'those' > default: value = 'those', tail = '' This seems to be the problem: value should be NULL in the last two lines. > FreeBSD 8.2, FreeBSD 9.0, OpenBSD 5.0, NetBSD 5.1, DragonflyBSD 3.1: > > INPUT: name=this,that,those > > NAME: value = 'this', tail = 'that,those' > default: value = '(null)', tail = 'those' > default: value = '(null)', tail = '' This seems consistent with POSIX. > A common feature in the BSD implementation is to empty VALUE in > > getsubopt(&tail, token, &value); > > in case an unrecognised suboption is found. The implementations > in eglibc and in SunOS libc do not behave that way. Can you also print out what the return value from getsubopt is in the 'default' value? Is it -1 or something else? I'm leaving your test case in this email below for the record. /Simon > > Best regards, > > Mats Erik Andersson > > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <errno.h> > > char *const token[] = { > "name", > NULL > }; > > int main(void) { > char *value, *tail = strdup("name=this,that,those"); > > printf("INPUT: %s\n\n", tail); > while (tail && *tail) { > switch (getsubopt(&tail, token, &value)) { > case 0: > printf("NAME: value = '%s', tail = '%s'\n", > value, tail); > break; > default: > printf("default: value = '%s', tail = '%s'\n", > value, tail); > } > } > > return errno; > } > > _______________________________________________ > Help-shishi mailing list > help-shi...@gnu.org > https://lists.gnu.org/mailman/listinfo/help-shishi