aj@zyx.UUCP (Arndt Jonasson) (03/26/88)
[If your interest is not Unix, skip the rest of this article.] This is a suggestion for a command line parsing routine for C programs in Unix. To be sure, 'getopt(3)' exists. It comes with SystemV, I believe, and there exists a public-domain version written by Henry Spencer. I find it a little bit too awkward to use, since I have to write a lot of code to interface to it (a loop with a case statement in it, usually). Another problem is that the names of the options occur twice, once in the argument to 'getopt' and once in the 'case' statement. It is never a good thing to duplicate information in a program. This is not really criticism of 'getopt'. No doubt it is being used by some, and after a few times of using it, I could probably remember its calling conventions. [Do many people actually use it? I don't know. Most Unix tools don't seem to use it.] Does the ANSI C committee address this issue? Probably not, since argument parsing can be quite different on various operating systems. POSIX, perhaps? Recently, I invented a parsing routine of my own that doesn't require the program logic to be supplied by the application programmer. Instead, a static option descriptor array is initialized at compile time and passed to the function 'O_parse_options' at runtime. Most programs won't need to access 'argc' and 'argv' at all (they have to be supplied to this function, of course). I post this in the hope of getting constructive comments on what features are missing in my scheme, and whether it is perhaps too restrictive or too general. If it seems to be generally useful, I will post the code to comp.unix.sources. An example program that exhibits nearly all the features follows: #include "options.h" #include <stdio.h> main (argc, argv) int argc; char **argv; { int n; static int flag = 0; static int number = 0; static double dbl = 3.14; static char character = 'A'; static char *string = "kvack"; static Option desc[] = { O_flg ('f', flag), O_int ('i', number), O_str ('s', string), O_chr ('c', character), O_dbl ('d', dbl), O_directive ("remaining: 1-2"), O_directive ("usage: [-f] [-i nn] [-cC] [-d float] [-s string] src [dst]"), O_end, }; n = O_parse_options (desc, argc, argv); } 'O_parse_options' uses the same model as 'getopt', i.e. first come the options, preceded by hyphens (they may be grouped together after one hyphen), then come the non-option arguments. If an option -s takes an argument, both '-sfoo' and '-s foo' are valid. It will either successfully parse all the options and store values in the appropriate variables, or exit the program with an error message. The error message describes what option was offending, and in what way, e.g.: 1 to 2 non-option arguments are required The -i option requires an argument There is no -q option Invalid integer 'foo' given to the -i option After the error message, the usage line will be printed, consisting of the contents of the "usage" directive with the name of the program inserted, like this: usage: tst [-f] [-i nn] [-cC] [-d float] [-s string] src [dst] This is also what 'usage()' will print when called from the application program, unless a '#undef usage' has been done. The name of the program is available in the variable O_programname for use by the application. If successful, 'O_parse_options' returns a positive integer which is the index in argv of the first non-option argument (if none, it will point past the argument list). The application program can thus easily pick up the remaining arguments; that they are not too few or too many has already been checked. -- Arndt Jonasson, ZYX Sweden AB, Styrmansgatan 6, 114 54 Stockholm, Sweden email address: aj@zyx.SE or <backbone>!mcvax!enea!zyx!aj
dan@srs.UUCP (Dan Kegel) (03/28/88)
In article <2414@zyx.UUCP> aj@zyx.SE (Arndt Jonasson) writes: > [Proposal for a more convenient way to parse command line options] > ...a static option descriptor array is initialized at compile > time and passed to the function 'O_parse_options' at runtime. > >An example program that exhibits nearly all the features follows: > >#include "options.h" > > int n; > static int flag = 0; > static double dbl = 3.14; > static char *string = "kvack"; > > static Option desc[] = { > O_flg ('f', flag), > O_str ('s', string), > O_dbl ('d', dbl), > O_directive ("remaining: 1-2"), > O_directive > ("usage: [-f] [-d float] [-s string] src [dst]"), > O_end, > }; > n = O_parse_options (desc, argc, argv); > >Arndt Jonasson, ZYX Sweden AB, Styrmansgatan 6, 114 54 Stockholm, Sweden >email address: aj@zyx.SE or <backbone>!mcvax!enea!zyx!aj We like this idea, but we implemented it a little differently. The "Option descriptors" can be placed into a scanf-style string. In our system, the above example would be coded argproc(argc, argv, "=f -d%g -s%s %s %s", &flag, &dbl, string, arg1, arg2); if (arg1[0] == '\0') { fprintf(stderr, "usage: [-f] [-d float] [-s string] src [dst]"), exit(1); } The format string to argproc contains flag names (-d, -s) optionally followed by value type specifiers a la scanf (%g %s). If the flag name is introduced by '=' instead of '-', a boolean variable in the argument list is set TRUE or FALSE according to whether the flag was given or not. We think this is more convenient than Arndt's implementation. Anybody agree/disagree? If there's enough interest we would consider posting the code. -- Dan Kegel "... earn it anew if thou wouldst possess it." - Goethe: Faust srs!dan@cs.rochester.edu rochester!srs!dan dan%srs.uucp@harvard.harvard.edu
walter@garth.UUCP (Walter Bays) (03/29/88)
In article <2414@zyx.UUCP> aj@zyx.SE (Arndt Jonasson) writes: >This is a suggestion for a command line parsing routine for C programs >in Unix. [...] >Recently, I invented a parsing routine of my own that doesn't require >the program logic to be supplied by the application programmer. [...] >If it seems to be generally useful, I will post the code to comp.unix.sources. >An example program that exhibits nearly all the features [followed] Sounds great to me. Thanks, I'd love to have a copy. A higher level routine than getopt() would induce lazy programmers like me to do it right. (It's only for my own use, getopt is too much trouble, and I'll never forget the argument order, right? :-) Some will say it should work like getopt(): "-AB" equals "-A -B". Others will argue for multiple character options: "-132 -postscript". SysV doesn't follow the SysV standard yet. I would like some standard, so I'm for following the Posix standard (whatever that is)? Please resist suggestions to add semantic checking routines (i.e. range of numbers, existence of files) which belong in the application program. I'd rather code such things directly rather than pass pointers to functions. -- ------------------------------------------------------------------------------ Any similarities between my opinions and those of the person who signs my paychecks is purely coincidental. E-Mail route: ...!pyramid!garth!walter USPS: Intergraph APD, 2400 Geng Road, Palo Alto, California 94303 Phone: (415) 852-2384 ------------------------------------------------------------------------------
crash@tsc3b21.UUCP (Frank "crash" Edwards) (03/29/88)
From article <2414@zyx.UUCP>, by aj@zyx.UUCP (Arndt Jonasson): > This is a suggestion for a command line parsing routine for C programs > in Unix. > > [ some stuff deleted. ] > > Does the ANSI C committee address this issue? Probably not, since > argument parsing can be quite different on various operating systems. > POSIX, perhaps? > > [ some more stuff deleted. ] > > Recently, I invented a parsing routine of my own that doesn't require > the program logic to be supplied by the application programmer. > Instead, a static option descriptor array is initialized at compile > time and passed to the function 'O_parse_options' at runtime. Most > programs won't need to access 'argc' and 'argv' at all (they have to > be supplied to this function, of course). I post this in the hope of > getting constructive comments on what features are missing in my > scheme, and whether it is perhaps too restrictive or too general. If > it seems to be generally useful, I will post the code to > comp.unix.sources. > > If successful, 'O_parse_options' returns a positive integer which is > the index in argv of the first non-option argument (if none, it will > point past the argument list). The application program can thus easily > pick up the remaining arguments; that they are not too few or too many > has already been checked. > -- > Arndt Jonasson, ZYX Sweden AB, Styrmansgatan 6, 114 54 Stockholm, Sweden > email address: aj@zyx.SE or <backbone>!mcvax!enea!zyx!aj I have also written an implmentation of two routines used on, at least, Revision 3 of the CRDS UNOS Operating System: getargs() and getallargs(). (I don't know if these routines are intrinsic to UNOS or to the OEM implmentation I was running.) The call is similar, but a structure isn't required. It goes something like this: main( argc, argv ) int argc; char **argv; { char *options = "h,help,b,bool,x#,file*"; char *filename = NULL; int stat, help = 0, boolean = 0, debug = 0; stat = getargs(&argc, &argv, options, &help, &help, /* First two options are mapped to a single variable */ &boolean, &boolean, /* as this one is, also. */ &debug, /* The 'x' option accepts a numeric count (default 1) */ &filename); /* Address of a char*; essentially copied from *argv */ if (stat < 0 || help) usage( ... ); . . . exit( 0 ); } After the return from this call, "help" and "boolean" will contain TRUE or FALSE, indicating that the corresponding option did or did not appear on the command line, respectively. Debug is the familiar "-xN" option specified as "x#" in the option string. If present on the command line, debug is set to one. Then a check is made for a numeric argument following. If one is, it is parsed (using strtol() -- any input base can be used) and stored in debug. And lastly, the char pointer from argv is copied to "filename" if the "file" option is present. Multi-character options options cannot be abbreviated by a single letter unless the abbreviation explicitly appears in the option string, i.e. "help" means the command line would have to contain "-help" for the option to be recognized, whereas "h,help" would allow either "-h" or "-help". As in the example above, both options would map to the same integer for simplicity. ------------ Well, I do tend to get a little long-winded at times. But I find this method very flexible and relatively easy to read while still hiding the parsing of command lines in a library call. There is a corresponding subroutine, getallargs(), which doesn't stop at the first non-option command line argument, but continues to parse all of the options on the command line. Normally, getargs() returns NULL and argc / argv are left pointing at the first argument that didn't parse as an option. So... the calling procedure can pick up right where the getargs() call left off. ---- Frank (crash) Edwards ...!codas!usfvax2!{pdn,jc3b21}!tsc3b21!crash TSC in Palm Harbor, FL Phone: (813) 785-0583 (voice) The Sweat Shop These opinions belong to no one.
schaefer@ogcvax.UUCP (Barton E. Schaefer) (03/30/88)
From article <2414@zyx.UUCP> aj@zyx.SE (Arndt Jonasson) is quoted: } [Proposal for a more convenient way to parse command line options] } ...a static option descriptor array is initialized at compile } time and passed to the function 'O_parse_options' at runtime. } }Arndt Jonasson, ZYX Sweden AB, Styrmansgatan 6, 114 54 Stockholm, Sweden }email address: aj@zyx.SE or <backbone>!mcvax!enea!zyx!aj In article <srs.738> srs!dan@cs.rochester.edu (Dan Kegel) responds: } We like this idea, but we implemented it a little differently. } The "Option descriptors" can be placed into a scanf-style string. } argproc(argc, argv, "=f -d%g -s%s %s %s", &flag, &dbl, string, } arg1, arg2); } The format string to argproc contains flag names (-d, -s) optionally followed } by value type specifiers a la scanf (%g %s). If the flag name is introduced } by '=' instead of '-', a boolean variable in the argument list is set TRUE } or FALSE according to whether the flag was given or not. } -- } Dan Kegel "... earn it anew if thou wouldst possess it." - Goethe: Faust } srs!dan@cs.rochester.edu rochester!srs!dan dan%srs.uucp@harvard.harvard.edu I like the second idea better than the first because no static/global storage is required; it's more modular. However, both seem to have (fixable) drawbacks. Arndt's option parser, as I recall (I don't have the original article here), returns "a pointer to the first non-option argument"; this seems to imply that all options must precede any non-option arguments on the command line. I'd prefer to be able to mix them arbitrarily (with obvious restrictions, e.g., if "-f" is used to introduce a file name, then that file name must immediately follow the option, if "--" appears then none of the remaining arguments are treated as options, etc.). I can't tell from the brief description given whether Dan's function can handle this or not, but I'll give the benefit of the doubt. The problem with Dan's function is that it appears to have no provision for parsing an arbitrary number of arguments (e.g., "rm" can take as many file names as the shell can handle in one command line). I therefore make the following suggestions: 1) Change the first argument of argproc to (int *) and return the number of arguments remaining after processing by storing through this pointer. It would normally be passed &argc as the first argument. 2) Allow argproc to rearrange the pointers in argv to move successfully processed arguments to the front of the array. THIS DOES NOT MEAN COPYING THE ARGUMENT STRINGS. I know what kind of chaos could result if argv[5], "antidisestablishmentarianism", were copied to argv[2], which might be "the". 3) Make the return value of argproc be of type (char **), a pointer to the first not-yet-processed argument. The rearranging in (2) will ensure that all unprocessed arguments are grouped in the last argc positions of argv, where argc has the value returned in (1). This allows successive calls to argproc to parse a long argv. Comments? Arguments (no pun intended :-) against doing (2), which is the most questionable step? Random flames? .... -- Bart Schaefer CSNET: schaefer@cse.ogc.edu UUCP: ...{tektronix,verdix}!ogcvax!schaefer "You can lead a yak to water, but you can't teach an old dog to make a silk purse out of a pig in a poke." -- Opus
daveb@geac.UUCP (David Collier-Brown) (03/31/88)
I did a parser with static control tables, and admit I like the scanf-style ones better. Feel free to post... --dave (what, me worry) c-b -- David Collier-Brown. {mnetor yunexus utgpu}!geac!daveb Geac Computers International Inc., | Computer Science loses its 350 Steelcase Road,Markham, Ontario, | memory (if not its mind) CANADA, L3R 1B3 (416) 475-0525 x3279 | every 6 months.
henry@utzoo.uucp (Henry Spencer) (03/31/88)
> To be sure, 'getopt(3)' exists... I find > it a little bit too awkward to use, since I have to write a lot of > code to interface to it (a loop with a case statement in it, usually). There's an easy fix for this one, actually: write that code once and put it somewhere where you can get at it. (See my paper "How To Steal Code", given at the winter Usenix in Dallas.) I agree it is a nuisance. > ... [Do many people actually use [getopt]? I don't know. > Most Unix tools don't seem to use it.] A lot of new development uses it, but it is difficult to retrofit it into many of the existing programs, because they often don't quite obey its conventions and hence the retrofit could break things. This would be a problem with almost any option parser. Actually, we've retrofitted getopt into quite a few things (the greater consistency is a considerable win), but there are programs that just don't fit its model. > Does the ANSI C committee address this issue? Probably not, since > argument parsing can be quite different on various operating systems. > POSIX, perhaps? This one seems to have fallen down the crack between them, actually. It's definitely not in X3J11, and it wasn't in POSIX the last time I looked. > Recently, I invented a parsing routine of my own... Not a bad one. One disadvantage, shared by many attempts to "pull things together" more than getopt does, is that it does not permit arbitrary actions for handling specific options. The one thing getopt's loop-and- switch really buys you is individual handling for each option, so you can do things like range checks "on the spot". How much this gets used, of course, is another story... One should also remember, for better or worse, that getopt is a de facto standard. (An official one, if you believe in the SVID.) -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry
karish@denali.UUCP (karish) (03/31/88)
In article <1988Mar30.233142.2040@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >> Does the ANSI C committee address this issue? Probably not, since >> argument parsing can be quite different on various operating systems. >> POSIX, perhaps? > >This one seems to have fallen down the crack between them, actually. >It's definitely not in X3J11, and it wasn't in POSIX the last time I looked. getopt() is, indeed, in POSIX, unless/until the 1003.2 committee change their collective mind. Chuck
gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/31/88)
In article <1988Mar30.233142.2040@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >This one seems to have fallen down the crack between them, actually. >It's definitely not in X3J11, and it wasn't in POSIX the last time I looked. My understanding is that IEEE 1003.2 is expected to deal with getopt or equivalent. >One should also remember, for better or worse, that getopt is a de facto >standard. (An official one, if you believe in the SVID.) getopt also evolved out of a Bell Labs study by Hemenway and Armitage of the existing UNIX command options. It was designed to be the best compromise common-ground facility, even though it was acknowledged that a totally different option syntax might be an improvement. It probably ought not to be foisted off on non-UNIX systems, but it makes a lot of sense to use it for most UNIX utilities. Many times I've been saved just by having "--" supported.
gold@trane.UUCP (Michael Gold) (04/01/88)
From article <2517@geac.UUCP>, by daveb@geac.UUCP (David Collier-Brown): > I did a parser with static control tables, and admit I like the > scanf-style ones better. Feel free to post... I agree that the 'scanf' paradigm is neater, assuming a fairly small set of options. For programs with more complex command lines, where the format string would overflow a line of source code and be otherwise unwieldy, I prefer the static data structure. The ideal solution would be a package that accepts either interface at the user's preference. I cite the various flavors of 'exec*(2)' as precedent. Or does that raise red flags on account of unnecessary multiplicity?? Anyway, I'd propose three more requirements for this package: 1) Capability of handling multi-character flags, 2) Acceptance of arguments to flags that may or may not be appended to the flag, as in the -I and -o flags of most 'cc's respectively, and 3) Positional independence of the tokens, except for arguments bound to particular flags. I sense from the volume and quality of this discussion that improving getopt() is both desirable and non-trivial. Let's keep at it. -------- Michael Gold / (415) 780-4903 / {ihnp4,ames,sun,pyramid,...}!pacbell!trane!gold
g-rh@cca.CCA.COM (Richard Harter) (04/01/88)
The discussions on options are of particular interest to me because I expect to be revising an options package in the near future. (Real soon now.) I don't mind a fair bit of work, but I want to get the spec's right. Here are some considerations: (1) Must be able to handle multiple calls with different argument vectors. [This is an internal requirement.] (2) Must be able to turn flags on and off. This is hand in hand with requirement (1). This is a problem. Currently we are using - for off and + for on. From a human engineering viewpoint this seems essential. However this conflicts with unix usage. (3) Must be case insensitive if the key values are all the same case. (4) Must be able to handle key values with more than one letter. (5) Must be able to handle abbreviations to the level of ambiguity. (6) Insofar as possible, must be consistent with getopt. In particular if all key values are unambiguous at the one letter level, one should be able to group them. (7) Should be able to handle various types and do the appropriate interpretation. Should also be able to invoke a processing routine for an option value. (8) Should be able to handle a list of positional arguments which don't have option keys. It should be possible to intermix these with options which do have keys. [Compatibility considerations.] (9) Must be able to return a list of all arguments which are not key value or postional options, or some equivalent mechanism. (10) For sundry internal reasons, must be able to support -key value and key=value. (11) Under consideration is white space elimination and white space requirement rules. In particular, if k is a key letter, getopt allows -kvalue We would like to do this, to be consistent with getopt. Precise rules for doing this while allowing multiple letter keys are yet to be determined. There are also questions about -foo-bar (12) Error handlers should be specifiable. (13) It would be preferable that the entire options processing package be self contained. (14) Also preferred is that there be no globals involved. As I say, these are preliminary desiderata. Any suggestions or comments would be appreciated. -- In the fields of Hell where the grass grows high Are the graves of dreams allowed to die. Richard Harter, SMDS Inc.
peter@athena.mit.edu (Peter J Desnoyers) (04/01/88)
When I worked at Bolt, Beranek, and Newman I wrote some software that used their option parsing code, which I remember was quite thorough. However, it was not quite standard Unix syntax, as values were passed as -a=something instead of -a something, and standard practice was to allow both a full keyword (-argument=something) and its abbreviation (-arg or -a or whatever you define it to be.) Is there someone from bbn out there on the net who could describe this more fully? My memory seems to be fading... I think Uncle Sam owns the code, so we should be able to get a pretty detailed description of it without worrying about proprietary concerns. Peter Desnoyers peter@athena.mit.edu [I hope this message comes out - I can barely use my editor due to the noise on the phone lines today.]
henry@utzoo.uucp (Henry Spencer) (04/03/88)
> getopt also evolved out of a Bell Labs study by Hemenway and Armitage > of the existing UNIX command options... Actually, unless the H&A work dates back much farther than I'm aware of, getopt pre-dates it. H&A's syntax standard is tougher than getopt in a number of places, most of which getopt can't really enforce, although I believe one or two small tightenings of the getopt specs were planned as a result. Their recommendations turned out to match getopt fairly closely. > It was designed to be the best compromise common-ground facility People who are gung-ho on new syntax standards should study the H&A work first. There are more issues than appear at first glance, and H&A spent quite a bit of effort crafting the best compromise, and explaining *why* the result came out the way it did. You can find their paper in the 1984 UniForum Conference proceedings, which may still be available from Usenix or /usr/group (that one was a joint conference). > even though it was acknowledged that > a totally different option syntax might be an improvement... People who favor a radically new syntax, e.g. multi-character option names, should consider one fact before investing much effort and shouting in settling on a new syntax: You Are Not The First To Try This. Or the second. Or the third. All previous attempts have been failures, because the pressure of backward compatibility and standardization is too strong. Before tilting at this windmill yet again, consider whether there is any reason why you will succeed where others have failed. The fact is that the existing syntax, warty though it is, works tolerably well. To get a new syntax accepted, it will have to be so much better that it sells itself despite the compatibility issue. Frankly, this isn't very likely. -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry
henry@utzoo.uucp (Henry Spencer) (04/03/88)
> I sense from the volume and quality of this discussion that improving > getopt() is both desirable and non-trivial. Let's keep at it. Please do not confuse improving getopt() with improving the option syntax. The former might be viable; the latter has been tried repeatedly, sometimes by quite bright people, and has always failed. If you must invent Yet Another New Syntax, please start a mailing list so you won't bother the rest of the community with this futility. -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry
dan@srs.UUCP (Dan Kegel) (04/04/88)
We've recently been mulling over what would be better than getopt(). aj@zyx.SE (Arndt Jonasson) started the discussion by describing his static-structure-style argument processor. I posted a description of a scanf-style argument processor, argproc(). Many people requested that I post argproc(). I'm ready to do so, but am still cleaning up the documentation. Richard Harter (g-rh@cca.cca.com) posted a thoughtful list of desired features, which deserve discussion. I agree strongly that, for most programs, o Long option names are a must. o The argument processor should handle ASCII-to-whatever conversion, preferably with sscanf(). o Options should be freely intermixable with other arguments. o Non-switch positional arguments should be allowed. o The caller should be able to step through the list of arguments which were ignored by the argument processor. Getopt() fails the first three. I also agree that some programs (e.g. command-line interpreters) want to be able to call the argument processor repeatedly with different parameter vectors. This implies o The argument processor shouldn't use any static or global variables o It should allow the caller to do as much of the error handling as desired. Getopt() fails both times. I disagree with his proposals that o switches may be abbreviated or case insensitive o the argument processor let the caller specify callback functions My dilemma is that argproc() doesn't allow optional spaces between switches and their arguments; i.e. it can't treat "-ofilename" and "-o filename" as equivalent. Changing this would require throwing out one of argproc's nifty features: optional arguments to switches (i.e. "-x " or "-x3.5") What do y'all think? Should I go for getopt() compatibility now, or just post argproc() as is? -- Dan Kegel "... earn it anew if thou wouldst possess it." - Goethe: Faust srs!dan@cs.rochester.edu rochester!srs!dan dan%srs.uucp@harvard.harvard.edu
g-rh@cca.CCA.COM (Richard Harter) (04/04/88)
I've put comp.lang.c back in, because that's where I've been following
the topic. I don't follow comp.unix.wizards regularly, but I will pick
it up for the duration of the discussion.
In article <761@srs.UUCP> srs!dan@cs.rochester.edu (Dan Kegel) writes:
]We've recently been mulling over what would be better than getopt().
]aj@zyx.SE (Arndt Jonasson) started the discussion by describing his
]static-structure-style argument processor.
]I posted a description of a scanf-style argument processor, argproc().
]Many people requested that I post argproc(). I'm ready to do so,
]but am still cleaning up the documentation.
]Richard Harter (g-rh@cca.cca.com) posted a thoughtful list of desired
]features, which deserve discussion. I agree strongly that, for most programs,
]o Long option names are a must.
]o The argument processor should handle ASCII-to-whatever conversion,
] preferably with sscanf().
What we use currently is a character translation array. In the
current implementation this is passed as a global, but it could (and
probably should) be passed as an argument. At this writing, my opinion
is that this is better; it seems cleaner, it avoids sscanf (which I would
prefer to avoid on various grounds), and it separates character translation
from string interpretation.
]o Options should be freely intermixable with other arguments.
]o Non-switch positional arguments should be allowed.
]o The caller should be able to step through the list of arguments which
] were ignored by the argument processor.
]Getopt() fails the first three.
Agreed.
]I also agree that some programs (e.g. command-line interpreters) want to
]be able to call the argument processor repeatedly with different parameter
]vectors. This implies
]o The argument processor shouldn't use any static or global variables
]o It should allow the caller to do as much of the error handling as desired.
]Getopt() fails both times.
Since we (SMDS) have a product that incorporates a command-line
interpreter this is a live issue. We strongly want to be able to use the
same option processing both in invoking the software and while running the
software.
Error handling is an unresolved issue. To put it politely, I
don't much care for the getopt approach to error handling. Here are some
of the issues that I see:
o The argument processor should be a one call routine, a contrasted
to getopt, which is called once for each argument.
o The error(s) should be returned. An issue is whether the argument
processor should process until an error is found and stop or whether
it should keep going. If if keeps going, should the error return
mechanism specify all errors or just the first. How should this be
done?
o If there is an error, should there be a partial setting of options
or should options be set only if processing is completely successful.
We do the latter -- this seems safer.
o However this raises another question. Should the argument processor
do string conversion? The reason for raising this question is that
is simple to pass back a pointer to a string; there are no type
conversion issues. It may be that it better to split the processing
into three parts: extraction, error handling, and processing.
]I disagree with his proposals that
]o switches may be abbreviated or case insensitive
]o the argument processor let the caller specify callback functions
I withdraw the suggestion that the caller be allowed to specify
processing functions -- this is beyond the scope of the argument processor.
Case insensitivity, if desired, can be handled at the translation level.
[This is actually important if you are dealing with operating systems which
are case insensitive.]
I am not so sure that I want to yield on the issue of abbreviation.
This may be simply prejudice -- I've worked with command processors that
did it each way and I find that I much prefer abbreviation. The argument
for abbreviation is that you have the full name for documentation and for
the uncertain, and the abbreviated name for routine use. A lot of DEC
operating systems use abbreviation. As I recall, so does IBM's CMS. PRIMOS
usually provides two forms, a long form and a short form.
A compromise is to let the caller supply alternatives to the
argument processor. This shifts the burden to the software writer, but
it does provide more flexibility and control.
]My dilemma is that argproc() doesn't allow optional spaces between switches
]and their arguments; i.e. it can't treat "-ofilename" and "-o filename"
]as equivalent. Changing this would require throwing out one of argproc's
]nifty features: optional arguments to switches (i.e. "-x " or "-x3.5")
]What do y'all think? Should I go for getopt() compatibility now,
]or just post argproc() as is?
I think your current version shouldn't be the final version --
there are too many holes and unresolved issues. However I do think that
you should post what you have now so that people can look at it and
think about it. A program is, in many ways, a detailed spec.
--
In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die.
Richard Harter, SMDS Inc.
g-rh@cca.CCA.COM (Richard Harter) (04/04/88)
Here are further issues for thought: o It is desirable that the argument processor be able to handle untokenized argument strings. The reason for bringing this up is that our current processor can do this. In applications with an interpretive command processor, the parser for the interpreter may not necessarily follow unix parsing command line parsing rules. o The objectives that I am concerned with are (a) functional extensions to the existing syntax [discussed previously], and (b) simplified usage. The latter is worthy of some comment. The getopt scheme typically involves an arguments processing routine which calls getopt in a loop and then acts on the option letter in a switch. Each of these little suckers has to be coded individually, even though they are all very similar. Almost all of the time the action is to set a flag or set a value. If those are the only actions being taken, the whole thing can and should be done in a standardized routine. Life (and maintenance) is a lot simpler that way. This raises the question of what to do about special cases. These fall into two categories, conversions, and other. The 'other' category is the user's problem. The consensus seems to be that the argument processor should have the smarts to be able to do the conversions. This is all very well, but my concern is that this be done in a portable way that cannot crash. What happens if the string being converted to int contains garbage? What had better not happen is that routine crash. Similarly, any system utilities used should be generic -- available across a variety of operating systems and not just flavor X of Unix. o When getopt processes an option with a value it returns a pointer to a location within a string that it is passed. The assumption is made that this string is null terminated at the right place. No copy of the string is made. My opinion is that the argument processor should generate a copy of the string or value. This is relevant in the case of an interpretive command processor -- the original token string may vanish. -- In the fields of Hell where the grass grows high Are the graves of dreams allowed to die. Richard Harter, SMDS Inc.
sjs@spectral.ctt.bellcore.com (Stan Switzer) (04/04/88)
> In article <761@srs.UUCP> srs!dan@cs.rochester.edu (Dan Kegel) writes: > ]We've recently been mulling over what would be better than getopt(). . . . > o Non-switch positional arguments should be allowed. > o The caller should be able to step through the list of arguments which > were ignored by the argument processor. . . . > o The argument processor shouldn't use any static or global variables > o It should allow the caller to do as much of the error handling as desired. In article <26550@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes: > o The argument processor should be a one call routine, a contrasted > to getopt, which is called once for each argument. All of these considerations suggest that getopt()' should be a coroutine style function. Harking back to a week-old discussion, I propose that a coroutine mechanism (actually some sort of policy-free state freeze/thaw) would greatly help in solving this sort of problem. The getopt()' coroutine would be instantiated with an argument vector, then be (co)invoked once per argument. Semantic error notifications could be conveyed back to getopt()' via the (co)returns. (In fact the Sys V getopt() routine does approximate this approach by using external variables and a bizarre calling convention. It just doesn't generalize.) Just another simple example of where coroutines can simplify things... Stan Switzer sjs@ctt.bellcore.com -or- bellcore!ctt!sjs
rouilj@umb.umb.edu (John P. Rouillard) (04/05/88)
The folowing structure allows a generic function to parse any cconcevable command line. The structure would have the form: struct command_entry { struct command_entry * next, /* for a linked list of these babies */ char *NAME, /* the full name of the option */ char *ABBREV, /* the shortest abbreviation for the option */ char *ARG_TYPE, /* the type of argument (string, char, int, float ...) char *format_type, /* Keyword = value, +keyword, -keyword ... */ type *VARIABLE_addr, /* the address of a variable to set */ enum v_type VAR_type, /* the type of the variable above */ int **FUNCTION_addr(), /* address of a function returning a pointer to int */ enum f_type FUNCT_type, /* the type the function actually returns */ int *Error_handler(), /* Your own personal error handler */ add you favorite options here }; a possible entry would be: (from the command make (augmented for show ) { NAME "file", ABBREV "f", ARG_TYPE string, /* ie char * */ format_type "-w" /* specifing "-"f and w signifies space between keyword and value */ VARIABLE_addr &makefile_name, VAR_type String, FUNCTION_addr NULL, /* not function needed */ FUNCT_TYPE NULL /* the type of a nonexistant function */ } This structure would allow: a: A long name that would be able to be abbreviated to the value in ABBREV. b: Handling multi character flags without values (I.E. "-las" in "ls -las") Simply loop over each character and set the appropriate flag. c: Whitespace elimination (I.E. -Kvalue) is easily done the value up to the next whitespace character is scanned according to its type. d: The setting of a variable to an argument value or if a function is specified the setting of the variable to the pointer value returned by the function. (The variable at the VARIABLE_addr is interpreted according to the value in VAR_type so appropriate casts can be made.) e: The ability to handle special parsing of the command line via calls to a function that takes 1) current argv location, 2) argc and 3) the address of the command_entry list as arguments. f: For those values that are multiples on the command line (i.e. multiple filenames), the function specified in the command_entry could create a list of the names (copying them if desired) and then have the variable in the command_entry point to the head of the list. g: Optionally to setting other variables, the values could be returned in the command_entry structure itself (maybe via a union in the struct??). h: The ability to specify in the command entry an error routine specific for the particular option being parsed. i: By adding the flexibility of calling a function to deal with funky parts of the command line the function to parse the command line will return only when it has parsed the whole command line thus eliminating the problem of dealing with the unparsed command line namely because it is an error [probably fatal] for it not to parse the whole command line. j: The command_entries could be created dynamically during runtime, or declared statically at compile time. k: The driver for Options_please (the get_ops lookalike ) would act similiarly to a LR or LL parser driver with a parse table (the linked list of command_entries). The driver is easy to maintain with all of the work actualy done during the creation of the parse tables. BUGS: a: This data for the command_entries could take up a lot of space and therefore may be troublesome. b: The second problem occurs because of the ambiguity in the command language. Please follow my description below: Assume we have defined: A keyword Kval that can have an optional argument, and boolean keywords (flags either on or off) "u" and "e". How do we parse "-Kvalue". Is it Kval with argument "ue" or is it Kval with no arguments and the boolean flags "u" and "e". If we allow eliding of whitespace between flag and value it is impossible to tell which is meant. By doing away with 'c' above we can then parse this as Kval with no arguments. Another ambiguity arises if we decide on having an argument that can be abbreviated "K" (Kval needs all four letters) and other arguments "v", "a", and "l". Now how does the above string parse: The boolean "K" the boolean "v" no wait those two letters are the prefix for Kval (ARRGH ;-[) (HELP LR GRAMMAR) Richard Harter also touched on this ambiguity problem in his article. This is a problem that is inherant with features a,b above. One way around this is to make sure that you never use the letters K,v,a, and l :-). A second way around the problem is to make the order of the keyword in the list of command_entries significant and therefore impart an priority to the commands. In the above example: if Kval appeared before K (which it would have to do in order to have Kval called at all) the interpretation of the flag Kval would occur first. A third way around it is to write the table such that no two command_entries have overlaping differences. The fourth way is to write a function that will allow the handling of this via look-ahead or whatever mechanism you devise. Basically you turn an NFA into a DFA by combining states. E.G. if a K was found a function would be called that would try to determine if the value was Kval or if the value was K followed by random characters. If you think this stuff was handled in The Dragon Book You are right on the money. But note the thing that causes all of the problems is allowing names and having possibly non-unique representations for every string that can be generated. However this facility seems to be the only way to even attempt generality and allow a way of working around the problem. PLEASE NOTE: that this is only an idea and I would like feedback on it. Please feel free to steal the idea and modify it as necessary. Sorry it is so long but I was trying to reply to everybodues favorite must haves. What do I know I am only a Physics major? ========================================================================== The opinions expressed above are all mine and belong to nobody else. To U-Mass I am just a number. E = M C**2 Not just an equation a way of life. John Rouillard U.S. Snail: Physics Department U-Mass Boston U-Mass Boston Physics Major Harbor Campus Boston, MA 02125 UUCP: harvard!umb husc6!umb
peter@athena.mit.edu (Peter J Desnoyers) (04/05/88)
I finally remembered the operation of the argument parser I mentioned in a previous posting. It was used as follows: [pretend 1-column text] #define OPT 0 optarray[OPT] = { "O", "Optimize", BOOLEAN}; #define MAXERR 1 optarray[MAXERR] = { "m", "maxerr", DECIMAL}; #define LIST 2 optarray[LIST] = { "l", "list", STRING}; This was usually done in the .h file for the main module. Then you would call get_args( argc, argv [,optarray?]) and it would shove everything into a global, but hidden, array. Finally, you would reference the resulting values with macros, sort of like: if (SET_P( LIST)) /* works for -l=list.out */ list_file = fopen( VALUE( LIST),"w"); /* and -list=list.out */ compile( ARG( 1)); /* handles args mixed with opts */ if (++errnum > VALUE( MAXERR)) /* parsed decimal value */ go_up_in_flames(); /* -maxerr=10, -m=10 */ if (SET_P( OPT)) /* simple flag '-O' */ go_off_and_optimize(); and suchlike. The global arrays were a kludge, but you need some type of sort-of-global flag for something like -O, and it will probably be a kludge, anyway. The only problem was that it wasn't re-entrant, and it supported a weird argument-passing style. (sort of like VMS but with '-' instead of '/'.) Peter Desnoyers peter@athena.mit.edu
bader+@andrew.cmu.edu (Miles Bader) (04/06/88)
g-rh@cca.CCA.COM (Richard Harter) writes: > o It is desirable that the argument processor be able to handle > untokenized argument strings. The reason for bringing this up > is that our current processor can do this. In applications with > an interpretive command processor, the parser for the interpreter > may not necessarily follow unix parsing command line parsing rules. Write a separate string tokenizer. > o When getopt processes an option with a value it returns a pointer > to a location within a string that it is passed. The assumption > is made that this string is null terminated at the right place. > No copy of the string is made. My opinion is that the argument > processor should generate a copy of the string or value. This > is relevant in the case of an interpretive command processor -- > the original token string may vanish. Again, you can do this outside the arg processor, in those cases where you need to keep the actual string. In many cases you don't. -Miles
ado@elsie.UUCP (Arthur David Olson) (04/07/88)
Here are three things I want from a command line option handler. 1. I want all the information about a particular option to appear in one place. So instead of an interface where I set up a table such as > static Option desc[] = { > O_flg ('f', flag), > O_int ('i', number), > O_str ('s', string), > O_chr ('c', character), > O_dbl ('d', dbl), > O_directive ("remaining: 1-2"), > O_directive > ("usage: [-f] [-i nn] [-cC] [-d float] [-s string] src [dst]"), > O_end, > }; (see the referenced article), I want an interface where I set up a table such as static Option desc[] = { O_flg('f', flag), O_int('i', number, "nn"), O_str('s', string, "string"), O_chr('c', character, "C"), O_dbl('d', dbl, "float"), O_directive("remaining: 1-2", "src [dst]"), O_end, }; This helps ensure that usage messages match what the program actually does, and eases the business of conditionally compiling options into a program. 2. I want some uniform way of getting programs to output their usage messages. Here at elsie, the convention we use is that if a (locally written) program's only argument is "=", as in the command line zic = or zic -l = (for the benefit of csh/ksh aliasing fanatics) the program outputs its usage message. The particular convention used is unimportant to me; what counts is having a uniform way to ask for the usage message, and an easy way to achieve uniformity is to push the logic into the command line option handler. 3. I want to be able to find out if "--" was used on the command line. Pike's Position is that Programs that accept multiple filenames should do nothing if given no arguments. (The name and wording are mine; see page 186 of "The UNIX Programming Environment" for details.) This ensures that if you use a command such as cat `find * -type f -print` to concatenate all the files in a directory and its subdirectories, you won't get surprised when there are NO files in the directory and cat starts reading from its standard input. My preference is to provide a uniform way of telling programs that you want them to do nothing if there are no arguments; one way I see of doing this is to use the presence of "--" on the command line for that purpose. So, for example, you'd cat -- `find * -type f -print` to avoid having cat do anything if find didn't find any files. With such a mechanism in place, you can avoid having to write cat - when you want to use cat as a filter, and still avoid surprises when you want to give cat a (potentially empty) list of file names. -- ado@ncifcrf.gov ADO is a trademark of Ampex.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/08/88)
In article <8039@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes: >I want some uniform way of getting programs to output their usage messages. Under the existing getopts scheme, typing command -? is guaranteed to get the usage message.
ado@elsie.UUCP (Arthur David Olson) (04/08/88)
> > I want some uniform way of getting programs to output their usage messages. > > Under the existing getopts scheme, typing > command -? > is guaranteed to get the usage message. A problem and a two questions. First, the problem: Script started on Thu Apr 7 18:51:58 1988 $ grep UNIX /vmunix 4.3 BSD UNIX #25: 12/12 02:45:12 PM $ man getopts No manual entry for getopts. $ exit script done on Thu Apr 7 18:52:34 1988 Second, the questions. Is a public-domain implementation of "the existing getopts scheme," or at least a public-domain manual page, available? And is the scheme idiot-proof enough to work when executed in directories with files named, for example, "-l"? -- ado@ncifcrf.gov ADO is a trademark of Ampex.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/08/88)
In article <8040@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes: >> > I want some uniform way of getting programs to output their usage messages. >> Under the existing getopts scheme, typing >> command -? >> is guaranteed to get the usage message. >A problem and a two questions. First, the problem: > No manual entry for getopts. "getopts" is a builtin in the SVR3 and later shells; it is also built into the current BRL version of the SVR2 shell. I was actually referring to the getopt() library function, since that's what the ongoing discussion was about. A command that uses getopt() will branch to the "error case" if you use the ? flag option. The normal response in the error case is to print a usage message. >Second, the questions. Is a public-domain implementation of "the existing >getopts scheme," or at least a public-domain manual page, available? AT&T placed the getopt() source code, its manual page, the now-obsolete "getopt" utility, and its manual page into the public domain a few years ago. You can get this free from the AT&T UNIX System ToolChest, and I believe it was posted to one of the sources newsgroups. I typed up a "getopts" shell builtin manual page that I can send you, if you can't find it in UNIX System V Release 3 documentation. >is the scheme idiot-proof enough to work when executed in directories with >files named, for example, "-l"? If you have reason to believe that your command may have to handle non-option arguments with names starting with -, then follow the options with the -- option, which causes getopt() to stop interpreting arguments as options.
lew@gsg.UUCP (Paul Lew) (04/08/88)
In article <7628@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > > Under the existing getopts scheme, typing > command -? > is guaranteed to get the usage message. Why use '?' character? I especially hate to type: command '-?' to avoid '?' to be expanded by shell. In Bourne shell, if you dont have any file like: -a, -x then -? will work without quoting. This is not true for csh. Choosing something that is not a special character might have less problem running on different environment. How about -H instead? Any program uses -H beside sysline? -- Paul Lew {oliveb,harvard,decvax}!gsg!lew (UUCP) General Systems Group, 5 Manor Parkway, Salem, NH 03079 (603) 893-1000
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/09/88)
In article <143@gsg.UUCP> lew@gsg.UUCP (Paul Lew) writes:
-Why use '?' character? I especially hate to type: command '-?' to avoid
-'?' to be expanded by shell. In Bourne shell, if you dont have any file
-like: -a, -x then -? will work without quoting. This is not true for csh.
-Choosing something that is not a special character might have less problem
-running on different environment. How about -H instead? Any program uses
--H beside sysline?
You miss the point; -? already has the desired property; it does not
have to be explicitly added to every application. I'm sorry if you
choose to use a shell that makes this too difficult to type.
mouse@mcgill-vision.UUCP (der Mouse) (04/09/88)
In article <2414@zyx.UUCP>, aj@zyx.UUCP (Arndt Jonasson) writes: > This is a suggestion for a command line parsing routine for C > programs in Unix. > I post this [suggestion] in the hope of getting constructive comments > on what features are missing in my scheme, and whether it is perhaps > too restrictive or too general [...]. Well, I can't say how constructive you will find these comments, but here's a critique of what I dislike in what you've said. (In the usual tradition of criticism, I'll ignore the points you've mentioned that I like. :-) > 'O_parse_options' uses the same model as 'getopt', i.e. first come > the options, preceded by hyphens (they may be grouped together after > one hyphen), then come the non-option arguments. How does one model an option which behaves like tar's -C or ld's -l, which can appear (almost) anywhere and whose position is significant? > If an option -s takes an argument, both '-sfoo' and '-s foo' are > valid. So you can group options on one hyphen - unless one of them takes an argument. Ugly inconsistency. Also unpleasant: you can't use both methods when the argument is to be a null string: foo -s '' -b - works foo -s'' -b - doesn't work > It will either successfully parse all the options and store values in > the appropriate variables, or exit the program with an error message. I want the option of handling the error myself. Perhaps I don't want to print a usage message; perhaps I want a usage message that looks different from yours; perhaps I want to produce the message on stdout instead; perhaps I want to ignore the offending option; perhaps I want to ignore the offending option depending on what it is.... How do you model the tar/dump/ar or dd styles of arglist? I wrote a program a while back which took an option -F, which required a following filename, as in % foo -F xyzzy except that the result was more verbose if the -F was doubled: % foo -FF xyzzy How would I model this? der Mouse uucp: mouse@mcgill-vision.uucp arpa: mouse@larry.mcrcim.mcgill.edu
bzs@bu-cs.BU.EDU (Barry Shein) (04/09/88)
From: gwyn@brl-smoke.ARPA (Doug Gwyn ) >You miss the point; -? already has the desired property; it does not >have to be explicitly added to every application. I'm sorry if you >choose to use a shell that makes this too difficult to type. Oh, brilliant idea. I just tried it under bourne shell and if you happen to have a file that starts with a dash then you lose also as it expands. Nothing like magical behavior in a HELP command... ..hmm, lessee, how do I get rid of this stupid file "-r" in my directory? guess I'll just use help...oops... lose lose. My candidate for this year's cream-pie-in-the face award for dumb user interface designs. -Barry Shein, Boston University
guy@gorodish.Sun.COM (Guy Harris) (04/09/88)
> You miss the point; -? already has the desired property; it does not > have to be explicitly added to every application. That's news to me; if you're talking about the "getopt()" subroutine, you must be talking about an implementation other than the System V Release 3.1 implementation, because that one sure doesn't cons up a usage message for you if you provide the '-?' option. In fact, I can't see how it *can* cons up a complete usage message; the best it can do is tell you what options it expects - it can't tell you that it expects two file names, a number from 1 to 10, and the air speed of a laden swallow. While the code to *recognize* '-?' doesn't have to be explicitly added to every application using "getopt()", the code to respond to it and print a usage message does. > I'm sorry if you choose to use a shell that makes this too difficult to type. Relying on the Bourne/Korn shell not expanding some string containing a pattern-matching metacharacter because you "know" there are no files that match that string is dangerous (although I do it anyway...). You may someday find that there *is* such a file.
ado@elsie.UUCP (Arthur David Olson) (04/09/88)
> > is the scheme idiot-proof enough to work when executed in directories with > > files named, for example, "-l"? > > If you have reason to believe that your command may have to handle > non-option arguments with names starting with -, then follow the > options with the -- option, which causes getopt() to stop interpreting > arguments as options. I clearly wasn't clear enough here. Let's say I have a command "-w" in my "bin" directory that I use as a shorthand for "chmod -w", and a command "-x" that I use as a shorthand for "chmod -x". (And yes, this is a real-life example). Now watch what happens with two different uses of "od -?": one in my home directory, and one in my bin directory: Script started on Fri Apr 8 19:59:31 1988 $ od -? od: bad flag -? usage: od [-abcdfhilopswvx] [file] [[+]offset[.][b] [label]] $ cd bin ./bin $ ls -w ls patch tclots uusnap -x mail ream tint vhf fit make rumors tip vnews gel3d mo shar ttyuse who headlines morebug stats uchist zap io narrow sysline unlj zget j nm tc uu linch pairsizes tclint uulast $ od -? 0000000 020443 027440 064542 027556 064163 005012 060543 062563 022040 020060 067151 004412 074055 026574 076167 074053 0000040 025574 024567 061411 066557 060555 062156 022075 020060 035473 004412 027452 074053 004451 061411 066557 060555 0000100 062156 025475 020170 035473 004412 027452 074055 004451 061411 066557 060555 062156 060475 074055 035440 005073 0000140 025011 025457 024567 004411 067543 066555 067141 036544 073453 035440 005073 025011 026457 024567 004411 067543 0000200 066555 067141 036544 026541 020167 035473 004412 024452 004411 067543 066555 067141 036544 061140 071541 067145 0000240 066541 020145 030044 020140 035473 062412 060563 005143 061412 071541 020145 021444 030444 064440 005156 030011 0000300 030574 024475 062411 064143 020157 022042 067543 066555 067141 035144 072440 060563 062547 064440 020163 061444 0000340 066557 060555 062156 063040 066151 027145 027056 020042 037061 031046 004412 062411 064570 020164 020061 035473 0000400 062412 060563 005143 062412 062570 020143 064143 067555 020144 061444 066557 060555 062156 021040 040044 005042 0000440 $ exit script done on Fri Apr 8 19:59:49 1988 The first time around I get the right result--a usage message. The second time, though, the contents of "-x" is dumped in wide format. Moral of the story: using "-?" to try to get messages sometimes won't work. That's why we use "=" here at elsie. -- ado@ncifcrf.gov ADO is a trademark of Ampex.
ok@quintus.UUCP (Richard A. O'Keefe) (04/09/88)
In article <48917@sun.uucp>, guy@gorodish.Sun.COM (Guy Harris) writes: > > You miss the point; -? already has the desired property; it does not > > have to be explicitly added to every application. > > Relying on the Bourne/Korn shell not expanding some string containing a > pattern-matching metacharacter because you "know" there are no files that match > that string is dangerous (although I do it anyway...). You may someday find > that there *is* such a file. This is more of a UNIX issue than a C issue by now (or do DEC now ship getopts with VMS?). As a UNIX issue, it should be pointed out that as a time-honoured hack for protecting important directories, some people create an empty file called "-i", so that an rm * command will turn into rm -i {everything else} So files matching "-?" are quite likely to exist. Me? Use an appalling hack like that? Only sometimes.
ekrell@hector.UUCP (Eduardo Krell) (04/09/88)
In article <8041@elsie.UUCP> ado@elsie.UUCP writes: >The first time around I get the right result--a usage message. The second >time, though, the contents of "-x" is dumped in wide format. That's because the shell is expanding -? to "-w -x". If there is no match, the shell leaves the -? alone. Eduardo Krell AT&T Bell Laboratories, Murray Hill, NJ UUCP: {ihnp4,ucbvax}!ulysses!ekrell ARPA: ekrell@ulysses.att.com
guy@gorodish.Sun.COM (Guy Harris) (04/10/88)
> >The first time around I get the right result--a usage message. The second > >time, though, the contents of "-x" is dumped in wide format. > > That's because the shell is expanding -? to "-w -x". If there is no > match, the shell leaves the -? alone. I think he already knew that - that was his whole point! He gave a real, not a hypothetical, case where the shell *will* expand "-?" to something, rather than leaving it alone, and therefore where "-?" won't do what it has, on occasion, been claimed to do. "-?" is *NOT* guaranteed to give you a usage message, with *ANY* shell, unless you put it in quotes.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/10/88)
In article <21370@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: >Oh, brilliant idea. I just tried it under bourne shell and if you >happen to have a file that starts with a dash then you lose also as it >expands. Nothing like magical behavior in a HELP command... > ..hmm, lessee, how do I get rid of this stupid file "-r" > in my directory? guess I'll just use help...oops... >lose lose. My candidate for this year's cream-pie-in-the face award >for dumb user interface designs. Maybe there is no such thing as a good interface for dumb users. Or perhaps dumb users should be encouraged to put '' around EVERY argument to every command, since they don't know what is a special shell metacharacter and what isn't. Personally I don't keep files around with names starting with -.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/10/88)
In article <8041@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes: >Moral of the story: using "-?" to try to get messages sometimes won't work. >That's why we use "=" here at elsie. -? always works, but if your shell interprets ? as a metacharacter AND if you have files with 2-character names starting with -, you're advised to quote the ? character. = is the name of a useful file on 8th Edition UNIX, so the same argument could be made against its use for help, as well as the additional observation that -? functions as a help request as a serendipitious side-effect of the design of getopt(), so that it already is supported and neither applications nor getopt() need to be changed to use it.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/10/88)
In article <48917@sun.uucp> guy@gorodish.Sun.COM (Guy Harris) writes: >In fact, I can't see how it *can* cons up a complete usage message; the best it >can do is tell you what options it expects - it can't tell you that it expects >two file names, a number from 1 to 10, and the air speed of a laden swallow. >While the code to *recognize* '-?' doesn't have to be explicitly added to every >application using "getopt()", the code to respond to it and print a usage >message does. $ ls -? ls: illegal option -- ? usage: ls -RadCxmnlogrtucpFbqisfL [files] The particular usage message produced depends entirely on what the implementor of the application decided was the appropriate response to an illegal option. (This is the "case '?':" section of the code, which should always exist because getopt() returns '?' for any illegal option.) You may think that the "ls" implementor should have provided more help than that. On UNIX, it is generally assumed that you just need to be reminded what the correct syntax is; if you need more help you're expected to use the "man" command to read the on-line manual entry. In other environments it may indeed be appropriate to have a verbose usage message. My point is that there is already the necessary hook for this under the present getopt() scheme; nothing needs to be changed to use it.
bzs@bu-cs.BU.EDU (Barry Shein) (04/10/88)
From Doug Gwyn... >Maybe there is no such thing as a good interface for dumb users. > >Or perhaps dumb users should be encouraged to put '' around EVERY >argument to every command, since they don't know what is a special >shell metacharacter and what isn't. > >Personally I don't keep files around with names starting with -. Or maybe, just maybe, we agree that using -x where 'x' is a shell meta-character is not a good idea for a standard, universal flag to appear in every Unix command as the help/usage flag. C'mon, I ain't talking dumb users, that's annoying to anyone and a design embarrassment. You've never even accidently found you've created a file with a name starting with dash? I have, maybe I'm a dumb user. I can't believe this needs argument, using a shell meta-character as a flag for help with a command's usage, it's unbelievable, it's textbook case bad design, I'll use it in my next systems class lecture on Tuesday, it's a wonderful example of how *not* to design something. What's wrong with using "-help" as a special case? Perhaps even with an option to pass it back and let the calling program handle the help, actually that could be handled by just having getopt() define a function usage() and letting the user define his/her own to override. -Barry Shein, Boston University
bzs@bu-cs.BU.EDU (Barry Shein) (04/10/88)
From Doug Gwyn >= is the name of a useful file on 8th Edition UNIX, so the same argument >could be made against its use for help, as well as the additional >observation that -? functions as a help request as a serendipitious >side-effect of the design of getopt(), so that it already is supported >and neither applications nor getopt() need to be changed to use it. Oh, now there you got us. Let's not concern ourselves with csh because that's merely the shell of choice among any vendors actually selling Unix. Noooo...let's make sure the thing doesn't conflict with nits on 8th Edition Unix. Now there's a universal concern, there must be almost a dozen computers running 8th Edition! My point is not to disparage 8th Edition, but how in the hell can you say it doesn't matter what conflicts with csh but 8th Edition must get its due? And besides, ? is a meta-character in Bourne, Ksh and Csh last I checked. -Barry Shein, Boston University
les@chinet.UUCP (Leslie Mikesell) (04/10/88)
In article <864@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >In article <48917@sun.uucp>, guy@gorodish.Sun.COM (Guy Harris) writes: >> > You miss the point; -? already has the desired property; it does not >a time-honoured hack for protecting important directories, some people >create an empty file called "-i", so that an > rm * >command will turn into > rm -i {everything else} >So files matching "-?" are quite likely to exist. If a person knows enough about shell behaviour to create such a hack he should also know enough to quote the "-?" to prevent expansion. On the other hand, I would be more sympathetic toward a novice that accidentally managed to create a file named -? and wondered why the * no longer worked at all. Les Mikesell
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/10/88)
In article <21419@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: >What's wrong with using "-help" as a special case? I explained how you could exploit a feature that is ALREADY PRESENT and you keep missing the point. -help does not currently work.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/10/88)
In article <21420@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: >From Doug Gwyn >>= is the name of a useful file on 8th Edition UNIX, so the same argument >>could be made against its use for help, ... >My point is not to disparage 8th Edition, but how in the hell can you >say it doesn't matter what conflicts with csh but 8th Edition must get >its due? Of course it's a stupid argument, but no more so than yours. It doesn't matter what conflicts with csh because nobody in his right mind would use csh. Is that better?
dave@sdeggo.UUCP (David L. Smith) (04/10/88)
In article <7639@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > In article <21370@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: > >Oh, brilliant idea. I just tried it under bourne shell and if you > >happen to have a file that starts with a dash then you lose also as it > >expands. Nothing like magical behavior in a HELP command... > > ..hmm, lessee, how do I get rid of this stupid file "-r" > > in my directory? guess I'll just use help...oops... > >lose lose. My candidate for this year's cream-pie-in-the face award > >for dumb user interface designs. > > Maybe there is no such thing as a good interface for dumb users. > > Or perhaps dumb users should be encouraged to put '' around EVERY > argument to every command, since they don't know what is a special > shell metacharacter and what isn't. > > Personally I don't keep files around with names starting with -. Geez Doug, get up on the wrong side of the keyboard? I don't keep files around that start with - either, but I have created them by mistake on occasion. If we're not perfect we shouldn't be allowed to us Unix? The point here is that it's stupid to make something that should be used commonly (the -? to get usage) be confusing and frustrating to use. We've already gone through it with ! style mail addressing when using csh (and @ style addressing when your erase characters are set to the old defaults of "@" for kill line). There's a basic flaw in this little scheme, why doesn't everyone just admit it and come up with a better idea? -- David L. Smith {sdcsvax!jack,ihnp4!jack, hp-sdd!crash, pyramid, uport}!sdeggo!dave sdeggo!dave@amos.ling.edu Sinners can repent, but stupid is forever.
friedl@vsi.UUCP (Stephen J. Friedl) (04/11/88)
In article <191@sdeggo.UUCP>, dave@sdeggo.UUCP (David L. Smith) writes: > In article <7639@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > > > > Personally I don't keep files around with names starting with -. > > > Geez Doug, get up on the wrong side of the keyboard? I don't keep files > around that start with - either, but I have created them by mistake on > occasion. If we're not perfect we shouldn't be allowed to use Unix? I don't want to get into the discussion on command line arg processors, and this is not directed to either of the above net.readers. For those wondering a good way to deal with files beginning with a `-', prefix the filename with `./': $ rm ./-silly.file $ cat ./-silly.file This works for many of the cases where the command simply will not talk to a file starting with a dash. -- Steve Friedl V-Systems, Inc. "Yes, I'm jeff@unh's brother" friedl@vsi.com {backbones}!vsi.com!friedl attmail!vsi!friedl
ford@kenobi.UUCP (Mike Ditto) (04/11/88)
Posting-Front-End: GNU Emacs 18.41.10 of Fri Oct 2 1987 on kenobi (usg-unix-v) In article <48963@sun.uucp> guy@gorodish.Sun.COM (Guy Harris) writes: > > That's because the shell is expanding -? to "-w -x". If there is no > > match, the shell leaves the -? alone. > > I think he already knew that - that was his whole point! He gave a > real, not a hypothetical, case where the shell *will* expand "-?" > to something, rather than leaving it alone, and therefore where "-?" > won't do what it has, on occasion, been claimed to do. > > "-?" is *NOT* guaranteed to give you a usage message, with *ANY* > shell, unless you put it in quotes. I think everybody already knew that - "-?" is *NOT* guaranteed to do *ANYTHING* in particular unless you put it in quotes. That's why it makes a good choice for a help option: it's too awkward ever to be used for a normal option, so you might as well reserve it for those times when you want a usage and you have no idea what options are valid. Of course, people who often find themselves needing help won't like the awkwardness of typing the quotes, but I think it's quite reasonable. -\? also works (less typing). -=] Ford [=- "Once there were parking lots, (In Real Life: Mike Ditto) now it's a peaceful oasis. ford%kenobi@crash.CTS.COM This was a Pizza Hut, ...!sdcsvax!crash!kenobi!ford now it's all covered with daisies." -- Talking Heads
bzs@bu-cs.BU.EDU (Barry Shein) (04/11/88)
Doug Gwyn writes >In article <21419@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: >>What's wrong with using "-help" as a special case? > >I explained how you could exploit a feature that is ALREADY PRESENT >and you keep missing the point. -help does not currently work. I don't miss the point, I don't see the difficulty in fixing something that's broken: if(strcmp(flag,"-help") == 0) return(usage()); /*usage() can be redefined by the programmer*/ I don't find the fact that -? (or -\? or '-?') happens to work wonderfully compelling, I guess you do, so we disagree. Ok, let me put it this way, if -? happens to work, fine, I wouldn't suggest undoing it (I assume -* and -[ and -] etc work also) but if one line of code is touched to codify that idea it ought to be something like I suggest and shell metacharacters should be avoided in getting help. It wouldn't undo the original idea, just make it useful. -Barry Shein, Boston University
guy@gorodish.Sun.COM (Guy Harris) (04/11/88)
> The particular usage message produced depends entirely on what the > implementor of the application decided was the appropriate response > to an illegal option. The usage message might very well be "bad syntax". I don't think this is a *good* usage message, but the point is that you're not *guaranteed* to get a usage message from '-?'. You may be *likely* to get one, but you're certainly not guaranteed to get one. The *only* thing that sets '-?' apart from any other convention is that "getopt()" returns '?' when it sees a syntax error. Were it not for the fact that "?" is a shell meta-character, this would give this convention a leg up as you don't have to put in any additional code to recognize "-?". However, each individual implementor still has to put in code to do something useful with this option. Yes, doing so is a good idea. So is using "perror" or "sys_errlist[]" to print error messages, and *that* idea seems to be ignored by all too many UNIX utilities. Just saying that implementers *should* do something does not mean that they will. > My point is that there is already the necessary hook for this under > the present getopt() scheme; nothing needs to be changed to use it. Other than user's habits; they have to remember to quote the '-?' any time there is any chance that it *might* expand to something. As Arthur Olson pointed out, this is *not* a hypothetical situation.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/11/88)
In article <191@sdeggo.UUCP> dave@sdeggo.UUCP (David L. Smith) writes: >There's a basic flaw in this little scheme, why doesn't >everyone just admit it and come up with a better idea? There is NOT a basic flaw in the scheme; I use it all the time and it works much better than the suggested alternatives (which DON'T WORK AT ALL because they are not currently implemented!). Note that I didn't have to do anything to have this feature available; it's already there. I thought you might like to hear about it so as to be able to exploit it, but feel free to not use it while you work on some grandiose scheme that practically nobody will adopt (as Henry has pointed out). If you think the existence of shell metacharacters is a "basic flaw", well perhaps it is if you plop naive users in front of a terminal running a raw Bourne shell or csh. They were not intended to serve as naive-user interfaces. Somehow I don't have trouble with this even when using the -? trick.
ed@mtxinu.UUCP (Ed Gould) (04/11/88)
Doug Gwyn: >You miss the point; -? already has the desired property; it does not >have to be explicitly added to every application. I'm sorry if you >choose to use a shell that makes this too difficult to type. Actually, I think that you miss the point. What shell do you use that doesn't expand -? when it matches a file name? The point is that this use in getopt() abuses an existing construct. -- Ed Gould mt Xinu, 2560 Ninth St., Berkeley, CA 94710 USA {ucbvax,uunet}!mtxinu!ed +1 415 644 0146 "`She's smart, for a woman, wonder how she got that way'..."
flaps@utcsri.UUCP (Alan J Rosenthal) (04/11/88)
Suppose you have a command, and it has a -h option which takes a filename argument, as in "command -h file". This is certainly reasonable. Suppose you have a file in your current directory named `elp'. This is not a weird file name. Suppose you therefore invoke the command as "command -h elp" or "command -help". Amusing, but syntactically correct. In article <21419@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: >What's wrong with using "-help" as a special case? This. The above command, although it worked fine for files `ela' through `elo', doesn't work for `elp'. In general, unix options are too terse to be likely to have a syntactic hole large enough to put a whole word through. We should be grateful that the implementation of getopt() guarantees (accidently, I'm sure) that "command '-?'" works. ajr -- "Don't put things you find on the street into your mouth."
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/11/88)
In article <583@mtxinu.UUCP> ed@mtxinu.UUCP (Ed Gould) writes: >Actually, I think that you miss the point. What shell do you use that >doesn't expand -? when it matches a file name? The point is that this >use in getopt() abuses an existing construct. Ok, so use -, instead of -? if you have problems with the latter. The only reason I called it -? is that I KNOW that ? is not a possible getopt() option, whereas with , you're just relying on the utility designer being moderately sane. I don't consider exploiting features of a design to necessarily be abusing anything. Otherwise almost all of UNIX would be one big abuse.
ado@elsie.UUCP (Arthur David Olson) (04/11/88)
> Ok, so use -, instead of -? if you have problems with the latter.
Or, for that matter, use -=, a la
findspots -=
Is this a technique that everyone can agree with?
--
ado@ncifcrf.gov ADO is a trademark of Ampex.
chip@ateng.UUCP (Chip Salzenberg) (04/11/88)
What's so hard about typing '-\?' to get help? I do it all the time. And it works in any shell and despite strangely named files. BTW, the argument against '-?' that goes "but what if I have a file named '-r'" is not very strong, since such a file kills you even if you don't ask for help: % ls -F -r foo bar important/ % rm * [pronounced "rim splat", by the way] % ls % [anguished scream] Kaboom. For those of you who want to make your programs a bit safer to use than rm, here is an idea: Before parsing for options, check to see if any arguments that begin with '-' are actually the names of existing files. If they are, emit a suitably alarming warning message and enable the "interactive" option so the user has a chance to back out. And if you see an argument '--', check to see if a file by that name exists, then stop looping since the rest of the arguments are not options. Of course, this gets complicated by a call to isatty(), since you don't want a cron task waiting for operator input; so perhaps this ends up being more of a kludge than a safety belt. But if your program is sufficiently destructive, CYA is a worthwhile policy. -- Chip Salzenberg "chip@ateng.UU.NET" or "codas!ateng!chip" A T Engineering My employer's opinions are a trade secret. "Anything that works is better than anything that doesn't."
dave@sdeggo.UUCP (David L. Smith) (04/11/88)
In article <7652@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > In article <191@sdeggo.UUCP> dave@sdeggo.UUCP (David L. Smith) writes: > >There's a basic flaw in this little scheme, why doesn't > >everyone just admit it and come up with a better idea? > > There is NOT a basic flaw in the scheme; I use it all the time > and it works much better than the suggested alternatives (which > DON'T WORK AT ALL because they are not currently implemented!). > Note that I didn't have to do anything to have this feature > available; it's already there. I thought you might like to hear > about it so as to be able to exploit it, but feel free to not > use it while you work on some grandiose scheme that practically > nobody will adopt (as Henry has pointed out). I don't see anything grandiose about adding "-HELP" into getopt and having that return a '?' to the calling program. Do you? This would only require recompilation to work. I doubt there are many existing programs that use this for anything other than help, it doesn't conflict with any metacharacters and it would be very easy to implement. The "-?" would not be useful with those programs like sed and grep which process regular expressions. > If you think the existence of shell metacharacters is a "basic > flaw", well perhaps it is if you plop naive users in front of > a terminal running a raw Bourne shell or csh. They were not > intended to serve as naive-user interfaces. Somehow I don't > have trouble with this even when using the -? trick. This is _not_ what I said. Overloading these operators in fifteen different ways is a problem. We have too many overloaded shell operators as it is. Why make more trouble? Maybe I'm just not as smart or as nimble-fingered as you are Doug, but I forget to quote things sometimes, or the \ key sticks after I press it the fifth time in a row in a single command line. I appreciate the shells' power, and hence their complexity, but there is no need to add needless complexity. -- David L. Smith {sdcsvax!jack,ihnp4!jack, hp-sdd!crash, pyramid, uport}!sdeggo!dave sdeggo!dave@amos.ling.edu Sinners can repent, but stupid is forever.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/12/88)
In article <192@sdeggo.UUCP> dave@sdeggo.UUCP (David L. Smith) writes: > I don't see anything grandiose about adding "-HELP" into getopt and having > that return a '?' to the calling program. Do you? This would only require > recompilation to work. It won't work at all! -HELP already has a standard meaning and getopt() supports it: this is equivalent to -H -E -L -P. > The "-?" would not be useful with those programs like sed and grep which > process regular expressions. Sure it would, so long as they follow the command syntax standard. In fact it ALREADY is useful with such commands.
levy@ttrdc.UUCP (Daniel R. Levy) (04/12/88)
In article <8043@elsie.UUCP>, ado@elsie.UUCP (Arthur David Olson) writes: # > Ok, so use -, instead of -? if you have problems with the latter. # # Or, for that matter, use -=, a la # findspots -= # Is this a technique that everyone can agree with? All youse guys are missing the REALLY illegal, non-wildcard getopt option. It is ":". (Think of the way that the list of possible options is passed to getopt and you'll know why.) -- |------------Dan Levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an Engihacker @ | <most AT&T machines>}!ttrdc!ttrda!levy | AT&T Data Systems Group | Disclaimer? Huh? What disclaimer??? |--------Skokie, Illinois--------|
bzs@bu-cs.BU.EDU (Barry Shein) (04/12/88)
From Doug Gwyn... >It won't work at all! -HELP already has a standard meaning and getopt() >supports it: this is equivalent to -H -E -L -P. Good point, absolutely correct and would introduce other mysteriousness. Gee, I'm glad we air these things in public. Howsabout '-=' ? (or is that "Howsabout -= =") -Barry Shein, Boston University
dhesi@bsu-cs.UUCP (Rahul Dhesi) (04/12/88)
gwyn@brl-smoke.ARPA (Doug Gwyn ): > > ...if you plop naive users in front of > > a terminal running a raw Bourne shell or csh. They were not > > intended to serve as naive-user interfaces. Delving into my old UNIX documentation, I find that naive users were expected to sometimes use ed as a user interface. That's right, raw ed. I think the Bourne shell *was* intended to be a naive-user interface, though it's admittedly a terrible one. The later C-shell and Korn shell are better user interfaces, and they too are definitely intended to be naive user interfaces. Naive user does not mean stupid user. -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
ok@quintus.UUCP (Richard A. O'Keefe) (04/12/88)
In article <21426@bu-cs.BU.EDU>, bzs@bu-cs.BU.EDU (Barry Shein) writes: > Doug Gwyn writes > >In article <21419@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: > >>What's wrong with using "-help" as a special case? > >I explained how you could exploit a feature that is ALREADY PRESENT > >and you keep missing the point. -help does not currently work. > I don't miss the point, I don't see the difficulty in fixing something > that's broken: > Ok, let me put it this way, if -? happens to work, fine, I wouldn't > suggest undoing it (I assume -* and -[ and -] etc work also) but if > one line of code is touched to codify that idea it ought to be > something like I suggest and shell metacharacters should be avoided in > getting help. Something which needs to be made clear is that programs which use getopt() do not in fact support -\? as a way of printing the "usage" message. The real story is that *ANY* unrecognised flag (yes, including -*, -[, -], and even -DEL) is reported AS AN ERROR. For example, if I do "ls -\&" under System V, this is what happens: % ls -\& ls: illegal option -- & usage: ls -RadCxmnlogrtucpFbqisfL [files] The fact that -\& can be used this way is something of a freakish accident. The fact that -\? can be used this way is less of an accident, but it is still freakish: '?' is the value that getopt() returns to its caller to say that something went wrong (but note that this behaviour CAN be disabled by the caller, so it is NOT guaranteed in all programs that use getopt). There is an important difference between the present -\? hack and a principled "-help" option: giving a program an invalid option is an error and should be signalled to the command interpreter as an error, but asking for help and getting it is not an error. For example, if I had a script which did something like echo "what program do you want help with" read program_name $program_name -help I would not expect this script to drop dead if help WAS printed. But -\? is an error, will be reported as an error, and if you set the right flags, will cause such a script to drop dead. It has long been considered good APL style to include a HELP function in every workspace. I'm embarrassed to say that I usually don't include anything more than a cursory Usage() in my C programs, but if there were some such conventional way to do a better job I'd follow the convention. (When I put anything in at all, it's -help or -h.)
ok@quintus.UUCP (Richard A. O'Keefe) (04/12/88)
To be perfectly fair, it is worth pointing out that the "-?" hack can be exploited in a way that is immune to meta-character vagaries. Instead of -? or -*, use -/ (/ being the unshifted ? on most keyboards). / is not going to be a meta-character in any sane UNIX shell, and it isn't going to be an option letter in any reasonable program either. Example: % date -/ usage: date [-u] [+format] [mmddhhmm[yy]] [-a sss.fff] It's still going to return an error code rather than being regarded as a normal use of the program, but that presumably won't bother most people.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/12/88)
In article <21471@bu-cs.BU.EDU> bzs@bu-cs.BU.EDU (Barry Shein) writes: >Howsabout '-=' ? This, as well as -, -. -: -_ -+ -~ -@ -# -% -^, should trip the usage message in the majority of getopt()-based utilities. Use the one that makes you happiest (presumably the one that interacts least with your shell). I'll stick to -? myself.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/12/88)
In article <2569@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: >All youse guys are missing the REALLY illegal, non-wildcard getopt option. >It is ":". Actually I didn't miss it. The same yoyo implementor who is likely to make = a valid option is also likely to pass getopts a list like ":abc:d:ef".
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/12/88)
In article <866@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >still freakish: '?' is the value that getopt() returns to its caller to >say that something went wrong (but note that this behaviour CAN be disabled >by the caller, so it is NOT guaranteed in all programs that use getopt). The only thing that can be disabled is the automatic error message produced by getopt() itself. An invalid flag is still returned as a '?' value by getopt(). Of course the application programmer may have chosen to be less than helpful in error situations. Nothing in any getopt()-like design can help this.
bzs@bu-cs.BU.EDU (Barry Shein) (04/12/88)
There is another good point in Richard O'Keefe's note, what exit status does the serendipitous '-\?' yield? Non-zero I assume, should it? -Barry Shein, Boston University
sullivan@vsi.UUCP (Michael T Sullivan) (04/13/88)
In article <7634@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > > You miss the point; -? already has the desired property; it does not But using -? only _has_ to say that -? is a bad option. You are relying on the fact that all programs have good usage messages. Some just say "Bad option" and die (none of mine do, of course :-). -- Michael Sullivan {uunet|attmail}!vsi!sullivan sullivan@vsi.com HE V MTL
levy@ttrdc.UUCP (Daniel R. Levy) (04/13/88)
In article <7663@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: # In article <2569@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: # >All youse guys are missing the REALLY illegal, non-wildcard getopt option. # >It is ":". # # Actually I didn't miss it. The same yoyo implementor who is likely to # make = a valid option is also likely to pass getopts a list like ":abc:d:ef". $ getopt :abc:d:ef -: foo getopt: illegal option -- : ':' is special-cased in getopt.c. Look at the code. -- |------------Dan Levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an Engihacker @ | <most AT&T machines>}!ttrdc!ttrda!levy | AT&T Data Systems Group | Disclaimer? Huh? What disclaimer??? |--------Skokie, Illinois--------|
crash@tsc3b21.UUCP (Colossus) (04/13/88)
From article <21426@bu-cs.BU.EDU>, by bzs@bu-cs.BU.EDU (Barry Shein): > I don't miss the point, I don't see the difficulty in fixing something > that's broken: > > if(strcmp(flag,"-help") == 0) > return(usage()); /*usage() can be redefined by the programmer*/ > > I don't find the fact that -? (or -\? or '-?') happens to work > wonderfully compelling, I guess you do, so we disagree. > > -Barry Shein, Boston University But what if I have a file in my directory called "-help"??? Sorry, I just couldn't resist ;-) !!! ----- Frank (crash) Edwards ...!codas!usfvax2!{pdn,jc3b21}!tsc3b21!crash TSC in Palm Harbor, FL Phone: (813) 785-0583 (voice) The Sweat Shop These opinions belong to no one.
henry@utzoo.uucp (Henry Spencer) (04/13/88)
> But using -? only _has_ to say that -? is a bad option. You are relying > on the fact that all programs have good usage messages. Some just say > "Bad option" and die... How do you propose to get around this? There is no way to force the programmer to supply useful error messages. -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry
jps@ihlpe.ATT.COM (452is-Schoonover) (04/14/88)
In article <8043@elsie.UUCP>, ado@elsie.UUCP (Arthur David Olson) writes: > > Ok, so use -, instead of -? if you have problems with the latter. > > Or, for that matter, use -=, a la > findspots -= > Is this a technique that everyone can agree with? > -- > ado@ncifcrf.gov ADO is a trademark of Ampex. Another possibility is to use -!. I have routinely used this in my own commands and enjoy the play on words: using the exclamation option to give an explanation of the command usage. (Yes, I am aware of commands that already use -! for other purposes). J. P. Schoonover ihlpe!jps
rdavis@convex.UUCP (Ray Davis) (04/14/88)
Filename expansion was in the shell a long time before getopt(1|3) existed. -? is intuitive to me, but using a filename generation metacharacter as a command line option was a stupid idea in the first place. -help is worse.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/14/88)
In article <524@vsi.UUCP> sullivan@vsi.UUCP (Michael T Sullivan) writes: >But using -? only _has_ to say that -? is a bad option. You are relying >on the fact that all programs have good usage messages. If you can't get a utility to provide a helpful usage message when you specify an incorrect option, you probably can't get it to provide such a message at all. I know of no way to force utilities to provide such help, but a thoughtful implementor will do his best in this regard.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/14/88)
In article <2576@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: >':' is special-cased in getopt.c. Look at the code. ls: illegal option -- : usage: ls -RadCxmnlogrtucpFbqisfL [files] Works same as -? etc.
levy@ttrdc.UUCP (Daniel R. Levy) (04/14/88)
In article <7680@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: # In article <2576@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: # >':' is special-cased in getopt.c. Look at the code. # # ls: illegal option -- : # usage: ls -RadCxmnlogrtucpFbqisfL [files] # # Works same as -? etc. Of course it does! What the dickens did you think I was saying? Let me spell it out. Because of the special status of ':' in getopt.c, not even the most yoyo, goony programmer can get getopt to recognize ':' as a valid option flag (contrary to what the article I replied to claimed). And, unlike the '-?' folks were complaining about in this group, '-:' cannot POSSIBLY trip you up by unexpected wildcard expansion under C, Bourne, or Korn shells. Have I made myself clear[er]? Hello? Helloooooooooo?!?!?!?!? -- |------------Dan Levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an Engihacker @ | <most AT&T machines>}!ttrdc!ttrda!levy | AT&T Data Systems Group | Disclaimer? Huh? What disclaimer??? |--------Skokie, Illinois--------|
sullivan@vsi.UUCP (Michael T Sullivan) (04/15/88)
In article <1988Apr13.164952.646@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: > > But using -? only _has_ to say that -? is a bad option. You are relying > > How do you propose to get around this? There is no way to force the > programmer to supply useful error messages. I never said there was a way around it. I just wanted to interject into this discussion that whatever one uses to get a usage message, be it -?, -:, -@, or -HELP isn't necessarily going to get a useful error message with every program. That's all. -- Michael Sullivan {uunet|attmail}!vsi!sullivan sullivan@vsi.com HE V MTL
aj@zyx.UUCP (Arndt Jonasson) (04/15/88)
In article <524@vsi.UUCP> sullivan@vsi.UUCP (Michael T Sullivan) writes: >In article <7634@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: >> >> You miss the point; -? already has the desired property; it does not > >But using -? only _has_ to say that -? is a bad option. You are relying >on the fact that all programs have good usage messages. Some just say >"Bad option" and die (none of mine do, of course :-). I don't have much of an opinion in this matter, so I'll provide some statistics instead. I tried calling all programs in /bin in a SysV.2 compatible system with -? as the single argument, and found the following: characteristic number of programs Print a usage line (or several) 36 Ignore it completely, although they do take options 5 Just say "bad option" in one way or another 14 Do something else 6 Don't count, since they don't take any options, and thus don't watch out for any 17 The total winner in silliness is 'wc': it does give a usage message, but only after the user has entered end-of-file! -- Arndt Jonasson, ZYX Sweden AB, Styrmansgatan 6, 114 54 Stockholm, Sweden email address: aj@zyx.SE or <backbone>!mcvax!enea!zyx!aj
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/15/88)
In article <2585@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: ># >':' is special-cased in getopt.c. Look at the code. >Have I made myself clear[er]? Yes, you're correct that AT&T's getopt() implementation doesn't support a ":opts" third argument, even though neither : nor ? is disallowed by the command syntax standard rules. Since the interface spec for getopt() gives a special meaning to '?' but not to ':' return, it is clear that no conforming getopt() implementation could support a ? option. It is not so clear that none could support : (which could also be specified via "x::yz"), but at least we now know that AT&T's (which is the one presumably everyone actually uses) doesn't. I must say it surprises me.. If anyone thinks we're nit-picking, they're right. I suspect very few getopt()-using applications use anything other than letters of the alphabet (in either case) for valid option designators.
allbery@ncoast.UUCP (Brandon Allbery) (04/18/88)
As quoted from <143@gsg.UUCP> by lew@gsg.UUCP (Paul Lew): +--------------- | In article <7628@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: | > Under the existing getopts scheme, typing | > command -? | > is guaranteed to get the usage message. | | Why use '?' character? I especially hate to type: command '-?' to avoid | '?' to be expanded by shell. In Bourne shell, if you dont have any file +--------------- (1) To the person who couldn't find "getopts" in the manual: it's "getopt", without the "s". Try "man 3 getopt" -- if Berkeley got around to putting it into libc, that is. (2) The point is not that "-?" is magic, it's that any unknown option will elicit a usage message. I personally use "-." to get the usage message, since I have yet to see a program which uses "-." as an option. Whereas some programs *do* use -H (System V /bin/who, for instance). -- Brandon S. Allbery, moderator of comp.sources.misc {well!hoptoad,uunet!marque,cbosgd,sun!mandrill}!ncoast!allbery Delphi: ALLBERY MCI Mail: BALLBERY
peter@sugar.UUCP (Peter da Silva) (04/18/88)
In article <7634@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > You miss the point; -? already has the desired property; it does not > have to be explicitly added to every application. I'm sorry if you > choose to use a shell that makes this too difficult to type. What, you mean there are actually people out there who don't set nonomatch in their .cshrc? Speaking of the bourne-again shell (System V shell), how do you get a shell function inherited by subshells? -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- "Have you hugged your U wolf today?" ...!bellcore!tness1!sugar!peter -- Disclaimer: These aren't mere opinions, these are *values*.
terry@wsccs.UUCP (Every system needs one) (04/20/88)
In article <2576@ttrdc.UUCP>, levy@ttrdc.UUCP (Daniel R. Levy) writes: | In article <7663@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: | # In article <2569@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: | # >All youse guys are missing the REALLY illegal, non-wildcard getopt option. | # >It is ":". | # | # Actually I didn't miss it. The same yoyo implementor who is likely to make | # = a valid option is also likely to pass getopts a list like ":abc:d:ef". | | $ getopt :abc:d:ef -: foo | getopt: illegal option -- : | | ':' is special-cased in getopt.c. Look at the code. Why not make a shell built-in "help" which passes a flag to the program that you can't get elsewhere without beating it over the head with a noodle? Say \377? terry@wsccs
stu@linus.UUCP (Stuart A. Werbner) (04/20/88)
In article <2478@zyx.UUCP> aj@zyx.UUCP (Arndt Jonasson) writes: >In article <524@vsi.UUCP> sullivan@vsi.UUCP (Michael T Sullivan) writes: >>In article <7634@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: >>> >>> You miss the point; -? already has the desired property; it does not >> >>But using -? only _has_ to say that -? is a bad option. You are relying >>on the fact that all programs have good usage messages. Some just say >>"Bad option" and die (none of mine do, of course :-). > >I don't have much of an opinion in this matter, so I'll provide some >statistics instead. I tried calling all programs in /bin in a SysV.2 >compatible system with -? as the single argument, and found the >following: > >characteristic number of programs > >Print a usage line (or several) 36 >Ignore it completely, although > they do take options 5 >Just say "bad option" in one > way or another 14 >Do something else 6 > >Don't count, since they don't > take any options, and thus > don't watch out for any 17 > >The total winner in silliness is 'wc': it does give a usage message, but >only after the user has entered end-of-file! > >-- >Arndt Jonasson, ZYX Sweden AB, Styrmansgatan 6, 114 54 Stockholm, Sweden >email address: aj@zyx.SE or <backbone>!mcvax!enea!zyx!aj No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! No more articles on "command line options"!! PLEAEAEAEAEAEAEAEAEAESE?????????
beres@cadnetix.COM (Tim Beres) (04/23/88)
In article <1864@sugar.UUCP> peter@sugar.UUCP (Peter da Silva) writes: > >Speaking of the bourne-again shell (System V shell), how do you get a shell >function inherited by subshells? At least on the SysVrel2 system on which I used to work: You can't. I remember a discussion about a year and a half ago in which the *shell* does this or that discussion came up. dmr posted on how the 8th edition shell could inherit functions. Since then, maybe this ability has been given to other variants of sh. -Tim -- Tim Beres Cadnetix 303/444-8075 x293 5775 Flatirons Pkwy {uunet,boulder,nbires}!cadnetix!beres Boulder, CO 80301 beres@cadnetix.com <disclaimers: my thoughts != Cadnetix's>
mouse@mcgill-vision.UUCP (der Mouse) (04/23/88)
In article <4751@chinet.UUCP>, les@chinet.UUCP (Leslie Mikesell) writes: > In article <864@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >> a time-honoured hack for protecting important directories, some >> people create an empty file called "-i", so that an >> rm * >> command will turn into >> rm -i {everything else} >> So files matching "-?" are quite likely to exist. (and hope there are no files beginning with control characters or space-through-comma! :-) > If a person knows enough about shell behaviour to create such a hack > he should also know enough to quote the "-?" to prevent expansion. You don't get the point. The -i file is created by the one who knows, to protect the directory against "rm *" issued by one who doesn't. That is, files matching -? are likely to exist in directories where novices are assumed to be issuing commands. der Mouse uucp: mouse@mcgill-vision.uucp arpa: mouse@larry.mcrcim.mcgill.edu
ljz@fxgrp.fx.com (Lloyd Zusman) (04/24/88)
Why is it that some of you are so fervently defending how '-?' is currently handled in getopt()? Are you trying to imply that getopt() is perfect and nothing better can ever be invented, and that those who try to suggest that something better might be possible are worthy of nothing more than derision and scorn? It sure seems that some of you feel this way. What if getopt() were to return '?' as an error UNLESS some global variable (how 'bout "getoptBADCH"?) is set to some other value? Then, those of us who believe that getopt() is perfect can continue to use it as is, and those of us who don't like the '?' behavior can do something different. Sheesh! -- Lloyd Zusman Master Byte Software Los Gatos, California Internet: ljz@fx.com "We take things well in hand." UUCP: ...!ames!fxgrp!ljz
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/25/88)
In article <283@fxgrp.UUCP> ljz@fx.com (Lloyd Zusman) writes: >Why is it that some of you are so fervently defending how '-?' is >currently handled in getopt()? Are you trying to imply that getopt() >is perfect and nothing better can ever be invented, and that those who >try to suggest that something better might be possible are worthy of >nothing more than derision and scorn? It sure seems that some of you >feel this way. Here's the situation as I see it. Sure, any of a number of spiffy argument parsing schemes can be designed. I've seen several such attempts, including one fairly good one contributed to a USENIX tape several years ago by the company for which I worked at the time. I don't think anybody has been arguing that getopt() could not be improved upon. When an effort was made in Bell Labs to consolidate the various argument handling schemes, a study was made and the various alternatives carefully considered. It was decided at that time that standardizing a la getopt() would be more widely useful than any other alternative. The command/option/argument syntax rules were written, reviewed, and eventually adopted as an AT&T standard (which several pre-existing UNIX utilities violated, of course). The code necessary to implement this scheme was placed into the public domain (the only instance I know of when this was done for AT&T code), and the command syntax rules were incorporated into the SVID. Gradually, older utilities have been revised to follow the new standard, which has several advantages over the ad hoc approach typically seen in non-getopts()-using utilities. The main advantage of getopt() is that it is HERE already, and it is widely ACCEPTED. I've been using it for years even though I could invent a nominally superior technical solution. The uniformity of the option parsing rules has proven its value for me many times. On the other hand, no "technically superior" design has received widespread support. You should feel free to try to change this, but based on past experience I doubt that you will succeed. As to "-?", I first raised that issue; it was intended to be an observation that there is ALREADY a feature in many utilities (those that use getopt() and have good usage messages) that can exploited to get help. I think it was misunderstood as an argument that that would be the ideal way to get help in a totally different design, which was never my contention.
rbutterworth@watmath.waterloo.edu (Ray Butterworth) (04/26/88)
In article <7680@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > usage: ls -RadCxmnlogrtucpFbqisfL [files] Are there actually people out there that find something like the above usage line of any practical use at all? Maybe I've been spoiled by growing up on non-unix-syntax machines, but "-RadCxmnlogrtucpFbqisfL" doesn't help me one bit. Options with real names are so much nicer. e.g. ======% imagen -help IMAGEN [file]* [Offset=0] [Lines=66] [Tabstops=4] [+Headings] [+Outline] [Columns=1] [+Reverse] [+Rule] [-Compress] [+Landscape] [-TitlePage] [Banner=] [Printer=imagen300] [-Submit] Submits text files to imagen dumb printer. ======% imagen +help IMAGEN [file]* [Offset=0] [Lines=66] [Tabstops=4] [+Headings] [+Outline] [Columns=1] [+Reverse] [+Rule] [-Compress] [+Landscape] [-TitlePage] [Banner=] [Printer=imagen300] [-Submit] Submits text files to imagen dumb printer. file Names of file(s) to be printed. Offset=0 How many characters offset from left margin. Lines=66 How many lines per page. Tabstops=4 How many positions between tab stops. +Headings Put headings at top of each page. +Outline Outline page borders. Columns=1 Number of pages per physical page. +Reverse Reverse page order. +Rule Print page rules every two lines. -Compress When Columns=2, a new file cannot begin in the second column. +Landscape Use page sideways. -TitlePage Don't print the job's title page. Banner= Name on banner page (default is name of first file). Printer=imagen300 Name of printer. -Submit Don't submit the job. Instead send output to stdout. P.S. Please don't flame me saying "that's not unix!". I know it isn't. I know I don't have the slightest chance of converting the unix world to this syntax. But I know which syntax I prefer and why.
lalonde@dalcsug.UUCP (Paul Lalonde) (04/26/88)
In article <18500@watmath.waterloo.edu> rbutterworth@watmath.waterloo.edu (Ray Butterworth) writes: >In article <7680@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: >> usage: ls -RadCxmnlogrtucpFbqisfL [files] >Maybe I've been spoiled by growing up on non-unix-syntax machines, >but "-RadCxmnlogrtucpFbqisfL" doesn't help me one bit. > >Options with real names are so much nicer. e.g. >======% imagen -help >IMAGEN [file]* [Offset=0] [Lines=66] [Tabstops=4] [+Headings] > [+Outline] [Columns=1] [+Reverse] [+Rule] [-Compress] > [+Landscape] [-TitlePage] [Banner=] [Printer=imagen300] > [-Submit] >Submits text files to imagen dumb printer. More examples of imagen +help deleted Most UNIX systems have such a feature: its called 'man'. If the usage: ls -RadCxmnlogrtucpFbqisfL [files] does nothing for you, do a man ls (or on some systems help ls) Big usage pages in your programs do little more than use disk and core space when a decent help system exists. Paul Lalonde BITNET: PLALONDE@DALAC UUCP: ...{uunet|watmath|utai}!dalcs!dalcsug!lalonde a a a a