|
Teuchos Package Browser (Single Doxygen Collection) Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Teuchos: Common Tools Package 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 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 /* ToDo: RAB: 2003/10/02: Add support for required options as per KRL's suggestion 00047 * 00048 * ToDo: Finish documentation. 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 // RAB: 2003/10/10: Note: I had to move this out of the private section since 00346 // the sun compiler (version 7) complained (rightly it now appears after looking 00347 // up what the ISO/ANSI C++ standard says) about the declaration for opt_val_val_t 00348 // not being able to access a private member of CommandLineProcessor. 00349 00350 private: 00351 00352 // ///////////////////////////////// 00353 // Private types 00354 00355 // ToDo: RAB: 2004/05/25: Clean up these data structures and add 00356 // support for a templated enum type. This will clean up usage 00357 // quite a bit. 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; // Will be bool*, int*, double*, std::string* or a small int (for OPT_ENUM_INT) 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; // only for bool 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 // Private data members 00425 00426 bool throwExceptions_; 00427 bool recogniseAllOptions_; 00428 bool addOutputSetupOptions_; 00429 std::string doc_string_; 00430 00431 //use pragmas to disable some false positive warnings in windows sharedlib exports 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 // Private member functions 00462 00463 // Set the extra output setup options 00464 void add_extra_output_setup_options() const; 00465 00466 // Set an integer enumeration option 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 // Set an enum int option 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 // Print the valid enum values 00488 void print_enum_opt_names( 00489 const int enum_id 00490 ,std::ostream &out 00491 ) const; 00492 00493 // Return the name of the default value for an enum 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 // Return the index given and option value 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 // Get the option and the value from an entry in argv[]. 00509 // Will return false if entry is not formated properly. 00510 bool get_opt_val( 00511 const char str[] 00512 ,std::string *opt_name 00513 ,std::string *opt_val_str // May be empty on return 00514 ) const; 00515 00516 // String for option type 00517 std::string opt_type_str( EOptType ) const; 00518 00519 // Print bad option 00520 void print_bad_opt( 00521 int argv_i 00522 ,char* argv[] 00523 ,std::ostream *errout 00524 ) const; 00525 00526 }; // end class CommandLineProcessor 00527 00528 // ///////////////////////// 00529 // Inline members 00530 00531 // Behavior modes 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 // RAB: 2004/05/25: Every C++ implementation that I know of just 00570 // represents enumerations as int's and therefore this will compile 00571 // just fine. However, the ISO/ANSI C++ standard says that 00572 // compilers are allowed to use a smaller storage type for an enum 00573 // but must not require storage any larger than an 'int'. If the 00574 // below compile-time assertion does not compile then we need to do 00575 // something different but it will be a lot of work! 00576 CompileTimeAssert<sizeof(int)-sizeof(EType)>(); 00577 //CompileTimeAssert<sizeof(int)-sizeof(EType)-1>(); // Uncomment to see compilation error 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); // Local programming error only 00611 } 00612 return str; 00613 } 00614 00615 } // end namespace Teuchos 00616 00617 #endif // TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
1.7.4