Aargh

A Simple Example

Suppose you want a -f option for a file name, a -n option for some kind of counter, and a -v option for "verbose." Your XML file, named (for example) sample_1.xml, could look like this:
<?xml version="1.0"?>
<Spec>
    <Options>
        <StringOpt letter="f" name="infile"/>
        <IntOpt letter="n" name="counter"/>
        <BoolOpt letter="v" name="verbose"/>
    </Options>
</Spec>
From the command line, enter the following:
aargh sample_1.xml
You can also use the -l option (that's a lower case L) to specify the output language, either C or C++. The default is C++, but for C you can enter the command:
aargh -l C sample_1.xml
If you don't supply a file name on the command line, aargh reads standard input.

When you enter this command, aargh creates a header file and an implementation file. By default the header file is named "opts.h", and the implementation file is named "opts.c" (for C) or "opts.C" (for C++). However the XML file can specify other names.

For C, the header file declares a struct to represent the results of the command line parsing. By default this struct is named Opts, but the XML file can give it a different name:

struct Opts
{
	int new_argc;
	char ** new_argv;

	char * infile;
	int infile_found;
	unsigned long counter;
	int counter_found;
	int verbose;
};
In most cases, the names of these members are based on the names assigned to the options in the XML file: The "new_argc" and "new_argv" members represent the original argc and argv, modified to reflect the number of option arguments consumed. That is, the original argc is one more than the number of command line arguments, and new_argc is one more than the number of non-option arguments. Likewise argv[ 1 ] points to the first command line argument, and new_argv[ 1 ] points to the first non-option argument.

Note that new_argv[ 0 ] does not necessarily point to the command name. It points either to the command name or to the last option argument. The original argv array is left unchanged.

The implementation file defines the function for parsing the command line:

int get_Opts( int argc, char * argv[], Opts * pOpts );

For C++, the header file declares a class instead of a struct. In your code, you would declare an instance of Opts and call its get() member function, as defined in the implementation file. Its parameters are argc and argv from main():

	int Opt::get( int argc, char * argv[] );
The results would be available through a series of accessor functions:
	const std::string & Opts::infile() const;
	bool Opts::infile_found() const;
	unsigned Opts::long counter() const;
	bool Opts::counter_found() const;
	bool Opts::verbose() const;
These functions correspond to the data members described above for the C version, except that infile() returns a reference to a const std::string rather than a pointer.

There are two additional member functions:

	int Opts::new_argc() const;
	char ** Opts::new_argv() const;
These functions correspond to the new_argc and new_argv data members described above for the C version. Again, the original argv array is left unchanged.

Home