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 
835 CommandLineProcessor::getTimeMonitorSurrogate()
836 {
837  return getRawTimeMonitorSurrogate();
838 }
839 
840 
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.
void printHelpMessage(const char program_name[], std::ostream &out) const
Print the help message.
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
bool throwExceptions() const
Returns true if an std::exception is thrown, there is a parse error, or help is printed.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
static void setPrintRCPNodeStatisticsOnExit(bool printRCPNodeStatisticsOnExit)
Set if RCPNode usage statistics will be printed when the program ends or not.
T * get() const
Get the raw C++ pointer to the underlying object.
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
Thrown if an unrecognized option was found and throwExceptions==true.
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
Parse a command line.
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.
static void barrier()
Call MPI_Barrier() on MPI_COMM_WORLD.
bool recogniseAllOptions() const
Returns true if all options must be recognized by the parser.
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.
Class that helps parse command line input arguments from (argc,argv[]) and set options.
#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...