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