Teuchos - Trilinos Tools Package  Version of the Day
Teuchos_CommandLineProcessor.cpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 // //////////////////////////////////////////////////
43 // Teuchos_CommandLineProcessor.cpp
44 
45 
48 #include "Teuchos_VerboseObject.hpp"
49 //#include "Teuchos_TimeMonitor.hpp"
50 #include "Teuchos_Assert.hpp"
51 #include "Teuchos_as.hpp"
52 
53 
54 namespace {
55 
56 
57 inline int my_max( int a, int b ) { return a > b ? a : b; }
58 
59 
60 std::string remove_quotes( const std::string& str )
61 {
62  if(str[0] != '\"')
63  return str;
64  return str.substr(1,str.size()-2);
65 }
66 
67 
68 std::string add_quotes( const std::string& str )
69 {
70  if(str[0] == '\"')
71  return str;
72  return "\"" + str + "\"";
73 }
74 
75 
76 } // end namespace
77 
78 
79 namespace Teuchos {
80 
81 
82 const bool CommandLineProcessor::output_all_front_matter_default_(false);
83 const bool CommandLineProcessor::output_show_line_prefix_default_(false);
84 const bool CommandLineProcessor::output_show_tab_count_default_(false);
85 const bool CommandLineProcessor::output_show_proc_rank_default_(false);
86 const int CommandLineProcessor::output_to_root_rank_only_default_(0);
87 const bool CommandLineProcessor::print_rcpnode_statistics_on_exit_default_(false);
88 const bool CommandLineProcessor::show_timer_summary_on_exit_default_(false);
89 
90 
92  bool throwExceptions_in
93  ,bool recogniseAllOptions_in
94  ,bool addOutputSetupOptions_in
95  )
96  :throwExceptions_(throwExceptions_in)
97  ,recogniseAllOptions_(recogniseAllOptions_in)
98  ,addOutputSetupOptions_(addOutputSetupOptions_in)
99  ,output_all_front_matter_(output_all_front_matter_default_)
100  ,output_show_line_prefix_(output_show_line_prefix_default_)
101  ,output_show_tab_count_(output_show_tab_count_default_)
102  ,output_show_proc_rank_(output_show_proc_rank_default_)
103  ,output_to_root_rank_only_(output_to_root_rank_only_default_)
104  ,print_rcpnode_statistics_on_exit_(print_rcpnode_statistics_on_exit_default_)
105  ,show_timer_summary_on_exit_(show_timer_summary_on_exit_default_)
106  ,printed_timer_summary_(false)
107  ,added_extra_output_setup_options_(false)
108  ,in_add_extra_output_setup_options_(false)
109 {}
110 
111 
113 {
115 }
116 
117 
118 // Set up options
119 
120 
121 void CommandLineProcessor::setDocString( const char doc_string[] )
122 {
123  doc_string_ = doc_string;
124 }
125 
126 
128  const char option_true[]
129  ,const char option_false[]
130  ,bool *option_val
131  ,const char documentation[]
132  )
133 {
134  add_extra_output_setup_options();
135  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
136  options_list_[std::string(option_true)]
137  = opt_val_val_t(OPT_BOOL_TRUE,any(option_val),false);
138  options_list_[std::string(option_false)]
139  = opt_val_val_t(OPT_BOOL_FALSE,any(option_val),false);
140  options_documentation_list_.push_back(
141  opt_doc_t(OPT_BOOL_TRUE, option_true, option_false,
142  std::string(documentation?documentation:""), any(option_val))
143  );
144 }
145 
146 
148  const char option_name[]
149  ,int *option_val
150  ,const char documentation[]
151  ,const bool required
152  )
153 {
154  add_extra_output_setup_options();
155  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
156  options_list_[std::string(option_name)]
157  = opt_val_val_t(OPT_INT,any(option_val),required);
158  options_documentation_list_.push_back(
159  opt_doc_t(OPT_INT, option_name, "", std::string(documentation?documentation:""),
160  any(option_val))
161  );
162 }
163 
164 
166  const char option_name[]
167  ,long int *option_val
168  ,const char documentation[]
169  ,const bool required
170  )
171 {
172  add_extra_output_setup_options();
173  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
174  options_list_[std::string(option_name)]
175  = opt_val_val_t(OPT_LONG_INT,any(option_val),required);
176  options_documentation_list_.push_back(
177  opt_doc_t(OPT_LONG_INT, option_name, "", std::string(documentation?documentation:""),
178  any(option_val))
179  );
180 }
181 
182 
184  const char option_name[]
185  ,size_t *option_val
186  ,const char documentation[]
187  ,const bool required
188  )
189 {
190  add_extra_output_setup_options();
191  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
192  options_list_[std::string(option_name)]
193  = opt_val_val_t(OPT_SIZE_T,any(option_val),required);
194  options_documentation_list_.push_back(
195  opt_doc_t(OPT_SIZE_T, option_name, "", std::string(documentation?documentation:""),
196  any(option_val))
197  );
198 }
199 
200 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
202  const char option_name[]
203  ,long long int *option_val
204  ,const char documentation[]
205  ,const bool required
206  )
207 {
208  add_extra_output_setup_options();
209  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
210  options_list_[std::string(option_name)]
211  = opt_val_val_t(OPT_LONG_LONG_INT,any(option_val),required);
212  options_documentation_list_.push_back(
213  opt_doc_t(OPT_LONG_LONG_INT, option_name, "", std::string(documentation?documentation:""),
214  any(option_val))
215  );
216 }
217 #endif
218 
219 
221  const char option_name[]
222  ,double *option_val
223  ,const char documentation[]
224  ,const bool required
225  )
226 {
227  add_extra_output_setup_options();
228  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
229  options_list_[std::string(option_name)]
230  = opt_val_val_t(OPT_DOUBLE,any(option_val),required);
231  options_documentation_list_.push_back(
232  opt_doc_t(OPT_DOUBLE, option_name, "", std::string(documentation?documentation:""),
233  any(option_val))
234  );
235 }
236 
237 
239  const char option_name[]
240  ,std::string *option_val
241  ,const char documentation[]
242  ,const bool required
243  )
244 {
245  add_extra_output_setup_options();
246  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
247  options_list_[std::string(option_name)]
248  = opt_val_val_t(OPT_STRING,any(option_val),required);
249  options_documentation_list_.push_back(
250  opt_doc_t(OPT_STRING, option_name, "", std::string(documentation?documentation:""),
251  any(option_val))
252  );
253 }
254 
255 
256 // Parse command line
257 
258 
261  int argc
262  ,char* argv[]
263  ,std::ostream *errout
264  ) const
265 {
266  add_extra_output_setup_options();
267  std::string opt_name;
268  std::string opt_val_str;
269  const std::string echo_cl_opt = "echo-command-line";
270  const std::string help_opt = "help";
271  const std::string pause_opt = "pause-for-debugging";
272  int procRank = GlobalMPISession::getRank();
273  for( int i = 1; i < argc; ++i ) {
274  bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
275  if( !gov_return ) {
276  if(procRank == 0)
277  print_bad_opt(i,argv,errout);
278  if( recogniseAllOptions() )
280  else {
281  continue;
282  }
283  }
284  if( opt_name == echo_cl_opt ) {
285  if(errout && procRank == 0) {
286  *errout << "\nEchoing the command-line:\n\n";
287  for( int j = 0; j < argc; ++j )
288  *errout << argv[j] << " ";
289  *errout << "\n\n";
290  }
291  continue;
292  }
293  if( opt_name == help_opt ) {
294  if(errout) printHelpMessage( argv[0], *errout );
295  return PARSE_HELP_PRINTED;
296  }
297  if( opt_name == pause_opt ) {
298  if(procRank == 0) {
299  std::cerr << "\nType 0 and press enter to continue : ";
300  int dummy_int = 0;
301  std::cin >> dummy_int;
302  }
304  continue;
305  }
306  // Lookup the option (we had better find it!)
307  options_list_t::iterator itr = options_list_.find(opt_name);
308  if( itr == options_list_.end() ) {
309  if(procRank == 0)
310  print_bad_opt(i,argv,errout);
311  if( recogniseAllOptions() )
313  else
314  continue;
315  }
316  // Changed access to second value of std::map to not use overloaded arrow operator,
317  // otherwise this code will not compile on Janus (HKT, 12/01/2003)
318  opt_val_val_t &opt_val_val = (*itr).second;
319  opt_val_val.was_read = true;
320  switch( opt_val_val.opt_type ) {
321  case OPT_BOOL_TRUE:
322  *(any_cast<bool*>(opt_val_val.opt_val)) = true;
323  break;
324  case OPT_BOOL_FALSE:
325  *(any_cast<bool*>(opt_val_val.opt_val)) = false;
326  break;
327  case OPT_INT:
328  *(any_cast<int*>(opt_val_val.opt_val)) = asSafe<int> (opt_val_str);
329  break;
330  case OPT_LONG_INT:
331  *(any_cast<long int*>(opt_val_val.opt_val)) = asSafe<long int> (opt_val_str);
332  break;
333  case OPT_SIZE_T:
334  *(any_cast<size_t *>(opt_val_val.opt_val)) = asSafe<size_t> (opt_val_str);
335  break;
336 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
337  case OPT_LONG_LONG_INT:
338  *(any_cast<long long int*>(opt_val_val.opt_val)) = asSafe<long long int> (opt_val_str);
339  break;
340 #endif
341  case OPT_DOUBLE:
342  *(any_cast<double*>(opt_val_val.opt_val)) = asSafe<double> (opt_val_str);
343  break;
344  case OPT_STRING:
345  *(any_cast<std::string*>(opt_val_val.opt_val)) = remove_quotes(opt_val_str);
346  break;
347  case OPT_ENUM_INT:
348  if( !set_enum_value( i, argv, opt_name, any_cast<int>(opt_val_val.opt_val),
349  remove_quotes(opt_val_str), errout ) )
350  {
352  }
353  break;
354  default:
355  TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
356  }
357  }
358  // Look for options that were required but were not set
359  for(
360  options_list_t::const_iterator itr = options_list_.begin();
361  itr != options_list_.end();
362  ++itr
363  )
364  {
365  const opt_val_val_t &opt_val_val = (*itr).second;
366  if( opt_val_val.required && !opt_val_val.was_read ) {
367  const std::string &opt_val_name = (*itr).first;
368 #define CLP_ERR_MSG \
369  "Error, the option --"<<opt_val_name<<" was required but was not set!"
370  if(errout)
371  *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
372  if( throwExceptions() ) {
373  TEUCHOS_TEST_FOR_EXCEPTION( true, ParseError, CLP_ERR_MSG );
374  }
375  return PARSE_ERROR;
376 #undef CLP_ERR_MSG
377  }
378  }
379  // Set the options of a default stream exists and if we are asked to
382  if (defaultOut.get() && addOutputSetupOptions_) {
383  if (output_all_front_matter_ != output_all_front_matter_default_)
384  defaultOut->setShowAllFrontMatter(output_all_front_matter_);
385  if (output_show_line_prefix_ != output_show_line_prefix_default_)
386  defaultOut->setShowLinePrefix(output_show_line_prefix_);
387  if (output_show_tab_count_ != output_show_tab_count_default_)
388  defaultOut->setShowTabCount(output_show_tab_count_);
389  if (output_show_proc_rank_ != output_show_proc_rank_default_)
390  defaultOut->setShowProcRank(output_show_proc_rank_);
391  if (output_to_root_rank_only_ != output_to_root_rank_only_default_)
392  defaultOut->setOutputToRootOnly(output_to_root_rank_only_);
393  RCPNodeTracer::setPrintRCPNodeStatisticsOnExit(print_rcpnode_statistics_on_exit_);
394  }
395  return PARSE_SUCCESSFUL;
396 }
397 
398 
399 void CommandLineProcessor::printHelpMessage( const char program_name[],
400  std::ostream &out ) const
401 {
402  add_extra_output_setup_options();
403  int procRank = GlobalMPISession::getRank();
404  if (procRank == 0) {
405  using std::setw;
406  using std::endl;
407 
408  const int opt_type_w = 14;
409  const char spc_chars[] = " ";
410 
411  // Get the maximum length of an option name
412  int opt_name_w = 19; // For the 'pause-for-debugging' option
413  options_documentation_list_t::const_iterator itr;
414  for (
415  itr = options_documentation_list_.begin();
416  itr != options_documentation_list_.end();
417  ++itr
418  )
419  {
420  opt_name_w = my_max(opt_name_w,itr->opt_name.length());
421  if( itr->opt_type )
422  opt_name_w = my_max(opt_name_w,itr->opt_name_false.length());
423  }
424  opt_name_w += 2;
425 
426  // Some built-in options
427  out
428  << "Usage: " << program_name << " [options]\n"
429  << spc_chars << "options:\n"
430  << spc_chars
431  << "--"
432 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
433  << std::left << setw(opt_name_w) << "help"
434  << std::left << setw(opt_type_w) << " "
435 #else
436  << std::setiosflags(std::ios::left) << setw(opt_name_w) << "help"
437  << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
438 #endif
439  << "Prints this help message"
440  << std::endl
441  << spc_chars
442  << "--"
443 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
444  << std::left << setw(opt_name_w) << "pause-for-debugging"
445  << std::left << setw(opt_type_w) << " "
446 #else
447  << std::setiosflags(std::ios::left) << setw(opt_name_w) << "pause-for-debugging"
448  << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
449 #endif
450  << "Pauses for user input to allow attaching a debugger"
451  << std::endl
452  << spc_chars
453  << "--"
454 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
455  << std::left << setw(opt_name_w) << "echo-command-line"
456  << std::left << setw(opt_type_w) << " "
457 #else
458  << std::setiosflags(std::ios::left) << setw(opt_name_w) << "echo-command-line"
459  << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
460 #endif
461  << "Echo the command-line but continue as normal"
462  << std::endl;
463  for(
464  itr = options_documentation_list_.begin();
465  itr != options_documentation_list_.end();
466  ++itr )
467  {
468  // print top line with option name, type and short documentation string
469  out
470  << spc_chars
471  << "--"
472 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
473  << std::left << setw(opt_name_w) << itr->opt_name
474  << std::left << setw(opt_type_w) << opt_type_str(itr->opt_type)
475 #else
476  << std::setiosflags(std::ios::left) << setw(opt_name_w) << itr->opt_name
477  << std::setiosflags(std::ios::left) << setw(opt_type_w) << opt_type_str(itr->opt_type)
478 #endif
479  << ( itr->documentation.length() ? itr->documentation.c_str() : "No documentation" )
480  << std::endl;
481  // If an enumeration option then the next line is the value options
482  if( itr->opt_type == OPT_ENUM_INT ) {
483  out
484  << spc_chars
485  << " "
486  << setw(opt_name_w) << ""
487  << setw(opt_type_w) << "";
488  print_enum_opt_names( any_cast<int>(itr->default_val), out );
489  out
490  << std::endl;
491  }
492  // Now print the line that contains the default values
493  if( itr->opt_type == OPT_BOOL_TRUE ) {
494  out
495  << spc_chars
496  << "--"
497  << setw(opt_name_w) << itr->opt_name_false;
498  }
499  else {
500  out
501  << spc_chars
502  << " "
503  << setw(opt_name_w) << " ";
504  }
505  out
506  << setw(opt_type_w) << " "
507  << "(default: ";
508  switch( itr->opt_type ) {
509  case OPT_BOOL_TRUE:
510  out << "--" << ( (*(any_cast<bool*>(itr->default_val))) ?
511  itr->opt_name : itr->opt_name_false );
512  break;
513  case OPT_INT:
514  case OPT_LONG_INT:
515  case OPT_SIZE_T:
516 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
517  case OPT_LONG_LONG_INT:
518 #endif
519  case OPT_DOUBLE:
520  case OPT_STRING:
521  case OPT_ENUM_INT:
522  out << "--" << itr->opt_name;
523  break;
524  default:
525  TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
526  }
527  switch( itr->opt_type ) {
528  case OPT_BOOL_TRUE:
529  break;
530  case OPT_INT:
531  out << "=" << (*(any_cast<int*>(itr->default_val)));
532  break;
533  case OPT_LONG_INT:
534  out << "=" << (*(any_cast<long int*>(itr->default_val)));
535  break;
536  case OPT_SIZE_T:
537  out << "=" << (*(any_cast<size_t*>(itr->default_val)));
538  break;
539 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
540  case OPT_LONG_LONG_INT:
541  out << "=" << (*(any_cast<long long int*>(itr->default_val)));
542  break;
543 #endif
544  case OPT_DOUBLE:
545  out << "=" << (*(any_cast<double*>(itr->default_val)));
546  break;
547  case OPT_STRING:
548  out << "=" << add_quotes(*(any_cast<std::string*>(itr->default_val)));
549  break;
550  case OPT_ENUM_INT:
551  out << "=" << add_quotes(
552  enum_opt_default_val_name(itr->opt_name,any_cast<int>(itr->default_val),&out));
553  break;
554  default:
555  TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
556  }
557  out << ")\n";
558  }
559  if(doc_string_.length()) {
560  out << "\nDETAILED DOCUMENTATION:\n\n" << doc_string_ << std::endl << std::endl;
561  }
562  if(throwExceptions_)
563  TEUCHOS_TEST_FOR_EXCEPTION( true, HelpPrinted, "Help message was printed" );
564  }
565 }
566 
567 
569  const Ptr<std::ostream> &out_inout
570  )
571 {
572  if (!printed_timer_summary_ && show_timer_summary_on_exit_) {
573  RCP<std::ostream> out;
574  if (nonnull(out_inout)) {
575  out = rcpFromPtr(out_inout);
576  }
577  else {
579  }
580  getTimeMonitorSurrogate()->summarize(*out << "\n");
581  printed_timer_summary_ = true;
582  }
583 }
584 
585 
586 // private
587 
588 
589 void CommandLineProcessor::add_extra_output_setup_options() const
590 {
591  if(
592  // Are we in this function already and calling it recursively?
593  in_add_extra_output_setup_options_
594  ||
595  // Have we already setup these options?
596  added_extra_output_setup_options_
597  ||
598  // Are we not supposed to setup these options?
599  !addOutputSetupOptions_
600  )
601  {
602  return; // If any of the above is true, we need to return right away!
603  }
604  // Set the commandline options for this ...
606  *clp = const_cast<CommandLineProcessor*>(this);
607  clp->in_add_extra_output_setup_options_ = true;
608  clp->setOption(
609  "output-all-front-matter","output-no-front-matter",&clp->output_all_front_matter_
610  ,"Set if all front matter is printed to the default FancyOStream or not"
611  );
612  clp->setOption(
613  "output-show-line-prefix","output-no-show-line-prefix",&clp->output_show_line_prefix_
614  ,"Set if the line prefix matter is printed to the default FancyOStream or not"
615  );
616  clp->setOption(
617  "output-show-tab-count","output-no-show-tab-count",&clp->output_show_tab_count_
618  ,"Set if the tab count is printed to the default FancyOStream or not"
619  );
620  clp->setOption(
621  "output-show-proc-rank","output-no-show-proc-rank",&clp->output_show_proc_rank_
622  ,"Set if the processor rank is printed to the default FancyOStream or not"
623  );
624  clp->setOption(
625  "output-to-root-rank-only",&clp->output_to_root_rank_only_
626  ,"Set which processor (the root) gets the output. If < 0, then all processors get output."
627  );
628  clp->setOption(
629  "print-rcpnode-statistics-on-exit", "no-print-rcpnode-statistics-on-exit",
630  &clp->print_rcpnode_statistics_on_exit_,
631  "Set if the RCPNode usage statistics will be printed on exit or not. Warning,"
632  " this prints to std::cerr or every process so do not turn this on for very large"
633  " parallel runs."
634  );
635  if (nonnull(getTimeMonitorSurrogate())) {
636  clp->setOption(
637  "show-timer-summary", "no-show-timer-sumary", &clp->show_timer_summary_on_exit_,
638  "If true, then Teuchos::TimeMonitor::summarize() is called in"
639  " CommandLineProcessor's destructor (usually at the end of main)."
640  );
641  }
642 
643  clp->added_extra_output_setup_options_ = true;
644  clp->in_add_extra_output_setup_options_ = false;
645 }
646 
647 
648 void CommandLineProcessor::setEnumOption(
649  const char enum_option_name[]
650  ,int *enum_option_val
651  ,const int num_enum_opt_values
652  ,const int enum_opt_values[]
653  ,const char* enum_opt_names[]
654  ,const char documentation[]
655  ,const bool required
656  )
657 {
658  add_extra_output_setup_options();
659 
660  TEUCHOS_TEST_FOR_EXCEPT(enum_option_val==NULL);
661  TEUCHOS_TEST_FOR_EXCEPT(num_enum_opt_values<=0);
662  TEUCHOS_TEST_FOR_EXCEPT(enum_opt_values==NULL);
663  TEUCHOS_TEST_FOR_EXCEPT(enum_opt_names==NULL);
664 
665  enum_opt_data_list_.push_back(
666  enum_opt_data_t(enum_option_val,num_enum_opt_values,enum_opt_values,enum_opt_names)
667  );
668  const int opt_id = enum_opt_data_list_.size()-1;
669  options_list_[std::string(enum_option_name)]
670  = opt_val_val_t(OPT_ENUM_INT,any(opt_id),required);
671  options_documentation_list_.push_back(
672  opt_doc_t(OPT_ENUM_INT,enum_option_name, "",
673  std::string(documentation?documentation:""), any(opt_id))
674  );
675 }
676 
677 
678 bool CommandLineProcessor::set_enum_value(
679  int argv_i
680  ,char* argv[]
681  ,const std::string &enum_opt_name
682  ,const int enum_id
683  ,const std::string &enum_str_val
684  ,std::ostream *errout
685  ) const
686 {
687  const enum_opt_data_t
688  &enum_opt_data = enum_opt_data_list_.at(enum_id);
689  std::vector<std::string>::const_iterator
690  itr_begin = enum_opt_data.enum_opt_names.begin(),
691  itr_end = enum_opt_data.enum_opt_names.end(),
692  itr = std::find( itr_begin, itr_end, enum_str_val );
693  if( itr == itr_end ) {
694  const int j = argv_i;
695 #define CLP_ERR_MSG \
696  "Error, the value \"" << enum_str_val << "\" for the " \
697  << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) << " option --" \
698  << enum_opt_name << " was not recognized (use --help)!"
699  if(errout)
700  *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
701  if( throwExceptions() ) {
702  TEUCHOS_TEST_FOR_EXCEPTION( true, UnrecognizedOption, CLP_ERR_MSG );
703  }
704  else {
705  return false;
706  }
707 #undef CLP_ERR_MSG
708  }
709  const int enum_opt_val_index = itr - itr_begin;
710  *enum_opt_data.enum_option_val = enum_opt_data.enum_opt_values.at(enum_opt_val_index);
711  return true;
712 }
713 
714 
715 void CommandLineProcessor::print_enum_opt_names(
716  const int enum_id
717  ,std::ostream &out
718  ) const
719 {
720  const enum_opt_data_t
721  &enum_opt_data = enum_opt_data_list_.at(enum_id);
722  typedef std::vector<std::string>::const_iterator itr_t;
723  out << "Valid options:";
724  for(
725  itr_t itr = enum_opt_data.enum_opt_names.begin();
726  itr != enum_opt_data.enum_opt_names.end();
727  ++itr
728  )
729  {
730  if( itr != enum_opt_data.enum_opt_names.begin() ) out << ",";
731  out << " " << add_quotes(*itr);
732  }
733 }
734 
735 
736 std::string
737 CommandLineProcessor::enum_opt_default_val_name(
738  const std::string &enum_name
739  ,const int enum_id
740  ,std::ostream *errout
741  ) const
742 {
743  const enum_opt_data_t
744  &enum_opt_data = enum_opt_data_list_.at(enum_id);
745  return enum_opt_data.enum_opt_names.at(
746  find_enum_opt_index(
747  enum_name,*enum_opt_data.enum_option_val,enum_opt_data,errout
748  )
749  );
750 }
751 
752 
753 int CommandLineProcessor::find_enum_opt_index(
754  const std::string &enum_opt_name
755  ,const int opt_value
756  ,const enum_opt_data_t &enum_data
757  ,std::ostream *errout
758  ) const
759 {
760  std::vector<int>::const_iterator
761  itr_begin = enum_data.enum_opt_values.begin(),
762  itr_end = enum_data.enum_opt_values.end(),
763  itr = std::find( itr_begin, itr_end, opt_value );
764  if( itr == itr_end ) {
765 #define CLP_ERR_MSG \
766  ( recogniseAllOptions() ? "Error" : "Warning" ) \
767  << ", option --" << enum_opt_name << " was given an invalid " \
768  "initial option value of " << opt_value << "!"
769  if(errout)
770  *errout << CLP_ERR_MSG << std::endl;
771  if( throwExceptions() )
772  TEUCHOS_TEST_FOR_EXCEPTION( true, std::invalid_argument, CLP_ERR_MSG );
773 #undef CLP_ERR_MSG
774  }
775  return itr - itr_begin;
776 }
777 
778 
779 bool CommandLineProcessor::get_opt_val(
780  const char str[]
781  ,std::string *opt_name
782  ,std::string *opt_val_str
783  ) const
784 {
785  const int len = std::strlen(str);
786  if( len < 3 )
787  return false; // Can't be an option with '--' followed by at least one char
788  if( str[0] != '-' || str[1] != '-' )
789  return false; // Not a recognised option
790  // Find the '='
791  int equ_i;
792  for( equ_i = 2; equ_i < len && str[equ_i] != '='; ++equ_i );
793  // Set opt_name
794  opt_name->assign( str + 2, equ_i-2 );
795  // Set opt_val_str
796  if( equ_i == len ) {
797  *opt_val_str = "";
798  }
799  else {
800  opt_val_str->assign( str + equ_i + 1, len - equ_i - 1 );
801  }
802  return true;
803 }
804 
805 void CommandLineProcessor::print_bad_opt(
806  int argv_i
807  ,char* argv[]
808  ,std::ostream *errout
809  ) const
810 {
811  const int j = argv_i;
812 #define CLP_ERR_MSG \
813  ( recogniseAllOptions() ? "Error" : "Warning" ) \
814  << ", the " << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) \
815  << " option \'" << argv[argv_i] << "\' was not recognized (use --help)!"
816  if(errout)
817  *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
819  TEUCHOS_TEST_FOR_EXCEPTION( true, UnrecognizedOption, CLP_ERR_MSG );
820 #undef CLP_ERR_MSG
821 }
822 
823 
824 // Hidden stuff
825 
826 
827 void CommandLineProcessor::setTimeMonitorSurrogate(
828  const RCP<CommandLineProcessor::TimeMonitorSurrogate> &timeMonitorSurrogate)
829 {
830  getRawTimeMonitorSurrogate() = timeMonitorSurrogate;
831 }
832 
833 
834 RCP<CommandLineProcessor::TimeMonitorSurrogate>
835 CommandLineProcessor::getTimeMonitorSurrogate()
836 {
837  return getRawTimeMonitorSurrogate();
838 }
839 
840 
841 RCP<CommandLineProcessor::TimeMonitorSurrogate>&
842 CommandLineProcessor::getRawTimeMonitorSurrogate()
843 {
844  static RCP<TimeMonitorSurrogate> timeMonitorSurrogate;
845  return timeMonitorSurrogate;
846 }
847 
848 
849 } // end namespace Teuchos
static int getRank()
The rank of the calling process in MPI_COMM_WORLD.
Thrown if –help was specified and throwExceptions==true.
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
bool recogniseAllOptions() const
Returns true if all options must be recognized by the parser.
static void setPrintRCPNodeStatisticsOnExit(bool printRCPNodeStatisticsOnExit)
Set if RCPNode usage statistics will be printed when the program ends or not.
CommandLineProcessor(bool throwExceptions=true, bool recogniseAllOptions=true, bool addOutputSetupOptions=false)
Default Constructor.
Modified boost::any class, which is a container for a templated value.
Definition: Teuchos_any.hpp:86
T * get() const
Get the raw C++ pointer to the underlying object.
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
Parse a command line.
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
EParseCommandLineReturn
Return value for CommandLineProcessor::parse(). Note: These enums are all given non-negative values s...
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
A MPI utilities class, providing methods for initializing, finalizing, and querying the global MPI se...
Basic command line parser for input from (argc,argv[])
void setDocString(const char doc_string[])
Set a documentation sting for the entire program printed when –help is specified.
bool throwExceptions() const
Returns true if an std::exception is thrown, there is a parse error, or help is printed.
void printHelpMessage(const char program_name[], std::ostream &out) const
Print the help message.
static void barrier()
Call MPI_Barrier() on MPI_COMM_WORLD.
Smart reference counting pointer class for automatic garbage collection.
void printFinalTimerSummary(const Ptr< std::ostream > &out=null)
Call to print timers so that they don&#39;t get printed in the destructor.
Definition of Teuchos::as, for conversions between types.
Thrown if a parse std::exception occurs and throwExceptions==true.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
This macro is designed to be a short version of TEUCHOS_TEST_FOR_EXCEPTION() that is easier to call...
Simple wrapper class for raw pointers to single objects where no persisting relationship exists...