Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_CommandLineProcessor.cpp
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 // //////////////////////////////////////////////////
11 // Teuchos_CommandLineProcessor.cpp
12 
13 
16 #include "Teuchos_VerboseObject.hpp"
17 //#include "Teuchos_TimeMonitor.hpp"
18 #include "Teuchos_Assert.hpp"
19 #include "Teuchos_as.hpp"
20 #ifndef _WIN32
21 #include "Teuchos_Array.hpp"
22 #include "unistd.h"
23 #endif
24 
25 namespace {
26 
27 
28 inline int my_max( int a, int b ) { return a > b ? a : b; }
29 
30 
31 std::string remove_quotes( const std::string& str )
32 {
33  if (str[0] == '\"' && str[str.size()-1] == '\"')
34  return str.substr(1,str.size()-2);
35  else if (str[0] == '\"')
36  return str.substr(1,str.size()-1);
37  else if (str[str.size()-1] == '\"')
38  return str.substr(0,str.size()-1);
39  return str;
40 }
41 
42 
43 std::string add_quotes( const std::string& str )
44 {
45  if(str[0] == '\"')
46  return str;
47  return "\"" + str + "\"";
48 }
49 
50 
51 } // end namespace
52 
53 
54 namespace Teuchos {
55 
56 
57 const bool CommandLineProcessor::output_all_front_matter_default_(false);
58 const bool CommandLineProcessor::output_show_line_prefix_default_(false);
59 const bool CommandLineProcessor::output_show_tab_count_default_(false);
60 const bool CommandLineProcessor::output_show_proc_rank_default_(false);
61 const int CommandLineProcessor::output_to_root_rank_only_default_(0);
62 const bool CommandLineProcessor::print_rcpnode_statistics_on_exit_default_(false);
63 const bool CommandLineProcessor::show_timer_summary_on_exit_default_(false);
64 
65 
67  bool throwExceptions_in
68  ,bool recogniseAllOptions_in
69  ,bool addOutputSetupOptions_in
70  )
71  :throwExceptions_(throwExceptions_in)
72  ,recogniseAllOptions_(recogniseAllOptions_in)
73  ,addOutputSetupOptions_(addOutputSetupOptions_in)
74  ,output_all_front_matter_(output_all_front_matter_default_)
75  ,output_show_line_prefix_(output_show_line_prefix_default_)
76  ,output_show_tab_count_(output_show_tab_count_default_)
77  ,output_show_proc_rank_(output_show_proc_rank_default_)
78  ,output_to_root_rank_only_(output_to_root_rank_only_default_)
79  ,print_rcpnode_statistics_on_exit_(print_rcpnode_statistics_on_exit_default_)
80  ,show_timer_summary_on_exit_(show_timer_summary_on_exit_default_)
81  ,printed_timer_summary_(false)
82  ,added_extra_output_setup_options_(false)
83  ,in_add_extra_output_setup_options_(false)
84 {}
85 
86 
88 {
90 }
91 
92 
93 // Set up options
94 
95 
96 void CommandLineProcessor::setDocString( const char doc_string[] )
97 {
98  doc_string_ = doc_string;
99 }
100 
101 
103  const char option_true[]
104  ,const char option_false[]
105  ,bool *option_val
106  ,const char documentation[]
107  )
108 {
109  add_extra_output_setup_options();
110  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
111  options_list_[std::string(option_true)]
112  = opt_val_val_t(OPT_BOOL_TRUE,any(option_val),false);
113  options_list_[std::string(option_false)]
114  = opt_val_val_t(OPT_BOOL_FALSE,any(option_val),false);
115  options_documentation_list_.push_back(
116  opt_doc_t(OPT_BOOL_TRUE, option_true, option_false,
117  std::string(documentation?documentation:""), any(option_val))
118  );
119 }
120 
121 
123  const char option_name[]
124  ,int *option_val
125  ,const char documentation[]
126  ,const bool required
127  )
128 {
129  add_extra_output_setup_options();
130  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
131  options_list_[std::string(option_name)]
132  = opt_val_val_t(OPT_INT,any(option_val),required);
133  options_documentation_list_.push_back(
134  opt_doc_t(OPT_INT, option_name, "", std::string(documentation?documentation:""),
135  any(option_val))
136  );
137 }
138 
139 
141  const char option_name[]
142  ,long int *option_val
143  ,const char documentation[]
144  ,const bool required
145  )
146 {
147  add_extra_output_setup_options();
148  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
149  options_list_[std::string(option_name)]
150  = opt_val_val_t(OPT_LONG_INT,any(option_val),required);
151  options_documentation_list_.push_back(
152  opt_doc_t(OPT_LONG_INT, option_name, "", std::string(documentation?documentation:""),
153  any(option_val))
154  );
155 }
156 
157 
159  const char option_name[]
160  ,size_t *option_val
161  ,const char documentation[]
162  ,const bool required
163  )
164 {
165  add_extra_output_setup_options();
166  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
167  options_list_[std::string(option_name)]
168  = opt_val_val_t(OPT_SIZE_T,any(option_val),required);
169  options_documentation_list_.push_back(
170  opt_doc_t(OPT_SIZE_T, option_name, "", std::string(documentation?documentation:""),
171  any(option_val))
172  );
173 }
174 
176  const char option_name[]
177  ,long long int *option_val
178  ,const char documentation[]
179  ,const bool required
180  )
181 {
182  add_extra_output_setup_options();
183  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
184  options_list_[std::string(option_name)]
185  = opt_val_val_t(OPT_LONG_LONG_INT,any(option_val),required);
186  options_documentation_list_.push_back(
187  opt_doc_t(OPT_LONG_LONG_INT, option_name, "", std::string(documentation?documentation:""),
188  any(option_val))
189  );
190 }
191 
193  const char option_name[]
194  ,double *option_val
195  ,const char documentation[]
196  ,const bool required
197  )
198 {
199  add_extra_output_setup_options();
200  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
201  options_list_[std::string(option_name)]
202  = opt_val_val_t(OPT_DOUBLE,any(option_val),required);
203  options_documentation_list_.push_back(
204  opt_doc_t(OPT_DOUBLE, option_name, "", std::string(documentation?documentation:""),
205  any(option_val))
206  );
207 }
208 
210  const char option_name[]
211  ,float *option_val
212  ,const char documentation[]
213  ,const bool required
214  )
215 {
216  add_extra_output_setup_options();
217  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
218  options_list_[std::string(option_name)]
219  = opt_val_val_t(OPT_FLOAT,any(option_val),required);
220  options_documentation_list_.push_back(
221  opt_doc_t(OPT_FLOAT, option_name, "", std::string(documentation?documentation:""),
222  any(option_val))
223  );
224 }
225 
227  const char option_name[]
228  ,std::string *option_val
229  ,const char documentation[]
230  ,const bool required
231  )
232 {
233  add_extra_output_setup_options();
234  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
235  options_list_[std::string(option_name)]
236  = opt_val_val_t(OPT_STRING,any(option_val),required);
237  options_documentation_list_.push_back(
238  opt_doc_t(OPT_STRING, option_name, "", std::string(documentation?documentation:""),
239  any(option_val))
240  );
241 }
242 
243 
244 // Parse command line
245 
246 
249  int argc
250  ,char* argv[]
251  ,std::ostream *errout
252  ) const
253 {
254  add_extra_output_setup_options();
255  std::string opt_name;
256  std::string opt_val_str;
257  const std::string echo_cl_opt = "echo-command-line";
258  const std::string help_opt = "help";
259  const std::string pause_opt = "pause-for-debugging";
260  int procRank = GlobalMPISession::getRank();
261 
262  // check for help options before any others as we modify
263  // the values afterwards
264  for( int i = 1; i < argc; ++i ) {
265  bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
266  if( gov_return && opt_name == help_opt ) {
267  if(errout) printHelpMessage( argv[0], *errout );
268  return PARSE_HELP_PRINTED;
269  }
270  }
271  // check all other options
272  for( int i = 1; i < argc; ++i ) {
273  bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
274  if( !gov_return ) {
275  if(procRank == 0)
276  print_bad_opt(i,argv,errout);
277  if( recogniseAllOptions() )
279  else {
280  continue;
281  }
282  }
283  if( opt_name == echo_cl_opt ) {
284  if(errout && procRank == 0) {
285  *errout << "\nEchoing the command-line:\n\n";
286  for( int j = 0; j < argc; ++j )
287  *errout << argv[j] << " ";
288  *errout << "\n\n";
289  }
290  continue;
291  }
292  if( opt_name == pause_opt ) {
293 #ifndef _WIN32
294  Array<int> pids;
296  int rank_pid = getpid();
297  GlobalMPISession::allGather(rank_pid,pids());
298  if(procRank == 0)
299  for (int k=0; k<GlobalMPISession::getNProc(); k++)
300  std::cerr << "Rank " << k << " has PID " << pids[k] << std::endl;
301 #endif
302  if(procRank == 0) {
303  std::cerr << "\nType 0 and press enter to continue : ";
304  int dummy_int = 0;
305  std::cin >> dummy_int;
306  }
308  continue;
309  }
310  // Lookup the option (we had better find it!)
311  options_list_t::iterator itr = options_list_.find(opt_name);
312  if( itr == options_list_.end() ) {
313  if(procRank == 0)
314  print_bad_opt(i,argv,errout);
315  if( recogniseAllOptions() )
317  else
318  continue;
319  }
320  // Changed access to second value of std::map to not use overloaded arrow operator,
321  // otherwise this code will not compile on Janus (HKT, 12/01/2003)
322  opt_val_val_t &opt_val_val = (*itr).second;
323  opt_val_val.was_read = true;
324  switch( opt_val_val.opt_type ) {
325  case OPT_BOOL_TRUE:
326  *(any_cast<bool*>(opt_val_val.opt_val)) = true;
327  break;
328  case OPT_BOOL_FALSE:
329  *(any_cast<bool*>(opt_val_val.opt_val)) = false;
330  break;
331  case OPT_INT:
332  *(any_cast<int*>(opt_val_val.opt_val)) = asSafe<int> (opt_val_str);
333  break;
334  case OPT_LONG_INT:
335  *(any_cast<long int*>(opt_val_val.opt_val)) = asSafe<long int> (opt_val_str);
336  break;
337  case OPT_SIZE_T:
338  *(any_cast<size_t *>(opt_val_val.opt_val)) = asSafe<size_t> (opt_val_str);
339  break;
340  case OPT_LONG_LONG_INT:
341  *(any_cast<long long int*>(opt_val_val.opt_val)) = asSafe<long long int> (opt_val_str);
342  break;
343  case OPT_DOUBLE:
344  *(any_cast<double*>(opt_val_val.opt_val)) = asSafe<double> (opt_val_str);
345  break;
346  case OPT_FLOAT:
347  *(any_cast<float*>(opt_val_val.opt_val)) = asSafe<float> (opt_val_str);
348  break;
349  case OPT_STRING:
350  *(any_cast<std::string*>(opt_val_val.opt_val)) = remove_quotes(opt_val_str);
351  break;
352  case OPT_ENUM_INT:
353  if( !set_enum_value( i, argv, opt_name, any_cast<int>(opt_val_val.opt_val),
354  remove_quotes(opt_val_str), errout ) )
355  {
357  }
358  break;
359  default:
360  TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
361  }
362  }
363  // Look for options that were required but were not set
364  for(
365  options_list_t::const_iterator itr = options_list_.begin();
366  itr != options_list_.end();
367  ++itr
368  )
369  {
370  const opt_val_val_t &opt_val_val = (*itr).second;
371  if( opt_val_val.required && !opt_val_val.was_read ) {
372  const std::string &opt_val_name = (*itr).first;
373 #define CLP_ERR_MSG \
374  "Error, the option --"<<opt_val_name<<" was required but was not set!"
375  if(errout)
376  *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
377  if( throwExceptions() ) {
378  TEUCHOS_TEST_FOR_EXCEPTION( true, ParseError, CLP_ERR_MSG );
379  }
380  return PARSE_ERROR;
381 #undef CLP_ERR_MSG
382  }
383  }
384  // Set the options of a default stream exists and if we are asked to
387  if (defaultOut.get() && addOutputSetupOptions_) {
388  if (output_all_front_matter_ != output_all_front_matter_default_)
389  defaultOut->setShowAllFrontMatter(output_all_front_matter_);
390  if (output_show_line_prefix_ != output_show_line_prefix_default_)
391  defaultOut->setShowLinePrefix(output_show_line_prefix_);
392  if (output_show_tab_count_ != output_show_tab_count_default_)
393  defaultOut->setShowTabCount(output_show_tab_count_);
394  if (output_show_proc_rank_ != output_show_proc_rank_default_)
395  defaultOut->setShowProcRank(output_show_proc_rank_);
396  if (output_to_root_rank_only_ != output_to_root_rank_only_default_)
397  defaultOut->setOutputToRootOnly(output_to_root_rank_only_);
398  RCPNodeTracer::setPrintRCPNodeStatisticsOnExit(print_rcpnode_statistics_on_exit_);
399  }
400  return PARSE_SUCCESSFUL;
401 }
402 
403 
404 void CommandLineProcessor::printHelpMessage( const char program_name[],
405  std::ostream &out ) const
406 {
407  add_extra_output_setup_options();
408  int procRank = GlobalMPISession::getRank();
409  if (procRank == 0) {
410  using std::setw;
411  using std::endl;
412 
413  const int opt_type_w = 14;
414  const char spc_chars[] = " ";
415 
416  // Get the maximum length of an option name
417  int opt_name_w = 19; // For the 'pause-for-debugging' option
418  options_documentation_list_t::const_iterator itr;
419  for (
420  itr = options_documentation_list_.begin();
421  itr != options_documentation_list_.end();
422  ++itr
423  )
424  {
425  opt_name_w = my_max(opt_name_w,static_cast<int>(itr->opt_name.length()));
426  if( itr->opt_type )
427  opt_name_w = my_max(opt_name_w,static_cast<int>(itr->opt_name_false.length()));
428  }
429  opt_name_w += 2;
430 
431  // Some built-in options
432  out
433  << "Usage: " << program_name << " [options]\n"
434  << spc_chars << "options:\n"
435  << spc_chars
436  << "--"
437 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
438  << std::left << setw(opt_name_w) << "help"
439  << std::left << setw(opt_type_w) << " "
440 #else
441  << std::setiosflags(std::ios::left) << setw(opt_name_w) << "help"
442  << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
443 #endif
444  << "Prints this help message"
445  << std::endl
446  << spc_chars
447  << "--"
448 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
449  << std::left << setw(opt_name_w) << "pause-for-debugging"
450  << std::left << setw(opt_type_w) << " "
451 #else
452  << std::setiosflags(std::ios::left) << setw(opt_name_w) << "pause-for-debugging"
453  << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
454 #endif
455  << "Pauses for user input to allow attaching a debugger"
456  << std::endl
457  << spc_chars
458  << "--"
459 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
460  << std::left << setw(opt_name_w) << "echo-command-line"
461  << std::left << setw(opt_type_w) << " "
462 #else
463  << std::setiosflags(std::ios::left) << setw(opt_name_w) << "echo-command-line"
464  << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
465 #endif
466  << "Echo the command-line but continue as normal"
467  << std::endl;
468  for(
469  itr = options_documentation_list_.begin();
470  itr != options_documentation_list_.end();
471  ++itr )
472  {
473  // print top line with option name, type and short documentation string
474  out
475  << spc_chars
476  << "--"
477 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
478  << std::left << setw(opt_name_w) << itr->opt_name
479  << std::left << setw(opt_type_w) << opt_type_str(itr->opt_type)
480 #else
481  << std::setiosflags(std::ios::left) << setw(opt_name_w) << itr->opt_name
482  << std::setiosflags(std::ios::left) << setw(opt_type_w) << opt_type_str(itr->opt_type)
483 #endif
484  << ( itr->documentation.length() ? itr->documentation.c_str() : "No documentation" )
485  << std::endl;
486  // If an enumeration option then the next line is the value options
487  if( itr->opt_type == OPT_ENUM_INT ) {
488  out
489  << spc_chars
490  << " "
491  << setw(opt_name_w) << ""
492  << setw(opt_type_w) << "";
493  print_enum_opt_names( any_cast<int>(itr->default_val), out );
494  out
495  << std::endl;
496  }
497  // Now print the line that contains the default values
498  if( itr->opt_type == OPT_BOOL_TRUE ) {
499  out
500  << spc_chars
501  << "--"
502  << setw(opt_name_w) << itr->opt_name_false;
503  }
504  else {
505  out
506  << spc_chars
507  << " "
508  << setw(opt_name_w) << " ";
509  }
510  out
511  << setw(opt_type_w) << " "
512  << "(default: ";
513  switch( itr->opt_type ) {
514  case OPT_BOOL_TRUE:
515  out << "--" << ( (*(any_cast<bool*>(itr->default_val))) ?
516  itr->opt_name : itr->opt_name_false );
517  break;
518  case OPT_INT:
519  case OPT_LONG_INT:
520  case OPT_SIZE_T:
521  case OPT_LONG_LONG_INT:
522  case OPT_DOUBLE:
523  case OPT_FLOAT:
524  case OPT_STRING:
525  case OPT_ENUM_INT:
526  out << "--" << itr->opt_name;
527  break;
528  default:
529  TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
530  }
531  switch( itr->opt_type ) {
532  case OPT_BOOL_TRUE:
533  break;
534  case OPT_INT:
535  out << "=" << (*(any_cast<int*>(itr->default_val)));
536  break;
537  case OPT_LONG_INT:
538  out << "=" << (*(any_cast<long int*>(itr->default_val)));
539  break;
540  case OPT_SIZE_T:
541  out << "=" << (*(any_cast<size_t*>(itr->default_val)));
542  break;
543  case OPT_LONG_LONG_INT:
544  out << "=" << (*(any_cast<long long int*>(itr->default_val)));
545  break;
546  case OPT_DOUBLE:
547  out << "=" << (*(any_cast<double*>(itr->default_val)));
548  break;
549  case OPT_FLOAT:
550  out << "=" << (*(any_cast<float*>(itr->default_val)));
551  break;
552  case OPT_STRING:
553  out << "=" << add_quotes(*(any_cast<std::string*>(itr->default_val)));
554  break;
555  case OPT_ENUM_INT:
556  out << "=" << add_quotes(
557  enum_opt_default_val_name(itr->opt_name,any_cast<int>(itr->default_val),&out));
558  break;
559  default:
560  TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
561  }
562  out << ")\n";
563  }
564  if(doc_string_.length()) {
565  out << "\nDETAILED DOCUMENTATION:\n\n" << doc_string_ << std::endl << std::endl;
566  }
567  if(throwExceptions_)
568  TEUCHOS_TEST_FOR_EXCEPTION( true, HelpPrinted, "Help message was printed" );
569  }
570 }
571 
572 
574  const Ptr<std::ostream> &out_inout
575  )
576 {
577  if (!printed_timer_summary_ && show_timer_summary_on_exit_) {
578  RCP<std::ostream> out;
579  if (nonnull(out_inout)) {
580  out = rcpFromPtr(out_inout);
581  }
582  else {
584  }
585  getTimeMonitorSurrogate()->summarize(*out << "\n");
586  printed_timer_summary_ = true;
587  }
588 }
589 
590 
591 // private
592 
593 
594 void CommandLineProcessor::add_extra_output_setup_options() const
595 {
596  if(
597  // Are we in this function already and calling it recursively?
598  in_add_extra_output_setup_options_
599  ||
600  // Have we already setup these options?
601  added_extra_output_setup_options_
602  ||
603  // Are we not supposed to setup these options?
604  !addOutputSetupOptions_
605  )
606  {
607  return; // If any of the above is true, we need to return right away!
608  }
609  // Set the commandline options for this ...
611  *clp = const_cast<CommandLineProcessor*>(this);
612  clp->in_add_extra_output_setup_options_ = true;
613  clp->setOption(
614  "output-all-front-matter","output-no-front-matter",&clp->output_all_front_matter_
615  ,"Set if all front matter is printed to the default FancyOStream or not"
616  );
617  clp->setOption(
618  "output-show-line-prefix","output-no-show-line-prefix",&clp->output_show_line_prefix_
619  ,"Set if the line prefix matter is printed to the default FancyOStream or not"
620  );
621  clp->setOption(
622  "output-show-tab-count","output-no-show-tab-count",&clp->output_show_tab_count_
623  ,"Set if the tab count is printed to the default FancyOStream or not"
624  );
625  clp->setOption(
626  "output-show-proc-rank","output-no-show-proc-rank",&clp->output_show_proc_rank_
627  ,"Set if the processor rank is printed to the default FancyOStream or not"
628  );
629  clp->setOption(
630  "output-to-root-rank-only",&clp->output_to_root_rank_only_
631  ,"Set which processor (the root) gets the output. If < 0, then all processors get output."
632  );
633  clp->setOption(
634  "print-rcpnode-statistics-on-exit", "no-print-rcpnode-statistics-on-exit",
635  &clp->print_rcpnode_statistics_on_exit_,
636  "Set if the RCPNode usage statistics will be printed on exit or not. Warning,"
637  " this prints to std::cerr or every process so do not turn this on for very large"
638  " parallel runs."
639  );
640  if (nonnull(getTimeMonitorSurrogate())) {
641  clp->setOption(
642  "show-timer-summary", "no-show-timer-sumary", &clp->show_timer_summary_on_exit_,
643  "If true, then Teuchos::TimeMonitor::summarize() is called in"
644  " CommandLineProcessor's destructor (usually at the end of main)."
645  );
646  }
647 
648  clp->added_extra_output_setup_options_ = true;
649  clp->in_add_extra_output_setup_options_ = false;
650 }
651 
652 
653 void CommandLineProcessor::setEnumOption(
654  const char enum_option_name[],
655  int* enum_option_val,
656  const int num_enum_opt_values,
657  const int enum_opt_values[],
658  const char * const enum_opt_names[],
659  const char documentation[],
660  const bool required
661  )
662 {
663  add_extra_output_setup_options();
664 
665  TEUCHOS_TEST_FOR_EXCEPT(enum_option_val==NULL);
666  TEUCHOS_TEST_FOR_EXCEPT(num_enum_opt_values<=0);
667  TEUCHOS_TEST_FOR_EXCEPT(enum_opt_values==NULL);
668  TEUCHOS_TEST_FOR_EXCEPT(enum_opt_names==NULL);
669 
670  enum_opt_data_list_.push_back(
671  enum_opt_data_t(enum_option_val,num_enum_opt_values,enum_opt_values,enum_opt_names)
672  );
673  const int opt_id = static_cast<int>(enum_opt_data_list_.size())-1;
674  options_list_[std::string(enum_option_name)]
675  = opt_val_val_t(OPT_ENUM_INT,any(opt_id),required);
676  options_documentation_list_.push_back(
677  opt_doc_t(OPT_ENUM_INT,enum_option_name, "",
678  std::string(documentation?documentation:""), any(opt_id))
679  );
680 }
681 
682 
683 bool CommandLineProcessor::set_enum_value(
684  int argv_i
685  ,char* argv[]
686  ,const std::string &enum_opt_name
687  ,const int enum_id
688  ,const std::string &enum_str_val
689  ,std::ostream *errout
690  ) const
691 {
692  const enum_opt_data_t
693  &enum_opt_data = enum_opt_data_list_.at(enum_id);
694  std::vector<std::string>::const_iterator
695  itr_begin = enum_opt_data.enum_opt_names.begin(),
696  itr_end = enum_opt_data.enum_opt_names.end(),
697  itr = std::find( itr_begin, itr_end, enum_str_val );
698  if( itr == itr_end ) {
699  const int j = argv_i;
700 #define CLP_ERR_MSG \
701  "Error, the value \"" << enum_str_val << "\" for the " \
702  << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) << " option --" \
703  << enum_opt_name << " was not recognized (use --help)!"
704  if(errout)
705  *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
706  if( throwExceptions() ) {
707  TEUCHOS_TEST_FOR_EXCEPTION( true, UnrecognizedOption, CLP_ERR_MSG );
708  }
709  else {
710  return false;
711  }
712 #undef CLP_ERR_MSG
713  }
714  const int enum_opt_val_index = static_cast<int>(itr - itr_begin);
715  *enum_opt_data.enum_option_val = enum_opt_data.enum_opt_values.at(enum_opt_val_index);
716  return true;
717 }
718 
719 
720 void CommandLineProcessor::print_enum_opt_names(
721  const int enum_id
722  ,std::ostream &out
723  ) const
724 {
725  const enum_opt_data_t
726  &enum_opt_data = enum_opt_data_list_.at(enum_id);
727  typedef std::vector<std::string>::const_iterator itr_t;
728  out << "Valid options:";
729  for(
730  itr_t itr = enum_opt_data.enum_opt_names.begin();
731  itr != enum_opt_data.enum_opt_names.end();
732  ++itr
733  )
734  {
735  if( itr != enum_opt_data.enum_opt_names.begin() ) out << ",";
736  out << " " << add_quotes(*itr);
737  }
738 }
739 
740 
741 std::string
742 CommandLineProcessor::enum_opt_default_val_name(
743  const std::string &enum_name
744  ,const int enum_id
745  ,std::ostream *errout
746  ) const
747 {
748  const enum_opt_data_t
749  &enum_opt_data = enum_opt_data_list_.at(enum_id);
750  return enum_opt_data.enum_opt_names.at(
751  find_enum_opt_index(
752  enum_name,*enum_opt_data.enum_option_val,enum_opt_data,errout
753  )
754  );
755 }
756 
757 
758 int CommandLineProcessor::find_enum_opt_index(
759  const std::string &enum_opt_name
760  ,const int opt_value
761  ,const enum_opt_data_t &enum_data
762  ,std::ostream *errout
763  ) const
764 {
765  std::vector<int>::const_iterator
766  itr_begin = enum_data.enum_opt_values.begin(),
767  itr_end = enum_data.enum_opt_values.end(),
768  itr = std::find( itr_begin, itr_end, opt_value );
769  if( itr == itr_end ) {
770 #define CLP_ERR_MSG \
771  ( recogniseAllOptions() ? "Error" : "Warning" ) \
772  << ", option --" << enum_opt_name << " was given an invalid " \
773  "initial option value of " << opt_value << "!"
774  if(errout)
775  *errout << CLP_ERR_MSG << std::endl;
776  if( throwExceptions() )
777  TEUCHOS_TEST_FOR_EXCEPTION( true, std::invalid_argument, CLP_ERR_MSG );
778 #undef CLP_ERR_MSG
779  }
780  return static_cast<int>(itr - itr_begin);
781 }
782 
783 
784 bool CommandLineProcessor::get_opt_val(
785  const char str[]
786  ,std::string *opt_name
787  ,std::string *opt_val_str
788  ) const
789 {
790  const int len = static_cast<int>(std::strlen(str));
791  if( len < 3 )
792  return false; // Can't be an option with '--' followed by at least one char
793  if( str[0] != '-' || str[1] != '-' )
794  return false; // Not a recognised option
795  // Find the '='
796  int equ_i;
797  for( equ_i = 2; equ_i < len && str[equ_i] != '='; ++equ_i );
798  // Set opt_name
799  opt_name->assign( str + 2, equ_i-2 );
800  // Set opt_val_str
801  if( equ_i == len ) {
802  *opt_val_str = "";
803  }
804  else {
805  opt_val_str->assign( str + equ_i + 1, len - equ_i - 1 );
806  }
807  return true;
808 }
809 
810 void CommandLineProcessor::print_bad_opt(
811  int argv_i
812  ,char* argv[]
813  ,std::ostream *errout
814  ) const
815 {
816  const int j = argv_i;
817 #define CLP_ERR_MSG \
818  ( recogniseAllOptions() ? "Error" : "Warning" ) \
819  << ", the " << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) \
820  << " option \'" << argv[argv_i] << "\' was not recognized (use --help)!"
821  if(errout)
822  *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
824  TEUCHOS_TEST_FOR_EXCEPTION( true, UnrecognizedOption, CLP_ERR_MSG );
825 #undef CLP_ERR_MSG
826 }
827 
828 
829 // Hidden stuff
830 
831 
832 void CommandLineProcessor::setTimeMonitorSurrogate(
833  const RCP<CommandLineProcessor::TimeMonitorSurrogate> &timeMonitorSurrogate)
834 {
835  getRawTimeMonitorSurrogate() = timeMonitorSurrogate;
836 }
837 
838 
839 RCP<CommandLineProcessor::TimeMonitorSurrogate>
840 CommandLineProcessor::getTimeMonitorSurrogate()
841 {
842  return getRawTimeMonitorSurrogate();
843 }
844 
845 
846 RCP<CommandLineProcessor::TimeMonitorSurrogate>&
847 CommandLineProcessor::getRawTimeMonitorSurrogate()
848 {
849  static RCP<TimeMonitorSurrogate> timeMonitorSurrogate;
850  return timeMonitorSurrogate;
851 }
852 
853 
854 } // end namespace Teuchos
static int getRank()
The rank of the calling process in MPI_COMM_WORLD.
Thrown if –help was specified and throwExceptions==true.
static int getNProc()
The number of processes in MPI_COMM_WORLD.
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.
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.
void resize(size_type new_size, const value_type &x=value_type())
EParseCommandLineReturn
Return value for CommandLineProcessor::parse(). Note: These enums are all given non-negative values s...
Templated array class derived from the STL std::vector.
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.
static void allGather(int localVal, const ArrayView< int > &allVals)
Global all-to-all of a set of integers across processes.
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...