|
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 // 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 // ////////////////////////////////////////////////// 00043 // Teuchos_CommandLineProcessor.cpp 00044 00045 00046 #include "Teuchos_CommandLineProcessor.hpp" 00047 #include "Teuchos_GlobalMPISession.hpp" 00048 #include "Teuchos_VerboseObject.hpp" 00049 //#include "Teuchos_TimeMonitor.hpp" 00050 #include "Teuchos_Assert.hpp" 00051 #include "Teuchos_as.hpp" 00052 00053 00054 namespace { 00055 00056 00057 inline int my_max( int a, int b ) { return a > b ? a : b; } 00058 00059 00060 std::string remove_quotes( const std::string& str ) 00061 { 00062 if(str[0] != '\"') 00063 return str; 00064 return str.substr(1,str.size()-2); 00065 } 00066 00067 00068 std::string add_quotes( const std::string& str ) 00069 { 00070 if(str[0] == '\"') 00071 return str; 00072 return "\"" + str + "\""; 00073 } 00074 00075 00076 } // end namespace 00077 00078 00079 namespace Teuchos { 00080 00081 00082 const bool CommandLineProcessor::output_all_front_matter_default_(false); 00083 const bool CommandLineProcessor::output_show_line_prefix_default_(false); 00084 const bool CommandLineProcessor::output_show_tab_count_default_(false); 00085 const bool CommandLineProcessor::output_show_proc_rank_default_(false); 00086 const int CommandLineProcessor::output_to_root_rank_only_default_(0); 00087 const bool CommandLineProcessor::print_rcpnode_statistics_on_exit_default_(false); 00088 const bool CommandLineProcessor::show_timer_summary_on_exit_default_(false); 00089 00090 00091 CommandLineProcessor::CommandLineProcessor( 00092 bool throwExceptions_in 00093 ,bool recogniseAllOptions_in 00094 ,bool addOutputSetupOptions_in 00095 ) 00096 :throwExceptions_(throwExceptions_in) 00097 ,recogniseAllOptions_(recogniseAllOptions_in) 00098 ,addOutputSetupOptions_(addOutputSetupOptions_in) 00099 ,output_all_front_matter_(output_all_front_matter_default_) 00100 ,output_show_line_prefix_(output_show_line_prefix_default_) 00101 ,output_show_tab_count_(output_show_tab_count_default_) 00102 ,output_show_proc_rank_(output_show_proc_rank_default_) 00103 ,output_to_root_rank_only_(output_to_root_rank_only_default_) 00104 ,print_rcpnode_statistics_on_exit_(print_rcpnode_statistics_on_exit_default_) 00105 ,show_timer_summary_on_exit_(show_timer_summary_on_exit_default_) 00106 ,printed_timer_summary_(false) 00107 ,added_extra_output_setup_options_(false) 00108 ,in_add_extra_output_setup_options_(false) 00109 {} 00110 00111 00112 CommandLineProcessor::~CommandLineProcessor() 00113 { 00114 printFinalTimerSummary(); 00115 } 00116 00117 00118 // Set up options 00119 00120 00121 void CommandLineProcessor::setDocString( const char doc_string[] ) 00122 { 00123 doc_string_ = doc_string; 00124 } 00125 00126 00127 void CommandLineProcessor::setOption( 00128 const char option_true[] 00129 ,const char option_false[] 00130 ,bool *option_val 00131 ,const char documentation[] 00132 ) 00133 { 00134 add_extra_output_setup_options(); 00135 TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL)); 00136 options_list_[std::string(option_true)] 00137 = opt_val_val_t(OPT_BOOL_TRUE,any(option_val),false); 00138 options_list_[std::string(option_false)] 00139 = opt_val_val_t(OPT_BOOL_FALSE,any(option_val),false); 00140 options_documentation_list_.push_back( 00141 opt_doc_t(OPT_BOOL_TRUE, option_true, option_false, 00142 std::string(documentation?documentation:""), any(option_val)) 00143 ); 00144 } 00145 00146 00147 void CommandLineProcessor::setOption( 00148 const char option_name[] 00149 ,int *option_val 00150 ,const char documentation[] 00151 ,const bool required 00152 ) 00153 { 00154 add_extra_output_setup_options(); 00155 TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL)); 00156 options_list_[std::string(option_name)] 00157 = opt_val_val_t(OPT_INT,any(option_val),required); 00158 options_documentation_list_.push_back( 00159 opt_doc_t(OPT_INT, option_name, "", std::string(documentation?documentation:""), 00160 any(option_val)) 00161 ); 00162 } 00163 00164 00165 void CommandLineProcessor::setOption( 00166 const char option_name[] 00167 ,long int *option_val 00168 ,const char documentation[] 00169 ,const bool required 00170 ) 00171 { 00172 add_extra_output_setup_options(); 00173 TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL)); 00174 options_list_[std::string(option_name)] 00175 = opt_val_val_t(OPT_LONG_INT,any(option_val),required); 00176 options_documentation_list_.push_back( 00177 opt_doc_t(OPT_LONG_INT, option_name, "", std::string(documentation?documentation:""), 00178 any(option_val)) 00179 ); 00180 } 00181 00182 00183 void CommandLineProcessor::setOption( 00184 const char option_name[] 00185 ,size_t *option_val 00186 ,const char documentation[] 00187 ,const bool required 00188 ) 00189 { 00190 add_extra_output_setup_options(); 00191 TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL)); 00192 options_list_[std::string(option_name)] 00193 = opt_val_val_t(OPT_SIZE_T,any(option_val),required); 00194 options_documentation_list_.push_back( 00195 opt_doc_t(OPT_SIZE_T, option_name, "", std::string(documentation?documentation:""), 00196 any(option_val)) 00197 ); 00198 } 00199 00200 #ifdef HAVE_TEUCHOS_LONG_LONG_INT 00201 void CommandLineProcessor::setOption( 00202 const char option_name[] 00203 ,long long int *option_val 00204 ,const char documentation[] 00205 ,const bool required 00206 ) 00207 { 00208 add_extra_output_setup_options(); 00209 TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL)); 00210 options_list_[std::string(option_name)] 00211 = opt_val_val_t(OPT_LONG_LONG_INT,any(option_val),required); 00212 options_documentation_list_.push_back( 00213 opt_doc_t(OPT_LONG_LONG_INT, option_name, "", std::string(documentation?documentation:""), 00214 any(option_val)) 00215 ); 00216 } 00217 #endif 00218 00219 00220 void CommandLineProcessor::setOption( 00221 const char option_name[] 00222 ,double *option_val 00223 ,const char documentation[] 00224 ,const bool required 00225 ) 00226 { 00227 add_extra_output_setup_options(); 00228 TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL)); 00229 options_list_[std::string(option_name)] 00230 = opt_val_val_t(OPT_DOUBLE,any(option_val),required); 00231 options_documentation_list_.push_back( 00232 opt_doc_t(OPT_DOUBLE, option_name, "", std::string(documentation?documentation:""), 00233 any(option_val)) 00234 ); 00235 } 00236 00237 00238 void CommandLineProcessor::setOption( 00239 const char option_name[] 00240 ,std::string *option_val 00241 ,const char documentation[] 00242 ,const bool required 00243 ) 00244 { 00245 add_extra_output_setup_options(); 00246 TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL)); 00247 options_list_[std::string(option_name)] 00248 = opt_val_val_t(OPT_STRING,any(option_val),required); 00249 options_documentation_list_.push_back( 00250 opt_doc_t(OPT_STRING, option_name, "", std::string(documentation?documentation:""), 00251 any(option_val)) 00252 ); 00253 } 00254 00255 00256 // Parse command line 00257 00258 00259 CommandLineProcessor::EParseCommandLineReturn 00260 CommandLineProcessor::parse( 00261 int argc 00262 ,char* argv[] 00263 ,std::ostream *errout 00264 ) const 00265 { 00266 add_extra_output_setup_options(); 00267 std::string opt_name; 00268 std::string opt_val_str; 00269 const std::string echo_cl_opt = "echo-command-line"; 00270 const std::string help_opt = "help"; 00271 const std::string pause_opt = "pause-for-debugging"; 00272 int procRank = GlobalMPISession::getRank(); 00273 for( int i = 1; i < argc; ++i ) { 00274 bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str ); 00275 if( !gov_return ) { 00276 if(procRank == 0) 00277 print_bad_opt(i,argv,errout); 00278 if( recogniseAllOptions() ) 00279 return PARSE_UNRECOGNIZED_OPTION; 00280 else { 00281 continue; 00282 } 00283 } 00284 if( opt_name == echo_cl_opt ) { 00285 if(errout && procRank == 0) { 00286 *errout << "\nEchoing the command-line:\n\n"; 00287 for( int j = 0; j < argc; ++j ) 00288 *errout << argv[j] << " "; 00289 *errout << "\n\n"; 00290 } 00291 continue; 00292 } 00293 if( opt_name == help_opt ) { 00294 if(errout) printHelpMessage( argv[0], *errout ); 00295 return PARSE_HELP_PRINTED; 00296 } 00297 if( opt_name == pause_opt ) { 00298 if(procRank == 0) { 00299 std::cerr << "\nType 0 and press enter to continue : "; 00300 int dummy_int = 0; 00301 std::cin >> dummy_int; 00302 } 00303 GlobalMPISession::barrier(); 00304 continue; 00305 } 00306 // Lookup the option (we had better find it!) 00307 options_list_t::iterator itr = options_list_.find(opt_name); 00308 if( itr == options_list_.end() ) { 00309 if(procRank == 0) 00310 print_bad_opt(i,argv,errout); 00311 if( recogniseAllOptions() ) 00312 return PARSE_UNRECOGNIZED_OPTION; 00313 else 00314 continue; 00315 } 00316 // Changed access to second value of std::map to not use overloaded arrow operator, 00317 // otherwise this code will not compile on Janus (HKT, 12/01/2003) 00318 opt_val_val_t &opt_val_val = (*itr).second; 00319 opt_val_val.was_read = true; 00320 switch( opt_val_val.opt_type ) { 00321 case OPT_BOOL_TRUE: 00322 *(any_cast<bool*>(opt_val_val.opt_val)) = true; 00323 break; 00324 case OPT_BOOL_FALSE: 00325 *(any_cast<bool*>(opt_val_val.opt_val)) = false; 00326 break; 00327 case OPT_INT: 00328 *(any_cast<int*>(opt_val_val.opt_val)) = asSafe<int> (opt_val_str); 00329 break; 00330 case OPT_LONG_INT: 00331 *(any_cast<long int*>(opt_val_val.opt_val)) = asSafe<long int> (opt_val_str); 00332 break; 00333 case OPT_SIZE_T: 00334 *(any_cast<size_t *>(opt_val_val.opt_val)) = asSafe<size_t> (opt_val_str); 00335 break; 00336 #ifdef HAVE_TEUCHOS_LONG_LONG_INT 00337 case OPT_LONG_LONG_INT: 00338 *(any_cast<long long int*>(opt_val_val.opt_val)) = asSafe<long long int> (opt_val_str); 00339 break; 00340 #endif 00341 case OPT_DOUBLE: 00342 *(any_cast<double*>(opt_val_val.opt_val)) = asSafe<double> (opt_val_str); 00343 break; 00344 case OPT_STRING: 00345 *(any_cast<std::string*>(opt_val_val.opt_val)) = remove_quotes(opt_val_str); 00346 break; 00347 case OPT_ENUM_INT: 00348 if( !set_enum_value( i, argv, opt_name, any_cast<int>(opt_val_val.opt_val), 00349 remove_quotes(opt_val_str), errout ) ) 00350 { 00351 return PARSE_UNRECOGNIZED_OPTION; 00352 } 00353 break; 00354 default: 00355 TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only 00356 } 00357 } 00358 // Look for options that were required but were not set 00359 for( 00360 options_list_t::const_iterator itr = options_list_.begin(); 00361 itr != options_list_.end(); 00362 ++itr 00363 ) 00364 { 00365 const opt_val_val_t &opt_val_val = (*itr).second; 00366 if( opt_val_val.required && !opt_val_val.was_read ) { 00367 const std::string &opt_val_name = (*itr).first; 00368 #define CLP_ERR_MSG \ 00369 "Error, the option --"<<opt_val_name<<" was required but was not set!" 00370 if(errout) 00371 *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl; 00372 if( throwExceptions() ) { 00373 TEUCHOS_TEST_FOR_EXCEPTION( true, ParseError, CLP_ERR_MSG ); 00374 } 00375 return PARSE_ERROR; 00376 #undef CLP_ERR_MSG 00377 } 00378 } 00379 // Set the options of a default stream exists and if we are asked to 00380 RCP<FancyOStream> 00381 defaultOut = VerboseObjectBase::getDefaultOStream(); 00382 if (defaultOut.get() && addOutputSetupOptions_) { 00383 if (output_all_front_matter_ != output_all_front_matter_default_) 00384 defaultOut->setShowAllFrontMatter(output_all_front_matter_); 00385 if (output_show_line_prefix_ != output_show_line_prefix_default_) 00386 defaultOut->setShowLinePrefix(output_show_line_prefix_); 00387 if (output_show_tab_count_ != output_show_tab_count_default_) 00388 defaultOut->setShowTabCount(output_show_tab_count_); 00389 if (output_show_proc_rank_ != output_show_proc_rank_default_) 00390 defaultOut->setShowProcRank(output_show_proc_rank_); 00391 if (output_to_root_rank_only_ != output_to_root_rank_only_default_) 00392 defaultOut->setOutputToRootOnly(output_to_root_rank_only_); 00393 RCPNodeTracer::setPrintRCPNodeStatisticsOnExit(print_rcpnode_statistics_on_exit_); 00394 } 00395 return PARSE_SUCCESSFUL; 00396 } 00397 00398 00399 void CommandLineProcessor::printHelpMessage( const char program_name[], 00400 std::ostream &out ) const 00401 { 00402 add_extra_output_setup_options(); 00403 int procRank = GlobalMPISession::getRank(); 00404 if (procRank == 0) { 00405 using std::setw; 00406 using std::endl; 00407 00408 const int opt_type_w = 14; 00409 const char spc_chars[] = " "; 00410 00411 // Get the maximum length of an option name 00412 int opt_name_w = 19; // For the 'pause-for-debugging' option 00413 options_documentation_list_t::const_iterator itr; 00414 for ( 00415 itr = options_documentation_list_.begin(); 00416 itr != options_documentation_list_.end(); 00417 ++itr 00418 ) 00419 { 00420 opt_name_w = my_max(opt_name_w,itr->opt_name.length()); 00421 if( itr->opt_type ) 00422 opt_name_w = my_max(opt_name_w,itr->opt_name_false.length()); 00423 } 00424 opt_name_w += 2; 00425 00426 // Some built-in options 00427 out 00428 << "Usage: " << program_name << " [options]\n" 00429 << spc_chars << "options:\n" 00430 << spc_chars 00431 << "--" 00432 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS 00433 << std::left << setw(opt_name_w) << "help" 00434 << std::left << setw(opt_type_w) << " " 00435 #else 00436 << std::setiosflags(std::ios::left) << setw(opt_name_w) << "help" 00437 << std::setiosflags(std::ios::left) << setw(opt_type_w) << " " 00438 #endif 00439 << "Prints this help message" 00440 << std::endl 00441 << spc_chars 00442 << "--" 00443 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS 00444 << std::left << setw(opt_name_w) << "pause-for-debugging" 00445 << std::left << setw(opt_type_w) << " " 00446 #else 00447 << std::setiosflags(std::ios::left) << setw(opt_name_w) << "pause-for-debugging" 00448 << std::setiosflags(std::ios::left) << setw(opt_type_w) << " " 00449 #endif 00450 << "Pauses for user input to allow attaching a debugger" 00451 << std::endl 00452 << spc_chars 00453 << "--" 00454 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS 00455 << std::left << setw(opt_name_w) << "echo-command-line" 00456 << std::left << setw(opt_type_w) << " " 00457 #else 00458 << std::setiosflags(std::ios::left) << setw(opt_name_w) << "echo-command-line" 00459 << std::setiosflags(std::ios::left) << setw(opt_type_w) << " " 00460 #endif 00461 << "Echo the command-line but continue as normal" 00462 << std::endl; 00463 for( 00464 itr = options_documentation_list_.begin(); 00465 itr != options_documentation_list_.end(); 00466 ++itr ) 00467 { 00468 // print top line with option name, type and short documentation string 00469 out 00470 << spc_chars 00471 << "--" 00472 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS 00473 << std::left << setw(opt_name_w) << itr->opt_name 00474 << std::left << setw(opt_type_w) << opt_type_str(itr->opt_type) 00475 #else 00476 << std::setiosflags(std::ios::left) << setw(opt_name_w) << itr->opt_name 00477 << std::setiosflags(std::ios::left) << setw(opt_type_w) << opt_type_str(itr->opt_type) 00478 #endif 00479 << ( itr->documentation.length() ? itr->documentation.c_str() : "No documentation" ) 00480 << std::endl; 00481 // If an enumeration option then the next line is the value options 00482 if( itr->opt_type == OPT_ENUM_INT ) { 00483 out 00484 << spc_chars 00485 << " " 00486 << setw(opt_name_w) << "" 00487 << setw(opt_type_w) << ""; 00488 print_enum_opt_names( any_cast<int>(itr->default_val), out ); 00489 out 00490 << std::endl; 00491 } 00492 // Now print the line that contains the default values 00493 if( itr->opt_type == OPT_BOOL_TRUE ) { 00494 out 00495 << spc_chars 00496 << "--" 00497 << setw(opt_name_w) << itr->opt_name_false; 00498 } 00499 else { 00500 out 00501 << spc_chars 00502 << " " 00503 << setw(opt_name_w) << " "; 00504 } 00505 out 00506 << setw(opt_type_w) << " " 00507 << "(default: "; 00508 switch( itr->opt_type ) { 00509 case OPT_BOOL_TRUE: 00510 out << "--" << ( (*(any_cast<bool*>(itr->default_val))) ? 00511 itr->opt_name : itr->opt_name_false ); 00512 break; 00513 case OPT_INT: 00514 case OPT_LONG_INT: 00515 case OPT_SIZE_T: 00516 #ifdef HAVE_TEUCHOS_LONG_LONG_INT 00517 case OPT_LONG_LONG_INT: 00518 #endif 00519 case OPT_DOUBLE: 00520 case OPT_STRING: 00521 case OPT_ENUM_INT: 00522 out << "--" << itr->opt_name; 00523 break; 00524 default: 00525 TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only 00526 } 00527 switch( itr->opt_type ) { 00528 case OPT_BOOL_TRUE: 00529 break; 00530 case OPT_INT: 00531 out << "=" << (*(any_cast<int*>(itr->default_val))); 00532 break; 00533 case OPT_LONG_INT: 00534 out << "=" << (*(any_cast<long int*>(itr->default_val))); 00535 break; 00536 case OPT_SIZE_T: 00537 out << "=" << (*(any_cast<size_t*>(itr->default_val))); 00538 break; 00539 #ifdef HAVE_TEUCHOS_LONG_LONG_INT 00540 case OPT_LONG_LONG_INT: 00541 out << "=" << (*(any_cast<long long int*>(itr->default_val))); 00542 break; 00543 #endif 00544 case OPT_DOUBLE: 00545 out << "=" << (*(any_cast<double*>(itr->default_val))); 00546 break; 00547 case OPT_STRING: 00548 out << "=" << add_quotes(*(any_cast<std::string*>(itr->default_val))); 00549 break; 00550 case OPT_ENUM_INT: 00551 out << "=" << add_quotes( 00552 enum_opt_default_val_name(itr->opt_name,any_cast<int>(itr->default_val),&out)); 00553 break; 00554 default: 00555 TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only 00556 } 00557 out << ")\n"; 00558 } 00559 if(doc_string_.length()) { 00560 out << "\nDETAILED DOCUMENTATION:\n\n" << doc_string_ << std::endl << std::endl; 00561 } 00562 if(throwExceptions_) 00563 TEUCHOS_TEST_FOR_EXCEPTION( true, HelpPrinted, "Help message was printed" ); 00564 } 00565 } 00566 00567 00568 void CommandLineProcessor::printFinalTimerSummary( 00569 const Ptr<std::ostream> &out_inout 00570 ) 00571 { 00572 if (!printed_timer_summary_ && show_timer_summary_on_exit_) { 00573 RCP<std::ostream> out; 00574 if (nonnull(out_inout)) { 00575 out = rcpFromPtr(out_inout); 00576 } 00577 else { 00578 out = VerboseObjectBase::getDefaultOStream(); 00579 } 00580 getTimeMonitorSurrogate()->summarize(*out << "\n"); 00581 printed_timer_summary_ = true; 00582 } 00583 } 00584 00585 00586 // private 00587 00588 00589 void CommandLineProcessor::add_extra_output_setup_options() const 00590 { 00591 if( 00592 // Are we in this function already and calling it recursively? 00593 in_add_extra_output_setup_options_ 00594 || 00595 // Have we already setup these options? 00596 added_extra_output_setup_options_ 00597 || 00598 // Are we not supposed to setup these options? 00599 !addOutputSetupOptions_ 00600 ) 00601 { 00602 return; // If any of the above is true, we need to return right away! 00603 } 00604 // Set the commandline options for this ... 00605 CommandLineProcessor 00606 *clp = const_cast<CommandLineProcessor*>(this); 00607 clp->in_add_extra_output_setup_options_ = true; 00608 clp->setOption( 00609 "output-all-front-matter","output-no-front-matter",&clp->output_all_front_matter_ 00610 ,"Set if all front matter is printed to the default FancyOStream or not" 00611 ); 00612 clp->setOption( 00613 "output-show-line-prefix","output-no-show-line-prefix",&clp->output_show_line_prefix_ 00614 ,"Set if the line prefix matter is printed to the default FancyOStream or not" 00615 ); 00616 clp->setOption( 00617 "output-show-tab-count","output-no-show-tab-count",&clp->output_show_tab_count_ 00618 ,"Set if the tab count is printed to the default FancyOStream or not" 00619 ); 00620 clp->setOption( 00621 "output-show-proc-rank","output-no-show-proc-rank",&clp->output_show_proc_rank_ 00622 ,"Set if the processor rank is printed to the default FancyOStream or not" 00623 ); 00624 clp->setOption( 00625 "output-to-root-rank-only",&clp->output_to_root_rank_only_ 00626 ,"Set which processor (the root) gets the output. If < 0, then all processors get output." 00627 ); 00628 clp->setOption( 00629 "print-rcpnode-statistics-on-exit", "no-print-rcpnode-statistics-on-exit", 00630 &clp->print_rcpnode_statistics_on_exit_, 00631 "Set if the RCPNode usage statistics will be printed on exit or not. Warning," 00632 " this prints to std::cerr or every process so do not turn this on for very large" 00633 " parallel runs." 00634 ); 00635 if (nonnull(getTimeMonitorSurrogate())) { 00636 clp->setOption( 00637 "show-timer-summary", "no-show-timer-sumary", &clp->show_timer_summary_on_exit_, 00638 "If true, then Teuchos::TimeMonitor::summarize() is called in" 00639 " CommandLineProcessor's destructor (usually at the end of main)." 00640 ); 00641 } 00642 00643 clp->added_extra_output_setup_options_ = true; 00644 clp->in_add_extra_output_setup_options_ = false; 00645 } 00646 00647 00648 void CommandLineProcessor::setEnumOption( 00649 const char enum_option_name[] 00650 ,int *enum_option_val 00651 ,const int num_enum_opt_values 00652 ,const int enum_opt_values[] 00653 ,const char* enum_opt_names[] 00654 ,const char documentation[] 00655 ,const bool required 00656 ) 00657 { 00658 add_extra_output_setup_options(); 00659 00660 TEUCHOS_TEST_FOR_EXCEPT(enum_option_val==NULL); 00661 TEUCHOS_TEST_FOR_EXCEPT(num_enum_opt_values<=0); 00662 TEUCHOS_TEST_FOR_EXCEPT(enum_opt_values==NULL); 00663 TEUCHOS_TEST_FOR_EXCEPT(enum_opt_names==NULL); 00664 00665 enum_opt_data_list_.push_back( 00666 enum_opt_data_t(enum_option_val,num_enum_opt_values,enum_opt_values,enum_opt_names) 00667 ); 00668 const int opt_id = enum_opt_data_list_.size()-1; 00669 options_list_[std::string(enum_option_name)] 00670 = opt_val_val_t(OPT_ENUM_INT,any(opt_id),required); 00671 options_documentation_list_.push_back( 00672 opt_doc_t(OPT_ENUM_INT,enum_option_name, "", 00673 std::string(documentation?documentation:""), any(opt_id)) 00674 ); 00675 } 00676 00677 00678 bool CommandLineProcessor::set_enum_value( 00679 int argv_i 00680 ,char* argv[] 00681 ,const std::string &enum_opt_name 00682 ,const int enum_id 00683 ,const std::string &enum_str_val 00684 ,std::ostream *errout 00685 ) const 00686 { 00687 const enum_opt_data_t 00688 &enum_opt_data = enum_opt_data_list_.at(enum_id); 00689 std::vector<std::string>::const_iterator 00690 itr_begin = enum_opt_data.enum_opt_names.begin(), 00691 itr_end = enum_opt_data.enum_opt_names.end(), 00692 itr = std::find( itr_begin, itr_end, enum_str_val ); 00693 if( itr == itr_end ) { 00694 const int j = argv_i; 00695 #define CLP_ERR_MSG \ 00696 "Error, the value \"" << enum_str_val << "\" for the " \ 00697 << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) << " option --" \ 00698 << enum_opt_name << " was not recognized (use --help)!" 00699 if(errout) 00700 *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl; 00701 if( throwExceptions() ) { 00702 TEUCHOS_TEST_FOR_EXCEPTION( true, UnrecognizedOption, CLP_ERR_MSG ); 00703 } 00704 else { 00705 return false; 00706 } 00707 #undef CLP_ERR_MSG 00708 } 00709 const int enum_opt_val_index = itr - itr_begin; 00710 *enum_opt_data.enum_option_val = enum_opt_data.enum_opt_values.at(enum_opt_val_index); 00711 return true; 00712 } 00713 00714 00715 void CommandLineProcessor::print_enum_opt_names( 00716 const int enum_id 00717 ,std::ostream &out 00718 ) const 00719 { 00720 const enum_opt_data_t 00721 &enum_opt_data = enum_opt_data_list_.at(enum_id); 00722 typedef std::vector<std::string>::const_iterator itr_t; 00723 out << "Valid options:"; 00724 for( 00725 itr_t itr = enum_opt_data.enum_opt_names.begin(); 00726 itr != enum_opt_data.enum_opt_names.end(); 00727 ++itr 00728 ) 00729 { 00730 if( itr != enum_opt_data.enum_opt_names.begin() ) out << ","; 00731 out << " " << add_quotes(*itr); 00732 } 00733 } 00734 00735 00736 std::string 00737 CommandLineProcessor::enum_opt_default_val_name( 00738 const std::string &enum_name 00739 ,const int enum_id 00740 ,std::ostream *errout 00741 ) const 00742 { 00743 const enum_opt_data_t 00744 &enum_opt_data = enum_opt_data_list_.at(enum_id); 00745 return enum_opt_data.enum_opt_names.at( 00746 find_enum_opt_index( 00747 enum_name,*enum_opt_data.enum_option_val,enum_opt_data,errout 00748 ) 00749 ); 00750 } 00751 00752 00753 int CommandLineProcessor::find_enum_opt_index( 00754 const std::string &enum_opt_name 00755 ,const int opt_value 00756 ,const enum_opt_data_t &enum_data 00757 ,std::ostream *errout 00758 ) const 00759 { 00760 std::vector<int>::const_iterator 00761 itr_begin = enum_data.enum_opt_values.begin(), 00762 itr_end = enum_data.enum_opt_values.end(), 00763 itr = std::find( itr_begin, itr_end, opt_value ); 00764 if( itr == itr_end ) { 00765 #define CLP_ERR_MSG \ 00766 ( recogniseAllOptions() ? "Error" : "Warning" ) \ 00767 << ", option --" << enum_opt_name << " was given an invalid " \ 00768 "initial option value of " << opt_value << "!" 00769 if(errout) 00770 *errout << CLP_ERR_MSG << std::endl; 00771 if( throwExceptions() ) 00772 TEUCHOS_TEST_FOR_EXCEPTION( true, std::invalid_argument, CLP_ERR_MSG ); 00773 #undef CLP_ERR_MSG 00774 } 00775 return itr - itr_begin; 00776 } 00777 00778 00779 bool CommandLineProcessor::get_opt_val( 00780 const char str[] 00781 ,std::string *opt_name 00782 ,std::string *opt_val_str 00783 ) const 00784 { 00785 const int len = std::strlen(str); 00786 if( len < 3 ) 00787 return false; // Can't be an option with '--' followed by at least one char 00788 if( str[0] != '-' || str[1] != '-' ) 00789 return false; // Not a recognised option 00790 // Find the '=' 00791 int equ_i; 00792 for( equ_i = 2; equ_i < len && str[equ_i] != '='; ++equ_i ); 00793 // Set opt_name 00794 opt_name->assign( str + 2, equ_i-2 ); 00795 // Set opt_val_str 00796 if( equ_i == len ) { 00797 *opt_val_str = ""; 00798 } 00799 else { 00800 opt_val_str->assign( str + equ_i + 1, len - equ_i - 1 ); 00801 } 00802 return true; 00803 } 00804 00805 void CommandLineProcessor::print_bad_opt( 00806 int argv_i 00807 ,char* argv[] 00808 ,std::ostream *errout 00809 ) const 00810 { 00811 const int j = argv_i; 00812 #define CLP_ERR_MSG \ 00813 ( recogniseAllOptions() ? "Error" : "Warning" ) \ 00814 << ", the " << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) \ 00815 << " option \'" << argv[argv_i] << "\' was not recognized (use --help)!" 00816 if(errout) 00817 *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl; 00818 if( recogniseAllOptions() && throwExceptions() ) 00819 TEUCHOS_TEST_FOR_EXCEPTION( true, UnrecognizedOption, CLP_ERR_MSG ); 00820 #undef CLP_ERR_MSG 00821 } 00822 00823 00824 // Hidden stuff 00825 00826 00827 void CommandLineProcessor::setTimeMonitorSurrogate( 00828 const RCP<CommandLineProcessor::TimeMonitorSurrogate> &timeMonitorSurrogate) 00829 { 00830 getRawTimeMonitorSurrogate() = timeMonitorSurrogate; 00831 } 00832 00833 00834 RCP<CommandLineProcessor::TimeMonitorSurrogate> 00835 CommandLineProcessor::getTimeMonitorSurrogate() 00836 { 00837 return getRawTimeMonitorSurrogate(); 00838 } 00839 00840 00841 RCP<CommandLineProcessor::TimeMonitorSurrogate>& 00842 CommandLineProcessor::getRawTimeMonitorSurrogate() 00843 { 00844 static RCP<TimeMonitorSurrogate> timeMonitorSurrogate; 00845 return timeMonitorSurrogate; 00846 } 00847 00848 00849 } // end namespace Teuchos
1.7.6.1