command line options

Arndt Jonasson aj at zyx.UUCP
Sat Mar 26 02:23:47 AEST 1988


[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 at zyx.SE	or	<backbone>!mcvax!enea!zyx!aj



More information about the Comp.unix.wizards mailing list