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 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 mutable options_list_t options_list_;
00431 options_documentation_list_t options_documentation_list_;
00432 enum_opt_data_list_t enum_opt_data_list_;
00433
00434 bool output_all_front_matter_;
00435 bool output_show_line_prefix_;
00436 bool output_show_tab_count_;
00437 bool output_show_proc_rank_;
00438 int output_to_root_rank_only_;
00439
00440 bool added_extra_output_setup_options_;
00441 bool in_add_extra_output_setup_options_;
00442
00443 static const bool output_all_front_matter_default_;
00444 static const bool output_show_line_prefix_default_;
00445 static const bool output_show_tab_count_default_;
00446 static const bool output_show_proc_rank_default_;
00447 static const int output_to_root_rank_only_default_;
00448
00449
00450
00451
00452
00453 void add_extra_output_setup_options() const;
00454
00455
00456 void setEnumOption(
00457 const char enum_option_name[]
00458 ,int *enum_option_val
00459 ,const int num_enum_opt_values
00460 ,const int enum_opt_values[]
00461 ,const char* enum_opt_names[]
00462 ,const char documentation[]
00463 ,const bool required
00464 );
00465
00466
00467 bool set_enum_value(
00468 int argv_i
00469 ,char* argv[]
00470 ,const std::string &enum_opt_name
00471 ,const int enum_id
00472 ,const std::string &enum_str_val
00473 ,std::ostream *errout
00474 ) const;
00475
00476
00477 void print_enum_opt_names(
00478 const int enum_id
00479 ,std::ostream &out
00480 ) const;
00481
00482
00483 std::string enum_opt_default_val_name(
00484 const std::string &enum_name
00485 ,const int enum_id
00486 ,std::ostream *errout
00487 ) const;
00488
00489
00490 int find_enum_opt_index(
00491 const std::string &enum_opt_name
00492 ,const int opt_value
00493 ,const enum_opt_data_t &enum_data
00494 ,std::ostream *errout
00495 ) const;
00496
00497
00498
00499 bool get_opt_val(
00500 const char str[]
00501 ,std::string *opt_name
00502 ,std::string *opt_val_str
00503 ) const;
00504
00505
00506 std::string opt_type_str( EOptType ) const;
00507
00508
00509 void print_bad_opt(
00510 int argv_i
00511 ,char* argv[]
00512 ,std::ostream *errout
00513 ) const;
00514
00515 };
00516
00517
00518
00519
00520
00521
00522 inline
00523 void CommandLineProcessor::throwExceptions( const bool & throwExceptions_in )
00524 { throwExceptions_ = throwExceptions_in; }
00525
00526 inline
00527 bool CommandLineProcessor::throwExceptions() const
00528 { return throwExceptions_; }
00529
00530 inline
00531 void CommandLineProcessor::recogniseAllOptions( const bool & recogniseAllOptions_in )
00532 { recogniseAllOptions_ = recogniseAllOptions_in; }
00533
00534 inline
00535 bool CommandLineProcessor::recogniseAllOptions() const
00536 { return recogniseAllOptions_; }
00537
00538 inline
00539 void CommandLineProcessor::addOutputSetupOptions( const bool &addOutputSetupOptions_in )
00540 { addOutputSetupOptions_ = addOutputSetupOptions_in; }
00541
00542 inline
00543 bool CommandLineProcessor::addOutputSetupOptions() const
00544 { return addOutputSetupOptions_; }
00545
00546 template <class EType>
00547 inline
00548 void CommandLineProcessor::setOption(
00549 const char enum_option_name[]
00550 ,EType *enum_option_val
00551 ,const int num_enum_opt_values
00552 ,const EType enum_opt_values[]
00553 ,const char* enum_opt_names[]
00554 ,const char documentation[]
00555 ,const bool required
00556 )
00557 {
00558
00559
00560
00561
00562
00563
00564
00565 CompileTimeAssert<sizeof(int)-sizeof(EType)>();
00566
00567 setEnumOption(
00568 enum_option_name
00569 ,reinterpret_cast<int*>(enum_option_val)
00570 ,num_enum_opt_values
00571 ,reinterpret_cast<const int*>(enum_opt_values)
00572 ,enum_opt_names
00573 ,documentation
00574 ,required
00575 );
00576 }
00577
00578 inline
00579 std::string CommandLineProcessor::opt_type_str( EOptType opt_type ) const
00580 {
00581 std::string str;
00582 switch( opt_type ) {
00583 case OPT_BOOL_TRUE:
00584 str = "bool";
00585 break;
00586 case OPT_INT:
00587 str = "int";
00588 break;
00589 case OPT_DOUBLE:
00590 str = "double";
00591 break;
00592 case OPT_STRING:
00593 str = "string";
00594 break;
00595 case OPT_ENUM_INT:
00596 str = "enum";
00597 break;
00598 default:
00599 assert(0);
00600 }
00601 return str;
00602 }
00603
00604 }
00605
00606 #endif // TEUCHOS_COMMAND_LINE_PROCESSOR_HPP