Options::Parse( int &, char ** &, const char *, int, const ErrorId &, Error * )

Manipulate argc and argv to extract command line arguments and associated values.

Virtual?

No

 

Class

Options

 

Arguments

int &argc

Number of arguments

 

char ** &argv

An array of arguments to parse

 

const char *opts

The list of valid options to extract

 

int flag

A flag indicating how many arguments are expected to remain when parsing is complete

 

const ErrorId &usage

An error message containing usage tips

 

Error *e

The Error object to collect any errors encountered

Returns

void

 

Notes

You must bypass argv[0\] (that is, the name of the calling program) before calling Options::Parse(). This is most easily done by decrementing argc and incrementing argv.

An argument by be of the form -avalue or -avalue. Although an argument of the form -avalue is passed as two entries in argv, the Options::Parse() method parses it as one logical argument.

As arguments are scanned from the caller’s argv, the caller’s argc and argv are modified to reflect the arguments scanned. Scanning stops when the next argument either:

  • does not begin with a -, or
  • is a - only, or
  • is not in the array of expected options.

Once scanning has stopped, argc and argv are returned "as-is"; that is, they are returned as they were when scanning stopped. There is no "shuffling" of arguments.

The opts argument is a format string indicating which options are to be scanned, and whether these options are to have associated values supplied by the user. Flags with associated values must be followed by a colon (“:”) or a period (“.”) in the format string. Using a colon allows arguments to be specified in the form -avalue or -avalue; using a period allows only the -avalue form.

If, based on the expectation set in the format string, the actual option string in argv does not provide a value where one is expected, an error is generated.

For instance, the p4 Command Line Client’s -V and -? flags are expected to be supplied without values, but the -p flag is expected to be accompanied with a setting for P4PORT. This is the format string used by the p4 Command Line Client:

"?c:C:d:GRhH:p:P:l:L:su:v:Vx:z:Z:"

Characters followed by colons (c, C, and so on) are command line flags that take values; all characters not followed by colons (?, G, R, h, s, and V) represent command line flags that require no values.

There is a limit of 20 options per command line, as defined in options.h by the constant N_OPTS.

The flag argument should be one of the following values (defined in options.h):

Argument Value Meaning

OPT_ONE

0x01

Exactly one argument is expected to remain after parsing

OPT_TWO

0x02

Exactly two arguments are expected to remain after parsing

OPT_THREE

0x04

Exactly three arguments are expected to remain after parsing

OPT_MORE

0x08

More than two arguments (three or more) are to remain after parsing

OPT_NONE

0x10

Require that zero arguments remain after parsing; if arguments remain after parsing, set an error.

OPT_MAKEONE

0x20

If no arguments remain after parsing, create one that points to NULL.

OPT_OPT

0x11

NONE, or ONE.

OPT_ANY

0x1F

ONE, TWO, THREE, MORE, or NONE.

OPT_DEFAULT

0x2F

ONE, TWO, THREE, MORE, or MAKEONE.

OPT_SOME

0x0F

ONE, TWO, THREE, or MORE.

See also

Options::GetValue() Options::operator[]()

Example

The following code and examples illustrate how Options::Parse() works.

#include <stdhdrs.h>
#include <strbuf.h>
#include <error.h>
#include <options.h>

int main( int argc, char **argv )
{
    // Parse options.
    Error *e = new Error();
    ErrorId usage = { E_FAILED, "Usage: parse optionstring flag args" };

    Options opts;

    // strip out the program name before parsing
    argc--;
    argv;

    // next argument is options to be parsed
    char *ParseOpts = argv[ 0 ];
    argc--;
    argv;

    // next argument is number of arguments remaining after parse
    int flag = strtol( argv[ 0 ], NULL, 0 );
    argc--;
    argv;

    // Echo pre-parse values
    int iargv;
    printf( "Prior to Options::Parse call:\n" );
    printf( "  ParseOpts is %s\n", ParseOpts );
    printf( "  flag is 0x%2.2X\n", flag );
    printf( "  argc is %d\n", argc );
    for ( iargv = 0; iargv &lt; argc; iargv )
    {
        printf( "  argv[ %d ] is %s\n", iargv, argv[ iargv ] );
    }
    printf( "\n" );

    opts.Parse( argc, argv, ParseOpts, flag, usage, e );
    if ( e->Test() )
    {
        // See example for Error::Fmt()
        StrBuf msg;
        e->Fmt( &msg );
        printf( "ERROR:\n%s\n", msg.Text() );
    }

    char *iParseOpts = ParseOpts;
    int isubopt;
    StrPtr *s;

    // Print values for options.
    while( *iParseOpts != '\0' )
    {
        if ( *iParseOpts != ':' )
        {
            isubopt = 0;
            while( s = opts.GetValue( *iParseOpts, isubopt ) )
            {
                printf( "opts.GetValue( %c, %d ) value is %s\n",
                        *iParseOpts, isubopt, s->Text() );

                isubopt;
            }
        }

        iParseOpts;
    }

    // Echo post-parse values
    printf( "\n" );
    printf( "After Options::Parse call:\n" );
    printf( "  argc is %d\n", argc );
    for ( iargv = 0; iargv < argc; iargv++ )
    {
        printf( "  argv[ %d ] is %s\n", iargv, argv[ iargv ] );
    }

    return 0;
}

Invoke parsedemo with a format string, a flag (as defined in options.h) to specify the number of options expected, and a series of arguments.

For instance, to allow arguments -a, -b and -c, where -a and -b take values, but -c does not take a value, and to use a flag of OPT_NONE (0x10) to require that no options remain unparsed after the call to Options::Parse(), invoke parsedemo as follows.

$ parsedemo a:b:c 0x10 -a vala -b valb -c

Arguments of the form -c one are passed as two entries in argv, but parsed as one logical argument:

$ parsedemo ha:b:c:d:e: 0x10 -cone
Prior to Options::Parse call:
  ParseOpts is ha:b:c:d:e:
  flag is 0x10
  argc is 1
  argv[ 0 ] is -cone

opts.GetValue( c, 0 ) value is one

After Options::Parse call:
  argc is 0

$ parsedemo ha:b:c:d:e: 0x10 -c one
Prior to Options::Parse call:
  ParseOpts is ha:b:c:d:e:
  flag is 0x10
  argc is 2
  argv[ 0 ] is -c
  argv[ 1 ] is one

opts.GetValue( c, 0 ) value is one

After Options::Parse call:
  argc is 0

Use of a period in the options string disallows the -c one form for the c option:

$ parsedemo ha:b:c.d:e: 0x10 -c one
Prior to Options::Parse call:
  ParseOpts is ha:b:c.d:e:
  flag is 0x10
  argc is 2
  argv[ 0 ] is -c
  argv[ 1 ] is one

ERROR:
Usage: parse optionstring flag args
Unexpected arguments.

opts.GetValue( c, 0 ) value is

After Options::Parse call:
  argc is 1
  argv[ 0 ] is one

Arguments not in the format string are permitted or rejected with the use of different flag values; OPT_NONE (0x10) requires that no arguments remain after the call to Options::Parse(), while OPT_ONE (0x01) requires that one argument remain.

$ parsedemo ha:b:c:d:e: 0x10 -c one two
Prior to Options::Parse call:
  ParseOpts is ha:b:c:d:e:
  flag is 0x10
  argc is 3
  argv[ 0 ] is -c
  argv[ 1 ] is one
  argv[ 2 ] is two

ERROR:
Usage: parse optionstring flag args
Unexpected arguments.

opts.GetValue( c, 0 ) value is one

$ parse ha:b:c:d:e: 0x01 -c one two
Prior to Options::Parse call:
  ParseOpts is ha:b:c:d:e:
  flag is 0x01
  argc is 3
  argv[ 0 ] is -c
  argv[ 1 ] is one
  argv[ 2 ] is two

opts.GetValue( c, 0 ) value is one

After Options::Parse call:
  argc is 1
  argv[ 0 ] is two