cgma
|
#include <ProgOptions.hpp>
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 > | |
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) |
ProgOpt * | lookup (const std::map< std::string, ProgOpt * > &, const std::string &) |
ProgOpt * | lookup_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_line > | option_help_strings |
std::vector< help_line > | arg_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 |
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.
typedef std::pair<ProgOpt*, std::string> ProgOptions::help_line [protected] |
Definition at line 276 of file ProgOptions.hpp.
ProgOptions::ProgOptions | ( | const std::string & | helptext = "" , |
const std::string & | briefdesc = "" |
||
) |
unimplemented flag for required arguments that may be given multiple times
helptext | A 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; } }
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.
namestring | The 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. |
helpstring | The help information displayed for the option when the program is invoked with --help |
value | A 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) |
flags | Option 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 ); } }
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 ); }
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)
count | The maximum number of optional arguments. Specify zero for unlimited. |
helpname | The name to give the argument in the help text |
helpstring | The 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) ); }
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)
helpname | The name to give the argument in the help text |
helpstring | The help text for the argument |
value | Pointer 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.
message | The 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.
option | Used only in error messages to state which option could not be successfully converted |
arg_idx | If 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(); }
void ProgOptions::getArgs | ( | const std::string & | namestring, |
std::vector< T > & | values | ||
) |
Append the values of any required or optional arguments
namestring | The 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 ); } }
bool ProgOptions::getOpt | ( | const std::string & | namestring, |
T * | value | ||
) |
Get the value of the named option.
namestring | The 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. |
value | Pointer to location to store option argument, if any is found |
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; }
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()
namestring | See similar argument to getOpt() |
values | Reference 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 ); } }
T ProgOptions::getReqArg | ( | const std::string & | namestring | ) |
Retrieve the value of a required command-line argument by name
namestring | The 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 | ) |
namestring | See similar argument to getOpt() |
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.
version_string | The version string |
addflag | If 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; }
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.
bool ProgOptions::expect_optional_args [protected] |
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.
unsigned ProgOptions::optional_args_position [protected] |
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.