roy@phri.UUCP (Roy Smith) (01/15/89)
[not strictly a C question, but comp.lang.c seems to be the best place] I'm writing a program which will take an optional range, in the style of graph(1)'s "-x xmin xmax". How do I tell getopt to parse something like that? I suppose I could diddle with optind to make getopt skip the next argument, but that hardly seems kosher. The obvious way to do this would be to have getopt support a syntax like "-r::" which means the "-r" flag has *two* arguments after it but it's too late now. -- Roy Smith, System Administrator Public Health Research Institute {allegra,philabs,cmcl2,rutgers}!phri!roy -or- phri!roy@uunet.uu.net "The connector is the network"
gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/16/89)
In article <3652@phri.UUCP> roy@phri.UUCP (Roy Smith) writes: > I'm writing a program which will take an optional range, in the >style of graph(1)'s "-x xmin xmax". How do I tell getopt to parse >something like that? You don't. getopt() was written to support the Command Syntax Standard, and that usage is a violation of the Standard.
henry@utzoo.uucp (Henry Spencer) (01/16/89)
In article <3652@phri.UUCP> roy@phri.UUCP (Roy Smith) writes: > I'm writing a program which will take an optional range, in the >style of graph(1)'s "-x xmin xmax". How do I tell getopt to parse >something like that? ... You can't. The only getopt-compatible way is to require the user to say "-x 'xmin xmax'" instead, and have your code pull the single argument apart. This is what the AT&T syntax standard mandates (with the further flourish that tabs and commas must work as separators, not just spaces, as I recall). Nobody has ever pretended that getopt or the syntax standard could handle all the old weird programs that hack their arguments in their own strange ways. From personal experience, I can testify that life is a lot better when everything uses getopt, even if this means some aggravation over backward compatibility. Just having things consistent is a huge win. -- "God willing, we will return." | Henry Spencer at U of Toronto Zoology -Eugene Cernan, the Moon, 1972 | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
bobmon@iuvax.cs.indiana.edu (RAMontante) (01/17/89)
henry@utzoo.uucp (Henry Spencer): - -ways. From personal experience, I can testify that life is a lot better -when everything uses getopt [ ... ] Spoken like a true author of the standard getopt program! :-) (yes, i use it on my msdos box, so it must be standard)
alanf%smile@Sun.COM (Alan Fargusson @ peace with the world) (01/18/89)
In article <1989Jan16.023712.29002@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: > In article <3652@phri.UUCP> roy@phri.UUCP (Roy Smith) writes: > > I'm writing a program which will take an optional range, in the > >style of graph(1)'s "-x xmin xmax". How do I tell getopt to parse > >something like that? ... > > You can't. The only getopt-compatible way is to require the user to > say "-x 'xmin xmax'" instead, and have your code pull the single argument > apart. This is what the AT&T syntax standard mandates (with the further > flourish that tabs and commas must work as separators, not just spaces, > as I recall). > I think the best way to do this would be to have the user type "-x xmin,xmax", and parse the 'xmin,xmax' yourself. This is what some AT&T software does. - - - - - - - - - - - - - - - - - - - - - Alan Fargusson Sun Microsystems alanf@sun.com ..!sun!alanf
levy@ttrdc.UUCP (Daniel R. Levy) (01/18/89)
In article <1989Jan16.023712.29002@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: > In article <3652@phri.UUCP> roy@phri.UUCP (Roy Smith) writes: > > I'm writing a program which will take an optional range, in the > >style of graph(1)'s "-x xmin xmax". How do I tell getopt to parse > >something like that? ... > > You can't. The only getopt-compatible way is to require the user to > say "-x 'xmin xmax'" instead, and have your code pull the single argument > apart. This is what the AT&T syntax standard mandates (with the further > flourish that tabs and commas must work as separators, not just spaces, > as I recall). Actually, what Roy had in mind IS possible. Yes it violates the syntax standard, but if one is masochistic enough to WANT that, it's doable through suitable abuse of optind. This permits argument sequences of the form "-x <xmin> <xmax>" or even "-bundledoptionlettersx<xmin> <xmax>" for the truly warped of mind: main(argc,argv) char **argv; { ... int c; extern char *optarg; extern int optind; double xmin, xmax, atof(); void exit(), usage(); ... while ((c=getopt(argc,argv,"x:abcdefgh")) != EOF) { switch(c) { case 'a': /* ordinary options */ ... case 'h': /* etc. */ case 'x': if (optind == argc || !isanumber(optarg) || !isanumber(argv[optind]) { usage(); exit(1); } else { xmin=atof(optarg); xmax=atof(argv[optind]); optind++; /* skip the next argument */ } break; ... } } ... } This will only work for compiled code; I know of no way that getopt(1) can be made to do something similar in a shell script. -- Daniel R. Levy UNIX(R) mail: att!ttbcad!levy AT&T Bell Laboratories 5555 West Touhy Avenue Any opinions expressed in the message above are Skokie, Illinois 60077 mine, and not necessarily AT&T's.
henry@utzoo.uucp (Henry Spencer) (01/20/89)
In article <3141@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: >Actually, what Roy had in mind IS possible. Yes it violates the syntax >standard, but if one is masochistic enough to WANT that, it's doable through >suitable abuse of optind... This is not portable; it assumes a specific implementation of getopt. Unless things have changed, the getopt(3) documentation makes no promise that user changes to optind will be reflected back into getopt's innards. It probably works in the existing implementations, but that's not the same thing. -- Allegedly heard aboard Mir: "A | Henry Spencer at U of Toronto Zoology toast to comrade Van Allen!!" | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
levy@ttrdc.UUCP (Daniel R. Levy) (01/21/89)
In article <1989Jan19.192946.15825@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: < In article <3141@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: < >Actually, what Roy had in mind IS possible. Yes it violates the syntax < >standard, but if one is masochistic enough to WANT that, it's doable through < >suitable abuse of optind... < < This is not portable; it assumes a specific implementation of getopt. < Unless things have changed, the getopt(3) documentation makes no promise < that user changes to optind will be reflected back into getopt's innards. Literally taken, you are quite right. I am reading between the lines of the man page and making an educated guess. Can you suggest a reason for the statement "Because optind is external, it is normally initialized to zero automatically before the first call to getopt," other than the implication that optind's value will influence the behavior of getopt? I mean, why else should we care what optind is prior to at least one usage of getopt? But, supposing we take your objection at face value, that we can't count on user changes in optind being reflected into the internal workings of getopt. O.K., how about mucking with argv and argc instead of with optind: ... int i; ... while (...getopt...) { ... case 'x': ... /* validate the presence of two numeric arguments */ ... xmin=atof(optarg); xmax=atof(argv[optind]); argv++; argc--; break; ... } The documentation doesn't say that we must give each call to getopt() the same argc and the same argv does it now? Huh? Huh? :-) -- Daniel R. Levy UNIX(R) mail: att!ttbcad!levy AT&T Bell Laboratories 5555 West Touhy Avenue Any opinions expressed in the message above are Skokie, Illinois 60077 mine, and not necessarily AT&T's.
henry@utzoo.uucp (Henry Spencer) (01/22/89)
In article <3146@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: >< Unless things have changed, the getopt(3) documentation makes no promise >< that user changes to optind will be reflected back into getopt's innards. > >Literally taken, you are quite right. I am reading between the lines of >the man page and making an educated guess. Can you suggest a reason for >the statement "Because optind is external, it is normally initialized to >zero automatically before the first call to getopt," other than the >implication that optind's value will influence the behavior of getopt? There is a clear implication here that the initial value matters. There is no similar statement about subsequent values. If one wants portable software, one is not allowed to make educated guesses about the software; one is entitled to trust only properties that are explicitly documented. >But, supposing we take your objection at face value, that we can't count on >user changes in optind being reflected into the internal workings of getopt. >O.K., how about mucking with argv and argc instead of with optind... >The documentation doesn't say that we must give each call to getopt() the same >argc and the same argv does it now? Huh? Huh? :-) No, it doesn't. It's also kind of vague on what might happen. I fear it comes under the same heading: "behavior not documented, may vary between implementations". -- Allegedly heard aboard Mir: "A | Henry Spencer at U of Toronto Zoology toast to comrade Van Allen!!" | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
john@frog.UUCP (John Woods) (01/24/89)
In article <3146@ttrdc.UUCP>, levy@ttrdc.UUCP (Daniel R. Levy) writes: N>In article <1989Jan19.192946.15825@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: e>< This is not portable; it assumes a specific implementation of getopt. c>< Unless things have changed, the getopt(3) documentation makes no promise r>< that user changes to optind will be reflected back into getopt's innards. o>Literally taken, you are quite right. I am reading between the lines of m>the man page and making an educated guess. Can you suggest a reason for a>the statement "Because optind is external, it is normally initialized to n>zero automatically before the first call to getopt," other than the c>implication that optind's value will influence the behavior of getopt? y>I mean, why else should we care what optind is prior to at least one usage >of getopt? Interesting. The SVID (Issue 2, Volume 1) says "The external variable optind is initialized to 1 before the first call to the function getopt." No statement of cause-and-effect, and a different initializer from your manual page. This also does not imply that optind influences getopt(), it merely implies that optind always has a reasonable value. If you really have to have a program which doesn't use getopt() argument semantics, why bang on getopt() to fool it into doing what you want? At the very worst, writing your own getopt() with your own semantic variations can't be all that hard (I wrote one a long time ago in a small amount of time, and I bet Henry's version didn't take all that long, either). That way, you can make sure that the next version of your libraries don't surprise you, and you have real documentation for what your preferred argument semantics are ("Use the Source, Luke!"). The real motivation for putting getopt() in the library isn't saving people gobs of coding time, it was to make having a uniform command syntax temptingly inviting. -- John Woods, Charles River Data Systems, Framingham MA, (508) 626-1101 ...!decvax!frog!john, john@frog.UUCP, ...!mit-eddie!jfw, jfw@eddie.mit.edu Presumably this means that it is vital to get the wrong answers quickly. Kernighan and Plauger, The Elements of Programming Style