cgma
ProgOptions Class Reference

#include <ProgOptions.hpp>

List of all members.

Public Member Functions

 ProgOptions (const std::string &helptext="", const std::string &briefdesc="")
 unimplemented flag for required arguments that may be given multiple times
 ~ProgOptions ()
void setVersion (const std::string &version_string, bool addFlag=true)
template<typename T >
void addOpt (const std::string &namestring, const std::string &helpstring, T *value, int flags=0)
template<typename T >
void addOpt (const std::string &namestring, const std::string &helpstring, int flags=0)
void addOptionHelpHeading (const std::string &)
template<typename T >
void addRequiredArg (const std::string &helpname, const std::string &helpstring, T *value=NULL, int flags=0)
template<typename T >
void addOptionalArgs (unsigned max_count, const std::string &helpname, const std::string &helpstring, int flags=0)
void printHelp (std::ostream &str=std::cout)
void printUsage (std::ostream &str=std::cout)
void printVersion (std::ostream &str=std::cout)
void parseCommandLine (int argc, char *argv[])
template<typename T >
bool getOpt (const std::string &namestring, T *value)
template<typename T >
void getOptAllArgs (const std::string &namestring, std::vector< T > &values)
int numOptSet (const std::string &namestring)
template<typename T >
getReqArg (const std::string &namestring)
template<typename T >
void getArgs (const std::string &namestring, std::vector< T > &values)
void error (const std::string &message)
void write_man_page (std::ostream &to_this_stream)

Static Public Attributes

static const int help_flag = 1<<0
static const int add_cancel_opt = 1<<1
static const int store_false = 1<<2
static const int int_flag = 1<<3
static const int rank_subst = 1<<4
static const int version_flag = 1<<5
 Set for a flag that, when detected, will call printVersion() and halt the program.
static const int store_true = 1<<6

Protected Types

typedef std::pair< ProgOpt
*, std::string > 
help_line

Protected Member Functions

std::string get_option_usage_prefix (const ProgOpt &option)
void get_namestrings (const std::string &input, std::string *l, std::string *s)
ProgOptlookup (const std::map< std::string, ProgOpt * > &, const std::string &)
ProgOptlookup_option (const std::string &)
bool evaluate (const ProgOpt &opt, void *target, const std::string &option, unsigned *arg_idx=NULL)
bool process_option (ProgOpt *opt, std::string arg, const char *value=0)

Protected Attributes

std::map< std::string, ProgOpt * > long_names
std::map< std::string, ProgOpt * > short_names
std::map< std::string, ProgOpt * > required_args
std::vector< help_lineoption_help_strings
std::vector< help_linearg_help_strings
std::vector< std::string > main_help
std::string brief_help
bool expect_optional_args
unsigned optional_args_position
unsigned max_optional_args
std::string progname
std::string progversion
std::string number_option_name

Detailed Description

A simple command-line option parser and help utility

Utility class to specify a program's command-line options arguments, produce a help message explaining how they work, and parse user's command line input (producing useful errors messages if any problems arise). Loosely (okay, very loosely) inspired by boost program_options.

Options are specified by a comma-separated namestring. An option named "foo,f" can be specified three ways on the command line: "-f val", "--foo val", or "--foo=val". The types of options and arguments are specified by function templates. Valid template values for positional argument and options are int, double, and std::string. void may also be used in options, and it indicates a command line option that does not take an argument.

Example usage: ProgOptions po( "Example usage of ProgOptions" ); po.addOpt<void>( "verbose,v", "Turn on verbose messages" ); po.addOpt<std::string> ("foo", "Specify the foo string" ); int x = 0; po.addOpt<int>( ",x", "Specify the x number", &x ); // x will be automatically set when options parsed po.parseCommandLine( argc, argv ); bool verbose = po.numOptSet("verbose") > 0; std::string foo; if( !po.getOpt( "foo", &foo ) ) foo = "default"; ...

See the file dagmc_preproc.cpp in the dagmc directory for a real-world example.

Definition at line 42 of file ProgOptions.hpp.


Member Typedef Documentation

typedef std::pair<ProgOpt*, std::string> ProgOptions::help_line [protected]

Definition at line 276 of file ProgOptions.hpp.


Constructor & Destructor Documentation

ProgOptions::ProgOptions ( const std::string &  helptext = "",
const std::string &  briefdesc = "" 
)

unimplemented flag for required arguments that may be given multiple times

Parameters:
helptextA brief summary of the program's function, to be printed when the help flag is detected

Definition at line 72 of file ProgOptions.cpp.

                                                                                  :
    expect_optional_args(false)
{
  brief_help = briefhelp;
  if (!helpstring.empty())
    main_help.push_back( helpstring );
 addOpt<void>( "help,h", "Show full help text", help_flag );
}

Definition at line 81 of file ProgOptions.cpp.

                         {
  for( std::vector<help_line>::iterator i = option_help_strings.begin();
       i != option_help_strings.end(); ++ i )
  {
    if( (*i).first ){ delete (*i).first; }
  }

  for( std::vector<help_line>::iterator i = arg_help_strings.begin();
       i != arg_help_strings.end(); ++ i )
  {
    delete (*i).first;
  }
}

Member Function Documentation

template<typename T >
void ProgOptions::addOpt ( const std::string &  namestring,
const std::string &  helpstring,
T *  value,
int  flags = 0 
)

Specify a new command-line option

Instruct the parser to accept a new command-line argument, as well as specifying how the argument should be handled. The template parameter indicates the type of command-line option being specified: acceptable types are void (indicating a flag without an argument), int, double, and std::string.

Parameters:
namestringThe command-line options name(s). Format is longname,shortname. If the comma is omitted, or appears only at the end, this option will have no shortname; if the comma is the first letter of the namestring, the option has no longname.
helpstringThe help information displayed for the option when the program is invoked with --help
valueA pointer to memory in which to store the parsed value for this option. If NULL, then the value of the option must be queried using the getOpt function. If the template parameter is void and value is non-NULL, treat value as a bool* and store 'true' into it when the flag is encountered. (See also store_false, above)
flagsOption behavior flags, which should come from static vars in the ProgOptions class

Definition at line 121 of file ProgOptions.cpp.

                                   {

  std::string shortname, longname;
  get_namestrings( namestring, &longname, &shortname );
  
  if (flags & int_flag) { // short name is implicit for this flag
    if (!shortname.empty()) 
      error( "Requested short name with int_flag option" );
    if (get_opt_type<T>() != INT)
      error( "Requested int_flag for non-integer option" );
    if (!number_option_name.empty()) 
      error( "Requested int_flag for multiple options" );
    number_option_name = longname;
  }

  ProgOpt* opt = new ProgOpt( longname, shortname, flags, get_opt_type<T>() );
  if( value ) opt->storage = value;


  if(longname.length())  long_names[longname] = opt;
  if(shortname.length()) short_names[shortname] = opt;

  help_line help = std::make_pair( opt, helpstring );
  option_help_strings.push_back( help );

  if( flags & add_cancel_opt ){
    std::string flag = "no-" + (longname.length() ? longname : shortname );
    ProgOpt* cancel_opt = new ProgOpt( flag, "", flags ^ ProgOptions::store_false, FLAG );
    if (value) cancel_opt->storage = value;
    
    cancel_opt->cancel_opt = opt;
    long_names[flag] = cancel_opt;
    std::string clear_helpstring = "Clear previous " + flag.substr(3,flag.npos) + " flag";
    help = std::make_pair( cancel_opt, clear_helpstring );
    option_help_strings.push_back( help );
  }
}
template<typename T >
void ProgOptions::addOpt ( const std::string &  namestring,
const std::string &  helpstring,
int  flags = 0 
) [inline]

Specify a new command-line option

This funtion is identical to the 4-arg version, but omits the value parameter, which is assumed to be NULL

Definition at line 137 of file ProgOptions.hpp.

                                                                                        {
    addOpt<T>( namestring, helpstring, NULL, flags );
  }
template<typename T >
void ProgOptions::addOptionalArgs ( unsigned  max_count,
const std::string &  helpname,
const std::string &  helpstring,
int  flags = 0 
)

Add optional positional arguments

Specify location in ordered argument list at which optional arguments may occur. Optional arguments are allowed at only one location it argument list (this function may not be called more than once.). The template parameter may be int, double, or std::string (but not void)

Parameters:
countThe maximum number of optional arguments. Specify zero for unlimited.
helpnameThe name to give the argument in the help text
helpstringThe help text for the arguments

Definition at line 177 of file ProgOptions.cpp.

{
    // If there was a previous one, we need to remove it
    // because there can be only one.  If we didn't remove
    // the old one then it would be treated as a required arg.
  if (expect_optional_args) {
    std::map<std::string, ProgOpt*>::iterator iter;
    iter = required_args.find( arg_help_strings[optional_args_position].second );
    assert(iter != required_args.end());
    delete iter->second;
    required_args.erase(iter);
    arg_help_strings.erase( arg_help_strings.begin() + optional_args_position );
  }

  expect_optional_args = true;
  optional_args_position = arg_help_strings.size();
  max_optional_args = max_count;
  addRequiredArg<T>( helpname, helpstring, 0, flags );
}
void ProgOptions::addOptionHelpHeading ( const std::string &  s)

Add a new line of help text to the option help printout

Add a line of text to the option-related help. Called between calls to addOpt(), this function can be used to divide the option list into groups of related options to make the help text more convenient.

Definition at line 201 of file ProgOptions.cpp.

                                                          {
  option_help_strings.push_back( std::make_pair( (ProgOpt*)NULL, s) );
}
template<typename T >
void ProgOptions::addRequiredArg ( const std::string &  helpname,
const std::string &  helpstring,
T *  value = NULL,
int  flags = 0 
)

Add required positional argument

Add a new required positional argument. The order in which arguments are specified is the order in which they will be expected on the command line. The template parameter may be int, double, or std::string (but not void)

Parameters:
helpnameThe name to give the argument in the help text
helpstringThe help text for the argument
valuePointer to where parsed value from command line should be stored. If NULL, the value must be queried using getReqArg()

Definition at line 162 of file ProgOptions.cpp.

                                             {
  
  OptType type = get_opt_type<T>();

  ProgOpt* opt = new ProgOpt( helpname, "", flags,  type );
  if( value ) opt->storage = value;
  help_line help = std::make_pair( opt, helpstring );
  arg_help_strings.push_back( help );
  required_args[helpname] = opt;
}
void ProgOptions::error ( const std::string &  message)

Prints an error message to std::cerr, along with a brief usage message, then halts the program. Used throughout ProgramOptions implementation. Users may call this directly if they detect an incorrect usage of program options that the ProgramOptions wasn't able to detect itself.

Parameters:
messageThe error message to print before program halt.

Definition at line 369 of file ProgOptions.cpp.

                                               {
  std::cerr << "Error: " << error << "\n"<< std::endl;;
  printUsage( std::cerr );
  std::cerr << std::endl;
  if (getenv("MOAB_PROG_OPT_ABORT"))
    abort();
  std::exit( EXIT_FAILURE );
}
bool ProgOptions::evaluate ( const ProgOpt opt,
void *  target,
const std::string &  option,
unsigned *  arg_idx = NULL 
) [protected]

Check the input to a given option for correctness, converting it to its expected type (e.g. int) and storing the result to target, if target is non-NULL.

Parameters:
optionUsed only in error messages to state which option could not be successfully converted
arg_idxIf non-NULL, evaluate the (*arg_idx)'th item in opt's args list

Definition at line 471 of file ProgOptions.cpp.

                                                                                                        {

  unsigned idx = arg_idx ? *arg_idx : opt.args.size()-1;

  switch( opt.type ){
  case FLAG:
    error("Cannot evaluate a flag");
    break;
  case INT:
    {
      int temp;
      int* i = target ? reinterpret_cast<int*>(target) : &temp;
      if( opt.args.size() < 1 ){
    error( "Missing argument to " + option + " option");
      }
      const char* arg = opt.args.at(idx).c_str();
      char* p;
      *i = std::strtol( arg, &p, 0 );
      if( *p != '\0' ){ error("Bad integer argument '" + opt.args.at(idx) + "' to " + option + " option."); }
      return true;
    }
  case REAL:
    {
      double temp;
      double* i = target ? reinterpret_cast<double*>(target) : &temp;
      if( opt.args.size() < 1 ){
    error( "Missing argument to " + option + " option");
      }
      const char* arg = opt.args.at(idx).c_str();
      char* p;
      *i = std::strtod( arg, &p );
      if( *p != '\0' ){ error("Bad real argument '" + opt.args.at(idx) + "' to " + option + " option."); }
      return true;
    
    }
  
  case STRING:
    {
      std::string temp;
      std::string* i = target ? reinterpret_cast<std::string*>(target) : &temp;
      if( opt.args.size() < 1 ){
    error( "Missing argument to " + option + " option");
      }
      if (opt.flags & rank_subst)
        *i = do_rank_subst( opt.args.at(idx) );
      else
        *i = opt.args.at(idx);
      return true;
    }
  
  case INT_VECT:
    {
      std::vector<int> temp;
      std::vector<int>* i = target ? reinterpret_cast<std::vector<int>*>(target) : &temp;
      if(!parse_int_list( opt.args.at(idx).c_str(), *i ))
        error( "Bad integer list '" + opt.args.at(idx) + "' to " + option + " option.");
      return true;
    }

  }

  return false;
}
void ProgOptions::get_namestrings ( const std::string &  input,
std::string *  l,
std::string *  s 
) [protected]

Definition at line 96 of file ProgOptions.cpp.

{
  *shortname = "";
  *longname = namestring;

  size_t idx = namestring.find_first_of(',');
  if( idx != namestring.npos ){
    *longname = namestring.substr(0, idx);
    *shortname = namestring.substr( idx+1, namestring.npos );
  }

  
}
std::string ProgOptions::get_option_usage_prefix ( const ProgOpt option) [protected]

Definition at line 289 of file ProgOptions.cpp.

                                                                      {
  bool has_shortname = option.shortname.length() > 0;
  bool has_longname  = option.longname.length() > 0;  
  std::string argstr = option.get_argstring();

  std::stringstream s;
  s << "  ";
  if( has_shortname ){
    
    s << "-" << option.shortname;
    if( has_longname ){ s << " "; }
    
  }
  else if ( option.flags & int_flag ) {
    
    s << "-<n>";
    if( has_longname ){ s << " "; }
    
  }
  if( has_longname ){
    
    if( has_shortname ) s << "[";
    s << "--" << option.longname; 
    if( has_shortname ) s << "]"; 
    
  }
  
  if( argstr.length() ) s << " <" << argstr << ">";
  return s.str();
}
template<typename T >
void ProgOptions::getArgs ( const std::string &  namestring,
std::vector< T > &  values 
)

Append the values of any required or optional arguments

Parameters:
namestringThe helpname that was given to addRequiredArg or addOptionalArgs.

Definition at line 612 of file ProgOptions.cpp.

{
  ProgOpt* opt = lookup( required_args, namestring );
  
  if( !opt ){
    error( "Could not look up required arg: " + namestring );
  }
  
  
  if( get_opt_type<T>() != opt->type ){
    error( "Option '" + namestring + "' looked up with incompatible type" );
  }
  
  values.resize( opt->args.size() );

  // These calls to evaluate are inefficient, because the arguments were evaluated when they were parsed
  for( unsigned i = 0; i < opt->args.size(); ++i ){
    evaluate( *opt, &(values[i]), "", &i );
  }

}
template<typename T >
bool ProgOptions::getOpt ( const std::string &  namestring,
T *  value 
)

Get the value of the named option.

Parameters:
namestringThe name string given when the option was created. This need not be idential to the created name; only the longname, or the shortname (with comma prefix), will also work.
valuePointer to location to store option argument, if any is found
Returns:
True if the option was set and its argument was stored into value; false otherwise.

Definition at line 536 of file ProgOptions.cpp.

                                                           {
 
  ProgOpt* opt = lookup_option( namestring );

  if( get_opt_type<T>() != opt->type ){
    error( "Option '" + namestring + "' looked up with incompatible type" );
  }
  
  // This call to evaluate is inefficient, because opt was already evaluated when it was parsed.
  if( opt->args.size() ){
    if (t)
      evaluate( *opt, t, "" );
    return true;
  }
  else return false;

}
template<typename T >
void ProgOptions::getOptAllArgs ( const std::string &  namestring,
std::vector< T > &  values 
)

Get a list of values for the named option-- one value for each time it was given on the command line.

This function cannot be called with void as the template parameter; compilers will reject vector<void> as a type. This means it cannot be called for flag-type options. To count the number of times a given flag was specified, use numOptSet()

Parameters:
namestringSee similar argument to getOpt()
valuesReference to list to store values into. Will have as many entries as there were instances of this option on the command line

Definition at line 555 of file ProgOptions.cpp.

                                                                                  {
  ProgOpt* opt = lookup_option( namestring );

    // special case: if user asks for list of int, but argument
    // was INT_VECT, concatenate all lists
  if (get_opt_type<T>() == INT && opt->type == INT_VECT) {
    for (unsigned i = 0; i < opt->args.size(); ++i)
      evaluate( *opt, &values, "", &i );
    return;
  }
  
  if( get_opt_type<T>() != opt->type ){
    error( "Option '" + namestring + "' looked up with incompatible type" );
  }
  
  values.resize( opt->args.size() );

  // These calls to evaluate are inefficient, because the arguments were evaluated when they were parsed
  for( unsigned i = 0; i < opt->args.size(); ++i ){
    evaluate( *opt, &(values[i]), "", &i );
  }

}
template<typename T >
T ProgOptions::getReqArg ( const std::string &  namestring)

Retrieve the value of a required command-line argument by name

Parameters:
namestringThe helpname that was given to addRequiredArg when the desired argument was created

Definition at line 595 of file ProgOptions.cpp.

                                                     {
  
  ProgOpt* opt = lookup( required_args, namestring );
  
  if( !opt ){
    error( "Could not look up required arg: " + namestring );
  }
  
  // if parseProgramOptions succeeded, we can assume each required arg has a value,
  // so calling evaluate is valid
  T value;
  evaluate( *opt, &value, "" );
  return value; 

}
ProgOpt * ProgOptions::lookup ( const std::map< std::string, ProgOpt * > &  table,
const std::string &  arg 
) [protected]

Definition at line 341 of file ProgOptions.cpp.

                                                                                             {
  std::map<std::string, ProgOpt*>::const_iterator it = table.find( arg );
  if (it != table.end())
    return it->second;
  else if (&table == &short_names && 
           arg.size() == 1 && 
           isdigit(arg[0]) &&
           !number_option_name.empty() &&
           (it = long_names.find(number_option_name)) != long_names.end())
    return it->second;
  else
    return 0;
}
ProgOpt * ProgOptions::lookup_option ( const std::string &  namestring) [protected]

Definition at line 355 of file ProgOptions.cpp.

                                                                {
  std::string longname, shortname;
  get_namestrings( namestring, &longname, &shortname );
  
  ProgOpt* opt = lookup( long_names, longname );
  if( !opt ) opt = lookup( short_names, shortname );
  
  if( !opt ){
    error( "Invalid option: " + namestring );
  }
  
  return opt;
}
int ProgOptions::numOptSet ( const std::string &  namestring)
Parameters:
namestringSee similar argument to getOpt()
Returns:
The number of times the named option appeared on the command line.

Definition at line 579 of file ProgOptions.cpp.

                                                       {
  std::string longname, shortname;
  get_namestrings( namestring, &longname, &shortname );
  
  ProgOpt* opt = lookup( long_names, longname );
  if( !opt ) opt = lookup( short_names, shortname );

  if( !opt ){
    error( "Could not look up option: " + namestring );
  }
  
  return opt->args.size();

}
void ProgOptions::parseCommandLine ( int  argc,
char *  argv[] 
)

Parse command-line inputs as given to main()

Definition at line 686 of file ProgOptions.cpp.

                                                          {
  const char* name = strrchr(argv[0],'/');
  if (name)
    this->progname = ++name;
  else
    this->progname = argv[0];

  std::vector<const char*> args;
  std::list<ProgOpt*> expected_vals;
  bool no_more_flags = false;                    

    // Loop over all command line arguments
  for( int i = 1; i < argc; ++i ) {
    std::string arg(argv[i]);
    if (arg.empty())
      continue;
    
    if (!expected_vals.empty()) {
      ProgOpt* opt = expected_vals.front();
      expected_vals.pop_front();
      assert(opt->type != FLAG);
      opt->args.push_back( arg );
      evaluate( *opt, opt->storage, arg );
    }
    else if (!no_more_flags && arg[0] == '-') {
      if (arg.length() > 2 && arg[1] == '-') { // long opt
        size_t eq = arg.find_first_of('=');
        if (eq != std::string::npos) {
          ProgOpt* opt = lookup( long_names, arg.substr( 2, eq-2 ) );
          process_option( opt, arg, arg.substr( eq+1 ).c_str() );
        }
        else {
          ProgOpt* opt = lookup( long_names, arg.substr( 2 ) );
          if (process_option( opt, arg )) 
            expected_vals.push_back( opt );
        }
      }
      else if (arg == "--") { // --
        no_more_flags = true;
      }
      else for (size_t f = 1; f < arg.length(); ++f) { // for each short opt
        ProgOpt* opt = lookup( short_names, std::string(1,arg[f]) );
        if (opt->flags & int_flag) {
          const char val[] = { arg[f], 0 };
          process_option( opt, std::string(1,arg[f]), val );
        }
        else if (process_option( opt, std::string(1,arg[f]) ))
          expected_vals.push_back( opt );
      }
    }
    else{ 
      /* arguments */
      args.push_back(argv[i]);
    }
  }/* End loop over inputs */

    // Print error if any missing values
  if (!expected_vals.empty()) {
    error( "Missing value for option: -" + 
           expected_vals.front()->shortname + ",--" + 
           expected_vals.front()->longname );
  }

    // Process non-option arguments
  std::vector<help_line>::iterator arg_help_pos = arg_help_strings.begin();
  std::vector<const char*>::iterator arg_val_pos = args.begin();
  std::vector<help_line>::iterator opt_args_pos = arg_help_strings.end();
  size_t min_required_args = required_args.size();
  size_t max_required_args = required_args.size();
  if (expect_optional_args) {
    min_required_args--;
    if (max_optional_args)
      max_required_args += max_optional_args;
    else
      max_required_args = std::numeric_limits<int>::max();
    opt_args_pos = arg_help_pos + optional_args_position;
  }
  // check valid number of non-flag arguments
  if (args.size() < min_required_args) {
    size_t missing_pos = args.size();
    if (expect_optional_args && missing_pos >= optional_args_position)
      ++missing_pos;
    
    const std::string& missed_arg = arg_help_strings[missing_pos].first->longname; 
    error("Did not find required positional argument: " + missed_arg );
  }
  else if (args.size() > max_required_args) {
    error( "Unexpected argument: " + std::string(args[max_required_args]) );  
  }
  
  // proccess arguments up to the first optional argument
  // (or all arguments if no optional args)
  while (arg_help_pos != opt_args_pos) {
    ProgOpt* opt = arg_help_pos->first;
    ++arg_help_pos;
    opt->args.push_back( *arg_val_pos );
    evaluate( *opt, opt->storage, *arg_val_pos );
    ++arg_val_pos;
  }
  // process any optional args
  if (arg_help_pos != arg_help_strings.end()) {
    assert( arg_help_pos == opt_args_pos );
    size_t num_opt_args = args.size() + 1 - required_args.size();
    ProgOpt* opt = arg_help_pos->first;
    ++arg_help_pos;
    while (num_opt_args--) {
      opt->args.push_back( *arg_val_pos );
      evaluate( *opt, opt->storage, *arg_val_pos );
      ++arg_val_pos;
    }
  }
  // process any remaining args
  while (arg_help_pos != arg_help_strings.end()) {
    assert(arg_val_pos != args.end());
    ProgOpt* opt = arg_help_pos->first;
    ++arg_help_pos;
    opt->args.push_back( *arg_val_pos );
    evaluate( *opt, opt->storage, *arg_val_pos );
    ++arg_val_pos;
  }
  assert(arg_val_pos == args.end());
}
void ProgOptions::printHelp ( std::ostream &  str = std::cout)

Print the full help to the given stream

Definition at line 209 of file ProgOptions.cpp.

                                            {
  
  /* Print introductory help text */
  if (!brief_help.empty())
    out << brief_help << std::endl;
  for( std::vector<std::string>::iterator i = main_help.begin(); i!= main_help.end(); ++i ){
    if( (*i).length() ){
      out << std::endl << *i << std::endl;
    }
  }

  printUsage( out );

  // max number of characters to pad argument/option names with
  // options with long names may exceed this, but will appear out of alignment in help text
  const int max_padding = 20;

  /* List required arguments, with help text */
  if( arg_help_strings.size() > 0 ){
    
    int max_arg_namelen = 0;
    
    for( std::vector<help_line>::iterator i = arg_help_strings.begin();
         i != arg_help_strings.end(); ++i )
      {
        max_arg_namelen = std::max( max_arg_namelen, (int)((*i).first->longname.length()) );
      }
    
    max_arg_namelen = std::min( max_arg_namelen+3, max_padding );

    out << "Arguments: " << std::endl;
    
    for( std::vector<help_line>::iterator i = arg_help_strings.begin();
         i != arg_help_strings.end(); ++i )
      {
        ProgOpt* option = (*i).first;
        std::string& info = (*i).second;

        std::stringstream s;
        s << "  " << option->longname;
        out << std::setw(max_arg_namelen) << std::left << s.str();
        out << ": " << info << std::endl;
        
      }
  }
    
  /* List options, with help text */
  out << "Options: " << std::endl;
  int max_option_prefix_len = 0;

  for( std::vector<help_line>::iterator i = option_help_strings.begin();
       i != option_help_strings.end(); ++ i )
  {
    ProgOpt* option = (*i).first;
    std::string& info = (*i).second;

    if( option ){

      if( max_option_prefix_len == 0 ){
        // iterate ahead in the option list to determine whitespace padding
        // stop if (*j).first is NULL, which indicates a help header message 
        for( std::vector<help_line>::iterator j = i; j!=option_help_strings.end() && (*j).first; ++j ){
          int len = get_option_usage_prefix( *((*j).first) ).length();
          max_option_prefix_len = std::max (max_option_prefix_len, len);
        }
      }
      max_option_prefix_len = std::min( max_option_prefix_len, max_padding );
      std::string option_prefix = get_option_usage_prefix( *option );

      out << std::setw(max_option_prefix_len) << std::left <<  option_prefix; 
      out << ": ";
    }
    else{ 
      // no option: this is a help header.  Reset max name length.
      max_option_prefix_len = 0;
    }
    out << info << std::endl;
  }
}
void ProgOptions::printUsage ( std::ostream &  str = std::cout)

Print only the usage message to the given stream

Definition at line 320 of file ProgOptions.cpp.

                                             {

  out << "Usage: " << progname << " --help | [options] ";

  for (size_t i = 0 ; i < arg_help_strings.size(); ++i)
  {
    if (!expect_optional_args || i != optional_args_position) 
      out << '<' << arg_help_strings[i].first->longname << "> "; 
    else if (0 == max_optional_args || max_optional_args > 3)
      out << "[<" << arg_help_strings[i].first->longname << "> ...] ";
    else if (1 == max_optional_args)
      out << "[" << arg_help_strings[i].first->longname << "] ";
    else for (unsigned j = 0; j < max_optional_args; ++j)
      out << "[" << arg_help_strings[i].first->longname << (j+1) << "] ";
  }
    
  out << std::endl;

}
void ProgOptions::printVersion ( std::ostream &  str = std::cout)

Print the version string to the given stream

Definition at line 205 of file ProgOptions.cpp.

                                               {
  out << progversion << std::endl;
}
bool ProgOptions::process_option ( ProgOpt opt,
std::string  arg,
const char *  value = 0 
) [protected]

Definition at line 640 of file ProgOptions.cpp.

{
  if( !opt ){
    if (arg == "--manpage") {
      write_man_page(std::cout);
      exit(0);
    }
    
    error ("Unknown option: " + arg );
  }

  if( opt->flags & help_flag ){
    printHelp( std::cout );
    exit( EXIT_SUCCESS );
  }

  if( opt->flags & version_flag ){
    printVersion( std::cout );
    exit( EXIT_SUCCESS );
  }
  
  if (opt->type != FLAG) {
    if (!value)
      return true;
    
    opt->args.push_back( value );
    evaluate( *opt, opt->storage, arg );
  }
  else {
    if (value) {
      error( "Unexpected value for flag: " + arg );
    }

    // do flag operations
    if( opt->cancel_opt ){ opt->cancel_opt->args.clear(); }
    if( opt->storage ){
      *static_cast<bool*>(opt->storage) = ( opt->flags & store_false ) ? false : true;            
      *static_cast<bool*>(opt->storage) = ( opt->flags & store_true ) ? true : false;            
    }
    opt->args.push_back(""); 
  }
  
  return false;
}
void ProgOptions::setVersion ( const std::string &  version_string,
bool  addFlag = true 
)

Specify the program version

Set the program version to a given string. This will be printed when printVersion() is called.

Parameters:
version_stringThe version string
addflagIf true, a default '--version' option will be added. If false, the version will be set, but no option will be added to the parser.

Definition at line 111 of file ProgOptions.cpp.

                                                                           {
  progversion = version_string;
  if( addFlag ){
    addOpt<void>( "version", "Print version number and exit", version_flag );
  }
}
void ProgOptions::write_man_page ( std::ostream &  to_this_stream)

Write help data formatted for use as a unix man page.

Definition at line 809 of file ProgOptions.cpp.

{
  // a leading '.' is a control character.  strip it if present.
  std::string lprogname;
  if (progname.empty() || progname[0] != '.')
    lprogname = progname;
  else {
    lprogname = progname.substr(1);
  }

  // Manpage controls:
  // .TH title
  // .SH section
  // .SS subsection
  // .P  paragraph
  // .HP hanging paragraph
  // .B  bold
  // .I  italic
  // .B  bold
  // .I  italic
  // .RS begin indent
  // .RE end indent
  // .RB alternating roman and blold
  // .BR alternating bold and roman

  std::vector<help_line>::iterator it;
  std::set<ProgOpt*> skip_list;

  // start man page
  s << std::endl << ".TH " << lprogname << " 1" << std::endl;

  // write NAME section
  s << std::endl << ".SH NAME" << std::endl
    << ".P " << std::endl
    << lprogname << " \\- ";
  if (brief_help.empty() && !main_help.empty())
    s << main_help.front();
  else
    s << brief_help;
  s << std::endl << std::endl;

  // write SYNOPSIS section
  s << std::endl << ".SH SYNOPSIS" << std::endl
    << ".HP" << std::endl 
    << ".B \"" << lprogname << '"' << std::endl;
  for (it = option_help_strings.begin(); it != option_help_strings.end(); ++it) {
    if (!it->first || 
        skip_list.find( it->first ) != skip_list.end() ||
        it->first->longname == "help")
      continue;
    
    if (it->first->type == FLAG) {
      char c = '[';
      s << ".RB";
      if (!it->first->shortname.empty()) {
        s << ' ' << c << " \"-" << it->first->shortname << '"';
        c = '|';
      }
      if (!it->first->longname.empty()) {
        s << ' ' << c << " \"--" << it->first->longname << '"';
      }
      if (it->first->cancel_opt) {
        skip_list.insert( it->first->cancel_opt );
        if (!it->first->cancel_opt->shortname.empty())
          s << " | \"-" << it->first->cancel_opt->shortname << '"';
        if (!it->first->cancel_opt->longname.empty()) 
          s << " | \"--" << it->first->cancel_opt->longname << '"';
      }
      s << " ]" << std::endl;
    }
    else if (it->first->flags & int_flag) {
      s << ".RB [ - <n>| \"--" << it->first->longname
        << "\" \"=" << it->first->get_argstring() << "]\"" << std::endl;
    }
    else {
      s << ".RB [ ";
      if (!it->first->shortname.empty()) 
        s << "\"-" << it->first->shortname << "\" \"\\ " << it->first->get_argstring();
      if (!it->first->shortname.empty() && !it->first->longname.empty())
        s << "|\" ";
      if (!it->first->longname.empty())
        s << "\"--" << it->first->longname
          << "\" \"=" << it->first->get_argstring();
      s << "]\"" << std::endl;
    }
  }
  for (it = arg_help_strings.begin(); it != arg_help_strings.end(); ++it) {
    if (!it->first)
      continue;
    
    if (!expect_optional_args || (it - arg_help_strings.begin()) != optional_args_position)
      s << it->first->longname << ' ';
    else if (1 == max_optional_args)
      s << '[' << it->first->longname << "] ";
    else 
      s << '[' << it->first->longname << " ...] ";
  }
  s << std::endl;
  s << ".HP" << std::endl 
    << ".B \"" << lprogname << " -h|--help\"" << std::endl;
  
    // write DESCRIPTION section
  s << std::endl << ".SH DESCRIPTION" << std::endl;
  if (main_help.empty())
    s << brief_help << std::endl;
  for (size_t i = 0; i < main_help.size(); ++i) {
    const std::string::size_type n = main_help[i].size();
    std::string::size_type j = 0, k;
    s << std::endl << ".P" << std::endl;
    while (j != n) {
      if (main_help[i][j] == '\n') {
        s << std::endl << ".P" << std::endl;
        ++j;
        continue;
      }
      k = main_help[i].find( "\n", j );
      if (k == std::string::npos)
        k = n;
      if (main_help[i][j] == '.')
        s << '\\';
      s << main_help[i].substr( j, k - j );
      j = k;
    }
  }
  
    // write OPTIONS section
  s << std::endl << ".SH OPTIONS" << std::endl;
  for (it = arg_help_strings.begin(); it != arg_help_strings.end(); ++it) {
    if (it->first) 
      s << ".IP \"" << it->first->longname << '"' << std::endl << it->second << std::endl;
    else
      s << ".SS " << it->first->longname << std::endl;
  }
  for (it = option_help_strings.begin(); it != option_help_strings.end(); ++it) {
    if (!it->first) {
      s << ".SS " << it->second << std::endl;
      continue;
    }
    
    s << ".IP \"";
    if (it->first->longname.empty())
      s << "-" << it->first->shortname;
    else if (it->first->shortname.empty())
      s << "--" << it->first->longname;
    else
      s << "-" << it->first->shortname << ", --" << it->first->longname;
    s << '"' << std::endl << it->second << std::endl;
  }
  s << std::endl;
}

Member Data Documentation

const int ProgOptions::add_cancel_opt = 1<<1 [static]

Flag indicating that an option should be given a "cancel" flag. This creates, for option --foo, an additional option --no-foo that clears all previously read instances of the foo option

Definition at line 59 of file ProgOptions.hpp.

std::vector< help_line > ProgOptions::arg_help_strings [protected]

Definition at line 278 of file ProgOptions.hpp.

std::string ProgOptions::brief_help [protected]

Definition at line 280 of file ProgOptions.hpp.

Definition at line 282 of file ProgOptions.hpp.

const int ProgOptions::help_flag = 1<<0 [static]

Flags for addOpt and addRequiredArg functions; may be combined with bitwise arithmetic (though not all combinations make sense!) Set for a flag that, when detected, prints help text and halts program. Constructor creates such a flag by default, so the user shouldn't need to use this directly.

Definition at line 54 of file ProgOptions.hpp.

const int ProgOptions::int_flag = 1<<3 [static]

Specify a numerical flag where any positive integer is an acceptable value. E.g. --dimension=3 is equivalent to -3. Only values in the range [0,9] are accepted and the flag type must be integer.

Definition at line 69 of file ProgOptions.hpp.

std::map< std::string, ProgOpt* > ProgOptions::long_names [protected]

Definition at line 272 of file ProgOptions.hpp.

std::vector< std::string > ProgOptions::main_help [protected]

Definition at line 279 of file ProgOptions.hpp.

unsigned ProgOptions::max_optional_args [protected]

Definition at line 283 of file ProgOptions.hpp.

std::string ProgOptions::number_option_name [protected]

Definition at line 290 of file ProgOptions.hpp.

std::vector< help_line > ProgOptions::option_help_strings [protected]

Definition at line 277 of file ProgOptions.hpp.

Definition at line 283 of file ProgOptions.hpp.

std::string ProgOptions::progname [protected]

Definition at line 285 of file ProgOptions.hpp.

std::string ProgOptions::progversion [protected]

Definition at line 286 of file ProgOptions.hpp.

const int ProgOptions::rank_subst = 1<<4 [static]

Substitue any occurance of the '' symbol in a string with the the MPI rank of this process in MPI_COMM_WORLD. This option has no effect if not compiled with MPI. This flag has no effect for non-string options.

Definition at line 76 of file ProgOptions.hpp.

std::map< std::string, ProgOpt* > ProgOptions::required_args [protected]

Definition at line 274 of file ProgOptions.hpp.

std::map< std::string, ProgOpt* > ProgOptions::short_names [protected]

Definition at line 273 of file ProgOptions.hpp.

const int ProgOptions::store_false = 1<<2 [static]

When applied to a flag argument (one with template type void), indicate that the value 'false' should be stored into the pointer that was given at option creation time. This overrides the default behavior, which is to store the value 'true'.

Definition at line 64 of file ProgOptions.hpp.

const int ProgOptions::store_true = 1<<6 [static]

When applied to a flag argument (one with template type void), indicate that the value 'true' should be stored into the pointer that was given at option creation time.

Definition at line 83 of file ProgOptions.hpp.

const int ProgOptions::version_flag = 1<<5 [static]

Set for a flag that, when detected, will call printVersion() and halt the program.

Definition at line 79 of file ProgOptions.hpp.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines