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