1# esl_getopts : command line parsing
2
3The `getopts` module interprets UNIX command line syntax. It allows
4both standard POSIX one-character options and GNU-style long options,
5in addition to command line arguments. The implementation shares
6similarities with POSIX `getopt()` and GNU's `getopt_long()`. It has
7additional abilities, at the cost of enforcing a specific style.
8
9In addition to setting options from the command line, options may also
10be configured so they can be set by environment variables, or by one
11or more configuration files.
12
13Option arguments can be automatically checked for valid type
14(integers, real numbers, characters, or strings). Numeric arguments
15can also be checked for valid range (for instance, ensuring that a
16probability is in the range $0 \leq x \leq 1$).
17
18Options can be linked into "toggle groups", such that setting one
19option automatically unsets others.
20
21You can specify that an option isn't legal unless other required
22options are also set, or conversely that an option is incompatible
23with one or more other options.
24
25A standardized usage/help display for command line options can be
26printed directly from the internal information, including default
27values and range restrictions when line length allows.
28
29This is all configured by defining an array of `ESL_OPTIONS`
30structures that provide the necessary information. This array is
31turned into a `ESL_GETOPTS` object, which is used to determine
32and store the configuration state of your application according to the
33command line, environment variables, and configuration files.
34
35The `ESL_GETOPTS` object can be queried directly when your program
36executes configuration-dependent steps. There is often no need to
37store configuration information in other variables in your
38program. This simplifies code structure, by allowing you to pass the
39complete configuration state of your application in one capsule to
40functions other than `main()`. This is especially useful in
41applications where `main()` is a dispatch wrapper, such as the masters
42and workers in a parallelized MPI program, for example.
43
44The module implements a `ESL_GETOPTS` object that holds the
45configuration state of the application, and an `ESL_OPTIONS` structure
46that contains information about one configurable option. An
47application defines an array of `ESL_OPTIONS` to declare what options
48it will allow.
49
50## example
51
52```
53#include <stdio.h>
54#include "easel.h"
55#include "esl_getopts.h"
56
57static ESL_OPTIONS options[] = {
58  /* name        type          def   env  range toggles reqs incomp help                       docgroup*/
59  { "-h",     eslARG_NONE,    FALSE, NULL, NULL, NULL, NULL, NULL, "show help and usage",       0},
60  { "-a",     eslARG_NONE,    FALSE, NULL, NULL, NULL, NULL, NULL, "a boolean switch",          0},
61  { "-b",     eslARG_NONE,"default", NULL, NULL, NULL, NULL, NULL, "another boolean switch",    0},
62  { "-n",     eslARG_INT,       "0", NULL, NULL, NULL, NULL, NULL, "an integer argument",       0},
63  { "-s",     eslARG_STRING,  "hi!", NULL, NULL, NULL, NULL, NULL, "a string argument",         0},
64  { "-x",     eslARG_REAL,    "1.0", NULL, NULL, NULL, NULL, NULL, "a real-valued argument",    0},
65  { "--file", eslARG_STRING,   NULL, NULL, NULL, NULL, NULL, NULL, "long option, filename arg", 0},
66  { "--char", eslARG_CHAR,       "", NULL, NULL, NULL, NULL, NULL, "long option, char arg",     0},
67  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
68};
69static char usage[] = "Usage: ./example [-options] <arg>";
70
71int
72main(int argc, char **argv)
73{
74  ESL_GETOPTS *go;
75  char        *arg;
76
77  if ((go = esl_getopts_Create(options))     == NULL)  esl_fatal("Bad options structure\n");
78  if (esl_opt_ProcessCmdline(go, argc, argv) != eslOK) esl_fatal("Failed to parse command line: %s\n", go->errbuf);
79  if (esl_opt_VerifyConfig(go)               != eslOK) esl_fatal("Failed to parse command line: %s\n", go->errbuf);
80
81  if (esl_opt_GetBoolean(go, "-h") == TRUE) {
82    printf("%s\n  where options are:", usage);
83    esl_opt_DisplayHelp(stdout, go, 0, 2, 80); /* 0=all docgroups; 2=indentation; 80=width */
84    return 0;
85  }
86
87  if (esl_opt_ArgNumber(go) != 1) esl_fatal("Incorrect number of command line arguments.\n%s\n", usage);
88  arg = esl_opt_GetArg(go, 1);
89
90  printf("Option -a:      %s\n", esl_opt_GetBoolean(go, "-a") ? "on" : "off");
91  printf("Option -b:      %s\n", esl_opt_GetBoolean(go, "-b") ? "on" : "off");
92  printf("Option -n:      %d\n", esl_opt_GetInteger(go, "-n"));
93  printf("Option -s:      %s\n", esl_opt_GetString( go, "-s"));
94  printf("Option -x:      %f\n", esl_opt_GetReal(   go, "-x"));
95  if (esl_opt_IsUsed(go, "--file")) printf("Option --file:  %s\n", esl_opt_GetString(go, "--file"));
96  else                              printf("Option --file:  (not set)\n");
97  printf("Option --char:  %c\n", esl_opt_GetChar(go, "--char"));
98  printf("Cmdline arg:    %s\n", arg);
99
100  esl_getopts_Destroy(go);
101  return 0;
102}
103```
104
105The code above shows an example of using five short options (including
106help) and two long options, without any of getopts' optional
107validation or configuration mechanisms (hence all the `NULL` in the
108`env` through `incomp` fields of the `ESL_OPTIONS` array). The steps
109are:
110
111* The application defines an array of `ESL_OPTIONS` structures, one
112  per option. Name, type, and default value fields are required. The
113  other fields are optional (though the help string shouldn't be left
114  `NULL` unless you're being lazy). The array is terminated by an entry
115  of all 0's.
116
117* An application typically defines a helpful "usage" string, which it
118  prints out as part of help messages or error messages.  The
119  `getopts` module doesn't need this, though, so you're free to format
120  your messages however you like.
121
122* A `ESL_GETOPTS` object is created, using the options array. At this
123  point, all options are initialized to default values inside the
124  object.
125
126* The application now processes option settings from the command line,
127  environment variables, and one or more configuration files. The
128  application can do this in any precedence order it chooses. In the
129  example, only the command line is processed.
130
131* The call to `esl_opt_VerifyConfig(go)` validates the configuration,
132  before you attempt to retrieve any information from it.
133
134* Many of my applications (including Easel applications) typically
135  look for a `-h` option immediately, to print a short help page. This
136  isn't required by `getopts`.
137
138* The application will typically retrieve, validate, and store its
139  non-optional command line arguments in order and one at a time using
140  `esl_opt_GetArg()` calls early in the program.
141
142* The application may then go off and do its thing, using `_Get*()`
143  calls (and `_IsUsed()` and `_IsDefault()` calls) to retrieve option
144  information when needed.
145
146* On exit, the `ESL\_GETOPTS` object is destroyed (free'd). This
147  object is the only place where memory is allocated. Any string
148  retrieved as an option or argument, for example, is only a pointer
149  to internal memory maintained by the object. This makes it dangerous
150  to free the object until you know you're not accessing any pointers
151  it's returned to you, unless you've made copies.
152
153
154An example of running this program:
155
156```
157   % ./getopts_example -ax 0.3 -n 42 --file foo --char x baz
158  Option -a:      on
159  Option -b:      on
160  Option -n:      42
161  Option -s:      hi!
162  Option -x:      0.300000
163  Option --file:  foo
164  Option --char:  x
165  Cmdline arg:    baz
166```
167
168Note that because we set the default value of `-b` to TRUE in
169this example, it is always on whether we use the `-b` option or
170not.
171
172## defining options in `ESL_OPTIONS`
173
174Since you define your options in a static array of
175`ESL_OPTIONS` structures, you need to know what an
176`ESL_OPTIONS` structure contains.  The `ESL_OPTIONS`
177structure is declared in `getopts.h` as:
178
179```
180typedef struct {
181  char *name;           /* either short "-a" or long "--foo" style               */
182  int   type;           /* arg type, for type checking: (eslARG_INT, etc.)       */
183  char *defval;         /* default setting, or NULL ("default" is a C keyword)   */
184  char *envvar;         /* associated environ var ("BLASTDB"), or NULL           */
185  char *range;          /* for range checking arg: ("0<=x<=1", etc.)             */
186  char *toggle_opts;    /* comma-sep'd optlist: turn these off if this opt is on */
187  char *required_opts;  /* comma-sep'd optlist: these must also be set           */
188  char *incompat_opts;  /* comma-sep'd optlist: these must not be set            */
189  char *help;           /* help/usage string                                     */
190  int   docgrouptag;    /* integer tag for documentation groups                  */
191} ESL_OPTIONS;
192```
193
194Each of these fields in the options array is described in detail below:
195
196### option name
197
198All options must start with `-`. Options that start with one `-` are
199**short options**. Options that start with `--` are
200**long options**.
201
202Short option names must be a single alphanumeric character: `-n`
203or `-1`, for example.  Short options can be concatenated on the
204command line: `-abc` is the same as `-a -b -c`.
205
206Long option names should contain only alphanumeric characters, `-`, or
207`_`: `--foo` or `--foo-tastic`, for example. They must not contain
208space, tab, newline, `=`, or `,` characters, because these will
209definitely confuse the option argument parsers. Other characters might
210happen to work, but nonetheless should not be used.
211
212Long options can be abbreviated (unambiguously) on the command line:
213if `--foobar` is an option, `--f` works too, so long as no other long
214option starts with the same prefix `--f`.
215
216You should avoid using option names that look like negative numbers if
217any of your other options would accept that value as a valid argument,
218so that Easel can robustly detect when a user forgets an option
219argument on the command line.  For example, if `-n` takes an integer
220argument and `-1` is an option, and a user types `-n -1` on a
221commandline, the `-1` will be parsed as `-n`'s option, even if the
222user meant the `-1` as an option and had forgotten to add an argument
223for `-n`.
224
225### type checking
226
227Seven argument types are recognized:
228
229| flag           | description             | arg abbrv | type checking           |
230|----------------|-------------------------|-----------|-------------------------|
231`eslARG_NONE`    | Boolean switch (on/off) | n/a       | n/a                     |
232`eslARG_INT`     | integer                 | `<n>`     | convertible by `atoi()` |
233`eslARG_REAL`    | float or double         | `<x>`     | convertible by `atof()` |
234`eslARG_CHAR`    | one character           | `<c>`     | single ASCII char       |
235`eslARG_STRING`  | any string              | `<s>`     | not checked             |
236`eslARG_INFILE`  | an input filename       | `<f>`     | not checked             |
237`eslARG_OUTFILE` | an output filename      | `<f>`     | not checked             |
238
239
240
241All arguments are declared, configured, and stored internally as
242strings in a `ESL_GETOPTS` object. For arguments that are declared to
243be of types `eslARG_INT`, `eslARG_REAL`, or `eslARG_CHAR`, the string
244is checked to be sure it can be completely converted to the declared
245type.
246
247Strings are of type `eslARG_STRING`, and since any string is valid
248(including a NULL pointer), this type is not checked. An application
249can also declare an argument to be of type `eslARG_STRING` if for some
250reason it wants to bypass type checking. The application would recover
251the option argument with `esl_opt_GetString()` and then deal with any
252type conversion itself.
253
254Input and output filenames can be declared as `eslARG_INFILE` and
255`eslARG_OUTFILE`, respectively. Currently both are unchecked types
256that are treated the same as a `eslARG_STRING`, except that their
257arguments are indicated as `<f>` instead of `<s>` in help output. In
258the future, it might be useful to automatically check that input files
259exist and can be read, and that output files can be written.
260
261### default values
262
263Since the `ESL_GETOPTS` object stores all values internally as
264strings, default settings in the options array are also all provided
265as strings.
266
267For any type of option, `NULL`, `FALSE`, or 0 are all
268interpreted as the option being unset (OFF). Any non-NULL string value
269is interpreted as the option being set (ON).
270
271For boolean defaults, any non-NULL string is interpreted as `TRUE`,
272and the option is ON.  For a boolean option that is ON by default, the
273only place where the string value matters is in formatting option
274help, where this string will be displayed as the default
275setting. Therefore, strings like `"default"`, `"on"`, or `"true"`
276would be typical, to make the help string look right.
277
278Note that the syntax here is a little weird. The quotes around
279`"true"` and the absence of quotes around `FALSE` are
280important. `FALSE`, `NULL`, and `0` are all identical in the internal
281representation (they evaluate to a null pointer).
282
283Integer, real-valued, and character arguments must be provided as
284strings: `"42"` not 42, `"1.0"` not 1.0, and `"x"` not 'x'.  String
285arguments can be set to any string.
286
287Sometimes it's natural to define your default parameter values as
288macros; for example `#define eslFOO_DEFAULT 42`. The problem is that
289your macro value is a number, but getopts needs a string constant.  To
290use `eslFOO_DEFAULT` in an `ESL_OPTIONS` array, use
291`ESL_STR(eslFOO_DEFAULT)`. The `ESL_STR()` macro uses a C preprocessor
292trick that evaluates to a string constant containing the value of the
293macro constant. The `ESL_STR()` trick only works for integer- and
294real-valued option arguments, not for booleans; we don't currently
295have a good way to define boolean defaults with macros that get
296automatically used in the OPTIONS array.
297
298Sometimes you want to have an option that is off by default, but can
299be optionally set to a value. That is, you may want to combine a
300boolean switch and a integer-, real-, char-, or string-valued
301option. To do this, make the default value `NULL`, which means
302"unset", and when your code checks for the value of such an option,
303first use `esl_opt_IsOn()` to check if it's been set, and if so,
304`esl_opt_Get*()` the value.
305
306There is no way to turn a boolean option off by a command line option,
307environment variable, or configuration file if its default setting is
308ON. Booleans (and strings, for that matter) can only be turned on when
309their option is selected. Booleans can be set to off by default, or
310toggled off indirectly by another option is turned on (see the section
311on toggle groups further below). If you need to turn a boolean off,
312say `-b`, you can provide a counteroption (`--no-b`), and toggle-tie
313them together (see below).
314
315### connecting an option to an environment variable
316
317When an option is connected to an environment variable, setting the
318environment variable has the same result as setting the option on the
319command line.
320
321To check and process environment variables, your application needs to
322call `esl_opt_ProcessEnvironment()`.
323
324Boolean options are set by setting the environment variable with any
325argument, for instance (in a bash shell),
326
327```
328  % export FOO_DEBUGGING=1
329```
330
331and other options are set by setting the environment variable to the
332appropriate argument, for instance (in a bash shell),
333
334```
335  % export FOO_DEBUG_LEVEL=5
336```
337
338For example, if we connected the option name `--debug` to
339environment variable `"FOO_DEBUGGING"` and option
340`--debuglevel` to environment variable `"FOO_DEBUG_LEVEL"`
341in an application `myapp`, then
342
343```
344  % myapp --debug --debuglevel 5
345```
346
347is the same as
348
349```
350  % export FOO_DEBUGGING=1
351  % export FOO_DEBUG_LEVEL=5
352  % myapp
353```
354
355An advantage of using environment variables is that if you want to
356configure some optional behavior more or less permanently, you can
357save yourself a lot of command line typing by setting that
358configuration in the environment (in your `.cshrc` or
359`.bashrc`, for example).
360
361
362### automatic range checking
363
364If a non-NULL range is provided, a configured argument (including the
365specified default setting) will be checked to be sure it satisfies a
366lower bound, upper bound, or both. Range checking only applies to
367integer, real, and char arguments. Boolean and string arguments should
368set their range fields to NULL.
369
370In a range string, a character `n`, `x`, or `c` is used to represent
371an integer, real, or char argument, respectively. Bounds may either be
372exclusive ($<$ or $>$) or inclusive ($>=$ or $<=$). Examples of range
373strings specifying lower bounds are `"n>=0"`, `"x>1.0"`, and
374`"c>=A"`. Examples of range strings specifying upper bounds are
375`"n<0"`, `"x<=100.0"`, and `"c<=Z"`. Examples of range strings
376specifying both lower and upper bounds are `"0<n<=100"`, `"0<=x<=1"`,
377and `"a<=c<=z"`.
378
379Char ranges are determined using ASCII coding.
380
381Range checking occurs before any option is set.
382
383
384### setting toggle groups of options
385
386If a non-NULL string `toggle_opts` of "toggle-tied" options is set for
387option X, this is a comma-delimited list of options that are turned
388off when option X is turned on. This allows the application to define
389a group of options for which only one may be on. The application would
390set an appropriate one to be on by default, and the others to be off
391by default.
392
393For example, if you configure an option `-a` to have a
394`toggle_opts` of `"-b,-c"`, then whenever `-a` is
395turned on, both `-b` and `-c` are automatically turned
396off.
397
398But this only defines the behavior when `-a` is selected.  To
399get all three options to behave as a toggle group, you'd also want to
400set `toggle_opts` for `-b` to `"-a,-c"`, and
401`toggle_opts` for `-c` to `"-a,-b"`. This is a
402little redundant and messy; it's the result of the line-oriented,
403one-option-at-a-time definition of the `ESL_OPTIONS`.  These
404lists can get quite long, too.
405
406An option has no effect on itself when it appears in its own
407toggle-tied list. This lets you reduce the mess a bit. You can
408`#define` a toggle group string:
409
410```
411  #define OPTGROUP1 "--option1,--option2,--option3,--option4"
412```
413
414and use that `#define` macro in the `ESL_OPTIONS`.
415
416Although booleans may only be turned ON when their option is present,
417you can easily get the semantics of an on/off switch by defining
418another option that works as the off switch when it is selected. For
419example, you could define (GNU-ish) boolean options `--foo` and
420`--no-foo`, and set `toggle_opts` for `--foo` to be
421`"--no-foo"` and vice versa.
422
423Toggle-tying should only be used for boolean options, but it will also
424work for string options (where turning a string option off means
425setting it to NULL). Toggle-tying an integer, real-valued, or char
426option will result in undefined behavior, because these options can't
427be turned off once set.
428
429Toggling behavior occurs immediately, whenever an option with a
430non-NULL `toggle_opts` field is set.
431
432### specifying required or incompatible options
433
434If a non-NULL string `required_opts` is provided for option X,
435this specifies a comma-delimited list of additional options that must
436also be on if option X is set.
437
438One case where this behavior is useful is when one (primary) option
439turns on a mode of application behavior, and other (secondary) options
440configure that mode. If a user tried to set the secondary options
441without turning on the mode in the first place, the application should
442issue a warning. So, if a mode was turned on by `--foomode` and
443configured by `--foolevel <x>`, one could set
444`required_opts` to `"--foomode"` for the option
445`--foolevel`.
446
447Required options are validated when the application calls
448`esl_opt_VerifyConfig()}, (presumably) after all configuration
449information has been processed. This delayed verification allows the
450primary options to be set anywhere and in any order, before or after
451secondary options are set.
452
453The `incompat_opts` field is the converse of
454`required_opts`.It specifies a comma-delimited list of options
455that may _not_ also be on if option X is on.
456
457
458
459## more complex `ESL_OPTIONS` example
460
461The test driver in `getopts.c` uses an options array that
462exercises all the optional features at least once:
463
464```
465#define BGROUP "-b,--no-b"
466static ESL_OPTIONS options[] = {
467  /* name    type        default env_var  range toggles req  incompat help                  docgroup */
468 { "-a",     eslARG_NONE, FALSE,"FOOTEST",NULL,  NULL,  NULL,  NULL,  "toggle a on",               1 },
469 { "-b",     eslARG_NONE, FALSE,  NULL,   NULL, BGROUP, NULL,  NULL,  "toggle b on",               1 },
470 { "--no-b", eslARG_NONE,"TRUE",  NULL,   NULL, BGROUP, NULL,  NULL,  "toggle b off",              1 },
471 { "-c",     eslARG_CHAR,   "x",  NULL,"a<=c<=z",NULL,  NULL,  NULL,  "character arg",             2 },
472 { "--d1",   eslARG_NONE,"TRUE",  NULL,   NULL, "--d2", NULL,  NULL,  "toggle d1 on, d2 off",      2 },
473 { "--d2",   eslARG_NONE, FALSE,  NULL,   NULL, "--d1", NULL,  NULL,  "toggle d2 on, d1 off",      2 },
474 { "-n",     eslARG_INT,    "0",  NULL,"0<=n<10",NULL,  NULL,  NULL,  "integer arg",               2 },
475 { "-x",     eslARG_REAL, "0.8",  NULL, "0<x<1", NULL,  NULL,  NULL,  "real-value arg",            2 },
476 { "--lowx", eslARG_REAL, "1.0",  NULL,   "x>0", NULL,  NULL,  NULL,  "real arg with lower bound", 2 },
477 { "--hix",  eslARG_REAL, "0.9",  NULL,   "x<1", NULL,  NULL,  NULL,  "real arg with upper bound", 2 },
478 { "--lown", eslARG_INT,   "42",  NULL,   "n>0", NULL,"-a,-b", NULL,  "int arg with lower bound",  2 },
479 { "--hin",  eslARG_INT,   "-1",  NULL,   "n<0", NULL,  NULL,"--no-b","int arg with upper bound",  2 },
480 { "--host", eslARG_STRING, "","HOSTTEST",NULL,  NULL,  NULL,  NULL,  "string arg with env var",   3 },
481 { "--multi",eslARG_STRING,NULL,  NULL,   NULL,  NULL,  NULL,  NULL,  "test quoted configfile arg",3 },
482 { "--mul",  eslARG_NONE, FALSE,  NULL,   NULL,  NULL,  NULL,  NULL,  "test long opt abbreviation",3 }, /* xref bug #e4 */
483 {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
484};
485```
486
487
488## formatting help/usage messages
489
490The `esl_opt_DisplayHelp()` function streamlines the job of printing a
491brief help message, reminding the user of the command line options. It
492uses the help string to produce output like (from the example code
493above):
494
495```
496% ./example -h
497Usage: ./example [-options] <arg>
498
499  where options are:
500  -h         : show help and usage
501  -a         : a boolean switch
502  -b         : another boolean switch  [default]
503  -n <n>     : an integer argument  [0]
504  -x <x>     : a real-valued argument  [1.0]
505  --file <s> : long option, with filename arg
506  --char <c> : long option, with character arg
507```
508
509One line is printed for each option, in the same order that they
510appear in the `ESL_OPTIONS` array. The line is constructed from
511the mandatory option name, the mandatory argument type, and the
512optional help string.
513
514If there is room on the lines, default values are shown in brackets
515(when they are on or non-`NULL`). This display is all or none;
516if any line is too long, no default values are displayed.
517
518If there is still room on the lines, range restrictions are shown in
519parentheses. Like the default values, this display is also all or
520none.
521
522The amount of space on the line (in characters) is specified by the
523`textwidth` argument to `esl_opt_DisplayHelp()`, which
524might typically be 80. If any line is too long even without printing a
525default value and range restriction, an error is thrown; you need to
526either shorten the help string or increase the specified
527`textwidth`. (This is not a memory allocation
528issue. `textwidth` is provided as a tool to help you keep all
529your text within the bounds of a user's terminal window, and warn you
530when you're going to wrap or truncate lines.)
531
532You can indent all the lines by some number of spaces using the
533`indent` argument, which was set to 2 in the example above.
534
535The base behavior of `esl_opt_DisplayHelp()` is to show all
536the options in one list. You might want to have separate lists. For
537example, you might want to consider some options as "expert"
538options, and only show help for those when a user really asks for it.
539Or you might simply want to group your options into sections, with
540different headers. This is what the `docgrouptag` field is for
541in the `ESL_OPTIONS` structure. If you pass
542`esl_opt_DisplayHelp()` a nonzero value for `docgroup`,
543it will only show help lines for options that have a matching
544`docgrouptag`. If you had some options with a
545`docgrouptag` of 1, and some more options with a
546`docgrouptag` of 2, you could format them into two help sections
547with this:
548
549```
550 if (show_help) {
551    puts(usage);
552    puts("\n  where some options are:");
553    esl_opt_DisplayHelp(stdout, go, 1, 2, 80); /* 1=docgroup 1; 2=indentation; 80=width */
554    puts("\n  and some more options are:");
555    esl_opt_DisplayHelp(stdout, go, 2, 2, 80); /* 1=docgroup 2; 2=indentation; 80=width */
556    return 0;
557  }
558```
559
560which, if you modified the above example in this way (setting the
561first three options to have a `docgrouptag` of 1 and the other
562four to be 2) would give you:
563
564```
565./example -h
566Usage: ./example [-options] <arg>
567
568  where some options are:
569  -h : show help and usage
570  -a : a boolean switch
571  -b : another boolean switch  [default]
572
573  and some more options are:
574  -n <n>     : an integer argument  [0]
575  -x <x>     : a real-valued argument  [1.0]
576  --file <s> : long option, with filename arg
577  --char <c> : long option, with character arg
578```
579
580
581
582
583## command line parsing, config files, and the shell environment
584
585Once a `ESL_GETOPTS` object has been loaded with an options
586array and initialized to default state by
587`esl_getopts_Create()`, a `esl_opt_ProcessCmdline()`
588call then processes all the options on the command line, updating the
589configuration.
590
591Internally, the object keeps track of where the options end and
592command line arguments begin. The macro `esl_opt_ArgNumber()`
593returns the number of arguments remaining after the options.  Calls to
594`esl_opt_GetArg()` recover the command line arguments by
595number.
596
597The getopts module can configure options not only via the command
598line, but via environment and/or config files.  Connections to the
599environment -- the `env_var` field of the options array -- are
600processed by a `esl_opt_ProcessEnvironment()` call.  An open
601config file is processed by a `esl_opt_ProcessConfigfile()`
602call. (The format of a config file is described below.) The
603application may process any number of config files -- for instance,
604there may be a master configuration installed in a system directory,
605and a personalized configuration in a user's home directory.
606
607The order of the different `Process*()` calls defines the
608precedence of who overrides who. For example, in the following code
609fragment:
610
611```
612   ESL_GETOPTS *g;        /* a created, initialized getopts config  */
613   FILE *masterfp;        /* a master config file, open for reading */
614   FILE *userfp;          /* a user's config file, open for reading */
615
616   esl_opt_ProcessConfigfile(g, "/usr/share/myapp/master.cfg", masterfp);
617   esl_opt_ProcessConfigfile(g, "~/.myapp.cfg",                userfp);
618   esl_opt_ProcessEnvironment(g);
619   esl_opt_ProcessCmdline(g, argc, argv);
620```
621
622the precedence is defined as: defaults, master config file, local
623config file, environment, command line arguments.
624
625
626## configuring an application that uses getopts
627
628(This section might usefully by cut and pasted into the documentation
629for a specific application, with modifications as appropriate.)
630
631### command line option syntax
632
633Command line syntax is essentially identical to the syntax used by GNU
634programs. Options must precede the mandatory arguments.
635
636Options are either short or long. Short options are a single character
637preceded by a single `-`; for example, `-a`. Long options
638are preceded by two dashes, and can have any wordlength; for example,
639`--option1`.
640
641If a short option takes an argument, the argument may either be
642attached (immediately follows the option character) or unattached (a
643space between the optchar and the argument. For example, `-n5`
644and `-n 5` both specify an argument `5` to option
645`-n`.
646
647Short options can be concatenated into a string of characters;
648`-abc` is equivalent to `-a -b -c`. (Concatenation may
649only be used on the command line, not in configuration files or in
650fields of the `ESL_OPTIONS` structure array.) Only the last
651option in such a string can take an argument, and the other options in
652the optstring must be simple on/off booleans. For example, if
653`-a` and `-b` are boolean switches, and `-W` takes a
654`<string>` argument, either `-abW foo` or `-abWfoo`
655is correct, but `-aWb foo` is not.
656
657For a long option that takes an argument, the argument can be provided
658either by `--foo arg` or `--foo=arg`.
659
660Long options may be abbreviated, if the abbreviation is unambiguous;
661for instance, `--foo` or `--foob` suffice to active an
662option `--foobar`. Like concatenation of short options,
663abbreviation of long options is a shorthand that may only be used on
664the command line.
665
666Multi-word arguments may be quoted: for example, `--hostname "my
667host"` or `-s="my string"`.
668
669Nonnumeric arguments may not start with '-' unless you use an
670argument-attached syntax: `-W=-myarg` and `--foo=-myarg`
671are accepted, but `-W -myarg` or `--foo -myarg` will result
672in an error message. This is so if you forget a required argument on
673the command line, we don't silently parse the following option as that
674argument. Numeric arguments aren't checked this way, but forgotten
675numeric argument errors would still usually be caught in typechecking
676(if `-n` takes an integer argument, `-n -a` would be an
677invalid argument error); stylistically, we want `-n -1` and
678`--param -1` to be a valid way of passing negative-valued
679arguments.  However, this does mean that some forgotten numeric
680argument cases will be undetectable by Easel: in the case where
681`-n` takes an integer argument, `-1` is a valid option,
682and the user types `-n -1`, the `-1` is parsed as
683`-n`'s option.
684
685
686## configuration file format
687
688Each line of a configuration file contains an option and an argument
689(if the option takes an argument). Blank lines are ignored.  Anything
690following a `#` character on a line is a comment and is
691ignored. The syntax of options and arguments is stricter than on
692command lines.  Concatenation of short options is not allowed,
693abbreviation of long options is not allowed, and arguments must always
694be separated from options by whitespace (not by `=`). For
695example:
696
697```
698   # Customized configuration file for my application.
699   #
700   -a                        # Turn -a on.
701   -b                        # Turn -b on.
702   -W      arg               # Set -W to "arg"
703   --multi "one two three"   # Multiword args can be quoted.
704```
705
706
707## available functions
708
709| Function                       | Synopsis                                                     |
710|--------------------------------|--------------------------------------------------------------|
711| esl_getopts_Create()           | Create a new `ESL_GETOPTS` object.                           |
712| esl_getopts_CreateDefaultApp() | Initialize a standard Easel application.                     |
713| esl_getopts_Reuse()            | Reset application state to default.                          |
714| esl_getopts_Destroy()          | Destroys an `ESL_GETOPTS` object.                            |
715| esl_getopts_Dump()             | Dumps a summary of a `ESL_GETOPTS` configuration.            |
716| esl_opt_ProcessConfigfile()    | Parses options in a config file.                             |
717| esl_opt_ProcessEnvironment()   | Parses options in the environment.                           |
718| esl_opt_ProcessCmdline()       | Parses options from the command line.                        |
719| esl_opt_ProcessSpoof()         | Parses a string as if it were a command line.                |
720| esl_opt_VerifyConfig()         | Validates configuration after options are set.               |
721| esl_opt_ArgNumber()            | Returns number of command line arguments.                    |
722| esl_opt_SpoofCmdline()         | Create faux command line from current option configuration.  |
723| esl_opt_IsDefault()            | Returns `TRUE` if option remained at default setting.        |
724| esl_opt_IsOn()                 | Returns `TRUE` if option is set to a non-`NULL` value.       |
725| esl_opt_IsUsed()               | Returns `TRUE` if option is on, and this is not the default. |
726| esl_opt_GetSetter()            | Returns code for who set this option.                        |
727| esl_opt_GetBoolean()           | Retrieve `TRUE`/`FALSE` for a boolean option.                |
728| esl_opt_GetInteger()           | Retrieve value of an integer option.                         |
729| esl_opt_GetChar()              | Retrieve value of a character option.                        |
730| esl_opt_GetString()            | Retrieve value of a string option.                           |
731| esl_opt_GetArg()               | Retrieve numbered command line argument.                     |
732| esl_opt_DisplayHelp()          | Formats one-line help for each option.                       |
733
734