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