Teuchos - Trilinos Tools Package Version of the Day
Teuchos_CommandLineProcessor.cpp
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines