The Option Parsing Library
0.2.0
|
Documentation for Option Parsing Library (CEL) More...
Data Structures | |
struct | opt_t |
represents an element of an option description table. More... | |
Defines | |
macros for describing option-arguments; see @c opt_t | |
#define | OPT_ARG_REQ (&opt_arg_req) |
#define | OPT_ARG_NO (&opt_arg_no) |
#define | OPT_ARG_OPT (&opt_arg_opt) |
Enumerations | |
enum | { OPT_TYPE_NO, OPT_TYPE_BOOL, OPT_TYPE_INT, OPT_TYPE_UINT, OPT_TYPE_REAL, OPT_TYPE_STR } |
defines enum contants for types of argument conversion. More... | |
Functions | |
option processing functions: | |
const char * | opt_init (const opt_t *, int *, char **[], const void **, const char *, int) |
prepares to start parsing program arguments. | |
int | opt_parse (void) |
parses program options. | |
void | opt_abort (void) |
aborts parsing options. | |
const char * | opt_errmsg (int) |
returns a diagnostic format string for an error code. | |
void | opt_free (void) |
cleans up any storage used and disables the internal state. |
Documentation for Option Parsing Library (CEL)
Header for Option Parsing Library (CEL)
#define OPT_ARG_NO (&opt_arg_no) |
no argument taken
#define OPT_ARG_OPT (&opt_arg_opt) |
optional argument
#define OPT_ARG_REQ (&opt_arg_req) |
mandatory argument
anonymous enum |
defines enum contants for types of argument conversion.
void opt_abort | ( | void | ) |
aborts parsing options.
opt_abort() aborts parsing options immediately handling the remaining arguments as operands. Having invoked opt_abort(), opt_parse() need not be called to access to operands; argc
and @ argv are properly adjusted as if opt_parse() has returned -1 except that the remaining options (if any) are treated as operands. If opt_parse() invoked after aborting the parsing, opt_parse() does nothing and returns -1.
const char* opt_errmsg | ( | int | c | ) |
returns a diagnostic format string for an error code.
Given an error code that is one of '?', '-', '+' and '*', opt_errmsg() returns a string that can be used as a format string for the printf() family. A typical way to handle exceptional cases opt_parse() may return is as follows:
switch(c) { ... cases for valid options ... case 0: break; case '?': fprintf(stderr, "%s: unknown option '%s'\n", option.prgname, (const char *)argptr); opt_free(); return EXIT_FAILURE; case '-': fprintf(stderr, "%s: no or invalid argument given for '%s'\n", option.prgname, (const char *)argptr); opt_free(); return EXIT_FAILURE; case '+': fprintf(stderr, "%s: option '%s' takes no argument\n", option.prgname, (const char *)argptr); opt_free(); return EXIT_FAILURE; case '*': fprintf(stderr, "%s: ambiguous option '%s'\n", option.prgname, (const char *)argptr); opt_free(); return EXIT_FAILURE; default: assert(!"not all options covered -- should never reach here"); break; }
where "case 0" is for options that sets a flag variable so in most cases leaves nothing for a user code to do. The following four case labels handle erroneous cases and the default case is there to handle what is never supposed to happen.
As repeating this construct for every program using this library is cumbersome, for convenience opt_errmsg() is provided to handle those four erroneous cases as follows:
switch(c) { ... cases for valid options ... case 0: break; case '?': case '-': case '+': case '*': fprintf(stderr, "%s: ", option.prgname); fprintf(stderr, opt_errmsg(c), (const char *)argptr); opt_free(); return EXIT_FAILURE; default: assert(!"not all options covered -- should never reach here"); break; }
or more compatly:
switch(c) { ... cases for valid options ... case 0: break; default: fprintf(stderr, "%s: ", option.prgname); fprintf(stderr, opt_errmsg(c), (const char *)argptr); opt_free(); return EXIT_FAILURE; }
The difference of the last two is that the latter turns the assertion in the former (that possibly gets dropped from the delivery code) into a defensive check (that does not). Note that the returned format string contains a newline.
If a user needs flexibility on the format of diagnostics or actions done in those cases, resort to the cumbersome method shown first.
Possible exceptions: none
Unchecked errors: none
[in] | c | error code opt_parse() returned |
void opt_free | ( | void | ) |
cleans up any storage used and disables the internal state.
opt_free() cleans up any storage allocated by opt_init() and used by opt_parse(). It also initializes the internal state, which allows for multiple scans; see opt_init() for some caveat when scanning options multiple times.
argv
of main(), and opt_free() releases storages for them, any access to them gets invalidated by opt_free().Possible exceptions: none
Unchecked errors: none
const char* opt_init | ( | const opt_t * | o, |
int * | pc, | ||
char ** | pv[], | ||
const void ** | pa, | ||
const char * | name, | ||
int | sep | ||
) |
prepares to start parsing program arguments.
opt_init() prepares to start parsing program arguments. It takes everything necessary to parse arguments and sets the internal state properly that is referred to by opt_parse() later. It also constructs a more readable program name by omitting any path preceeding the pure name. To do this job, it takes a directory separator character through sep
and a default program name through name
that is used when no name is available through argv
. A typical use of opt_init() is given at the commented-out example code in the source file.
On success, opt_init() returns a program name (non-null pointer). On failure, it returns the null pointer; opt_init() may fail only when allocating small-sized storage fails, in which case further execution of the program is very likely to fail due to the same problem.
opt_init() can be called again for multiple scans of options, but only after opt_free() has been invoked. Note that, in such a case, only the internal state and flag variables given with an option description table are initialized. Other objects probably used for processing options in a user code retain their values, thus should be initialized explicitly by a user code. A convenient way to handle that initialization is to introduce a structure grouping all such objects. For example:
struct option { int html; const char *input; double val; ... } option;
where, say, html
is a flag variable for --html, input
is an argument for -i or --input, val
is an argument for -n or --number, and so on. By assigning a properly initialized value to the structure, the initialization can be readily done:
For C90: struct option empty = { 0, }; option = empty; For C99: option = (struct option){ 0, };
Note that, in this example, the object option
should have the static storage duration in order for the html
member to be given as an initalizer for an option description table; C99 has no such restriction.
Possible exceptions: none
Unchecked errors: non-null but invalid arguments given
[in] | o | option description table |
[in] | pc | pointer to argc |
[in] | pv | pointer to argv |
[in] | pa | pointer to object to contain argument or erroneous option |
[in] | name | default program name |
[in] | sep | directory separator (e.g., '/' on UNIX-like systems) |
non-null | program name |
null | failure |
int opt_parse | ( | void | ) |
parses program options.
opt_parse() parses program options. In typical cases, the caller of opt_parse() has to behave based on the result of opt_parse() that is one of:
pa
points to a string that represents the optionpa
points to a string that represents the optionpa
points to a string that represents the optionpa
points to the operandThis means that a valid short-named option cannot have the value of '?', '-', '+', '*', -1 or 1; 0 is allowed to say no short-named option given when a flag variable is provided; see opt_t
for details. In addition, '=' cannot also be used.
If an option takes an option-argument, the pointer whose address passed to opt_init() through pa
is set to point to the argument. A subsequent call to opt_parse() may overwrite it unless the type is OPT_TYPE_STR
.
After opt_parse() returns -1, argc
and argv
(precisely, objects whose addresses are passed to opt_init() through pc
and pv
) are adjusted for a user code to process remaining operands as if there were no options or option-arguments in program arguments; see the commented-out example code given in the source file. Once opt_parse() starts the parsing, argc
and the elements of argv
are indeterminate, thus an access to them is not allowed.
opt_parse() changes neither the original contents of argv
nor strings pointed to by the elements of argv
, thus by granting copies of argc
and argv
to opt_init() as in the following example, a user code can access to program arguments unchanged if necessary even after options have been parsed by opt_parse().
int main(int argc, char *argv[]) { const void *arg; int argc2 = argc; char **argv2 = argv; ... pname = opt_init(options, &argc2, &argv2, &arg, "program", '/'); while (opt_parse() != -1) { ... } for (i = 1; i < argc2; i++) printf("operands: %s\n", argv2[i]); opt_free(); for (i = 1; i < argc; i++) printf("untouched program arguments: %s\n", argv[i]); ... }
Possible exceptions: none
Unchecked errors: argc
or argv
modified by a user between calls to opt_parse(), modifying an object containing an option-argument or a problematic option