Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
Teuchos_CommandLineProcessor.cpp
Go to the documentation of this file.
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 
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 
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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() ) {
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_) {
384  defaultOut->setShowAllFrontMatter(output_all_front_matter_);
386  defaultOut->setShowLinePrefix(output_show_line_prefix_);
388  defaultOut->setShowTabCount(output_show_tab_count_);
390  defaultOut->setShowProcRank(output_show_proc_rank_);
392  defaultOut->setOutputToRootOnly(output_to_root_rank_only_);
394  }
395  return PARSE_SUCCESSFUL;
396 }
397 
398 
399 void CommandLineProcessor::printHelpMessage( const char program_name[],
400  std::ostream &out ) const
401 {
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 {
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 
590 {
591  if(
592  // Are we in this function already and calling it recursively?
594  ||
595  // Have we already setup these options?
597  ||
598  // Are we not supposed to setup these options?
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);
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",
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  );
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 
645 }
646 
647 
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 {
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 
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() ) {
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 
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
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(
747  enum_name,*enum_opt_data.enum_option_val,enum_opt_data,errout
748  )
749  );
750 }
751 
752 
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 
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 
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;
820 #undef CLP_ERR_MSG
821 }
822 
823 
824 // Hidden stuff
825 
826 
828  const RCP<CommandLineProcessor::TimeMonitorSurrogate> &timeMonitorSurrogate)
829 {
830  getRawTimeMonitorSurrogate() = timeMonitorSurrogate;
831 }
832 
833 
836 {
838 }
839 
840 
843 {
844  static RCP<TimeMonitorSurrogate> timeMonitorSurrogate;
845  return timeMonitorSurrogate;
846 }
847 
848 
849 } // end namespace Teuchos
#define CLP_ERR_MSG
static int getRank()
The rank of the calling process in MPI_COMM_WORLD.
Thrown if –help was specified and throwExceptions==true.
void setEnumOption(const char enum_option_name[], int *enum_option_val, const int num_enum_opt_values, const int enum_opt_values[], const char *enum_opt_names[], const char documentation[], const bool required)
int find_enum_opt_index(const std::string &enum_opt_name, const int opt_value, const enum_opt_data_t &enum_data, std::ostream *errout) const
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.
static void setTimeMonitorSurrogate(const RCP< TimeMonitorSurrogate > &timeMonitorSurrogate)
Thrown if an unrecognized option was found and throwExceptions==true.
options_documentation_list_t options_documentation_list_
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
bool get_opt_val(const char str[], std::string *opt_name, std::string *opt_val_str) const
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.
static RCP< TimeMonitorSurrogate > getTimeMonitorSurrogate()
void print_bad_opt(int argv_i, char *argv[], std::ostream *errout) const
bool set_enum_value(int argv_i, char *argv[], const std::string &enum_opt_name, const int enum_id, const std::string &enum_str_val, std::ostream *errout) const
std::string enum_opt_default_val_name(const std::string &enum_name, const int enum_id, std::ostream *errout) const
EParseCommandLineReturn
Return value for CommandLineProcessor::parse(). Note: These enums are all given non-negative values s...
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.
void print_enum_opt_names(const int enum_id, std::ostream &out) const
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.
static RCP< TimeMonitorSurrogate > & getRawTimeMonitorSurrogate()
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...