MOAB: Mesh Oriented datABase
(version 5.4.1)
|
#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. | |
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 35 of file ProgOptions.hpp.
typedef std::pair< ProgOpt*, std::string > ProgOptions::help_line [protected] |
Definition at line 262 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 94 of file ProgOptions.cpp.
References brief_help, help_flag, and main_help.
: expect_optional_args( false ), optional_args_position( 0 ), max_optional_args( 0 ) { brief_help = briefhelp; if( !helpstring.empty() ) main_help.push_back( helpstring ); addOpt< void >( "help,h", "Show full help text", help_flag ); }
Definition at line 102 of file ProgOptions.cpp.
References arg_help_strings, and option_help_strings.
{ 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 141 of file ProgOptions.cpp.
References add_cancel_opt, ProgOpt::cancel_opt, error(), FLAG, get_namestrings(), help(), INT, int_flag, long_names, number_option_name, option_help_strings, short_names, ProgOpt::storage, and store_false.
Referenced by main(), parse_options(), ToolContext::ParseCLOptions(), test_flag_cancel(), test_flag_opt_long(), test_flag_opt_long_short(), test_flag_opt_short(), test_flag_store_false(), test_int_opt(), test_int_vect_opt(), test_real_opt(), test_squashed_short(), test_string_opt(), and test_string_rank_subst().
{ 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 122 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 192 of file ProgOptions.cpp.
References arg_help_strings, expect_optional_args, max_optional_args, optional_args_position, and required_args.
Referenced by test_optional_arg(), and test_optional_args().
{ // 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 216 of file ProgOptions.cpp.
References option_help_strings.
Referenced by main().
{ 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 179 of file ProgOptions.cpp.
References arg_help_strings, help(), and required_args.
Referenced by main(), test_int_arg(), test_int_vect_arg(), test_optional_arg(), test_optional_args(), test_real_arg(), test_string_arg(), and test_string_rank_subst().
{ 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 396 of file ProgOptions.cpp.
References printUsage().
Referenced by addOpt(), evaluate(), getArgs(), getOpt(), getOptAllArgs(), getReqArg(), lookup_option(), main(), numOptSet(), parseCommandLine(), and process_option().
{ std::cerr << "Error: " << err << "\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 501 of file ProgOptions.cpp.
References ProgOpt::args, do_rank_subst(), error(), FLAG, ProgOpt::flags, INT, INT_VECT, parse_int_list(), rank_subst, REAL, STRING, and ProgOpt::type.
Referenced by getArgs(), getOpt(), getOptAllArgs(), getReqArg(), parseCommandLine(), and process_option().
{ 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 118 of file ProgOptions.cpp.
Referenced by addOpt(), lookup_option(), and numOptSet().
{ *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 309 of file ProgOptions.cpp.
References ProgOpt::flags, ProgOpt::get_argstring(), int_flag, ProgOpt::longname, and ProgOpt::shortname.
Referenced by printHelp().
{ 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 655 of file ProgOptions.cpp.
References ProgOpt::args, error(), evaluate(), lookup(), required_args, and ProgOpt::type.
Referenced by test_optional_arg(), and test_optional_args().
{ 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 571 of file ProgOptions.cpp.
References ProgOpt::args, error(), evaluate(), lookup_option(), and ProgOpt::type.
Referenced by main(), test_int_opt(), test_int_vect_opt(), test_real_opt(), test_string_opt(), and test_string_rank_subst().
{ 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 592 of file ProgOptions.cpp.
References ProgOpt::args, error(), evaluate(), INT, INT_VECT, lookup_option(), and ProgOpt::type.
Referenced by main(), ToolContext::ParseCLOptions(), test_int_opt(), test_int_vect_opt(), test_real_opt(), test_string_opt(), and test_string_rank_subst().
{ 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 637 of file ProgOptions.cpp.
References error(), evaluate(), lookup(), required_args, and T.
Referenced by test_int_arg(), test_int_vect_arg(), test_real_arg(), test_string_arg(), and test_string_rank_subst().
ProgOpt * ProgOptions::lookup | ( | const std::map< std::string, ProgOpt * > & | table, |
const std::string & | arg | ||
) | [protected] |
Definition at line 368 of file ProgOptions.cpp.
References long_names, number_option_name, and short_names.
Referenced by getArgs(), getReqArg(), lookup_option(), numOptSet(), and parseCommandLine().
{ 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 380 of file ProgOptions.cpp.
References error(), get_namestrings(), long_names, lookup(), and short_names.
Referenced by getOpt(), and getOptAllArgs().
{ 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 620 of file ProgOptions.cpp.
References ProgOpt::args, error(), get_namestrings(), long_names, lookup(), and short_names.
Referenced by main(), ToolContext::ParseCLOptions(), test_flag_opt_long(), test_flag_opt_long_short(), test_flag_opt_short(), and test_squashed_short().
{ 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 737 of file ProgOptions.cpp.
References arg_help_strings, args, ProgOpt::args, error(), evaluate(), expect_optional_args, FLAG, ProgOpt::flags, int_flag, long_names, lookup(), max_optional_args, optional_args_position, process_option(), progname, required_args, short_names, ProgOpt::storage, and ProgOpt::type.
Referenced by main(), ToolContext::ParseCLOptions(), test_flag_cancel(), test_flag_opt_long(), test_flag_opt_long_short(), test_flag_opt_short(), test_flag_store_false(), test_int_arg(), test_int_opt(), test_int_vect_arg(), test_int_vect_opt(), test_optional_arg(), test_optional_args(), test_real_arg(), test_real_opt(), test_squashed_short(), test_string_arg(), test_string_opt(), and test_string_rank_subst().
{ 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 && ( 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 226 of file ProgOptions.cpp.
References arg_help_strings, brief_help, get_option_usage_prefix(), ProgOpt::longname, main_help, option_help_strings, and printUsage().
Referenced by main(), and process_option().
{ /* 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 347 of file ProgOptions.cpp.
References arg_help_strings, expect_optional_args, moab::GeomUtil::first(), max_optional_args, optional_args_position, and progname.
Referenced by error(), and printHelp().
{ 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 221 of file ProgOptions.cpp.
References progversion.
Referenced by process_option().
{ out << progversion << std::endl; }
bool ProgOptions::process_option | ( | ProgOpt * | opt, |
std::string | arg, | ||
const char * | value = 0 |
||
) | [protected] |
Definition at line 683 of file ProgOptions.cpp.
References ProgOpt::args, ProgOpt::cancel_opt, error(), evaluate(), FLAG, ProgOpt::flags, help_flag, printHelp(), printVersion(), ProgOpt::storage, store_false, ProgOpt::type, version_flag, and write_man_page().
Referenced by parseCommandLine().
{ 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; } 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 131 of file ProgOptions.cpp.
References progversion, and version_flag.
{ 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 876 of file ProgOptions.cpp.
References arg_help_strings, brief_help, expect_optional_args, FLAG, int_flag, main_help, max_optional_args, option_help_strings, optional_args_position, and progname.
Referenced by process_option().
{ // 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 || (unsigned)( 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 51 of file ProgOptions.hpp.
Referenced by addOpt(), main(), and test_flag_cancel().
std::vector< help_line > ProgOptions::arg_help_strings [protected] |
Definition at line 264 of file ProgOptions.hpp.
Referenced by addOptionalArgs(), addRequiredArg(), parseCommandLine(), printHelp(), printUsage(), write_man_page(), and ~ProgOptions().
std::string ProgOptions::brief_help [protected] |
Definition at line 266 of file ProgOptions.hpp.
Referenced by printHelp(), ProgOptions(), and write_man_page().
bool ProgOptions::expect_optional_args [protected] |
Definition at line 268 of file ProgOptions.hpp.
Referenced by addOptionalArgs(), parseCommandLine(), printUsage(), and write_man_page().
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 46 of file ProgOptions.hpp.
Referenced by process_option(), and ProgOptions().
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 61 of file ProgOptions.hpp.
Referenced by addOpt(), get_option_usage_prefix(), main(), parse_options(), parseCommandLine(), and write_man_page().
std::map< std::string, ProgOpt* > ProgOptions::long_names [protected] |
Definition at line 258 of file ProgOptions.hpp.
Referenced by addOpt(), lookup(), lookup_option(), numOptSet(), and parseCommandLine().
std::vector< std::string > ProgOptions::main_help [protected] |
Definition at line 265 of file ProgOptions.hpp.
Referenced by printHelp(), ProgOptions(), and write_man_page().
unsigned ProgOptions::max_optional_args [protected] |
Definition at line 269 of file ProgOptions.hpp.
Referenced by addOptionalArgs(), parseCommandLine(), printUsage(), and write_man_page().
std::string ProgOptions::number_option_name [protected] |
Definition at line 276 of file ProgOptions.hpp.
std::vector< help_line > ProgOptions::option_help_strings [protected] |
Definition at line 263 of file ProgOptions.hpp.
Referenced by addOpt(), addOptionHelpHeading(), printHelp(), write_man_page(), and ~ProgOptions().
unsigned ProgOptions::optional_args_position [protected] |
Definition at line 269 of file ProgOptions.hpp.
Referenced by addOptionalArgs(), parseCommandLine(), printUsage(), and write_man_page().
std::string ProgOptions::progname [protected] |
Definition at line 271 of file ProgOptions.hpp.
Referenced by parseCommandLine(), printUsage(), and write_man_page().
std::string ProgOptions::progversion [protected] |
Definition at line 272 of file ProgOptions.hpp.
Referenced by printVersion(), and setVersion().
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 68 of file ProgOptions.hpp.
Referenced by evaluate(), and test_string_rank_subst().
std::map< std::string, ProgOpt* > ProgOptions::required_args [protected] |
Definition at line 260 of file ProgOptions.hpp.
Referenced by addOptionalArgs(), addRequiredArg(), getArgs(), getReqArg(), and parseCommandLine().
std::map< std::string, ProgOpt* > ProgOptions::short_names [protected] |
Definition at line 259 of file ProgOptions.hpp.
Referenced by addOpt(), lookup(), lookup_option(), numOptSet(), and parseCommandLine().
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 56 of file ProgOptions.hpp.
Referenced by addOpt(), process_option(), and test_flag_store_false().
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 71 of file ProgOptions.hpp.
Referenced by process_option(), and setVersion().