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