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
00040 #include "Teuchos_map.hpp"
00041 #include "Teuchos_any.hpp"
00042 #include "Teuchos_CompileTimeAssert.hpp"
00043
00044 namespace Teuchos {
00045
00046
00047
00048
00049
00050
00063 class TEUCHOS_LIB_DLL_EXPORT CommandLineProcessor {
00064 public:
00065
00067
00068
00070 class ParseError : public std::logic_error
00071 {public: ParseError(const std::string& what_arg) : std::logic_error(what_arg) {}};
00072
00074 class HelpPrinted : public ParseError
00075 {public: HelpPrinted(const std::string& what_arg) : ParseError(what_arg) {}};
00076
00078 class UnrecognizedOption : public ParseError
00079 {public: UnrecognizedOption(const std::string& what_arg) : ParseError(what_arg) {}};
00080
00085 enum EParseCommandLineReturn {
00086 PARSE_SUCCESSFUL = 0
00087 ,PARSE_HELP_PRINTED = 1
00088 ,PARSE_UNRECOGNIZED_OPTION = 2
00089 };
00090
00092
00094
00095
00108 CommandLineProcessor(
00109 bool throwExceptions = true
00110 ,bool recogniseAllOptions = true
00111 ,bool addOutputSetupOptions = false
00112 );
00113
00115
00117
00118
00120 void throwExceptions( const bool & throwExceptions );
00121
00123 bool throwExceptions() const;
00124
00126 void recogniseAllOptions( const bool & recogniseAllOptions );
00127
00129 bool recogniseAllOptions() const;
00130
00132 void addOutputSetupOptions( const bool &addOutputSetupOptions );
00133
00135 bool addOutputSetupOptions() const;
00136
00138
00140
00141
00144 void setDocString( const char doc_string[] );
00145
00158 void setOption(
00159 const char option_true[]
00160 ,const char option_false[]
00161 ,bool *option_val
00162 ,const char documentation[] = NULL
00163 );
00164
00175 void setOption(
00176 const char option_name[]
00177 ,int *option_val
00178 ,const char documentation[] = NULL
00179 ,const bool required = false
00180 );
00181
00192 void setOption(
00193 const char option_name[]
00194 ,double *option_val
00195 ,const char documentation[] = NULL
00196 ,const bool required = false
00197 );
00198
00209 void setOption(
00210 const char option_name[]
00211 ,std::string *option_val
00212 ,const char documentation[] = NULL
00213 ,const bool required = false
00214 );
00215
00244 template <class EType>
00245 void setOption(
00246 const char enum_option_name[]
00247 ,EType *enum_option_val
00248 ,const int num_enum_opt_values
00249 ,const EType enum_opt_values[]
00250 ,const char* enum_opt_names[]
00251 ,const char documentation[] = NULL
00252 ,const bool required = false
00253 );
00254
00256
00258
00259
00319 EParseCommandLineReturn parse(
00320 int argc
00321 ,char* argv[]
00322 ,std::ostream *errout = &std::cerr
00323 ) const;
00324
00326
00328
00329
00338 void printHelpMessage( const char program_name[], std::ostream &out ) const;
00339
00341
00342 public:
00343
00344 enum EOptType { OPT_NONE, OPT_BOOL_TRUE, OPT_BOOL_FALSE, OPT_INT, OPT_DOUBLE, OPT_STRING, OPT_ENUM_INT };
00345
00346
00347
00348
00349
00350 private:
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 struct opt_val_val_t {
00361 opt_val_val_t()
00362 :opt_type(OPT_NONE)
00363 {}
00364 opt_val_val_t( EOptType opt_type_in, const any& opt_val_in, bool required_in )
00365 :opt_type(opt_type_in),opt_val(opt_val_in),required(required_in),was_read(false)
00366 {}
00367 EOptType opt_type;
00368 any opt_val;
00369 bool required;
00370 bool was_read;
00371 };
00372
00373
00374 typedef Teuchos::map<std::string,opt_val_val_t> options_list_t;
00375
00376
00377 struct opt_doc_t {
00378 opt_doc_t()
00379 :opt_type(OPT_NONE)
00380 {}
00381 opt_doc_t(EOptType opt_type_in, const std::string& opt_name_in, const std::string& opt_name_false_in
00382 ,const std::string &documentation_in, const any &default_val_in )
00383 :opt_type(opt_type_in),opt_name(opt_name_in),opt_name_false(opt_name_false_in)
00384 ,documentation(documentation_in),default_val(default_val_in)
00385 {}
00386 EOptType opt_type;
00387 std::string opt_name;
00388 std::string opt_name_false;
00389 std::string documentation;
00390 any default_val;
00391 };
00392
00393
00394 typedef std::vector<opt_doc_t> options_documentation_list_t;
00395
00396
00397 struct enum_opt_data_t {
00398 enum_opt_data_t()
00399 :enum_option_val(NULL), num_enum_opt_values(0)
00400 {}
00401 enum_opt_data_t(
00402 int *_enum_option_val
00403 ,const int _num_enum_opt_values
00404 ,const int _enum_opt_values[]
00405 ,const char* _enum_opt_names[]
00406 )
00407 :enum_option_val(_enum_option_val)
00408 ,num_enum_opt_values(_num_enum_opt_values)
00409 ,enum_opt_values(_enum_opt_values,_enum_opt_values+_num_enum_opt_values)
00410 {
00411 for( int k = 0; k < num_enum_opt_values; ++k )
00412 enum_opt_names.push_back(std::string(_enum_opt_names[k]));
00413 }
00414 int *enum_option_val;
00415 int num_enum_opt_values;
00416 std::vector<int> enum_opt_values;
00417 std::vector<std::string> enum_opt_names;
00418 };
00419
00420
00421 typedef std::vector<enum_opt_data_t> enum_opt_data_list_t;
00422
00423
00424
00425
00426 bool throwExceptions_;
00427 bool recogniseAllOptions_;
00428 bool addOutputSetupOptions_;
00429 std::string doc_string_;
00430
00431
00432 #ifdef _MSC_VER
00433 #pragma warning(push)
00434 #pragma warning(disable:4251)
00435 #endif
00436 mutable options_list_t options_list_;
00437 options_documentation_list_t options_documentation_list_;
00438 enum_opt_data_list_t enum_opt_data_list_;
00439 #ifdef _MSC_VER
00440 #pragma warning(pop)
00441 #endif
00442
00443 bool output_all_front_matter_;
00444 bool output_show_line_prefix_;
00445 bool output_show_tab_count_;
00446 bool output_show_proc_rank_;
00447 int output_to_root_rank_only_;
00448 bool print_rcpnode_statistics_on_exit_;
00449
00450 bool added_extra_output_setup_options_;
00451 bool in_add_extra_output_setup_options_;
00452
00453 static const bool output_all_front_matter_default_;
00454 static const bool output_show_line_prefix_default_;
00455 static const bool output_show_tab_count_default_;
00456 static const bool output_show_proc_rank_default_;
00457 static const int output_to_root_rank_only_default_;
00458 static const bool print_rcpnode_statistics_on_exit_default_;
00459
00460
00461
00462
00463
00464 void add_extra_output_setup_options() const;
00465
00466
00467 void setEnumOption(
00468 const char enum_option_name[]
00469 ,int *enum_option_val
00470 ,const int num_enum_opt_values
00471 ,const int enum_opt_values[]
00472 ,const char* enum_opt_names[]
00473 ,const char documentation[]
00474 ,const bool required
00475 );
00476
00477
00478 bool set_enum_value(
00479 int argv_i
00480 ,char* argv[]
00481 ,const std::string &enum_opt_name
00482 ,const int enum_id
00483 ,const std::string &enum_str_val
00484 ,std::ostream *errout
00485 ) const;
00486
00487
00488 void print_enum_opt_names(
00489 const int enum_id
00490 ,std::ostream &out
00491 ) const;
00492
00493
00494 std::string enum_opt_default_val_name(
00495 const std::string &enum_name
00496 ,const int enum_id
00497 ,std::ostream *errout
00498 ) const;
00499
00500
00501 int find_enum_opt_index(
00502 const std::string &enum_opt_name
00503 ,const int opt_value
00504 ,const enum_opt_data_t &enum_data
00505 ,std::ostream *errout
00506 ) const;
00507
00508
00509
00510 bool get_opt_val(
00511 const char str[]
00512 ,std::string *opt_name
00513 ,std::string *opt_val_str
00514 ) const;
00515
00516
00517 std::string opt_type_str( EOptType ) const;
00518
00519
00520 void print_bad_opt(
00521 int argv_i
00522 ,char* argv[]
00523 ,std::ostream *errout
00524 ) const;
00525
00526 };
00527
00528
00529
00530
00531
00532
00533 inline
00534 void CommandLineProcessor::throwExceptions( const bool & throwExceptions_in )
00535 { throwExceptions_ = throwExceptions_in; }
00536
00537 inline
00538 bool CommandLineProcessor::throwExceptions() const
00539 { return throwExceptions_; }
00540
00541 inline
00542 void CommandLineProcessor::recogniseAllOptions( const bool & recogniseAllOptions_in )
00543 { recogniseAllOptions_ = recogniseAllOptions_in; }
00544
00545 inline
00546 bool CommandLineProcessor::recogniseAllOptions() const
00547 { return recogniseAllOptions_; }
00548
00549 inline
00550 void CommandLineProcessor::addOutputSetupOptions( const bool &addOutputSetupOptions_in )
00551 { addOutputSetupOptions_ = addOutputSetupOptions_in; }
00552
00553 inline
00554 bool CommandLineProcessor::addOutputSetupOptions() const
00555 { return addOutputSetupOptions_; }
00556
00557 template <class EType>
00558 inline
00559 void CommandLineProcessor::setOption(
00560 const char enum_option_name[]
00561 ,EType *enum_option_val
00562 ,const int num_enum_opt_values
00563 ,const EType enum_opt_values[]
00564 ,const char* enum_opt_names[]
00565 ,const char documentation[]
00566 ,const bool required
00567 )
00568 {
00569
00570
00571
00572
00573
00574
00575
00576 CompileTimeAssert<sizeof(int)-sizeof(EType)>();
00577
00578 setEnumOption(
00579 enum_option_name
00580 ,reinterpret_cast<int*>(enum_option_val)
00581 ,num_enum_opt_values
00582 ,reinterpret_cast<const int*>(enum_opt_values)
00583 ,enum_opt_names
00584 ,documentation
00585 ,required
00586 );
00587 }
00588
00589 inline
00590 std::string CommandLineProcessor::opt_type_str( EOptType opt_type ) const
00591 {
00592 std::string str;
00593 switch( opt_type ) {
00594 case OPT_BOOL_TRUE:
00595 str = "bool";
00596 break;
00597 case OPT_INT:
00598 str = "int";
00599 break;
00600 case OPT_DOUBLE:
00601 str = "double";
00602 break;
00603 case OPT_STRING:
00604 str = "string";
00605 break;
00606 case OPT_ENUM_INT:
00607 str = "enum";
00608 break;
00609 default:
00610 assert(0);
00611 }
00612 return str;
00613 }
00614
00615 }
00616
00617 #endif // TEUCHOS_COMMAND_LINE_PROCESSOR_HPP