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