#include <CNCL/ParseArgs.h>
CN_PARSEARGS
CNObject
None
None
CNParseArgs provides a simple argument parser mainly intended (but not limited) to parse numeric arguments given in the command line of a program.
One enumeration and two additional structures are defined in ParseArgs.h in order to allow easy use of this class:
enum BlankHandling {NO_BLANK, BLANK}; // handling of blanks after option struct OptionDescription { char * option_string; // option string to be parsed BlankHandling blank; char * default_argument; // default argument char * usage; // optional string for usage char * argument_string; // contains the argument on return }; struct CNParseArgsList { int number_of_args; // number of elements of args_array OptionDescription * args_array; // array containing description // of options int mandatory_args; // number of args that have to be given int positional_args; // number of args that may be given without // option but in correct positional order void (*usage_func)(int argc, char **argv); // Pointer to a user // supplied usage function };
Main features of the class are:
Default arguments:
Usage function:
Positional arguments:
cnhisto -i infile
-o outfile
can be specified as cnhisto infile outfile
if the
first two arguments are specified as positional.
Blank format:
BLANK
between option and argument or
be specified as NO_BLANK
in which case no blank must be
specified. This is usefull e.g. to allow the specification of a printer
in the usual manner with the option -P
like -Php4m
. It is
necessary, that no such option appears as the prefix of any other
option. This is checked automatically.
Option format:
-a
-e
can not be expressed as -ae
.
Numeric format:
BLANK
option an additional hyphen ('-') has to be given in order to distingush
the number from an option string. More generally, every argument
starting with a hyphen, has to be specified with one additional
hyphen. This does not apply to NO_BLANK
options.
In order to make use of the class an array has to be defined consisting
of OptionDescription
s containing the option strings to be
recognized together with the necessary specifications. E.g.:
// Number of arguments to be recognized const int arg_desc_size = 4; OptionDescription arg_desc[arg_desc_size] = { {"'option'", BLANK/NO_BLANK, "'default_argument'", "'usage'"} {"i", BLANK, NIL, "input file name"}, {"o", BLANK, "result.dat", "output file name (default `result.dat'"}, {"rho", BLANK, "0.15", "Processing time (default 0.15)"} {"P", NO_BLANK, "hp4m", "Printer (stdout if not specified, default hp4m)"} }; const int mandatory = 1; const int positional = 2; // Forward declartion of `user_function' to allow specification in // initialization of `args' static void user_function(int argc, char **argv); CNParseArgsList args = { arg_desc_size, arg_desc, mandatory, positional, user_function };
In the example above, the program is designed to take four arguments, the first two being positional, the first one also mandatory, and the fourth one must be specified without blank. Valid invocations of the program include:
prog infile -Php4w prog infile outfile -P prog -o outfile infile
In order to create an object of class CNParseArgs
an object of
struct CNParseArgsList
has to be defined as shown above. The
pointer to the user supplied function (*usage_func)
may be given
as NIL. Then the default usage function is called if neccessary. This
default function is accessible to the user as the static member function
static void CNParseArgs::usage_screen(char * name, CNParseArgsList
&args)
.
In the main function of the program the object args
of type
CNParseArgsList
is passed in the call of the constructor of
CNParseArgs
:
int main(int argc, char **argv) { CNParseArgs parse_args(argc, argv, args); }
The constructor of the object parse_args
parses the array
argv
and (if the syntax is correct) the address of each argument
string given in argv
is written into
args.args_array[..].argument_string
of the corresponding option.
If an option is not specified at all, the value NIL
is assigned
to the corresponding [..].argument_string
.
To allow easy access to the argument_strings, the operator `[..]' is
overloaded in the class and returns the value of
args.args_array[..].argument_string
.
If an option is given, but no argument, the corresponding
[..].argument_string
holds the address of the string
default_argument
specified in arg_desc
, i.e. it is set to
the specified default.
In this way it is possible, to distinguish whether an option has or has not been specified, e.g.:
if (args.args_array[3].argument_string == NIL){ // option -P not specified // print to stdout } else { // print to device given in args.args_array[3].argument_string // this will be the default `hp4m' if only -P was specified // without an argument. }
The member function void CNParseArgs::override_nil(int first_arg,
int last_arg = 0)
can be used to assign the default string also if an
option has not been specified at all, i.e. if it contains NIL
,
e.g. in the above case:
parse_args.override_nil(0,2);
Thus the arguments of the first three options in the above example are
assigned their default values if they are not specified. If
last_arg
equals `0', only the argument string of option
first_arg
is overriden with the default value (provided that it
contained NIL
before!).
As shown in the example above, a default string can not be specified
for a mandatory option and must instead be initialized with
NIL
. This is checked by the constructor.
If an option is not specified at all, NIL is returned. If an option is given, but no argument, the default is returned. Thus it is possible to distinguish an option not specified from one specified but without an argument.
If args.args_array[i].blank
equals BLANK
the argument has
to be separated from the option string by white space characters. If it
equals NO_BLANK
the option must be followed immediately by the
argument without any separating character. Such an option must not occur
as the prefix of any other argument in the list. This is checked by the
program. If the same option string is specified more than once the
result is undefined.
A -
as the first character of an argument has to be given as
--
. This is necessary to allow the specification of negative
numbers as arguments. The pointer which is returned in
args.args_array[i].argument_string
is pointing to the second
-
. Thus the argument can directly be parsed semantically!
The first mandatory_args
arguments of args.args_array
have
to be specified, otherwise the program exits (as long as
usage_func
is NIL
) and prints a usage text created
automatically from the parameters given in args
. If the
pointer usage_func
is different from NIL
, that function is
called.
The number positional_args
of arguments may be specified without
a preceding option string.
If an argument is specified several times for the same option, the last specification is valid.
It is not possible to specify an empty string `""' for a positional argument without specifying the option.
Depending on which number of `mandatory_args' and `positional_args' is smaller this number of the first arguments is as well mandatory as positional. It is not possible to specify the positional and mandatory property separately for these arguments.
CNParseArgs();
CNParseArgs(CNParam *);
CNParseArgs (int argc, char **argv, CNParseArgsList &args)
CNParseArgs
.
In addition to the member functions required by CNCL, CNParseArgs
provides:
static void usage_screen(char * prog_name, CNParseArgsList &args);
args
equals NIL. It writes all possible option switches (defined
by the user in the instance of OptionDescription
) together with
their meanings and the syntax rules to standard output. The user may
also call this function from his own program as it is defined in the
public part of the class.
void override_nil(int first_arg, int last_arg = 0);
CNParseArgsList
that contain the value NIL
are set to the default string. This is
done starting with element first_arg and ending with element last_arg. If
last_arg equals 0 only element first_arg is processed.
char * operator[](int index);
The following template is also defined in ParseArgs.h to allow an easy parsing of numerical arguments.
template <class T> void assign_from_string(const char *string, T &input) { // Reads input from `string' and assigns the value to the referent of // `input'. The string stream object is only created as a temporary // and will be destructed as the statement is finished. istrstream(string, strlen(string)) >> input; }
Example of use:
double rho assign_from_string(args.args_array[2].argument_string, rho);
or equivalently:
assign_from_string(parse_args[2], rho);
Go to the first, previous, next, last section, table of contents.