|
Teuchos - Trilinos Tools Package
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 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #ifndef TEUCHOS_COMMAND_LINE_PROCESSOR_HPP 00043 #define TEUCHOS_COMMAND_LINE_PROCESSOR_HPP 00044 00053 #include "Teuchos_map.hpp" 00054 #include "Teuchos_any.hpp" 00055 #include "Teuchos_CompileTimeAssert.hpp" 00056 #include "Teuchos_Ptr.hpp" 00057 00073 namespace Teuchos { 00074 00075 class TEUCHOSCORE_LIB_DLL_EXPORT CommandLineProcessor { 00076 public: 00077 00079 00080 00082 class ParseError : public std::logic_error 00083 {public: ParseError(const std::string& what_arg) : std::logic_error(what_arg) {}}; 00084 00086 class HelpPrinted : public ParseError 00087 {public: HelpPrinted(const std::string& what_arg) : ParseError(what_arg) {}}; 00088 00090 class UnrecognizedOption : public ParseError 00091 {public: UnrecognizedOption(const std::string& what_arg) : ParseError(what_arg) {}}; 00092 00097 enum EParseCommandLineReturn { 00098 PARSE_SUCCESSFUL = 0 00099 ,PARSE_HELP_PRINTED = 1 00100 ,PARSE_UNRECOGNIZED_OPTION = 2 00101 ,PARSE_ERROR = 3 00102 }; 00103 00105 00107 00108 00124 CommandLineProcessor( 00125 bool throwExceptions = true 00126 ,bool recogniseAllOptions = true 00127 ,bool addOutputSetupOptions = false 00128 ); 00129 00132 ~CommandLineProcessor(); 00133 00135 00137 00138 00140 void throwExceptions( const bool & throwExceptions ); 00141 00143 bool throwExceptions() const; 00144 00146 void recogniseAllOptions( const bool & recogniseAllOptions ); 00147 00149 bool recogniseAllOptions() const; 00150 00152 void addOutputSetupOptions( const bool &addOutputSetupOptions ); 00153 00155 bool addOutputSetupOptions() const; 00156 00158 00160 00161 00164 void setDocString( const char doc_string[] ); 00165 00178 void setOption( 00179 const char option_true[] 00180 ,const char option_false[] 00181 ,bool *option_val 00182 ,const char documentation[] = NULL 00183 ); 00184 00195 void setOption( 00196 const char option_name[] 00197 ,int *option_val 00198 ,const char documentation[] = NULL 00199 ,const bool required = false 00200 ); 00201 00212 void setOption( 00213 const char option_name[] 00214 ,long int *option_val 00215 ,const char documentation[] = NULL 00216 ,const bool required = false 00217 ); 00218 00229 void setOption( 00230 const char option_name[] 00231 ,size_t *option_val 00232 ,const char documentation[] = NULL 00233 ,const bool required = false 00234 ); 00235 #ifdef HAVE_TEUCHOS_LONG_LONG_INT 00236 00246 void setOption( 00247 const char option_name[] 00248 ,long long int *option_val 00249 ,const char documentation[] = NULL 00250 ,const bool required = false 00251 ); 00252 #endif 00253 00264 void setOption( 00265 const char option_name[] 00266 ,double *option_val 00267 ,const char documentation[] = NULL 00268 ,const bool required = false 00269 ); 00270 00281 void setOption( 00282 const char option_name[] 00283 ,std::string *option_val 00284 ,const char documentation[] = NULL 00285 ,const bool required = false 00286 ); 00287 00316 template <class EType> 00317 void setOption( 00318 const char enum_option_name[] 00319 ,EType *enum_option_val 00320 ,const int num_enum_opt_values 00321 ,const EType enum_opt_values[] 00322 ,const char* enum_opt_names[] 00323 ,const char documentation[] = NULL 00324 ,const bool required = false 00325 ); 00326 00328 00330 00331 00391 EParseCommandLineReturn parse( 00392 int argc 00393 ,char* argv[] 00394 ,std::ostream *errout = &std::cerr 00395 ) const; 00396 00398 00400 00401 00410 void printHelpMessage( const char program_name[], std::ostream &out ) const; 00411 00417 void printFinalTimerSummary(const Ptr<std::ostream> &out = null); 00418 00420 00421 public: 00422 // 00423 enum EOptType { OPT_NONE, OPT_BOOL_TRUE, OPT_BOOL_FALSE, OPT_INT, OPT_LONG_INT, OPT_SIZE_T, 00424 #ifdef HAVE_TEUCHOS_LONG_LONG_INT 00425 OPT_LONG_LONG_INT, 00426 #endif 00427 OPT_DOUBLE, OPT_STRING, OPT_ENUM_INT }; 00428 00429 // RAB: 2003/10/10: Note: I had to move this out of the private section since 00430 // the sun compiler (version 7) complained (rightly it now appears after looking 00431 // up what the ISO/ANSI C++ standard says) about the declaration for opt_val_val_t 00432 // not being able to access a private member of CommandLineProcessor. 00433 00434 private: 00435 00436 // ///////////////////////////////// 00437 // Private types 00438 00439 // ToDo: RAB: 2004/05/25: Clean up these data structures and add 00440 // support for a templated enum type. This will clean up usage 00441 // quite a bit. 00442 00443 // 00444 struct opt_val_val_t { 00445 opt_val_val_t(): 00446 opt_type(OPT_NONE), 00447 required(false), 00448 was_read(false) 00449 {} 00450 opt_val_val_t( EOptType opt_type_in, const any& opt_val_in, bool required_in ) 00451 :opt_type(opt_type_in),opt_val(opt_val_in),required(required_in),was_read(false) 00452 {} 00453 EOptType opt_type; 00454 any opt_val; // Will be bool*, int*, double*, std::string* or a small int (for OPT_ENUM_INT) 00455 bool required; 00456 bool was_read; 00457 }; 00458 00459 // 00460 typedef Teuchos::map<std::string,opt_val_val_t> options_list_t; 00461 00462 // 00463 struct opt_doc_t { 00464 opt_doc_t() 00465 :opt_type(OPT_NONE) 00466 {} 00467 opt_doc_t(EOptType opt_type_in, const std::string& opt_name_in, const std::string& opt_name_false_in 00468 ,const std::string &documentation_in, const any &default_val_in ) 00469 :opt_type(opt_type_in),opt_name(opt_name_in),opt_name_false(opt_name_false_in) 00470 ,documentation(documentation_in),default_val(default_val_in) 00471 {} 00472 EOptType opt_type; 00473 std::string opt_name; 00474 std::string opt_name_false; // only for bool 00475 std::string documentation; 00476 any default_val; 00477 }; 00478 00479 // 00480 typedef std::vector<opt_doc_t> options_documentation_list_t; 00481 00482 // 00483 struct enum_opt_data_t { 00484 enum_opt_data_t() 00485 :enum_option_val(NULL), num_enum_opt_values(0) 00486 {} 00487 enum_opt_data_t( 00488 int *_enum_option_val 00489 ,const int _num_enum_opt_values 00490 ,const int _enum_opt_values[] 00491 ,const char* _enum_opt_names[] 00492 ) 00493 :enum_option_val(_enum_option_val) 00494 ,num_enum_opt_values(_num_enum_opt_values) 00495 ,enum_opt_values(_enum_opt_values,_enum_opt_values+_num_enum_opt_values) 00496 { 00497 for( int k = 0; k < num_enum_opt_values; ++k ) 00498 enum_opt_names.push_back(std::string(_enum_opt_names[k])); 00499 } 00500 int *enum_option_val; 00501 int num_enum_opt_values; 00502 std::vector<int> enum_opt_values; 00503 std::vector<std::string> enum_opt_names; 00504 }; 00505 00506 // 00507 typedef std::vector<enum_opt_data_t> enum_opt_data_list_t; 00508 00509 // ///////////////////////////////// 00510 // Private data members 00511 00512 bool throwExceptions_; 00513 bool recogniseAllOptions_; 00514 bool addOutputSetupOptions_; 00515 std::string doc_string_; 00516 00517 //use pragmas to disable some false positive warnings in windows sharedlib exports 00518 #ifdef _MSC_VER 00519 #pragma warning(push) 00520 #pragma warning(disable:4251) 00521 #endif 00522 mutable options_list_t options_list_; 00523 options_documentation_list_t options_documentation_list_; 00524 enum_opt_data_list_t enum_opt_data_list_; 00525 #ifdef _MSC_VER 00526 #pragma warning(pop) 00527 #endif 00528 00529 bool output_all_front_matter_; 00530 bool output_show_line_prefix_; 00531 bool output_show_tab_count_; 00532 bool output_show_proc_rank_; 00533 int output_to_root_rank_only_; 00534 bool print_rcpnode_statistics_on_exit_; 00535 bool show_timer_summary_on_exit_; 00536 00537 bool printed_timer_summary_; 00538 00539 bool added_extra_output_setup_options_; 00540 bool in_add_extra_output_setup_options_; 00541 00542 static const bool output_all_front_matter_default_; 00543 static const bool output_show_line_prefix_default_; 00544 static const bool output_show_tab_count_default_; 00545 static const bool output_show_proc_rank_default_; 00546 static const int output_to_root_rank_only_default_; 00547 static const bool print_rcpnode_statistics_on_exit_default_; 00548 static const bool show_timer_summary_on_exit_default_; 00549 00550 // ///////////////////////////////// 00551 // Private member functions 00552 00553 // Set the extra output setup options 00554 void add_extra_output_setup_options() const; 00555 00556 // Set an integer enumeration option 00557 void setEnumOption( 00558 const char enum_option_name[] 00559 ,int *enum_option_val 00560 ,const int num_enum_opt_values 00561 ,const int enum_opt_values[] 00562 ,const char* enum_opt_names[] 00563 ,const char documentation[] 00564 ,const bool required 00565 ); 00566 00567 // Set an enum int option 00568 bool set_enum_value( 00569 int argv_i 00570 ,char* argv[] 00571 ,const std::string &enum_opt_name 00572 ,const int enum_id 00573 ,const std::string &enum_str_val 00574 ,std::ostream *errout 00575 ) const; 00576 00577 // Print the valid enum values 00578 void print_enum_opt_names( 00579 const int enum_id 00580 ,std::ostream &out 00581 ) const; 00582 00583 // Return the name of the default value for an enum 00584 std::string enum_opt_default_val_name( 00585 const std::string &enum_name 00586 ,const int enum_id 00587 ,std::ostream *errout 00588 ) const; 00589 00590 // Return the index given and option value 00591 int find_enum_opt_index( 00592 const std::string &enum_opt_name 00593 ,const int opt_value 00594 ,const enum_opt_data_t &enum_data 00595 ,std::ostream *errout 00596 ) const; 00597 00598 // Get the option and the value from an entry in argv[]. 00599 // Will return false if entry is not formated properly. 00600 bool get_opt_val( 00601 const char str[] 00602 ,std::string *opt_name 00603 ,std::string *opt_val_str // May be empty on return 00604 ) const; 00605 00606 // String for option type 00607 std::string opt_type_str( EOptType ) const; 00608 00609 // Print bad option 00610 void print_bad_opt( 00611 int argv_i 00612 ,char* argv[] 00613 ,std::ostream *errout 00614 ) const; 00615 00616 public: // Hidden implementation stuff that clients should never see 00617 00652 class TimeMonitorSurrogate { 00653 public: 00655 virtual ~TimeMonitorSurrogate() {} 00657 virtual void summarize(std::ostream &out=std::cout) = 0; 00658 }; 00659 00660 static void setTimeMonitorSurrogate(const RCP<TimeMonitorSurrogate> &timeMonitorSurrogate); 00661 00662 static RCP<TimeMonitorSurrogate> getTimeMonitorSurrogate(); 00663 00664 private: 00665 00666 static RCP<TimeMonitorSurrogate>& getRawTimeMonitorSurrogate(); 00667 00668 }; // end class CommandLineProcessor 00669 00670 00671 // ///////////////////////// 00672 // Inline members 00673 00674 00675 // Behavior modes 00676 00677 00678 inline 00679 void CommandLineProcessor::throwExceptions( const bool & throwExceptions_in ) 00680 { throwExceptions_ = throwExceptions_in; } 00681 00682 00683 inline 00684 bool CommandLineProcessor::throwExceptions() const 00685 { return throwExceptions_; } 00686 00687 00688 inline 00689 void CommandLineProcessor::recogniseAllOptions( const bool & recogniseAllOptions_in ) 00690 { recogniseAllOptions_ = recogniseAllOptions_in; } 00691 00692 00693 inline 00694 bool CommandLineProcessor::recogniseAllOptions() const 00695 { return recogniseAllOptions_; } 00696 00697 00698 inline 00699 void CommandLineProcessor::addOutputSetupOptions( const bool &addOutputSetupOptions_in ) 00700 { addOutputSetupOptions_ = addOutputSetupOptions_in; } 00701 00702 00703 inline 00704 bool CommandLineProcessor::addOutputSetupOptions() const 00705 { return addOutputSetupOptions_; } 00706 00707 00708 template <class EType> 00709 inline 00710 void CommandLineProcessor::setOption( 00711 const char enum_option_name[] 00712 ,EType *enum_option_val 00713 ,const int num_enum_opt_values 00714 ,const EType enum_opt_values[] 00715 ,const char* enum_opt_names[] 00716 ,const char documentation[] 00717 ,const bool required 00718 ) 00719 { 00720 // RAB: 2004/05/25: Every C++ implementation that I know of just 00721 // represents enumerations as int's and therefore this will compile 00722 // just fine. However, the ISO/ANSI C++ standard says that 00723 // compilers are allowed to use a smaller storage type for an enum 00724 // but must not require storage any larger than an 'int'. If the 00725 // below compile-time assertion does not compile then we need to do 00726 // something different but it will be a lot of work! 00727 CompileTimeAssert<sizeof(int)-sizeof(EType)>(); 00728 //CompileTimeAssert<sizeof(int)-sizeof(EType)-1>(); // Uncomment to see compilation error 00729 setEnumOption( 00730 enum_option_name 00731 ,reinterpret_cast<int*>(enum_option_val) 00732 ,num_enum_opt_values 00733 ,reinterpret_cast<const int*>(enum_opt_values) 00734 ,enum_opt_names 00735 ,documentation 00736 ,required 00737 ); 00738 } 00739 00740 00741 inline 00742 std::string CommandLineProcessor::opt_type_str( EOptType opt_type ) const 00743 { 00744 std::string str; 00745 switch( opt_type ) { 00746 case OPT_BOOL_TRUE: 00747 str = "bool"; 00748 break; 00749 case OPT_INT: 00750 str = "int"; 00751 break; 00752 case OPT_LONG_INT: 00753 str = "long int"; 00754 break; 00755 case OPT_SIZE_T: 00756 str = "size_t"; 00757 break; 00758 #ifdef HAVE_TEUCHOS_LONG_LONG_INT 00759 case OPT_LONG_LONG_INT: 00760 str = "long long int"; 00761 break; 00762 #endif 00763 case OPT_DOUBLE: 00764 str = "double"; 00765 break; 00766 case OPT_STRING: 00767 str = "string"; 00768 break; 00769 case OPT_ENUM_INT: 00770 str = "enum"; 00771 break; 00772 default: 00773 assert(0); // Local programming error only 00774 } 00775 return str; 00776 } 00777 00778 00779 } // end namespace Teuchos 00780 00781 00782 #endif // TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
1.7.6.1