Teuchos - Trilinos Tools Package  Version of the Day
Teuchos_CommandLineProcessor.hpp
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 #ifndef TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
43 #define TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
44 
53 #include "Teuchos_map.hpp"
54 #include "Teuchos_any.hpp"
56 #include "Teuchos_Ptr.hpp"
57 
73 namespace Teuchos {
74 
75 class TEUCHOSCORE_LIB_DLL_EXPORT CommandLineProcessor {
76 public:
77 
79 
80 
82  class ParseError : public std::logic_error
83  {public: ParseError(const std::string& what_arg) : std::logic_error(what_arg) {}};
84 
86  class HelpPrinted : public ParseError
87  {public: HelpPrinted(const std::string& what_arg) : ParseError(what_arg) {}};
88 
91  {public: UnrecognizedOption(const std::string& what_arg) : ParseError(what_arg) {}};
92 
98  PARSE_SUCCESSFUL = 0
99  ,PARSE_HELP_PRINTED = 1
100  ,PARSE_UNRECOGNIZED_OPTION = 2
101  ,PARSE_ERROR = 3
102  };
103 
105 
107 
108 
125  bool throwExceptions = true
126  ,bool recogniseAllOptions = true
127  ,bool addOutputSetupOptions = false
128  );
129 
133 
135 
137 
138 
140  void throwExceptions( const bool & throwExceptions );
141 
143  bool throwExceptions() const;
144 
146  void recogniseAllOptions( const bool & recogniseAllOptions );
147 
149  bool recogniseAllOptions() const;
150 
152  void addOutputSetupOptions( const bool &addOutputSetupOptions );
153 
155  bool addOutputSetupOptions() const;
156 
158 
160 
161 
164  void setDocString( const char doc_string[] );
165 
178  void setOption(
179  const char option_true[]
180  ,const char option_false[]
181  ,bool *option_val
182  ,const char documentation[] = NULL
183  );
184 
195  void setOption(
196  const char option_name[]
197  ,int *option_val
198  ,const char documentation[] = NULL
199  ,const bool required = false
200  );
201 
212  void setOption(
213  const char option_name[]
214  ,long int *option_val
215  ,const char documentation[] = NULL
216  ,const bool required = false
217  );
218 
229  void setOption(
230  const char option_name[]
231  ,size_t *option_val
232  ,const char documentation[] = NULL
233  ,const bool required = false
234  );
235 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
236 
246  void setOption(
247  const char option_name[]
248  ,long long int *option_val
249  ,const char documentation[] = NULL
250  ,const bool required = false
251  );
252 #endif
253 
264  void setOption(
265  const char option_name[]
266  ,double *option_val
267  ,const char documentation[] = NULL
268  ,const bool required = false
269  );
270 
281  void setOption(
282  const char option_name[]
283  ,std::string *option_val
284  ,const char documentation[] = NULL
285  ,const bool required = false
286  );
287 
316  template <class EType>
317  void setOption(
318  const char enum_option_name[]
319  ,EType *enum_option_val
320  ,const int num_enum_opt_values
321  ,const EType enum_opt_values[]
322  ,const char* enum_opt_names[]
323  ,const char documentation[] = NULL
324  ,const bool required = false
325  );
326 
328 
330 
331 
392  int argc
393  ,char* argv[]
394  ,std::ostream *errout = &std::cerr
395  ) const;
396 
398 
400 
401 
410  void printHelpMessage( const char program_name[], std::ostream &out ) const;
411 
417  void printFinalTimerSummary(const Ptr<std::ostream> &out = null);
418 
420 
421 public:
422  //
423  enum EOptType { OPT_NONE, OPT_BOOL_TRUE, OPT_BOOL_FALSE, OPT_INT, OPT_LONG_INT, OPT_SIZE_T,
424 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
425  OPT_LONG_LONG_INT,
426 #endif
427  OPT_DOUBLE, OPT_STRING, OPT_ENUM_INT };
428 
429  // RAB: 2003/10/10: Note: I had to move this out of the private section since
430  // the sun compiler (version 7) complained (rightly it now appears after looking
431  // up what the ISO/ANSI C++ standard says) about the declaration for opt_val_val_t
432  // not being able to access a private member of CommandLineProcessor.
433 
434 private:
435 
436  // /////////////////////////////////
437  // Private types
438 
439  // ToDo: RAB: 2004/05/25: Clean up these data structures and add
440  // support for a templated enum type. This will clean up usage
441  // quite a bit.
442 
443  //
444  struct opt_val_val_t {
445  opt_val_val_t():
446  opt_type(OPT_NONE),
447  required(false),
448  was_read(false)
449  {}
450  opt_val_val_t( EOptType opt_type_in, const any& opt_val_in, bool required_in )
451  :opt_type(opt_type_in),opt_val(opt_val_in),required(required_in),was_read(false)
452  {}
453  EOptType opt_type;
454  any opt_val; // Will be bool*, int*, double*, std::string* or a small int (for OPT_ENUM_INT)
455  bool required;
456  bool was_read;
457  };
458 
459  //
460  typedef Teuchos::map<std::string,opt_val_val_t> options_list_t;
461 
462  //
463  struct opt_doc_t {
464  opt_doc_t()
465  :opt_type(OPT_NONE)
466  {}
467  opt_doc_t(EOptType opt_type_in, const std::string& opt_name_in, const std::string& opt_name_false_in
468  ,const std::string &documentation_in, const any &default_val_in )
469  :opt_type(opt_type_in),opt_name(opt_name_in),opt_name_false(opt_name_false_in)
470  ,documentation(documentation_in),default_val(default_val_in)
471  {}
472  EOptType opt_type;
473  std::string opt_name;
474  std::string opt_name_false; // only for bool
475  std::string documentation;
476  any default_val;
477  };
478 
479  //
480  typedef std::vector<opt_doc_t> options_documentation_list_t;
481 
482  //
483  struct enum_opt_data_t {
484  enum_opt_data_t()
485  :enum_option_val(NULL), num_enum_opt_values(0)
486  {}
487  enum_opt_data_t(
488  int *_enum_option_val
489  ,const int _num_enum_opt_values
490  ,const int _enum_opt_values[]
491  ,const char* _enum_opt_names[]
492  )
493  :enum_option_val(_enum_option_val)
494  ,num_enum_opt_values(_num_enum_opt_values)
495  ,enum_opt_values(_enum_opt_values,_enum_opt_values+_num_enum_opt_values)
496  {
497  for( int k = 0; k < num_enum_opt_values; ++k )
498  enum_opt_names.push_back(std::string(_enum_opt_names[k]));
499  }
500  int *enum_option_val;
501  int num_enum_opt_values;
502  std::vector<int> enum_opt_values;
503  std::vector<std::string> enum_opt_names;
504  };
505 
506  //
507  typedef std::vector<enum_opt_data_t> enum_opt_data_list_t;
508 
509  // /////////////////////////////////
510  // Private data members
511 
512  bool throwExceptions_;
513  bool recogniseAllOptions_;
514  bool addOutputSetupOptions_;
515  std::string doc_string_;
516 
517  //use pragmas to disable some false positive warnings in windows sharedlib exports
518 #ifdef _MSC_VER
519 #pragma warning(push)
520 #pragma warning(disable:4251)
521 #endif
522  mutable options_list_t options_list_;
523  options_documentation_list_t options_documentation_list_;
524  enum_opt_data_list_t enum_opt_data_list_;
525 #ifdef _MSC_VER
526 #pragma warning(pop)
527 #endif
528 
529  bool output_all_front_matter_;
530  bool output_show_line_prefix_;
531  bool output_show_tab_count_;
532  bool output_show_proc_rank_;
533  int output_to_root_rank_only_;
534  bool print_rcpnode_statistics_on_exit_;
535  bool show_timer_summary_on_exit_;
536 
537  bool printed_timer_summary_;
538 
539  bool added_extra_output_setup_options_;
540  bool in_add_extra_output_setup_options_;
541 
542  static const bool output_all_front_matter_default_;
543  static const bool output_show_line_prefix_default_;
544  static const bool output_show_tab_count_default_;
545  static const bool output_show_proc_rank_default_;
546  static const int output_to_root_rank_only_default_;
547  static const bool print_rcpnode_statistics_on_exit_default_;
548  static const bool show_timer_summary_on_exit_default_;
549 
550  // /////////////////////////////////
551  // Private member functions
552 
553  // Set the extra output setup options
554  void add_extra_output_setup_options() const;
555 
556  // Set an integer enumeration option
557  void setEnumOption(
558  const char enum_option_name[]
559  ,int *enum_option_val
560  ,const int num_enum_opt_values
561  ,const int enum_opt_values[]
562  ,const char* enum_opt_names[]
563  ,const char documentation[]
564  ,const bool required
565  );
566 
567  // Set an enum int option
568  bool set_enum_value(
569  int argv_i
570  ,char* argv[]
571  ,const std::string &enum_opt_name
572  ,const int enum_id
573  ,const std::string &enum_str_val
574  ,std::ostream *errout
575  ) const;
576 
577  // Print the valid enum values
578  void print_enum_opt_names(
579  const int enum_id
580  ,std::ostream &out
581  ) const;
582 
583  // Return the name of the default value for an enum
584  std::string enum_opt_default_val_name(
585  const std::string &enum_name
586  ,const int enum_id
587  ,std::ostream *errout
588  ) const;
589 
590  // Return the index given and option value
591  int find_enum_opt_index(
592  const std::string &enum_opt_name
593  ,const int opt_value
594  ,const enum_opt_data_t &enum_data
595  ,std::ostream *errout
596  ) const;
597 
598  // Get the option and the value from an entry in argv[].
599  // Will return false if entry is not formated properly.
600  bool get_opt_val(
601  const char str[]
602  ,std::string *opt_name
603  ,std::string *opt_val_str // May be empty on return
604  ) const;
605 
606  // String for option type
607  std::string opt_type_str( EOptType ) const;
608 
609  // Print bad option
610  void print_bad_opt(
611  int argv_i
612  ,char* argv[]
613  ,std::ostream *errout
614  ) const;
615 
616 public: // Hidden implementation stuff that clients should never see
617 
653  public:
657  virtual void summarize(std::ostream &out=std::cout) = 0;
658  };
659 
660  static void setTimeMonitorSurrogate(const RCP<TimeMonitorSurrogate> &timeMonitorSurrogate);
661 
662  static RCP<TimeMonitorSurrogate> getTimeMonitorSurrogate();
663 
664 private:
665 
666  static RCP<TimeMonitorSurrogate>& getRawTimeMonitorSurrogate();
667 
668 }; // end class CommandLineProcessor
669 
670 
671 // /////////////////////////
672 // Inline members
673 
674 
675 // Behavior modes
676 
677 
678 inline
679 void CommandLineProcessor::throwExceptions( const bool & throwExceptions_in )
680 { throwExceptions_ = throwExceptions_in; }
681 
682 
683 inline
685 { return throwExceptions_; }
686 
687 
688 inline
689 void CommandLineProcessor::recogniseAllOptions( const bool & recogniseAllOptions_in )
690 { recogniseAllOptions_ = recogniseAllOptions_in; }
691 
692 
693 inline
695 { return recogniseAllOptions_; }
696 
697 
698 inline
699 void CommandLineProcessor::addOutputSetupOptions( const bool &addOutputSetupOptions_in )
700 { addOutputSetupOptions_ = addOutputSetupOptions_in; }
701 
702 
703 inline
705 { return addOutputSetupOptions_; }
706 
707 
708 template <class EType>
709 inline
711  const char enum_option_name[]
712  ,EType *enum_option_val
713  ,const int num_enum_opt_values
714  ,const EType enum_opt_values[]
715  ,const char* enum_opt_names[]
716  ,const char documentation[]
717  ,const bool required
718  )
719 {
720  // RAB: 2004/05/25: Every C++ implementation that I know of just
721  // represents enumerations as int's and therefore this will compile
722  // just fine. However, the ISO/ANSI C++ standard says that
723  // compilers are allowed to use a smaller storage type for an enum
724  // but must not require storage any larger than an 'int'. If the
725  // below compile-time assertion does not compile then we need to do
726  // something different but it will be a lot of work!
727  CompileTimeAssert<sizeof(int)-sizeof(EType)>();
728  //CompileTimeAssert<sizeof(int)-sizeof(EType)-1>(); // Uncomment to see compilation error
729  setEnumOption(
730  enum_option_name
731  ,reinterpret_cast<int*>(enum_option_val)
732  ,num_enum_opt_values
733  ,reinterpret_cast<const int*>(enum_opt_values)
734  ,enum_opt_names
735  ,documentation
736  ,required
737  );
738 }
739 
740 
741 inline
742 std::string CommandLineProcessor::opt_type_str( EOptType opt_type ) const
743 {
744  std::string str;
745  switch( opt_type ) {
746  case OPT_BOOL_TRUE:
747  str = "bool";
748  break;
749  case OPT_INT:
750  str = "int";
751  break;
752  case OPT_LONG_INT:
753  str = "long int";
754  break;
755  case OPT_SIZE_T:
756  str = "size_t";
757  break;
758 #ifdef HAVE_TEUCHOS_LONG_LONG_INT
759  case OPT_LONG_LONG_INT:
760  str = "long long int";
761  break;
762 #endif
763  case OPT_DOUBLE:
764  str = "double";
765  break;
766  case OPT_STRING:
767  str = "string";
768  break;
769  case OPT_ENUM_INT:
770  str = "enum";
771  break;
772  default:
773  assert(0); // Local programming error only
774  }
775  return str;
776 }
777 
778 
779 } // end namespace Teuchos
780 
781 
782 #endif // TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
Modified boost::any class for holding a templated value.
Thrown if –help was specified and throwExceptions==true.
Template classes for testing assertions at compile time.
bool throwExceptions() const
Returns true if an std::exception is thrown, there is a parse error, or help is printed.
Modified boost::any class, which is a container for a templated value.
Definition: Teuchos_any.hpp:86
Thrown if an unrecognized option was found and throwExceptions==true.
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
Interface by which CommandLineProcessor may use TimeMonitor.
bool addOutputSetupOptions() const
Returns true options will be automatically added to setup Teuchos::VerboseObjectBase::getDefaultOStre...
Provides std::map class for deficient platforms.
EParseCommandLineReturn
Return value for CommandLineProcessor::parse(). Note: These enums are all given non-negative values s...
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
bool recogniseAllOptions() const
Returns true if all options must be recognized by the parser.
Smart reference counting pointer class for automatic garbage collection.
If instantiated (for Test!=0) then this should not compile!
Thrown if a parse std::exception occurs and throwExceptions==true.
Class that helps parse command line input arguments from (argc,argv[]) and set options.
Simple wrapper class for raw pointers to single objects where no persisting relationship exists...