Command-line Parser: General Documentation

There are four steps for a complete parsing of the command-line arguments:

  1. Initialization (Initialization)
  2. Options inclusion (Declaring the Options)
  3. The parsing itself (Parsing)
  4. Getting the values of the options (Getting the Values)

Initialization

In the initialization phase it is given to parser two variables: (1) an integer indicating the number of strings (tokens) provided; (2) the char** argv, containing a null-terminated list of strings (the command-line itself). There are two ways to call the CmdLine::Parser constructor:

   CmdLine::Parser Opts( argc, argv );

that creates the parser object Opts over the command-line argv. Also, one could pass some flags:

   CmdLine::Parser Opts( m_argc, m_argv, CmdLine::SILENT | 
                         CmdLine::OUT_OF_RANGE | CmdLine::NO_VALUE );

The possible flags are:

Declaring the Options

An user may specify five types of option: boolean (Bool), integer (Int), float (Float), char (Char), and string (String) options.

The basic declaration format is: Object.<type>.Add( "--option-name" ). For instance:

   Opts.Bool.Add( "-h" );

will declare a boolean option labeled "-h". You can also create an alias for an option:

   Opts.Bool.Add( "-h", "--help" );

so the following two command-lines are equivalent:

   program -h
   program --help
   

For the integer and float options it is possible to provide a default value and a range of accepted values (min and max). For example:

   Opts.Int.Add( "-age", "", 18, 10, 65 );
   Opts.Float.Add( "-f", "--float", 3.14, -1.0, numeric_limits<float>::max() );

will declare an option labeled -age with no alias, default value 18, minimum value 10 and maximum allowed value 65. Analogically, a float option -f/--float is declared with a maximum value defined as the maximum value supported by a primitive float type.

The Char and String options go further allowing the specification, respectively, of a set of valid characters or strings. For instance, the code:

   Opts.Char.Add( "-c", "", 'a', "abcXYZ\n" );

declares an option '-c' with default value 'a' and allows one of 'a', 'b', 'c', 'X', 'Y', 'Z', and '\n' chars. If the user gives a value not in this valid set, the default value 'a' is used or an exception out of range is thrown (if OUT_OF_RANGE is set).

The String type uses a slightly different mode:

   Opts.String.Add( "-s", "", "low", "low", "high", NULL );

In the above declaration, the valid values for -s are "low" and "high"; the default is "low".

Attention:
Since that version of the Add function allows variable number of arguments, the keyword NULL is required in order to close the list of valid strings. An unexpected error will be caused if you forget that.
Also, one can specify custom flags to each option. E.g.:

   // Adding flags (use the operator | to add more than one at a time):
   Opts.Int.Add( "-i", "--int" ).Set( CmdLine::NO_VALUE );

   // Unsetting flags:
   Opts.Int.Add( "-i", "--int" ).UnSet( CmdLine::NO_VALUE );
   
   // Reseting default flags and adding specific ones:
   Opts.Int.Add( "-i", "--int" ).Flags( CmdLine::SILENT | CmdLine::NO_VALUE );

   // Reseting all default flags:
   Opts.Int.Add( "-i", "--int" ).Flags( CmdLine::NONE );

Parsing

The parsing is done by the Parser::Process() function. It searches the command-line, store the values of the arguments of each declared option and finally returns the number of found (matched) options.

If the user wants to access the unrecognized options--like filenames--, it is possible to pass a STL container as argument of Process(), e.g.:

   vector<string> residue;
   Opts.Process( residue ); // will fill residue with the unrecognized tokens

One could also char* and const char* instead of string. Moreover, Process( T& ), being a template function, will accept any container provided that it implements clear() and push_back() member functions.

Getting the Values

Finally, the processed values of the arguments of the options can be accessed by the Get() function. Also, finding out whether an option was found or not may be useful; this can be achieved by the function Found( "option label" ). Consider the examples below:

   if( Opts.Bool.Get( "-h" ) ) { ShowHelp(); return; }
   
   // If not provided by the user, it returns the default value
   int age = Opts.Int.Get( "-age" );

   // Alternative mode
   int age;
   bool found = Opts.Int.Get( "-age", age );
   if( found )
      cout << "The age is: " << age;
   else
      cout << "-age option not provided."

   // Still, if the user just needs to know whether an option was
   // provided on the command-line:
   if( Opts.Int.Found( "-age" ) ) cout << "Age not specified."