Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
ProgOptions Class Reference

#include <ProgOptions.hpp>

+ Collaboration diagram for ProgOptions:

Public Member Functions

 ProgOptions (const std::string &helptext="", const std::string &briefdesc="")
 unimplemented flag for required arguments that may be given multiple times More...
 
 ~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
 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. More...
 
static const int add_cancel_opt = 1 << 1
 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. More...
 
static const int store_false = 1 << 2
 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'. More...
 
static const int int_flag = 1 << 3
 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. More...
 
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. More...
 

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.

Examples
ComputeTriDual.cpp, CrystalRouterExample.cpp, DeformMeshRemap.cpp, DirectAccessNoHoles.cpp, DirectAccessWithHoles.cpp, ExtractLand.cpp, GenLargeMesh.cpp, LaplacianSmoother.cpp, StructuredMeshSimple.cpp, addPCdata.cpp, and copyPartition.cpp.

Definition at line 35 of file ProgOptions.hpp.

Member Typedef Documentation

◆ help_line

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

Definition at line 262 of file ProgOptions.hpp.

Constructor & Destructor Documentation

◆ ProgOptions()

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 94 of file ProgOptions.cpp.

96 {
97  brief_help = briefhelp;
98  if( !helpstring.empty() ) main_help.push_back( helpstring );
99  addOpt< void >( "help,h", "Show full help text", help_flag );
100 }

References brief_help, help_flag, and main_help.

◆ ~ProgOptions()

ProgOptions::~ProgOptions ( )

Definition at line 102 of file ProgOptions.cpp.

103 {
104  for( std::vector< help_line >::iterator i = option_help_strings.begin(); i != option_help_strings.end(); ++i )
105  {
106  if( ( *i ).first )
107  {
108  delete( *i ).first;
109  }
110  }
111 
112  for( std::vector< help_line >::iterator i = arg_help_strings.begin(); i != arg_help_strings.end(); ++i )
113  {
114  delete( *i ).first;
115  }
116 }

References arg_help_strings, and option_help_strings.

Member Function Documentation

◆ addOpt() [1/2]

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 122 of file ProgOptions.hpp.

123  {
124  addOpt< T >( namestring, helpstring, NULL, flags );
125  }

◆ addOpt() [2/2]

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
Examples
ComputeTriDual.cpp, CrystalRouterExample.cpp, DirectAccessNoHoles.cpp, DirectAccessWithHoles.cpp, ExtractLand.cpp, GenLargeMesh.cpp, LaplacianSmoother.cpp, StructuredMeshSimple.cpp, addPCdata.cpp, and copyPartition.cpp.

Definition at line 141 of file ProgOptions.cpp.

142 {
143 
144  std::string shortname, longname;
145  get_namestrings( namestring, &longname, &shortname );
146 
147  if( flags & int_flag )
148  { // short name is implicit for this flag
149  if( !shortname.empty() ) error( "Requested short name with int_flag option" );
150  if( get_opt_type< T >() != INT ) error( "Requested int_flag for non-integer option" );
151  if( !number_option_name.empty() ) error( "Requested int_flag for multiple options" );
152  number_option_name = longname;
153  }
154 
155  ProgOpt* opt = new ProgOpt( longname, shortname, flags, get_opt_type< T >() );
156  if( value ) opt->storage = value;
157 
158  if( longname.length() ) long_names[longname] = opt;
159  if( shortname.length() ) short_names[shortname] = opt;
160 
161  help_line help = std::make_pair( opt, helpstring );
162  option_help_strings.push_back( help );
163 
164  if( flags & add_cancel_opt )
165  {
166  std::string flag = "no-" + ( longname.length() ? longname : shortname );
167  ProgOpt* cancel_opt = new ProgOpt( flag, "", flags ^ ProgOptions::store_false, FLAG );
168  if( value ) cancel_opt->storage = value;
169 
170  cancel_opt->cancel_opt = opt;
171  long_names[flag] = cancel_opt;
172  std::string clear_helpstring = "Clear previous " + flag.substr( 3, flag.npos ) + " flag";
173  help = std::make_pair( cancel_opt, clear_helpstring );
174  option_help_strings.push_back( help );
175  }
176 }

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(), RuntimeContext::ParseCLOptions(), and ToolContext::ParseCLOptions().

◆ addOptionalArgs()

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 192 of file ProgOptions.cpp.

196 {
197  // If there was a previous one, we need to remove it
198  // because there can be only one. If we didn't remove
199  // the old one then it would be treated as a required arg.
201  {
202  std::map< std::string, ProgOpt* >::iterator iter;
204  assert( iter != required_args.end() );
205  delete iter->second;
206  required_args.erase( iter );
208  }
209 
210  expect_optional_args = true;
212  max_optional_args = max_count;
213  addRequiredArg< T >( helpname, helpstring, 0, flags );
214 }

References arg_help_strings, expect_optional_args, max_optional_args, optional_args_position, and required_args.

◆ addOptionHelpHeading()

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.

217 {
218  option_help_strings.push_back( std::make_pair( (ProgOpt*)NULL, s ) );
219 }

References option_help_strings.

Referenced by main().

◆ addRequiredArg()

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 179 of file ProgOptions.cpp.

180 {
181 
182  OptType type = get_opt_type< T >();
183 
184  ProgOpt* opt = new ProgOpt( helpname, "", flags, type );
185  if( value ) opt->storage = value;
186  help_line help = std::make_pair( opt, helpstring );
187  arg_help_strings.push_back( help );
188  required_args[helpname] = opt;
189 }

References arg_help_strings, help(), required_args, and ProgOpt::storage.

Referenced by main().

◆ error()

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 396 of file ProgOptions.cpp.

397 {
398  std::cerr << "Error: " << err << "\n" << std::endl;
399  ;
400  printUsage( std::cerr );
401  std::cerr << std::endl;
402  if( getenv( "MOAB_PROG_OPT_ABORT" ) ) abort();
403  std::exit( EXIT_FAILURE );
404 }

References printUsage().

Referenced by addOpt(), evaluate(), getArgs(), getOpt(), getOptAllArgs(), getReqArg(), lookup_option(), main(), numOptSet(), parseCommandLine(), and process_option().

◆ evaluate()

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 501 of file ProgOptions.cpp.

502 {
503 
504  unsigned idx = arg_idx ? *arg_idx : opt.args.size() - 1;
505 
506  switch( opt.type )
507  {
508  case FLAG:
509  error( "Cannot evaluate a flag" );
510  break;
511  case INT: {
512  int temp;
513  int* i = target ? reinterpret_cast< int* >( target ) : &temp;
514  if( opt.args.size() < 1 )
515  {
516  error( "Missing argument to " + option + " option" );
517  }
518  const char* arg = opt.args.at( idx ).c_str();
519  char* p;
520  *i = std::strtol( arg, &p, 0 );
521  if( *p != '\0' )
522  {
523  error( "Bad integer argument '" + opt.args.at( idx ) + "' to " + option + " option." );
524  }
525  return true;
526  }
527  case REAL: {
528  double temp;
529  double* i = target ? reinterpret_cast< double* >( target ) : &temp;
530  if( opt.args.size() < 1 )
531  {
532  error( "Missing argument to " + option + " option" );
533  }
534  const char* arg = opt.args.at( idx ).c_str();
535  char* p;
536  *i = std::strtod( arg, &p );
537  if( *p != '\0' )
538  {
539  error( "Bad real argument '" + opt.args.at( idx ) + "' to " + option + " option." );
540  }
541  return true;
542  }
543 
544  case STRING: {
545  std::string temp;
546  std::string* i = target ? reinterpret_cast< std::string* >( target ) : &temp;
547  if( opt.args.size() < 1 )
548  {
549  error( "Missing argument to " + option + " option" );
550  }
551  if( opt.flags & rank_subst )
552  *i = do_rank_subst( opt.args.at( idx ) );
553  else
554  *i = opt.args.at( idx );
555  return true;
556  }
557 
558  case INT_VECT: {
559  std::vector< int > temp;
560  std::vector< int >* i = target ? reinterpret_cast< std::vector< int >* >( target ) : &temp;
561  if( !parse_int_list( opt.args.at( idx ).c_str(), *i ) )
562  error( "Bad integer list '" + opt.args.at( idx ) + "' to " + option + " option." );
563  return true;
564  }
565  }
566 
567  return false;
568 }

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().

◆ get_namestrings()

void ProgOptions::get_namestrings ( const std::string &  input,
std::string *  l,
std::string *  s 
)
protected

Definition at line 118 of file ProgOptions.cpp.

119 {
120  *shortname = "";
121  *longname = namestring;
122 
123  size_t idx = namestring.find_first_of( ',' );
124  if( idx != namestring.npos )
125  {
126  *longname = namestring.substr( 0, idx );
127  *shortname = namestring.substr( idx + 1, namestring.npos );
128  }
129 }

Referenced by addOpt(), lookup_option(), and numOptSet().

◆ get_option_usage_prefix()

std::string ProgOptions::get_option_usage_prefix ( const ProgOpt option)
protected

Definition at line 309 of file ProgOptions.cpp.

310 {
311  bool has_shortname = option.shortname.length() > 0;
312  bool has_longname = option.longname.length() > 0;
313  std::string argstr = option.get_argstring();
314 
315  std::stringstream s;
316  s << " ";
317  if( has_shortname )
318  {
319 
320  s << "-" << option.shortname;
321  if( has_longname )
322  {
323  s << " ";
324  }
325  }
326  else if( option.flags & int_flag )
327  {
328 
329  s << "-<n>";
330  if( has_longname )
331  {
332  s << " ";
333  }
334  }
335  if( has_longname )
336  {
337 
338  if( has_shortname ) s << "[";
339  s << "--" << option.longname;
340  if( has_shortname ) s << "]";
341  }
342 
343  if( argstr.length() ) s << " <" << argstr << ">";
344  return s.str();
345 }

References ProgOpt::flags, ProgOpt::get_argstring(), int_flag, ProgOpt::longname, and ProgOpt::shortname.

Referenced by printHelp().

◆ getArgs()

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 655 of file ProgOptions.cpp.

656 {
657  ProgOpt* opt = lookup( required_args, namestring );
658 
659  if( !opt )
660  {
661  error( "Could not look up required arg: " + namestring );
662  }
663 
664  if( get_opt_type< T >() != opt->type )
665  {
666  error( "Option '" + namestring + "' looked up with incompatible type" );
667  }
668 
669  values.resize( opt->args.size() );
670 
671  // These calls to evaluate are inefficient, because the arguments were evaluated when they were
672  // parsed
673  for( unsigned i = 0; i < opt->args.size(); ++i )
674  {
675  evaluate( *opt, &( values[i] ), "", &i );
676  }
677 }

References ProgOpt::args, error(), evaluate(), lookup(), required_args, and ProgOpt::type.

◆ getOpt()

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 571 of file ProgOptions.cpp.

572 {
573 
574  ProgOpt* opt = lookup_option( namestring );
575 
576  if( get_opt_type< T >() != opt->type )
577  {
578  error( "Option '" + namestring + "' looked up with incompatible type" );
579  }
580 
581  // This call to evaluate is inefficient, because opt was already evaluated when it was parsed.
582  if( opt->args.size() )
583  {
584  if( t ) evaluate( *opt, t, "" );
585  return true;
586  }
587  else
588  return false;
589 }

References ProgOpt::args, error(), evaluate(), lookup_option(), and ProgOpt::type.

Referenced by main().

◆ getOptAllArgs()

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
Examples
GenLargeMesh.cpp.

Definition at line 592 of file ProgOptions.cpp.

593 {
594  ProgOpt* opt = lookup_option( namestring );
595 
596  // special case: if user asks for list of int, but argument
597  // was INT_VECT, concatenate all lists
598  if( get_opt_type< T >() == INT && opt->type == INT_VECT )
599  {
600  for( unsigned i = 0; i < opt->args.size(); ++i )
601  evaluate( *opt, &values, "", &i );
602  return;
603  }
604 
605  if( get_opt_type< T >() != opt->type )
606  {
607  error( "Option '" + namestring + "' looked up with incompatible type" );
608  }
609 
610  values.resize( opt->args.size() );
611 
612  // These calls to evaluate are inefficient, because the arguments were evaluated when they were
613  // parsed
614  for( unsigned i = 0; i < opt->args.size(); ++i )
615  {
616  evaluate( *opt, &( values[i] ), "", &i );
617  }
618 }

References ProgOpt::args, error(), evaluate(), INT, INT_VECT, lookup_option(), and ProgOpt::type.

Referenced by main(), and ToolContext::ParseCLOptions().

◆ getReqArg()

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 637 of file ProgOptions.cpp.

638 {
639 
640  ProgOpt* opt = lookup( required_args, namestring );
641 
642  if( !opt )
643  {
644  error( "Could not look up required arg: " + namestring );
645  }
646 
647  // if parseProgramOptions succeeded, we can assume each required arg has a value,
648  // so calling evaluate is valid
649  T value;
650  evaluate( *opt, &value, "" );
651  return value;
652 }

References error(), evaluate(), lookup(), and required_args.

Referenced by main().

◆ lookup()

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

Definition at line 368 of file ProgOptions.cpp.

369 {
370  std::map< std::string, ProgOpt* >::const_iterator it = table.find( arg );
371  if( it != table.end() )
372  return it->second;
373  else if( &table == &short_names && arg.size() == 1 && isdigit( arg[0] ) && !number_option_name.empty() &&
374  ( it = long_names.find( number_option_name ) ) != long_names.end() )
375  return it->second;
376  else
377  return 0;
378 }

References long_names, number_option_name, and short_names.

Referenced by getArgs(), getReqArg(), lookup_option(), numOptSet(), and parseCommandLine().

◆ lookup_option()

ProgOpt * ProgOptions::lookup_option ( const std::string &  namestring)
protected

Definition at line 380 of file ProgOptions.cpp.

381 {
382  std::string longname, shortname;
383  get_namestrings( namestring, &longname, &shortname );
384 
385  ProgOpt* opt = lookup( long_names, longname );
386  if( !opt ) opt = lookup( short_names, shortname );
387 
388  if( !opt )
389  {
390  error( "Invalid option: " + namestring );
391  }
392 
393  return opt;
394 }

References error(), get_namestrings(), long_names, lookup(), and short_names.

Referenced by getOpt(), and getOptAllArgs().

◆ numOptSet()

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 620 of file ProgOptions.cpp.

621 {
622  std::string longname, shortname;
623  get_namestrings( namestring, &longname, &shortname );
624 
625  ProgOpt* opt = lookup( long_names, longname );
626  if( !opt ) opt = lookup( short_names, shortname );
627 
628  if( !opt )
629  {
630  error( "Could not look up option: " + namestring );
631  }
632 
633  return opt->args.size();
634 }

References ProgOpt::args, error(), get_namestrings(), long_names, lookup(), and short_names.

Referenced by main(), and ToolContext::ParseCLOptions().

◆ parseCommandLine()

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

Parse command-line inputs as given to main()

Examples
ComputeTriDual.cpp, CrystalRouterExample.cpp, DirectAccessNoHoles.cpp, DirectAccessWithHoles.cpp, ExtractLand.cpp, GenLargeMesh.cpp, LaplacianSmoother.cpp, StructuredMeshSimple.cpp, addPCdata.cpp, and copyPartition.cpp.

Definition at line 737 of file ProgOptions.cpp.

738 {
739  const char* name = strrchr( argv[0], '/' );
740  if( name )
741  this->progname = ++name;
742  else
743  this->progname = argv[0];
744 
745  std::vector< const char* > args;
746  std::list< ProgOpt* > expected_vals;
747  bool no_more_flags = false;
748 
749  // Loop over all command line arguments
750  for( int i = 1; i < argc; ++i )
751  {
752  std::string arg( argv[i] );
753  if( arg.empty() ) continue;
754 
755  if( !expected_vals.empty() )
756  {
757  ProgOpt* opt = expected_vals.front();
758  expected_vals.pop_front();
759  assert( opt->type != FLAG );
760  opt->args.push_back( arg );
761  evaluate( *opt, opt->storage, arg );
762  }
763  else if( !no_more_flags && arg[0] == '-' )
764  {
765  if( arg.length() > 2 && arg[1] == '-' )
766  { // long opt
767  size_t eq = arg.find_first_of( '=' );
768  if( eq != std::string::npos )
769  {
770  ProgOpt* opt = lookup( long_names, arg.substr( 2, eq - 2 ) );
771  process_option( opt, arg, arg.substr( eq + 1 ).c_str() );
772  }
773  else
774  {
775  ProgOpt* opt = lookup( long_names, arg.substr( 2 ) );
776  if( process_option( opt, arg ) ) expected_vals.push_back( opt );
777  }
778  }
779  else if( arg == "--" )
780  { // --
781  no_more_flags = true;
782  }
783  else
784  for( size_t f = 1; f < arg.length(); ++f )
785  { // for each short opt
786  ProgOpt* opt = lookup( short_names, std::string( 1, arg[f] ) );
787  if( opt && ( opt->flags & int_flag ) )
788  {
789  const char val[] = { arg[f], 0 };
790  process_option( opt, std::string( 1, arg[f] ), val );
791  }
792  else if( process_option( opt, std::string( 1, arg[f] ) ) )
793  expected_vals.push_back( opt );
794  }
795  }
796  else
797  {
798  /* arguments */
799  args.push_back( argv[i] );
800  }
801  } /* End loop over inputs */
802 
803  // Print error if any missing values
804  if( !expected_vals.empty() )
805  {
806  error( "Missing value for option: -" + expected_vals.front()->shortname + ",--" +
807  expected_vals.front()->longname );
808  }
809 
810  // Process non-option arguments
811  std::vector< help_line >::iterator arg_help_pos = arg_help_strings.begin();
812  std::vector< const char* >::iterator arg_val_pos = args.begin();
813  std::vector< help_line >::iterator opt_args_pos = arg_help_strings.end();
814  size_t min_required_args = required_args.size();
815  size_t max_required_args = required_args.size();
817  {
818  min_required_args--;
819  if( max_optional_args )
820  max_required_args += max_optional_args;
821  else
822  max_required_args = std::numeric_limits< int >::max();
823  opt_args_pos = arg_help_pos + optional_args_position;
824  }
825  // check valid number of non-flag arguments
826  if( args.size() < min_required_args )
827  {
828  size_t missing_pos = args.size();
829  if( expect_optional_args && missing_pos >= optional_args_position ) ++missing_pos;
830 
831  const std::string& missed_arg = arg_help_strings[missing_pos].first->longname;
832  error( "Did not find required positional argument: " + missed_arg );
833  }
834  else if( args.size() > max_required_args )
835  {
836  error( "Unexpected argument: " + std::string( args[max_required_args] ) );
837  }
838 
839  // proccess arguments up to the first optional argument
840  // (or all arguments if no optional args)
841  while( arg_help_pos != opt_args_pos )
842  {
843  ProgOpt* opt = arg_help_pos->first;
844  ++arg_help_pos;
845  opt->args.push_back( *arg_val_pos );
846  evaluate( *opt, opt->storage, *arg_val_pos );
847  ++arg_val_pos;
848  }
849  // process any optional args
850  if( arg_help_pos != arg_help_strings.end() )
851  {
852  assert( arg_help_pos == opt_args_pos );
853  size_t num_opt_args = args.size() + 1 - required_args.size();
854  ProgOpt* opt = arg_help_pos->first;
855  ++arg_help_pos;
856  while( num_opt_args-- )
857  {
858  opt->args.push_back( *arg_val_pos );
859  evaluate( *opt, opt->storage, *arg_val_pos );
860  ++arg_val_pos;
861  }
862  }
863  // process any remaining args
864  while( arg_help_pos != arg_help_strings.end() )
865  {
866  assert( arg_val_pos != args.end() );
867  ProgOpt* opt = arg_help_pos->first;
868  ++arg_help_pos;
869  opt->args.push_back( *arg_val_pos );
870  evaluate( *opt, opt->storage, *arg_val_pos );
871  ++arg_val_pos;
872  }
873  assert( arg_val_pos == args.end() );
874 }

References arg_help_strings, 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(), RuntimeContext::ParseCLOptions(), and ToolContext::ParseCLOptions().

◆ printHelp()

void ProgOptions::printHelp ( std::ostream &  str = std::cout)

Print the full help to the given stream

Examples
ExtractLand.cpp, addPCdata.cpp, and copyPartition.cpp.

Definition at line 226 of file ProgOptions.cpp.

227 {
228 
229  /* Print introductory help text */
230  if( !brief_help.empty() ) out << brief_help << std::endl;
231  for( std::vector< std::string >::iterator i = main_help.begin(); i != main_help.end(); ++i )
232  {
233  if( ( *i ).length() )
234  {
235  out << std::endl << *i << std::endl;
236  }
237  }
238 
239  printUsage( out );
240 
241  // max number of characters to pad argument/option names with
242  // options with long names may exceed this, but will appear out of alignment in help text
243  const int max_padding = 20;
244 
245  /* List required arguments, with help text */
246  if( arg_help_strings.size() > 0 )
247  {
248 
249  int max_arg_namelen = 0;
250 
251  for( std::vector< help_line >::iterator i = arg_help_strings.begin(); i != arg_help_strings.end(); ++i )
252  {
253  max_arg_namelen = std::max( max_arg_namelen, (int)( ( *i ).first->longname.length() ) );
254  }
255 
256  max_arg_namelen = std::min( max_arg_namelen + 3, max_padding );
257 
258  out << "Arguments: " << std::endl;
259 
260  for( std::vector< help_line >::iterator i = arg_help_strings.begin(); i != arg_help_strings.end(); ++i )
261  {
262  ProgOpt* option = ( *i ).first;
263  std::string& info = ( *i ).second;
264 
265  std::stringstream s;
266  s << " " << option->longname;
267  out << std::setw( max_arg_namelen ) << std::left << s.str();
268  out << ": " << info << std::endl;
269  }
270  }
271 
272  /* List options, with help text */
273  out << "Options: " << std::endl;
274  int max_option_prefix_len = 0;
275 
276  for( std::vector< help_line >::iterator i = option_help_strings.begin(); i != option_help_strings.end(); ++i )
277  {
278  ProgOpt* option = ( *i ).first;
279  std::string& info = ( *i ).second;
280 
281  if( option )
282  {
283 
284  if( max_option_prefix_len == 0 )
285  {
286  // iterate ahead in the option list to determine whitespace padding
287  // stop if (*j).first is NULL, which indicates a help header message
288  for( std::vector< help_line >::iterator j = i; j != option_help_strings.end() && ( *j ).first; ++j )
289  {
290  int len = get_option_usage_prefix( *( ( *j ).first ) ).length();
291  max_option_prefix_len = std::max( max_option_prefix_len, len );
292  }
293  }
294  max_option_prefix_len = std::min( max_option_prefix_len, max_padding );
295  std::string option_prefix = get_option_usage_prefix( *option );
296 
297  out << std::setw( max_option_prefix_len ) << std::left << option_prefix;
298  out << ": ";
299  }
300  else
301  {
302  // no option: this is a help header. Reset max name length.
303  max_option_prefix_len = 0;
304  }
305  out << info << std::endl;
306  }
307 }

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().

◆ printUsage()

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.

348 {
349 
350  out << "Usage: " << progname << " --help | [options] ";
351 
352  for( size_t i = 0; i < arg_help_strings.size(); ++i )
353  {
355  out << '<' << arg_help_strings[i].first->longname << "> ";
356  else if( 0 == max_optional_args || max_optional_args > 3 )
357  out << "[<" << arg_help_strings[i].first->longname << "> ...] ";
358  else if( 1 == max_optional_args )
359  out << "[" << arg_help_strings[i].first->longname << "] ";
360  else
361  for( unsigned j = 0; j < max_optional_args; ++j )
362  out << "[" << arg_help_strings[i].first->longname << ( j + 1 ) << "] ";
363  }
364 
365  out << std::endl;
366 }

References arg_help_strings, expect_optional_args, moab::GeomUtil::first(), max_optional_args, optional_args_position, and progname.

Referenced by error(), and printHelp().

◆ printVersion()

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

Print the version string to the given stream

Definition at line 221 of file ProgOptions.cpp.

222 {
223  out << progversion << std::endl;
224 }

References progversion.

Referenced by process_option().

◆ process_option()

bool ProgOptions::process_option ( ProgOpt opt,
std::string  arg,
const char *  value = 0 
)
protected

Definition at line 683 of file ProgOptions.cpp.

684 {
685  if( !opt )
686  {
687  if( arg == "--manpage" )
688  {
689  write_man_page( std::cout );
690  exit( 0 );
691  }
692 
693  error( "Unknown option: " + arg );
694  }
695 
696  if( opt->flags & help_flag )
697  {
698  printHelp( std::cout );
699  exit( EXIT_SUCCESS );
700  }
701 
702  if( opt->flags & version_flag )
703  {
704  printVersion( std::cout );
705  exit( EXIT_SUCCESS );
706  }
707 
708  if( opt->type != FLAG )
709  {
710  if( !value ) return true;
711 
712  opt->args.push_back( value );
713  evaluate( *opt, opt->storage, arg );
714  }
715  else
716  {
717  if( value )
718  {
719  error( "Unexpected value for flag: " + arg );
720  }
721 
722  // do flag operations
723  if( opt->cancel_opt )
724  {
725  opt->cancel_opt->args.clear();
726  }
727  if( opt->storage )
728  {
729  *static_cast< bool* >( opt->storage ) = ( opt->flags & store_false ) ? false : true;
730  }
731  opt->args.push_back( "" );
732  }
733 
734  return false;
735 }

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().

◆ setVersion()

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 131 of file ProgOptions.cpp.

132 {
133  progversion = version_string;
134  if( addFlag )
135  {
136  addOpt< void >( "version", "Print version number and exit", version_flag );
137  }
138 }

References progversion, and version_flag.

◆ write_man_page()

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.

877 {
878  // a leading '.' is a control character. strip it if present.
879  std::string lprogname;
880  if( progname.empty() || progname[0] != '.' )
881  lprogname = progname;
882  else
883  {
884  lprogname = progname.substr( 1 );
885  }
886 
887  // Manpage controls:
888  // .TH title
889  // .SH section
890  // .SS subsection
891  // .P paragraph
892  // .HP hanging paragraph
893  // .B bold
894  // .I italic
895  // .B bold
896  // .I italic
897  // .RS begin indent
898  // .RE end indent
899  // .RB alternating roman and blold
900  // .BR alternating bold and roman
901 
902  std::vector< help_line >::iterator it;
903  std::set< ProgOpt* > skip_list;
904 
905  // start man page
906  s << std::endl << ".TH " << lprogname << " 1" << std::endl;
907 
908  // write NAME section
909  s << std::endl << ".SH NAME" << std::endl << ".P " << std::endl << lprogname << " \\- ";
910  if( brief_help.empty() && !main_help.empty() )
911  s << main_help.front();
912  else
913  s << brief_help;
914  s << std::endl << std::endl;
915 
916  // write SYNOPSIS section
917  s << std::endl << ".SH SYNOPSIS" << std::endl << ".HP" << std::endl << ".B \"" << lprogname << '"' << std::endl;
918  for( it = option_help_strings.begin(); it != option_help_strings.end(); ++it )
919  {
920  if( !it->first || skip_list.find( it->first ) != skip_list.end() || it->first->longname == "help" ) continue;
921 
922  if( it->first->type == FLAG )
923  {
924  char c = '[';
925  s << ".RB";
926  if( !it->first->shortname.empty() )
927  {
928  s << ' ' << c << " \"-" << it->first->shortname << '"';
929  c = '|';
930  }
931  if( !it->first->longname.empty() )
932  {
933  s << ' ' << c << " \"--" << it->first->longname << '"';
934  }
935  if( it->first->cancel_opt )
936  {
937  skip_list.insert( it->first->cancel_opt );
938  if( !it->first->cancel_opt->shortname.empty() )
939  s << " | \"-" << it->first->cancel_opt->shortname << '"';
940  if( !it->first->cancel_opt->longname.empty() ) s << " | \"--" << it->first->cancel_opt->longname << '"';
941  }
942  s << " ]" << std::endl;
943  }
944  else if( it->first->flags & int_flag )
945  {
946  s << ".RB [ - <n>| \"--" << it->first->longname << "\" \"=" << it->first->get_argstring() << "]\""
947  << std::endl;
948  }
949  else
950  {
951  s << ".RB [ ";
952  if( !it->first->shortname.empty() )
953  s << "\"-" << it->first->shortname << "\" \"\\ " << it->first->get_argstring();
954  if( !it->first->shortname.empty() && !it->first->longname.empty() ) s << "|\" ";
955  if( !it->first->longname.empty() )
956  s << "\"--" << it->first->longname << "\" \"=" << it->first->get_argstring();
957  s << "]\"" << std::endl;
958  }
959  }
960  for( it = arg_help_strings.begin(); it != arg_help_strings.end(); ++it )
961  {
962  if( !it->first ) continue;
963 
964  if( !expect_optional_args || (unsigned)( it - arg_help_strings.begin() ) != optional_args_position )
965  s << it->first->longname << ' ';
966  else if( 1 == max_optional_args )
967  s << '[' << it->first->longname << "] ";
968  else
969  s << '[' << it->first->longname << " ...] ";
970  }
971  s << std::endl;
972  s << ".HP" << std::endl << ".B \"" << lprogname << " -h|--help\"" << std::endl;
973 
974  // write DESCRIPTION section
975  s << std::endl << ".SH DESCRIPTION" << std::endl;
976  if( main_help.empty() ) s << brief_help << std::endl;
977  for( size_t i = 0; i < main_help.size(); ++i )
978  {
979  const std::string::size_type n = main_help[i].size();
980  std::string::size_type j = 0, k;
981  s << std::endl << ".P" << std::endl;
982  while( j != n )
983  {
984  if( main_help[i][j] == '\n' )
985  {
986  s << std::endl << ".P" << std::endl;
987  ++j;
988  continue;
989  }
990  k = main_help[i].find( "\n", j );
991  if( k == std::string::npos ) k = n;
992  if( main_help[i][j] == '.' ) s << '\\';
993  s << main_help[i].substr( j, k - j );
994  j = k;
995  }
996  }
997 
998  // write OPTIONS section
999  s << std::endl << ".SH OPTIONS" << std::endl;
1000  for( it = arg_help_strings.begin(); it != arg_help_strings.end(); ++it )
1001  {
1002  if( it->first )
1003  s << ".IP \"" << it->first->longname << '"' << std::endl << it->second << std::endl;
1004  else
1005  s << ".SS " << it->first->longname << std::endl;
1006  }
1007  for( it = option_help_strings.begin(); it != option_help_strings.end(); ++it )
1008  {
1009  if( !it->first )
1010  {
1011  s << ".SS " << it->second << std::endl;
1012  continue;
1013  }
1014 
1015  s << ".IP \"";
1016  if( it->first->longname.empty() )
1017  s << "-" << it->first->shortname;
1018  else if( it->first->shortname.empty() )
1019  s << "--" << it->first->longname;
1020  else
1021  s << "-" << it->first->shortname << ", --" << it->first->longname;
1022  s << '"' << std::endl << it->second << std::endl;
1023  }
1024  s << std::endl;
1025 }

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().

Member Data Documentation

◆ add_cancel_opt

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(), and main().

◆ arg_help_strings

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

◆ brief_help

std::string ProgOptions::brief_help
protected

Definition at line 266 of file ProgOptions.hpp.

Referenced by printHelp(), ProgOptions(), and write_man_page().

◆ expect_optional_args

bool ProgOptions::expect_optional_args
protected

Definition at line 268 of file ProgOptions.hpp.

Referenced by addOptionalArgs(), parseCommandLine(), printUsage(), and write_man_page().

◆ help_flag

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

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.

Flags for addOpt and addRequiredArg functions; may be combined with bitwise arithmetic (though not all combinations make sense!)

Definition at line 46 of file ProgOptions.hpp.

Referenced by process_option(), and ProgOptions().

◆ int_flag

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(), parseCommandLine(), and write_man_page().

◆ long_names

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().

◆ main_help

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

Definition at line 265 of file ProgOptions.hpp.

Referenced by printHelp(), ProgOptions(), and write_man_page().

◆ max_optional_args

unsigned ProgOptions::max_optional_args
protected

Definition at line 269 of file ProgOptions.hpp.

Referenced by addOptionalArgs(), parseCommandLine(), printUsage(), and write_man_page().

◆ number_option_name

std::string ProgOptions::number_option_name
protected

Definition at line 276 of file ProgOptions.hpp.

Referenced by addOpt(), and lookup().

◆ option_help_strings

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

◆ optional_args_position

unsigned ProgOptions::optional_args_position
protected

Definition at line 269 of file ProgOptions.hpp.

Referenced by addOptionalArgs(), parseCommandLine(), printUsage(), and write_man_page().

◆ progname

std::string ProgOptions::progname
protected

Definition at line 271 of file ProgOptions.hpp.

Referenced by parseCommandLine(), printUsage(), and write_man_page().

◆ progversion

std::string ProgOptions::progversion
protected

Definition at line 272 of file ProgOptions.hpp.

Referenced by printVersion(), and setVersion().

◆ rank_subst

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().

◆ required_args

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

◆ short_names

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().

◆ store_false

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(), and process_option().

◆ version_flag

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().


The documentation for this class was generated from the following files: