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