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