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 //
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 
238  const char option_name[]
239  ,float *option_val
240  ,const char documentation[]
241  ,const bool required
242  )
243 {
244  add_extra_output_setup_options();
245  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
246  options_list_[std::string(option_name)]
247  = opt_val_val_t(OPT_FLOAT,any(option_val),required);
248  options_documentation_list_.push_back(
249  opt_doc_t(OPT_FLOAT, option_name, "", std::string(documentation?documentation:""),
250  any(option_val))
251  );
252 }
253 
255  const char option_name[]
256  ,std::string *option_val
257  ,const char documentation[]
258  ,const bool required
259  )
260 {
261  add_extra_output_setup_options();
262  TEUCHOS_TEST_FOR_EXCEPT(!(option_val!=NULL));
263  options_list_[std::string(option_name)]
264  = opt_val_val_t(OPT_STRING,any(option_val),required);
265  options_documentation_list_.push_back(
266  opt_doc_t(OPT_STRING, option_name, "", std::string(documentation?documentation:""),
267  any(option_val))
268  );
269 }
270 
271 
272 // Parse command line
273 
274 
277  int argc
278  ,char* argv[]
279  ,std::ostream *errout
280  ) const
281 {
282  add_extra_output_setup_options();
283  std::string opt_name;
284  std::string opt_val_str;
285  const std::string echo_cl_opt = "echo-command-line";
286  const std::string help_opt = "help";
287  const std::string pause_opt = "pause-for-debugging";
288  int procRank = GlobalMPISession::getRank();
289 
290  // check for help options before any others as we modify
291  // the values afterwards
292  for( int i = 1; i < argc; ++i ) {
293  bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
294  if( gov_return && opt_name == help_opt ) {
295  if(errout) printHelpMessage( argv[0], *errout );
296  return PARSE_HELP_PRINTED;
297  }
298  }
299  // check all other options
300  for( int i = 1; i < argc; ++i ) {
301  bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
302  if( !gov_return ) {
303  if(procRank == 0)
304  print_bad_opt(i,argv,errout);
305  if( recogniseAllOptions() )
307  else {
308  continue;
309  }
310  }
311  if( opt_name == echo_cl_opt ) {
312  if(errout && procRank == 0) {
313  *errout << "\nEchoing the command-line:\n\n";
314  for( int j = 0; j < argc; ++j )
315  *errout << argv[j] << " ";
316  *errout << "\n\n";
317  }
318  continue;
319  }
320  if( opt_name == pause_opt ) {
321 #ifndef _WIN32
322  Array<int> pids;
324  int rank_pid = getpid();
325  GlobalMPISession::allGather(rank_pid,pids());
326  if(procRank == 0)
327  for (int k=0; k<GlobalMPISession::getNProc(); k++)
328  std::cerr << "Rank " << k << " has PID " << pids[k] << std::endl;
329 #endif
330  if(procRank == 0) {
331  std::cerr << "\nType 0 and press enter to continue : ";
332  int dummy_int = 0;
333  std::cin >> dummy_int;
334  }
336  continue;
337  }
338  // Lookup the option (we had better find it!)
339  options_list_t::iterator itr = options_list_.find(opt_name);
340  if( itr == options_list_.end() ) {
341  if(procRank == 0)
342  print_bad_opt(i,argv,errout);
343  if( recogniseAllOptions() )
345  else
346  continue;
347  }
348  // Changed access to second value of std::map to not use overloaded arrow operator,
349  // otherwise this code will not compile on Janus (HKT, 12/01/2003)
350  opt_val_val_t &opt_val_val = (*itr).second;
351  opt_val_val.was_read = true;
352  switch( opt_val_val.opt_type ) {
353  case OPT_BOOL_TRUE:
354  *(any_cast<bool*>(opt_val_val.opt_val)) = true;
355  break;
356  case OPT_BOOL_FALSE:
357  *(any_cast<bool*>(opt_val_val.opt_val)) = false;
358  break;
359  case OPT_INT:
360  *(any_cast<int*>(opt_val_val.opt_val)) = asSafe<int> (opt_val_str);
361  break;
362  case OPT_LONG_INT:
363  *(any_cast<long int*>(opt_val_val.opt_val)) = asSafe<long int> (opt_val_str);
364  break;
365  case OPT_SIZE_T:
366  *(any_cast<size_t *>(opt_val_val.opt_val)) = asSafe<size_t> (opt_val_str);
367  break;
368  case OPT_LONG_LONG_INT:
369  *(any_cast<long long int*>(opt_val_val.opt_val)) = asSafe<long long int> (opt_val_str);
370  break;
371  case OPT_DOUBLE:
372  *(any_cast<double*>(opt_val_val.opt_val)) = asSafe<double> (opt_val_str);
373  break;
374  case OPT_FLOAT:
375  *(any_cast<float*>(opt_val_val.opt_val)) = asSafe<float> (opt_val_str);
376  break;
377  case OPT_STRING:
378  *(any_cast<std::string*>(opt_val_val.opt_val)) = remove_quotes(opt_val_str);
379  break;
380  case OPT_ENUM_INT:
381  if( !set_enum_value( i, argv, opt_name, any_cast<int>(opt_val_val.opt_val),
382  remove_quotes(opt_val_str), errout ) )
383  {
385  }
386  break;
387  default:
388  TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
389  }
390  }
391  // Look for options that were required but were not set
392  for(
393  options_list_t::const_iterator itr = options_list_.begin();
394  itr != options_list_.end();
395  ++itr
396  )
397  {
398  const opt_val_val_t &opt_val_val = (*itr).second;
399  if( opt_val_val.required && !opt_val_val.was_read ) {
400  const std::string &opt_val_name = (*itr).first;
401 #define CLP_ERR_MSG \
402  "Error, the option --"<<opt_val_name<<" was required but was not set!"
403  if(errout)
404  *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
405  if( throwExceptions() ) {
406  TEUCHOS_TEST_FOR_EXCEPTION( true, ParseError, CLP_ERR_MSG );
407  }
408  return PARSE_ERROR;
409 #undef CLP_ERR_MSG
410  }
411  }
412  // Set the options of a default stream exists and if we are asked to
415  if (defaultOut.get() && addOutputSetupOptions_) {
416  if (output_all_front_matter_ != output_all_front_matter_default_)
417  defaultOut->setShowAllFrontMatter(output_all_front_matter_);
418  if (output_show_line_prefix_ != output_show_line_prefix_default_)
419  defaultOut->setShowLinePrefix(output_show_line_prefix_);
420  if (output_show_tab_count_ != output_show_tab_count_default_)
421  defaultOut->setShowTabCount(output_show_tab_count_);
422  if (output_show_proc_rank_ != output_show_proc_rank_default_)
423  defaultOut->setShowProcRank(output_show_proc_rank_);
424  if (output_to_root_rank_only_ != output_to_root_rank_only_default_)
425  defaultOut->setOutputToRootOnly(output_to_root_rank_only_);
426  RCPNodeTracer::setPrintRCPNodeStatisticsOnExit(print_rcpnode_statistics_on_exit_);
427  }
428  return PARSE_SUCCESSFUL;
429 }
430 
431 
432 void CommandLineProcessor::printHelpMessage( const char program_name[],
433  std::ostream &out ) const
434 {
435  add_extra_output_setup_options();
436  int procRank = GlobalMPISession::getRank();
437  if (procRank == 0) {
438  using std::setw;
439  using std::endl;
440 
441  const int opt_type_w = 14;
442  const char spc_chars[] = " ";
443 
444  // Get the maximum length of an option name
445  int opt_name_w = 19; // For the 'pause-for-debugging' option
446  options_documentation_list_t::const_iterator itr;
447  for (
448  itr = options_documentation_list_.begin();
449  itr != options_documentation_list_.end();
450  ++itr
451  )
452  {
453  opt_name_w = my_max(opt_name_w,static_cast<int>(itr->opt_name.length()));
454  if( itr->opt_type )
455  opt_name_w = my_max(opt_name_w,static_cast<int>(itr->opt_name_false.length()));
456  }
457  opt_name_w += 2;
458 
459  // Some built-in options
460  out
461  << "Usage: " << program_name << " [options]\n"
462  << spc_chars << "options:\n"
463  << spc_chars
464  << "--"
465 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
466  << std::left << setw(opt_name_w) << "help"
467  << std::left << setw(opt_type_w) << " "
468 #else
469  << std::setiosflags(std::ios::left) << setw(opt_name_w) << "help"
470  << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
471 #endif
472  << "Prints this help message"
473  << std::endl
474  << spc_chars
475  << "--"
476 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
477  << std::left << setw(opt_name_w) << "pause-for-debugging"
478  << std::left << setw(opt_type_w) << " "
479 #else
480  << std::setiosflags(std::ios::left) << setw(opt_name_w) << "pause-for-debugging"
481  << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
482 #endif
483  << "Pauses for user input to allow attaching a debugger"
484  << std::endl
485  << spc_chars
486  << "--"
487 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
488  << std::left << setw(opt_name_w) << "echo-command-line"
489  << std::left << setw(opt_type_w) << " "
490 #else
491  << std::setiosflags(std::ios::left) << setw(opt_name_w) << "echo-command-line"
492  << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
493 #endif
494  << "Echo the command-line but continue as normal"
495  << std::endl;
496  for(
497  itr = options_documentation_list_.begin();
498  itr != options_documentation_list_.end();
499  ++itr )
500  {
501  // print top line with option name, type and short documentation string
502  out
503  << spc_chars
504  << "--"
505 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
506  << std::left << setw(opt_name_w) << itr->opt_name
507  << std::left << setw(opt_type_w) << opt_type_str(itr->opt_type)
508 #else
509  << std::setiosflags(std::ios::left) << setw(opt_name_w) << itr->opt_name
510  << std::setiosflags(std::ios::left) << setw(opt_type_w) << opt_type_str(itr->opt_type)
511 #endif
512  << ( itr->documentation.length() ? itr->documentation.c_str() : "No documentation" )
513  << std::endl;
514  // If an enumeration option then the next line is the value options
515  if( itr->opt_type == OPT_ENUM_INT ) {
516  out
517  << spc_chars
518  << " "
519  << setw(opt_name_w) << ""
520  << setw(opt_type_w) << "";
521  print_enum_opt_names( any_cast<int>(itr->default_val), out );
522  out
523  << std::endl;
524  }
525  // Now print the line that contains the default values
526  if( itr->opt_type == OPT_BOOL_TRUE ) {
527  out
528  << spc_chars
529  << "--"
530  << setw(opt_name_w) << itr->opt_name_false;
531  }
532  else {
533  out
534  << spc_chars
535  << " "
536  << setw(opt_name_w) << " ";
537  }
538  out
539  << setw(opt_type_w) << " "
540  << "(default: ";
541  switch( itr->opt_type ) {
542  case OPT_BOOL_TRUE:
543  out << "--" << ( (*(any_cast<bool*>(itr->default_val))) ?
544  itr->opt_name : itr->opt_name_false );
545  break;
546  case OPT_INT:
547  case OPT_LONG_INT:
548  case OPT_SIZE_T:
549  case OPT_LONG_LONG_INT:
550  case OPT_DOUBLE:
551  case OPT_FLOAT:
552  case OPT_STRING:
553  case OPT_ENUM_INT:
554  out << "--" << itr->opt_name;
555  break;
556  default:
557  TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
558  }
559  switch( itr->opt_type ) {
560  case OPT_BOOL_TRUE:
561  break;
562  case OPT_INT:
563  out << "=" << (*(any_cast<int*>(itr->default_val)));
564  break;
565  case OPT_LONG_INT:
566  out << "=" << (*(any_cast<long int*>(itr->default_val)));
567  break;
568  case OPT_SIZE_T:
569  out << "=" << (*(any_cast<size_t*>(itr->default_val)));
570  break;
571  case OPT_LONG_LONG_INT:
572  out << "=" << (*(any_cast<long long int*>(itr->default_val)));
573  break;
574  case OPT_DOUBLE:
575  out << "=" << (*(any_cast<double*>(itr->default_val)));
576  break;
577  case OPT_FLOAT:
578  out << "=" << (*(any_cast<float*>(itr->default_val)));
579  break;
580  case OPT_STRING:
581  out << "=" << add_quotes(*(any_cast<std::string*>(itr->default_val)));
582  break;
583  case OPT_ENUM_INT:
584  out << "=" << add_quotes(
585  enum_opt_default_val_name(itr->opt_name,any_cast<int>(itr->default_val),&out));
586  break;
587  default:
588  TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
589  }
590  out << ")\n";
591  }
592  if(doc_string_.length()) {
593  out << "\nDETAILED DOCUMENTATION:\n\n" << doc_string_ << std::endl << std::endl;
594  }
595  if(throwExceptions_)
596  TEUCHOS_TEST_FOR_EXCEPTION( true, HelpPrinted, "Help message was printed" );
597  }
598 }
599 
600 
602  const Ptr<std::ostream> &out_inout
603  )
604 {
605  if (!printed_timer_summary_ && show_timer_summary_on_exit_) {
606  RCP<std::ostream> out;
607  if (nonnull(out_inout)) {
608  out = rcpFromPtr(out_inout);
609  }
610  else {
612  }
613  getTimeMonitorSurrogate()->summarize(*out << "\n");
614  printed_timer_summary_ = true;
615  }
616 }
617 
618 
619 // private
620 
621 
622 void CommandLineProcessor::add_extra_output_setup_options() const
623 {
624  if(
625  // Are we in this function already and calling it recursively?
626  in_add_extra_output_setup_options_
627  ||
628  // Have we already setup these options?
629  added_extra_output_setup_options_
630  ||
631  // Are we not supposed to setup these options?
632  !addOutputSetupOptions_
633  )
634  {
635  return; // If any of the above is true, we need to return right away!
636  }
637  // Set the commandline options for this ...
639  *clp = const_cast<CommandLineProcessor*>(this);
640  clp->in_add_extra_output_setup_options_ = true;
641  clp->setOption(
642  "output-all-front-matter","output-no-front-matter",&clp->output_all_front_matter_
643  ,"Set if all front matter is printed to the default FancyOStream or not"
644  );
645  clp->setOption(
646  "output-show-line-prefix","output-no-show-line-prefix",&clp->output_show_line_prefix_
647  ,"Set if the line prefix matter is printed to the default FancyOStream or not"
648  );
649  clp->setOption(
650  "output-show-tab-count","output-no-show-tab-count",&clp->output_show_tab_count_
651  ,"Set if the tab count is printed to the default FancyOStream or not"
652  );
653  clp->setOption(
654  "output-show-proc-rank","output-no-show-proc-rank",&clp->output_show_proc_rank_
655  ,"Set if the processor rank is printed to the default FancyOStream or not"
656  );
657  clp->setOption(
658  "output-to-root-rank-only",&clp->output_to_root_rank_only_
659  ,"Set which processor (the root) gets the output. If < 0, then all processors get output."
660  );
661  clp->setOption(
662  "print-rcpnode-statistics-on-exit", "no-print-rcpnode-statistics-on-exit",
663  &clp->print_rcpnode_statistics_on_exit_,
664  "Set if the RCPNode usage statistics will be printed on exit or not. Warning,"
665  " this prints to std::cerr or every process so do not turn this on for very large"
666  " parallel runs."
667  );
668  if (nonnull(getTimeMonitorSurrogate())) {
669  clp->setOption(
670  "show-timer-summary", "no-show-timer-sumary", &clp->show_timer_summary_on_exit_,
671  "If true, then Teuchos::TimeMonitor::summarize() is called in"
672  " CommandLineProcessor's destructor (usually at the end of main)."
673  );
674  }
675 
676  clp->added_extra_output_setup_options_ = true;
677  clp->in_add_extra_output_setup_options_ = false;
678 }
679 
680 
681 void CommandLineProcessor::setEnumOption(
682  const char enum_option_name[]
683  ,int *enum_option_val
684  ,const int num_enum_opt_values
685  ,const int enum_opt_values[]
686  ,const char* enum_opt_names[]
687  ,const char documentation[]
688  ,const bool required
689  )
690 {
691  add_extra_output_setup_options();
692 
693  TEUCHOS_TEST_FOR_EXCEPT(enum_option_val==NULL);
694  TEUCHOS_TEST_FOR_EXCEPT(num_enum_opt_values<=0);
695  TEUCHOS_TEST_FOR_EXCEPT(enum_opt_values==NULL);
696  TEUCHOS_TEST_FOR_EXCEPT(enum_opt_names==NULL);
697 
698  enum_opt_data_list_.push_back(
699  enum_opt_data_t(enum_option_val,num_enum_opt_values,enum_opt_values,enum_opt_names)
700  );
701  const int opt_id = static_cast<int>(enum_opt_data_list_.size())-1;
702  options_list_[std::string(enum_option_name)]
703  = opt_val_val_t(OPT_ENUM_INT,any(opt_id),required);
704  options_documentation_list_.push_back(
705  opt_doc_t(OPT_ENUM_INT,enum_option_name, "",
706  std::string(documentation?documentation:""), any(opt_id))
707  );
708 }
709 
710 
711 bool CommandLineProcessor::set_enum_value(
712  int argv_i
713  ,char* argv[]
714  ,const std::string &enum_opt_name
715  ,const int enum_id
716  ,const std::string &enum_str_val
717  ,std::ostream *errout
718  ) const
719 {
720  const enum_opt_data_t
721  &enum_opt_data = enum_opt_data_list_.at(enum_id);
722  std::vector<std::string>::const_iterator
723  itr_begin = enum_opt_data.enum_opt_names.begin(),
724  itr_end = enum_opt_data.enum_opt_names.end(),
725  itr = std::find( itr_begin, itr_end, enum_str_val );
726  if( itr == itr_end ) {
727  const int j = argv_i;
728 #define CLP_ERR_MSG \
729  "Error, the value \"" << enum_str_val << "\" for the " \
730  << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) << " option --" \
731  << enum_opt_name << " was not recognized (use --help)!"
732  if(errout)
733  *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
734  if( throwExceptions() ) {
735  TEUCHOS_TEST_FOR_EXCEPTION( true, UnrecognizedOption, CLP_ERR_MSG );
736  }
737  else {
738  return false;
739  }
740 #undef CLP_ERR_MSG
741  }
742  const int enum_opt_val_index = static_cast<int>(itr - itr_begin);
743  *enum_opt_data.enum_option_val = enum_opt_data.enum_opt_values.at(enum_opt_val_index);
744  return true;
745 }
746 
747 
748 void CommandLineProcessor::print_enum_opt_names(
749  const int enum_id
750  ,std::ostream &out
751  ) const
752 {
753  const enum_opt_data_t
754  &enum_opt_data = enum_opt_data_list_.at(enum_id);
755  typedef std::vector<std::string>::const_iterator itr_t;
756  out << "Valid options:";
757  for(
758  itr_t itr = enum_opt_data.enum_opt_names.begin();
759  itr != enum_opt_data.enum_opt_names.end();
760  ++itr
761  )
762  {
763  if( itr != enum_opt_data.enum_opt_names.begin() ) out << ",";
764  out << " " << add_quotes(*itr);
765  }
766 }
767 
768 
769 std::string
770 CommandLineProcessor::enum_opt_default_val_name(
771  const std::string &enum_name
772  ,const int enum_id
773  ,std::ostream *errout
774  ) const
775 {
776  const enum_opt_data_t
777  &enum_opt_data = enum_opt_data_list_.at(enum_id);
778  return enum_opt_data.enum_opt_names.at(
779  find_enum_opt_index(
780  enum_name,*enum_opt_data.enum_option_val,enum_opt_data,errout
781  )
782  );
783 }
784 
785 
786 int CommandLineProcessor::find_enum_opt_index(
787  const std::string &enum_opt_name
788  ,const int opt_value
789  ,const enum_opt_data_t &enum_data
790  ,std::ostream *errout
791  ) const
792 {
793  std::vector<int>::const_iterator
794  itr_begin = enum_data.enum_opt_values.begin(),
795  itr_end = enum_data.enum_opt_values.end(),
796  itr = std::find( itr_begin, itr_end, opt_value );
797  if( itr == itr_end ) {
798 #define CLP_ERR_MSG \
799  ( recogniseAllOptions() ? "Error" : "Warning" ) \
800  << ", option --" << enum_opt_name << " was given an invalid " \
801  "initial option value of " << opt_value << "!"
802  if(errout)
803  *errout << CLP_ERR_MSG << std::endl;
804  if( throwExceptions() )
805  TEUCHOS_TEST_FOR_EXCEPTION( true, std::invalid_argument, CLP_ERR_MSG );
806 #undef CLP_ERR_MSG
807  }
808  return static_cast<int>(itr - itr_begin);
809 }
810 
811 
812 bool CommandLineProcessor::get_opt_val(
813  const char str[]
814  ,std::string *opt_name
815  ,std::string *opt_val_str
816  ) const
817 {
818  const int len = static_cast<int>(std::strlen(str));
819  if( len < 3 )
820  return false; // Can't be an option with '--' followed by at least one char
821  if( str[0] != '-' || str[1] != '-' )
822  return false; // Not a recognised option
823  // Find the '='
824  int equ_i;
825  for( equ_i = 2; equ_i < len && str[equ_i] != '='; ++equ_i );
826  // Set opt_name
827  opt_name->assign( str + 2, equ_i-2 );
828  // Set opt_val_str
829  if( equ_i == len ) {
830  *opt_val_str = "";
831  }
832  else {
833  opt_val_str->assign( str + equ_i + 1, len - equ_i - 1 );
834  }
835  return true;
836 }
837 
838 void CommandLineProcessor::print_bad_opt(
839  int argv_i
840  ,char* argv[]
841  ,std::ostream *errout
842  ) const
843 {
844  const int j = argv_i;
845 #define CLP_ERR_MSG \
846  ( recogniseAllOptions() ? "Error" : "Warning" ) \
847  << ", the " << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) \
848  << " option \'" << argv[argv_i] << "\' was not recognized (use --help)!"
849  if(errout)
850  *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
852  TEUCHOS_TEST_FOR_EXCEPTION( true, UnrecognizedOption, CLP_ERR_MSG );
853 #undef CLP_ERR_MSG
854 }
855 
856 
857 // Hidden stuff
858 
859 
860 void CommandLineProcessor::setTimeMonitorSurrogate(
861  const RCP<CommandLineProcessor::TimeMonitorSurrogate> &timeMonitorSurrogate)
862 {
863  getRawTimeMonitorSurrogate() = timeMonitorSurrogate;
864 }
865 
866 
867 RCP<CommandLineProcessor::TimeMonitorSurrogate>
868 CommandLineProcessor::getTimeMonitorSurrogate()
869 {
870  return getRawTimeMonitorSurrogate();
871 }
872 
873 
874 RCP<CommandLineProcessor::TimeMonitorSurrogate>&
875 CommandLineProcessor::getRawTimeMonitorSurrogate()
876 {
877  static RCP<TimeMonitorSurrogate> timeMonitorSurrogate;
878  return timeMonitorSurrogate;
879 }
880 
881 
882 } // 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...