% x\_getopt() -- long options processing % Jessica L. Parsons % Wed Jan 16 11:58:41 PST 2008 #Long options handling ##Name `X_getopt()` -- processes *long options*. ##Synopsis #include struct x_option { int optval; char flag; char *name; char *has_argument; char *description; }; int x_getopt(int argc, char **argv, int optcount, struct x_option *opts); extern char *x_optarg; extern int x_optind, x_opterr, x_optopt; ##Description The **`x_getopt()`** function returns the next option in `argv` that matches an option in `opts`. The `opts` argument is an array of option definitions containing the following fields: =`optval`= is the value that `x_getopt()` returns to the program. =`flag`= is the one-character option. =`name`= is the long options name. =`has_arguments`= if the option has an argument associated with it, this is set to some descriptive word describing the contents of that argument (like "**FILE**" if the option wants a file argument.) =`description`= A one line description of the argument. The **`x_getopt()`** function places the `argv` index of the next argument to be processed into the `x_optind` variable. `x_optind` is external and is initialized to **`1`** every time you call `x_getopt()` with a different `argc`/`argv` pair. When all options have been processed, `x_getopt()` returns `EOF`. The special option "`--`" is used to tell `x_getopt()` that no further options are to be found in `argv`. This is useful for delimiting non-option arguments that begin with a "`-`". When **`x_getopt()`** encounters an option not listed in `opts`, it returns `NULL`. In addition, if the `x_opterr` variable is nonzero, it also prints an error message to `stderr`. ##Example #include #include struct x_option options[] = { { 'a', 'a', "opta", 0, "Option A" }, { 'b', 'b', "optb", 0, "Option B" }, { 'o', 'o', "output", "FILE", "Write output to FILE" }, { 'h', 0 , "help", 0, "Print this help message" }, }; #define NROPTS (sizeof options/sizeof options[0]) main(int argc, char **argv) { int c; int aflag = 0, bflag = 0; char *output = "-"; while ( (c = x_getopt(argc, argv, NROPTS, options)) != EOF) { switch (c) { case 'a': aflag++; break; case 'b': bflag++; break; case 'f': output = x_optarg; break; case 0: case 'h': fprintf(stderr, "usage: program [-ab] [-o file] ...\n"); exit( (c == 'h') ? 0 : 1 ); } } for ( ; x_optind < argc; x_optind++) printf("%d: %s\n", x_optind, argv[x_optind]); } ##Source code I put the [header file](options.h) in `/usr/include/basis`, to avoid collisions with the seventy or so other `options.h` files out there. I usually just build [`options.c`](options.c) as part of the objects list of the programs I build it with, but I've also built it into the libraries `liboptions.a` and `libc.a` * [`options.h`](options.h) * [`options.c`](options.c)