Options A C++ Option-Parser
Options A C++ Option-Parser
Introduction to Options
Options is a C++ library for parsing Unix-style command-line options. The full source code
distribution for Options may be found in Options.tar.gz (22.5KB, gzipped tar file).
Options understands options and gnu-long-options and the parsing behavior is somewhat
configurable: You may specify options to be be case insensitive, matched by long (keyword)
name or short (single character) name; and a number of other features (see the file
<options.h> for a complete description).
Using Options
Options defines a C++ class of the same name which represents the allowable set of
command-line options and how to parse them:
#include <options.h>
Now you can iterate over your options from the command-line as follows:
#include <stdlib.h>
#include <options.h>
The remainder of the string must be the long-option name. Please note that long-option names
are matched case-insensitive and only a unique prefix of the name needs to be specified. By
default, option-name characters are case-sensitive (but this may be changed by turning on a run-
time flag).
If desired, the long-option name may be followed by one or more spaces and then by the name
of the option value. This name will be used when printing usage messages. If the option-value-
name is not given then the string "<value>" will be used in usage messages.
One may use a space to indicate that a particular option does not have a corresponding long-
option. For example, "c: " (or "c:") means the -c option takes a value and has no
corresponding long-option.
To specify a long-option that has no corresponding single-character option is a bit trickier:
Options::operator() still needs an "option-character" to return when that option is
matched. One may use a whitespace character or a non-printable character as the single-
character option in such a case. (hence " |hello" would only match "--hello").
Using the previous example, optv[] now corresponds to the following command-line syntax:
progname [-c <number>] [-s [<string>]] [-x]
Using long-options, optv[] corresponds to the following ("-" or "+" may be used instead of "--
" as the prefix):
progname [--count <number>] [--str [<string>]] [--xmode]
Noteworthy Exceptions:
If the 1st character of the string is '-', then the rest of the string must correspond to the above
format, and the option is considered to be a hidden-option. This means it will be parsed when
actually matching options from the command-line, but will not show-up if a usage message is
printed using the usage() member function. Such an example might be "-h|hidden". If you
want to use any "dummy" options (options that are not parsed, but that to show up in the usage
message), you can specify them along with any positional parameters to the usage() member
function.
If the 2nd character of the string is '\0' then it is assumed that there is no corresponding long-
option and that the option takes no argument (hence "f", and "f| " are equivalent).
Examples:
const char * optv[] = {
"c:count <number>",
"s?str <string>",
"x",
" |hello",
"g+groups <newsgroup>",
NULL
} ;
If you want Options to parse your positional arguments too (in case they are intermingled in
with your options) then you can do that by turning on a special control-flag:
#include <options.h>
opts.ctrls(Options::PARSE_POS);
while( char optchar = opts(iter, optarg) ) {
switch (optchar) {
case 's' :
str = optarg; break;
case 'x' :
++xflag; break;
case 'c' :
if (optarg == NULL) ++errors;
else count = (int) atol(optarg);
break;
case Options::POSITIONAL :
// handle positional arguments here ...
// (optarg points to the positional argument)
break;
default : ++errors; break;
} //switch
}
}
opts.ctrls(Options::PARSE_POS);
while( char optchar = opts(iter, optarg) ) {
switch (optchar) {
case 's' :
str = optarg; break;
case 'x' :
++xflag; break;
case 'c' :
if (optarg == NULL) ++errors;
else count = (int) atol(optarg);
break;
case Options::POSITIONAL :
// Push all positional arguments to the front. Note that
// we could swap argv[npos] with argv[iter.index() - 1]
// (assuming we have made sure they arent in fact one and
// the same) if we dont want to lose its previous value.
argv[npos++] = optarg;
break;
default : ++errors; break;
} //switch
}
The above simply replaces the beginning elements in argv[] with an argument that have
already been parsed, thus moving all the positional parameters to the front. If you prefer not to
lose the already parsed options, you could do a number of different things. You could simply
perform a swap instead of a replacement (as is mentioned in the comment above) or you could
allocate a new array to hold the positional arguments, or you could go to the effort of truly
permuting argv[] yourself.
An Extended Example
The following is the C++ code for a simple program that uses Options to parse the command-
line and then print out each command-line option and argument that was specified:
#include <stdlib.h>
#include <options.h>