|
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 00071 namespace Teuchos { 00072 00073 class TEUCHOS_LIB_DLL_EXPORT CommandLineProcessor { 00074 public: 00075 00077 00078 00080 class ParseError : public std::logic_error 00081 {public: ParseError(const std::string& what_arg) : std::logic_error(what_arg) {}}; 00082 00084 class HelpPrinted : public ParseError 00085 {public: HelpPrinted(const std::string& what_arg) : ParseError(what_arg) {}}; 00086 00088 class UnrecognizedOption : public ParseError 00089 {public: UnrecognizedOption(const std::string& what_arg) : ParseError(what_arg) {}}; 00090 00095 enum EParseCommandLineReturn { 00096 PARSE_SUCCESSFUL = 0 00097 ,PARSE_HELP_PRINTED = 1 00098 ,PARSE_UNRECOGNIZED_OPTION = 2 00099 ,PARSE_ERROR = 3 00100 }; 00101 00103 00105 00106 00122 CommandLineProcessor( 00123 bool throwExceptions = true 00124 ,bool recogniseAllOptions = true 00125 ,bool addOutputSetupOptions = false 00126 ); 00127 00130 ~CommandLineProcessor(); 00131 00133 00135 00136 00138 void throwExceptions( const bool & throwExceptions ); 00139 00141 bool throwExceptions() const; 00142 00144 void recogniseAllOptions( const bool & recogniseAllOptions ); 00145 00147 bool recogniseAllOptions() const; 00148 00150 void addOutputSetupOptions( const bool &addOutputSetupOptions ); 00151 00153 bool addOutputSetupOptions() const; 00154 00156 00158 00159 00162 void setDocString( const char doc_string[] ); 00163 00176 void setOption( 00177 const char option_true[] 00178 ,const char option_false[] 00179 ,bool *option_val 00180 ,const char documentation[] = NULL 00181 ); 00182 00193 void setOption( 00194 const char option_name[] 00195 ,int *option_val 00196 ,const char documentation[] = NULL 00197 ,const bool required = false 00198 ); 00199 00210 void setOption( 00211 const char option_name[] 00212 ,double *option_val 00213 ,const char documentation[] = NULL 00214 ,const bool required = false 00215 ); 00216 00227 void setOption( 00228 const char option_name[] 00229 ,std::string *option_val 00230 ,const char documentation[] = NULL 00231 ,const bool required = false 00232 ); 00233 00262 template <class EType> 00263 void setOption( 00264 const char enum_option_name[] 00265 ,EType *enum_option_val 00266 ,const int num_enum_opt_values 00267 ,const EType enum_opt_values[] 00268 ,const char* enum_opt_names[] 00269 ,const char documentation[] = NULL 00270 ,const bool required = false 00271 ); 00272 00274 00276 00277 00337 EParseCommandLineReturn parse( 00338 int argc 00339 ,char* argv[] 00340 ,std::ostream *errout = &std::cerr 00341 ) const; 00342 00344 00346 00347 00356 void printHelpMessage( const char program_name[], std::ostream &out ) const; 00357 00363 void printFinalTimerSummary(const Ptr<std::ostream> &out = null); 00364 00366 00367 public: 00368 // 00369 enum EOptType { OPT_NONE, OPT_BOOL_TRUE, OPT_BOOL_FALSE, OPT_INT, OPT_DOUBLE, OPT_STRING, OPT_ENUM_INT }; 00370 // RAB: 2003/10/10: Note: I had to move this out of the private section since 00371 // the sun compiler (version 7) complained (rightly it now appears after looking 00372 // up what the ISO/ANSI C++ standard says) about the declaration for opt_val_val_t 00373 // not being able to access a private member of CommandLineProcessor. 00374 00375 private: 00376 00377 // ///////////////////////////////// 00378 // Private types 00379 00380 // ToDo: RAB: 2004/05/25: Clean up these data structures and add 00381 // support for a templated enum type. This will clean up usage 00382 // quite a bit. 00383 00384 // 00385 struct opt_val_val_t { 00386 opt_val_val_t() 00387 :opt_type(OPT_NONE) 00388 {} 00389 opt_val_val_t( EOptType opt_type_in, const any& opt_val_in, bool required_in ) 00390 :opt_type(opt_type_in),opt_val(opt_val_in),required(required_in),was_read(false) 00391 {} 00392 EOptType opt_type; 00393 any opt_val; // Will be bool*, int*, double*, std::string* or a small int (for OPT_ENUM_INT) 00394 bool required; 00395 bool was_read; 00396 }; 00397 00398 // 00399 typedef Teuchos::map<std::string,opt_val_val_t> options_list_t; 00400 00401 // 00402 struct opt_doc_t { 00403 opt_doc_t() 00404 :opt_type(OPT_NONE) 00405 {} 00406 opt_doc_t(EOptType opt_type_in, const std::string& opt_name_in, const std::string& opt_name_false_in 00407 ,const std::string &documentation_in, const any &default_val_in ) 00408 :opt_type(opt_type_in),opt_name(opt_name_in),opt_name_false(opt_name_false_in) 00409 ,documentation(documentation_in),default_val(default_val_in) 00410 {} 00411 EOptType opt_type; 00412 std::string opt_name; 00413 std::string opt_name_false; // only for bool 00414 std::string documentation; 00415 any default_val; 00416 }; 00417 00418 // 00419 typedef std::vector<opt_doc_t> options_documentation_list_t; 00420 00421 // 00422 struct enum_opt_data_t { 00423 enum_opt_data_t() 00424 :enum_option_val(NULL), num_enum_opt_values(0) 00425 {} 00426 enum_opt_data_t( 00427 int *_enum_option_val 00428 ,const int _num_enum_opt_values 00429 ,const int _enum_opt_values[] 00430 ,const char* _enum_opt_names[] 00431 ) 00432 :enum_option_val(_enum_option_val) 00433 ,num_enum_opt_values(_num_enum_opt_values) 00434 ,enum_opt_values(_enum_opt_values,_enum_opt_values+_num_enum_opt_values) 00435 { 00436 for( int k = 0; k < num_enum_opt_values; ++k ) 00437 enum_opt_names.push_back(std::string(_enum_opt_names[k])); 00438 } 00439 int *enum_option_val; 00440 int num_enum_opt_values; 00441 std::vector<int> enum_opt_values; 00442 std::vector<std::string> enum_opt_names; 00443 }; 00444 00445 // 00446 typedef std::vector<enum_opt_data_t> enum_opt_data_list_t; 00447 00448 // ///////////////////////////////// 00449 // Private data members 00450 00451 bool throwExceptions_; 00452 bool recogniseAllOptions_; 00453 bool addOutputSetupOptions_; 00454 std::string doc_string_; 00455 00456 //use pragmas to disable some false positive warnings in windows sharedlib exports 00457 #ifdef _MSC_VER 00458 #pragma warning(push) 00459 #pragma warning(disable:4251) 00460 #endif 00461 mutable options_list_t options_list_; 00462 options_documentation_list_t options_documentation_list_; 00463 enum_opt_data_list_t enum_opt_data_list_; 00464 #ifdef _MSC_VER 00465 #pragma warning(pop) 00466 #endif 00467 00468 bool output_all_front_matter_; 00469 bool output_show_line_prefix_; 00470 bool output_show_tab_count_; 00471 bool output_show_proc_rank_; 00472 int output_to_root_rank_only_; 00473 bool print_rcpnode_statistics_on_exit_; 00474 bool show_timer_summary_on_exit_; 00475 00476 bool printed_timer_summary_; 00477 00478 bool added_extra_output_setup_options_; 00479 bool in_add_extra_output_setup_options_; 00480 00481 static const bool output_all_front_matter_default_; 00482 static const bool output_show_line_prefix_default_; 00483 static const bool output_show_tab_count_default_; 00484 static const bool output_show_proc_rank_default_; 00485 static const int output_to_root_rank_only_default_; 00486 static const bool print_rcpnode_statistics_on_exit_default_; 00487 static const bool show_timer_summary_on_exit_default_; 00488 00489 // ///////////////////////////////// 00490 // Private member functions 00491 00492 // Set the extra output setup options 00493 void add_extra_output_setup_options() const; 00494 00495 // Set an integer enumeration option 00496 void setEnumOption( 00497 const char enum_option_name[] 00498 ,int *enum_option_val 00499 ,const int num_enum_opt_values 00500 ,const int enum_opt_values[] 00501 ,const char* enum_opt_names[] 00502 ,const char documentation[] 00503 ,const bool required 00504 ); 00505 00506 // Set an enum int option 00507 bool set_enum_value( 00508 int argv_i 00509 ,char* argv[] 00510 ,const std::string &enum_opt_name 00511 ,const int enum_id 00512 ,const std::string &enum_str_val 00513 ,std::ostream *errout 00514 ) const; 00515 00516 // Print the valid enum values 00517 void print_enum_opt_names( 00518 const int enum_id 00519 ,std::ostream &out 00520 ) const; 00521 00522 // Return the name of the default value for an enum 00523 std::string enum_opt_default_val_name( 00524 const std::string &enum_name 00525 ,const int enum_id 00526 ,std::ostream *errout 00527 ) const; 00528 00529 // Return the index given and option value 00530 int find_enum_opt_index( 00531 const std::string &enum_opt_name 00532 ,const int opt_value 00533 ,const enum_opt_data_t &enum_data 00534 ,std::ostream *errout 00535 ) const; 00536 00537 // Get the option and the value from an entry in argv[]. 00538 // Will return false if entry is not formated properly. 00539 bool get_opt_val( 00540 const char str[] 00541 ,std::string *opt_name 00542 ,std::string *opt_val_str // May be empty on return 00543 ) const; 00544 00545 // String for option type 00546 std::string opt_type_str( EOptType ) const; 00547 00548 // Print bad option 00549 void print_bad_opt( 00550 int argv_i 00551 ,char* argv[] 00552 ,std::ostream *errout 00553 ) const; 00554 00555 }; // end class CommandLineProcessor 00556 00557 // ///////////////////////// 00558 // Inline members 00559 00560 // Behavior modes 00561 00562 inline 00563 void CommandLineProcessor::throwExceptions( const bool & throwExceptions_in ) 00564 { throwExceptions_ = throwExceptions_in; } 00565 00566 inline 00567 bool CommandLineProcessor::throwExceptions() const 00568 { return throwExceptions_; } 00569 00570 inline 00571 void CommandLineProcessor::recogniseAllOptions( const bool & recogniseAllOptions_in ) 00572 { recogniseAllOptions_ = recogniseAllOptions_in; } 00573 00574 inline 00575 bool CommandLineProcessor::recogniseAllOptions() const 00576 { return recogniseAllOptions_; } 00577 00578 inline 00579 void CommandLineProcessor::addOutputSetupOptions( const bool &addOutputSetupOptions_in ) 00580 { addOutputSetupOptions_ = addOutputSetupOptions_in; } 00581 00582 inline 00583 bool CommandLineProcessor::addOutputSetupOptions() const 00584 { return addOutputSetupOptions_; } 00585 00586 template <class EType> 00587 inline 00588 void CommandLineProcessor::setOption( 00589 const char enum_option_name[] 00590 ,EType *enum_option_val 00591 ,const int num_enum_opt_values 00592 ,const EType enum_opt_values[] 00593 ,const char* enum_opt_names[] 00594 ,const char documentation[] 00595 ,const bool required 00596 ) 00597 { 00598 // RAB: 2004/05/25: Every C++ implementation that I know of just 00599 // represents enumerations as int's and therefore this will compile 00600 // just fine. However, the ISO/ANSI C++ standard says that 00601 // compilers are allowed to use a smaller storage type for an enum 00602 // but must not require storage any larger than an 'int'. If the 00603 // below compile-time assertion does not compile then we need to do 00604 // something different but it will be a lot of work! 00605 CompileTimeAssert<sizeof(int)-sizeof(EType)>(); 00606 //CompileTimeAssert<sizeof(int)-sizeof(EType)-1>(); // Uncomment to see compilation error 00607 setEnumOption( 00608 enum_option_name 00609 ,reinterpret_cast<int*>(enum_option_val) 00610 ,num_enum_opt_values 00611 ,reinterpret_cast<const int*>(enum_opt_values) 00612 ,enum_opt_names 00613 ,documentation 00614 ,required 00615 ); 00616 } 00617 00618 inline 00619 std::string CommandLineProcessor::opt_type_str( EOptType opt_type ) const 00620 { 00621 std::string str; 00622 switch( opt_type ) { 00623 case OPT_BOOL_TRUE: 00624 str = "bool"; 00625 break; 00626 case OPT_INT: 00627 str = "int"; 00628 break; 00629 case OPT_DOUBLE: 00630 str = "double"; 00631 break; 00632 case OPT_STRING: 00633 str = "string"; 00634 break; 00635 case OPT_ENUM_INT: 00636 str = "enum"; 00637 break; 00638 default: 00639 assert(0); // Local programming error only 00640 } 00641 return str; 00642 } 00643 00644 } // end namespace Teuchos 00645 00646 #endif // TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
1.7.6.1