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 #ifndef TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
00030 #define TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
00031
00035 #include "Teuchos_map.hpp"
00036 #include "Teuchos_any.hpp"
00037 #include "Teuchos_CompileTimeAssert.hpp"
00038
00039 namespace Teuchos {
00040
00054
00055
00056
00057
00058
00059 class CommandLineProcessor {
00060 public:
00061
00065 enum EParseCommandLineReturn {
00066 PARSE_SUCCESSFUL = 0
00067 ,PARSE_HELP_PRINTED = 1
00068 ,PARSE_UNRECOGNIZED_OPTION = -1
00069 };
00070
00072
00073
00082 CommandLineProcessor(
00083 bool throwExceptions = true
00084 ,bool recogniseAllOptions = true
00085 );
00086
00088
00090
00103 void setOption(
00104 const char option_true[]
00105 ,const char option_false[]
00106 ,bool *option_val
00107 ,const char documentation[] = NULL
00108 );
00109
00120 void setOption(
00121 const char option_name[]
00122 ,int *option_val
00123 ,const char documentation[] = NULL
00124 );
00125
00136 void setOption(
00137 const char option_name[]
00138 ,double *option_val
00139 ,const char documentation[] = NULL
00140 );
00141
00152 void setOption(
00153 const char option_name[]
00154 ,std::string *option_val
00155 ,const char documentation[] = NULL
00156 );
00157
00186 template <class EType>
00187 void setOption(
00188 const char enum_option_name[]
00189 ,EType *enum_option_val
00190 ,const int num_enum_opt_values
00191 ,const EType enum_opt_values[]
00192 ,const char* enum_opt_names[]
00193 ,const char documentation[] = NULL
00194 );
00195
00197
00199
00253 EParseCommandLineReturn parse(
00254 int argc
00255 ,char* argv[]
00256 ,std::ostream *errout = &std::cerr
00257 ) const;
00258
00260
00262
00271 void printHelpMessage( const char program_name[], std::ostream &out ) const;
00272
00274
00276
00278 void throwExceptions ( const bool & throwExceptions ) { throwExceptions_ = throwExceptions; };
00279
00281 const bool& throwExceptions() const { return throwExceptions_; };
00282
00284 void recogniseAllOptions ( const bool & recogniseAllOptions ) { recogniseAllOptions_ = recogniseAllOptions; };
00285
00287 const bool& recogniseAllOptions() const { return recogniseAllOptions_; };
00288
00290
00292
00294 class ParseError : public std::logic_error
00295 {public: ParseError(const std::string& what_arg) : std::logic_error(what_arg) {}};
00296
00298 class HelpPrinted : public ParseError
00299 {public: HelpPrinted(const std::string& what_arg) : ParseError(what_arg) {}};
00300
00302 class UnrecognizedOption : public ParseError
00303 {public: UnrecognizedOption(const std::string& what_arg) : ParseError(what_arg) {}};
00304
00306
00307 public:
00308
00309 enum EOptType { OPT_NONE, OPT_BOOL_TRUE, OPT_BOOL_FALSE, OPT_INT, OPT_DOUBLE, OPT_STRING, OPT_ENUM_INT };
00310
00311
00312
00313
00314
00315 private:
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 struct opt_val_val_t {
00326 opt_val_val_t()
00327 :opt_type(OPT_NONE)
00328 {}
00329 opt_val_val_t( EOptType opt_type_in, const any& opt_val_in )
00330 :opt_type(opt_type_in),opt_val(opt_val_in)
00331 {}
00332 EOptType opt_type;
00333 any opt_val;
00334 };
00335
00336
00337 typedef Teuchos::map<std::string,opt_val_val_t> options_list_t;
00338
00339
00340 struct opt_doc_t {
00341 opt_doc_t()
00342 :opt_type(OPT_NONE)
00343 {}
00344 opt_doc_t(EOptType opt_type_in, const std::string& opt_name_in, const std::string& opt_name_false_in
00345 ,const std::string &documentation_in, const any &default_val_in )
00346 :opt_type(opt_type_in),opt_name(opt_name_in),opt_name_false(opt_name_false_in)
00347 ,documentation(documentation_in),default_val(default_val_in)
00348 {}
00349 EOptType opt_type;
00350 std::string opt_name;
00351 std::string opt_name_false;
00352 std::string documentation;
00353 any default_val;
00354 };
00355
00356
00357 typedef std::vector<opt_doc_t> options_documentation_list_t;
00358
00359
00360 struct enum_opt_data_t {
00361 enum_opt_data_t()
00362 :enum_option_val(NULL), num_enum_opt_values(0)
00363 {}
00364 enum_opt_data_t(
00365 int *_enum_option_val
00366 ,const int _num_enum_opt_values
00367 ,const int _enum_opt_values[]
00368 ,const char* _enum_opt_names[]
00369 )
00370 :enum_option_val(_enum_option_val)
00371 ,num_enum_opt_values(_num_enum_opt_values)
00372 ,enum_opt_values(_enum_opt_values,_enum_opt_values+_num_enum_opt_values)
00373 {
00374 for( int k = 0; k < num_enum_opt_values; ++k )
00375 enum_opt_names.push_back(std::string(_enum_opt_names[k]));
00376 }
00377 int *enum_option_val;
00378 int num_enum_opt_values;
00379 std::vector<int> enum_opt_values;
00380 std::vector<string> enum_opt_names;
00381 };
00382
00383
00384 typedef std::vector<enum_opt_data_t> enum_opt_data_list_t;
00385
00386
00387
00388
00389 bool throwExceptions_;
00390 bool recogniseAllOptions_;
00391 options_list_t options_list_;
00392 options_documentation_list_t options_documentation_list_;
00393 enum_opt_data_list_t enum_opt_data_list_;
00394
00395
00396
00397
00398
00399 void setEnumOption(
00400 const char enum_option_name[]
00401 ,int *enum_option_val
00402 ,const int num_enum_opt_values
00403 ,const int enum_opt_values[]
00404 ,const char* enum_opt_names[]
00405 ,const char documentation[]
00406 );
00407
00408
00409 bool set_enum_value(
00410 int argv_i
00411 ,char* argv[]
00412 ,const std::string &enum_opt_name
00413 ,const int enum_id
00414 ,const std::string &enum_str_val
00415 ,std::ostream *errout
00416 ) const;
00417
00418
00419 void print_enum_opt_names(
00420 const int enum_id
00421 ,std::ostream &out
00422 ) const;
00423
00424
00425 std::string enum_opt_default_val_name(
00426 const std::string &enum_name
00427 ,const int enum_id
00428 ,std::ostream *errout
00429 ) const;
00430
00431
00432 int find_enum_opt_index(
00433 const std::string &enum_opt_name
00434 ,const int opt_value
00435 ,const enum_opt_data_t &enum_data
00436 ,std::ostream *errout
00437 ) const;
00438
00439
00440
00441 bool get_opt_val(
00442 const char str[]
00443 ,std::string *opt_name
00444 ,std::string *opt_val_str
00445 ) const;
00446
00447
00448 std::string opt_type_str( EOptType ) const;
00449
00450
00451 void print_bad_opt(
00452 int argv_i
00453 ,char* argv[]
00454 ,std::ostream *errout
00455 ) const;
00456
00457 };
00458
00459
00460
00461
00462 template <class EType>
00463 inline
00464 void CommandLineProcessor::setOption(
00465 const char enum_option_name[]
00466 ,EType *enum_option_val
00467 ,const int num_enum_opt_values
00468 ,const EType enum_opt_values[]
00469 ,const char* enum_opt_names[]
00470 ,const char documentation[]
00471 )
00472 {
00473
00474
00475
00476
00477
00478
00479
00480 CompileTimeAssert<sizeof(int)-sizeof(EType)>();
00481
00482 setEnumOption(
00483 enum_option_name
00484 ,reinterpret_cast<int*>(enum_option_val)
00485 ,num_enum_opt_values
00486 ,reinterpret_cast<const int*>(enum_opt_values)
00487 ,enum_opt_names
00488 ,documentation
00489 );
00490 }
00491
00492 inline
00493 std::string CommandLineProcessor::opt_type_str( EOptType opt_type ) const
00494 {
00495 std::string str;
00496 switch( opt_type ) {
00497 case OPT_BOOL_TRUE:
00498 str = "bool";
00499 break;
00500 case OPT_INT:
00501 str = "int";
00502 break;
00503 case OPT_DOUBLE:
00504 str = "double";
00505 break;
00506 case OPT_STRING:
00507 str = "string";
00508 break;
00509 case OPT_ENUM_INT:
00510 str = "enum";
00511 break;
00512 default:
00513 assert(0);
00514 }
00515 return str;
00516 }
00517
00518 }
00519
00520 #endif // TEUCHOS_COMMAND_LINE_PROCESSOR_HPP