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