00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
00033 #define TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
00034
00038 #include "Teuchos_map.hpp"
00039 #include "Teuchos_any.hpp"
00040 #include "Teuchos_CompileTimeAssert.hpp"
00041
00042 namespace Teuchos {
00043
00045
00058
00059
00060
00061
00062
00063 class CommandLineProcessor {
00064 public:
00065
00069 enum EParseCommandLineReturn {
00070 PARSE_SUCCESSFUL = 0
00071 ,PARSE_HELP_PRINTED = 1
00072 ,PARSE_UNRECOGNIZED_OPTION = -1
00073 };
00074
00076
00077
00086 CommandLineProcessor(
00087 bool throwExceptions = true
00088 ,bool recogniseAllOptions = true
00089 );
00090
00092
00094
00096
00108 void setOption(
00109 const char option_true[]
00110 ,const char option_false[]
00111 ,bool *option_val
00112 ,const char documentation[] = NULL
00113 );
00114
00116
00126 void setOption(
00127 const char option_name[]
00128 ,int *option_val
00129 ,const char documentation[] = NULL
00130 );
00131
00133
00143 void setOption(
00144 const char option_name[]
00145 ,double *option_val
00146 ,const char documentation[] = NULL
00147 );
00148
00150
00160 void setOption(
00161 const char option_name[]
00162 ,std::string *option_val
00163 ,const char documentation[] = NULL
00164 );
00165
00167
00195 template <class EType>
00196 void setOption(
00197 const char enum_option_name[]
00198 ,EType *enum_option_val
00199 ,const int num_enum_opt_values
00200 ,const EType enum_opt_values[]
00201 ,const char* enum_opt_names[]
00202 ,const char documentation[] = NULL
00203 );
00204
00206
00208
00210
00263 EParseCommandLineReturn parse(
00264 int argc
00265 ,char* argv[]
00266 ,std::ostream *errout = &std::cerr
00267 ) const;
00268
00270
00272
00274
00282 void printHelpMessage( const char program_name[], std::ostream &out ) const;
00283
00285
00287
00289 void throwExceptions ( const bool & throwExceptions ) { throwExceptions_ = throwExceptions; };
00290
00292 const bool& throwExceptions() const { return throwExceptions_; };
00293
00295 void recogniseAllOptions ( const bool & recogniseAllOptions ) { recogniseAllOptions_ = recogniseAllOptions; };
00296
00298 const bool& recogniseAllOptions() const { return recogniseAllOptions_; };
00299
00301
00303
00305 class ParseError : public std::logic_error
00306 {public: ParseError(const std::string& what_arg) : std::logic_error(what_arg) {}};
00307
00309 class HelpPrinted : public ParseError
00310 {public: HelpPrinted(const std::string& what_arg) : ParseError(what_arg) {}};
00311
00313 class UnrecognizedOption : public ParseError
00314 {public: UnrecognizedOption(const std::string& what_arg) : ParseError(what_arg) {}};
00315
00317
00318 public:
00319
00320 enum EOptType { OPT_NONE, OPT_BOOL_TRUE, OPT_BOOL_FALSE, OPT_INT, OPT_DOUBLE, OPT_STRING, OPT_ENUM_INT };
00321
00322
00323
00324
00325
00326 private:
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 struct opt_val_val_t {
00337 opt_val_val_t()
00338 :opt_type(OPT_NONE)
00339 {}
00340 opt_val_val_t( EOptType opt_type_in, const any& opt_val_in )
00341 :opt_type(opt_type_in),opt_val(opt_val_in)
00342 {}
00343 EOptType opt_type;
00344 any opt_val;
00345 };
00346
00347
00348 typedef Teuchos::map<std::string,opt_val_val_t> options_list_t;
00349
00350
00351 struct opt_doc_t {
00352 opt_doc_t()
00353 :opt_type(OPT_NONE)
00354 {}
00355 opt_doc_t(EOptType opt_type_in, const std::string& opt_name_in, const std::string& opt_name_false_in
00356 ,const std::string &documentation_in, const any &default_val_in )
00357 :opt_type(opt_type_in),opt_name(opt_name_in),opt_name_false(opt_name_false_in)
00358 ,documentation(documentation_in),default_val(default_val_in)
00359 {}
00360 EOptType opt_type;
00361 std::string opt_name;
00362 std::string opt_name_false;
00363 std::string documentation;
00364 any default_val;
00365 };
00366
00367
00368 typedef std::vector<opt_doc_t> options_documentation_list_t;
00369
00370
00371 struct enum_opt_data_t {
00372 enum_opt_data_t()
00373 :enum_option_val(NULL), num_enum_opt_values(0)
00374 {}
00375 enum_opt_data_t(
00376 int *_enum_option_val
00377 ,const int _num_enum_opt_values
00378 ,const int _enum_opt_values[]
00379 ,const char* _enum_opt_names[]
00380 )
00381 :enum_option_val(_enum_option_val)
00382 ,num_enum_opt_values(_num_enum_opt_values)
00383 ,enum_opt_values(_enum_opt_values,_enum_opt_values+_num_enum_opt_values)
00384 {
00385 for( int k = 0; k < num_enum_opt_values; ++k )
00386 enum_opt_names.push_back(std::string(_enum_opt_names[k]));
00387 }
00388 int *enum_option_val;
00389 int num_enum_opt_values;
00390 std::vector<int> enum_opt_values;
00391 std::vector<string> enum_opt_names;
00392 };
00393
00394
00395 typedef std::vector<enum_opt_data_t> enum_opt_data_list_t;
00396
00397
00398
00399
00400 bool throwExceptions_;
00401 bool recogniseAllOptions_;
00402 options_list_t options_list_;
00403 options_documentation_list_t options_documentation_list_;
00404 enum_opt_data_list_t enum_opt_data_list_;
00405
00406
00407
00408
00409
00410 void setEnumOption(
00411 const char enum_option_name[]
00412 ,int *enum_option_val
00413 ,const int num_enum_opt_values
00414 ,const int enum_opt_values[]
00415 ,const char* enum_opt_names[]
00416 ,const char documentation[]
00417 );
00418
00419
00420 bool set_enum_value(
00421 int argv_i
00422 ,char* argv[]
00423 ,const std::string &enum_opt_name
00424 ,const int enum_id
00425 ,const std::string &enum_str_val
00426 ,std::ostream *errout
00427 ) const;
00428
00429
00430 void print_enum_opt_names(
00431 const int enum_id
00432 ,std::ostream &out
00433 ) const;
00434
00435
00436 std::string enum_opt_default_val_name(
00437 const std::string &enum_name
00438 ,const int enum_id
00439 ,std::ostream *errout
00440 ) const;
00441
00442
00443 int find_enum_opt_index(
00444 const std::string &enum_opt_name
00445 ,const int opt_value
00446 ,const enum_opt_data_t &enum_data
00447 ,std::ostream *errout
00448 ) const;
00449
00450
00451
00452 bool get_opt_val(
00453 const char str[]
00454 ,std::string *opt_name
00455 ,std::string *opt_val_str
00456 ) const;
00457
00458
00459 std::string opt_type_str( EOptType ) const;
00460
00461
00462 void print_bad_opt(
00463 int argv_i
00464 ,char* argv[]
00465 ,std::ostream *errout
00466 ) const;
00467
00468 };
00469
00470
00471
00472
00473 template <class EType>
00474 inline
00475 void CommandLineProcessor::setOption(
00476 const char enum_option_name[]
00477 ,EType *enum_option_val
00478 ,const int num_enum_opt_values
00479 ,const EType enum_opt_values[]
00480 ,const char* enum_opt_names[]
00481 ,const char documentation[]
00482 )
00483 {
00484
00485
00486
00487
00488
00489
00490
00491 CompileTimeAssert<sizeof(int)-sizeof(EType)>();
00492
00493 setEnumOption(
00494 enum_option_name
00495 ,reinterpret_cast<int*>(enum_option_val)
00496 ,num_enum_opt_values
00497 ,reinterpret_cast<const int*>(enum_opt_values)
00498 ,enum_opt_names
00499 ,documentation
00500 );
00501 }
00502
00503 inline
00504 std::string CommandLineProcessor::opt_type_str( EOptType opt_type ) const
00505 {
00506 std::string str;
00507 switch( opt_type ) {
00508 case OPT_BOOL_TRUE:
00509 str = "bool";
00510 break;
00511 case OPT_INT:
00512 str = "int";
00513 break;
00514 case OPT_DOUBLE:
00515 str = "double";
00516 break;
00517 case OPT_STRING:
00518 str = "string";
00519 break;
00520 case OPT_ENUM_INT:
00521 str = "enum";
00522 break;
00523 default:
00524 assert(0);
00525 }
00526 return str;
00527 }
00528
00529 }
00530
00531 #endif // TEUCHOS_COMMAND_LINE_PROCESSOR_HPP