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 #include <vector>
58 
74 namespace Teuchos {
75 
76 class TEUCHOSCORE_LIB_DLL_EXPORT CommandLineProcessor {
77 public:
78 
80 
81 
83  class ParseError : public std::logic_error
84  {public: ParseError(const std::string& what_arg) : std::logic_error(what_arg) {}};
85 
87  class HelpPrinted : public ParseError
88  {public: HelpPrinted(const std::string& what_arg) : ParseError(what_arg) {}};
89 
92  {public: UnrecognizedOption(const std::string& what_arg) : ParseError(what_arg) {}};
93 
99  PARSE_SUCCESSFUL = 0
100  ,PARSE_HELP_PRINTED = 1
101  ,PARSE_UNRECOGNIZED_OPTION = 2
102  ,PARSE_ERROR = 3
103  };
104 
106 
108 
109 
126  bool throwExceptions = true
127  ,bool recogniseAllOptions = true
128  ,bool addOutputSetupOptions = false
129  );
130 
134 
136 
138 
139 
141  void throwExceptions( const bool & throwExceptions );
142 
144  bool throwExceptions() const;
145 
147  void recogniseAllOptions( const bool & recogniseAllOptions );
148 
150  bool recogniseAllOptions() const;
151 
153  void addOutputSetupOptions( const bool &addOutputSetupOptions );
154 
156  bool addOutputSetupOptions() const;
157 
159 
161 
162 
165  void setDocString( const char doc_string[] );
166 
179  void setOption(
180  const char option_true[]
181  ,const char option_false[]
182  ,bool *option_val
183  ,const char documentation[] = NULL
184  );
185 
196  void setOption(
197  const char option_name[]
198  ,int *option_val
199  ,const char documentation[] = NULL
200  ,const bool required = false
201  );
202 
213  void setOption(
214  const char option_name[]
215  ,long int *option_val
216  ,const char documentation[] = NULL
217  ,const bool required = false
218  );
219 
230  void setOption(
231  const char option_name[]
232  ,size_t *option_val
233  ,const char documentation[] = NULL
234  ,const bool required = false
235  );
236 
247  void setOption(
248  const char option_name[]
249  ,long long int *option_val
250  ,const char documentation[] = NULL
251  ,const bool required = false
252  );
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  ,float *option_val
284  ,const char documentation[] = NULL
285  ,const bool required = false
286  );
287 
298  void setOption(
299  const char option_name[]
300  ,std::string *option_val
301  ,const char documentation[] = NULL
302  ,const bool required = false
303  );
304 
333  template <class EType>
334  void setOption(
335  const char enum_option_name[]
336  ,EType *enum_option_val
337  ,const int num_enum_opt_values
338  ,const EType enum_opt_values[]
339  ,const char* enum_opt_names[]
340  ,const char documentation[] = NULL
341  ,const bool required = false
342  );
343 
345 
347 
348 
408  EParseCommandLineReturn parse(
409  int argc
410  ,char* argv[]
411  ,std::ostream *errout = &std::cerr
412  ) const;
413 
415 
417 
418 
427  void printHelpMessage( const char program_name[], std::ostream &out ) const;
428 
434  void printFinalTimerSummary(const Ptr<std::ostream> &out = null);
435 
437 
438 public:
439  //
440  enum EOptType { OPT_NONE, OPT_BOOL_TRUE, OPT_BOOL_FALSE, OPT_INT, OPT_LONG_INT, OPT_SIZE_T,
441  OPT_LONG_LONG_INT,
442  OPT_DOUBLE, OPT_FLOAT, OPT_STRING, OPT_ENUM_INT };
443 
444  // RAB: 2003/10/10: Note: I had to move this out of the private section since
445  // the sun compiler (version 7) complained (rightly it now appears after looking
446  // up what the ISO/ANSI C++ standard says) about the declaration for opt_val_val_t
447  // not being able to access a private member of CommandLineProcessor.
448 
449 private:
450 
451  // /////////////////////////////////
452  // Private types
453 
454  // ToDo: RAB: 2004/05/25: Clean up these data structures and add
455  // support for a templated enum type. This will clean up usage
456  // quite a bit.
457 
458  //
459  struct opt_val_val_t {
460  opt_val_val_t():
461  opt_type(OPT_NONE),
462  required(false),
463  was_read(false)
464  {}
465  opt_val_val_t( EOptType opt_type_in, const any& opt_val_in, bool required_in )
466  :opt_type(opt_type_in),opt_val(opt_val_in),required(required_in),was_read(false)
467  {}
468  EOptType opt_type;
469  any opt_val; // Will be bool*, int*, double*, std::string* or a small int (for OPT_ENUM_INT)
470  bool required;
471  bool was_read;
472  };
473 
474  //
475  typedef Teuchos::map<std::string,opt_val_val_t> options_list_t;
476 
477  //
478  struct opt_doc_t {
479  opt_doc_t()
480  :opt_type(OPT_NONE)
481  {}
482  opt_doc_t(EOptType opt_type_in, const std::string& opt_name_in, const std::string& opt_name_false_in
483  ,const std::string &documentation_in, const any &default_val_in )
484  :opt_type(opt_type_in),opt_name(opt_name_in),opt_name_false(opt_name_false_in)
485  ,documentation(documentation_in),default_val(default_val_in)
486  {}
487  EOptType opt_type;
488  std::string opt_name;
489  std::string opt_name_false; // only for bool
490  std::string documentation;
491  any default_val;
492  };
493 
494  //
495  typedef std::vector<opt_doc_t> options_documentation_list_t;
496 
497  //
498  struct enum_opt_data_t {
499  enum_opt_data_t()
500  :enum_option_val(NULL), num_enum_opt_values(0)
501  {}
502  enum_opt_data_t(
503  int *_enum_option_val
504  ,const int _num_enum_opt_values
505  ,const int _enum_opt_values[]
506  ,const char* _enum_opt_names[]
507  )
508  :enum_option_val(_enum_option_val)
509  ,num_enum_opt_values(_num_enum_opt_values)
510  ,enum_opt_values(_enum_opt_values,_enum_opt_values+_num_enum_opt_values)
511  {
512  for( int k = 0; k < num_enum_opt_values; ++k )
513  enum_opt_names.push_back(std::string(_enum_opt_names[k]));
514  }
515  int *enum_option_val;
516  int num_enum_opt_values;
517  std::vector<int> enum_opt_values;
518  std::vector<std::string> enum_opt_names;
519  };
520 
521  //
522  typedef std::vector<enum_opt_data_t> enum_opt_data_list_t;
523 
524  // /////////////////////////////////
525  // Private data members
526 
527  bool throwExceptions_;
528  bool recogniseAllOptions_;
529  bool addOutputSetupOptions_;
530  std::string doc_string_;
531 
532  //use pragmas to disable some false positive warnings in windows sharedlib exports
533 #ifdef _MSC_VER
534 #pragma warning(push)
535 #pragma warning(disable:4251)
536 #endif
537  mutable options_list_t options_list_;
538  options_documentation_list_t options_documentation_list_;
539  enum_opt_data_list_t enum_opt_data_list_;
540 #ifdef _MSC_VER
541 #pragma warning(pop)
542 #endif
543 
544  bool output_all_front_matter_;
545  bool output_show_line_prefix_;
546  bool output_show_tab_count_;
547  bool output_show_proc_rank_;
548  int output_to_root_rank_only_;
549  bool print_rcpnode_statistics_on_exit_;
550  bool show_timer_summary_on_exit_;
551 
552  bool printed_timer_summary_;
553 
554  bool added_extra_output_setup_options_;
555  bool in_add_extra_output_setup_options_;
556 
557  static const bool output_all_front_matter_default_;
558  static const bool output_show_line_prefix_default_;
559  static const bool output_show_tab_count_default_;
560  static const bool output_show_proc_rank_default_;
561  static const int output_to_root_rank_only_default_;
562  static const bool print_rcpnode_statistics_on_exit_default_;
563  static const bool show_timer_summary_on_exit_default_;
564 
565  // /////////////////////////////////
566  // Private member functions
567 
568  // Set the extra output setup options
569  void add_extra_output_setup_options() const;
570 
571  // Set an integer enumeration option
572  void setEnumOption(
573  const char enum_option_name[]
574  ,int *enum_option_val
575  ,const int num_enum_opt_values
576  ,const int enum_opt_values[]
577  ,const char* enum_opt_names[]
578  ,const char documentation[]
579  ,const bool required
580  );
581 
582  // Set an enum int option
583  bool set_enum_value(
584  int argv_i
585  ,char* argv[]
586  ,const std::string &enum_opt_name
587  ,const int enum_id
588  ,const std::string &enum_str_val
589  ,std::ostream *errout
590  ) const;
591 
592  // Print the valid enum values
593  void print_enum_opt_names(
594  const int enum_id
595  ,std::ostream &out
596  ) const;
597 
598  // Return the name of the default value for an enum
599  std::string enum_opt_default_val_name(
600  const std::string &enum_name
601  ,const int enum_id
602  ,std::ostream *errout
603  ) const;
604 
605  // Return the index given and option value
606  int find_enum_opt_index(
607  const std::string &enum_opt_name
608  ,const int opt_value
609  ,const enum_opt_data_t &enum_data
610  ,std::ostream *errout
611  ) const;
612 
613  // Get the option and the value from an entry in argv[].
614  // Will return false if entry is not formated properly.
615  bool get_opt_val(
616  const char str[]
617  ,std::string *opt_name
618  ,std::string *opt_val_str // May be empty on return
619  ) const;
620 
621  // String for option type
622  std::string opt_type_str( EOptType ) const;
623 
624  // Print bad option
625  void print_bad_opt(
626  int argv_i
627  ,char* argv[]
628  ,std::ostream *errout
629  ) const;
630 
631 public: // Hidden implementation stuff that clients should never see
632 
668  public:
672  virtual void summarize(std::ostream &out=std::cout) = 0;
673  };
674 
675  static void setTimeMonitorSurrogate(const RCP<TimeMonitorSurrogate> &timeMonitorSurrogate);
676 
677  static RCP<TimeMonitorSurrogate> getTimeMonitorSurrogate();
678 
679 private:
680 
681  static RCP<TimeMonitorSurrogate>& getRawTimeMonitorSurrogate();
682 
683 }; // end class CommandLineProcessor
684 
685 
686 // /////////////////////////
687 // Inline members
688 
689 
690 // Behavior modes
691 
692 
693 inline
694 void CommandLineProcessor::throwExceptions( const bool & throwExceptions_in )
695 { throwExceptions_ = throwExceptions_in; }
696 
697 
698 inline
700 { return throwExceptions_; }
701 
702 
703 inline
704 void CommandLineProcessor::recogniseAllOptions( const bool & recogniseAllOptions_in )
705 { recogniseAllOptions_ = recogniseAllOptions_in; }
706 
707 
708 inline
710 { return recogniseAllOptions_; }
711 
712 
713 inline
714 void CommandLineProcessor::addOutputSetupOptions( const bool &addOutputSetupOptions_in )
715 { addOutputSetupOptions_ = addOutputSetupOptions_in; }
716 
717 
718 inline
720 { return addOutputSetupOptions_; }
721 
722 
723 template <class EType>
724 inline
726  const char enum_option_name[]
727  ,EType *enum_option_val
728  ,const int num_enum_opt_values
729  ,const EType enum_opt_values[]
730  ,const char* enum_opt_names[]
731  ,const char documentation[]
732  ,const bool required
733  )
734 {
735  // RAB: 2004/05/25: Every C++ implementation that I know of just
736  // represents enumerations as int's and therefore this will compile
737  // just fine. However, the ISO/ANSI C++ standard says that
738  // compilers are allowed to use a smaller storage type for an enum
739  // but must not require storage any larger than an 'int'. If the
740  // below compile-time assertion does not compile then we need to do
741  // something different but it will be a lot of work!
742  CompileTimeAssert<sizeof(int)-sizeof(EType)>();
743  //CompileTimeAssert<sizeof(int)-sizeof(EType)-1>(); // Uncomment to see compilation error
744  setEnumOption(
745  enum_option_name
746  ,reinterpret_cast<int*>(enum_option_val)
747  ,num_enum_opt_values
748  ,reinterpret_cast<const int*>(enum_opt_values)
749  ,enum_opt_names
750  ,documentation
751  ,required
752  );
753 }
754 
755 
756 inline
757 std::string CommandLineProcessor::opt_type_str( EOptType opt_type ) const
758 {
759  std::string str;
760  switch( opt_type ) {
761  case OPT_BOOL_TRUE:
762  str = "bool";
763  break;
764  case OPT_INT:
765  str = "int";
766  break;
767  case OPT_LONG_INT:
768  str = "long int";
769  break;
770  case OPT_SIZE_T:
771  str = "size_t";
772  break;
773  case OPT_LONG_LONG_INT:
774  str = "long long int";
775  break;
776  case OPT_DOUBLE:
777  str = "double";
778  break;
779  case OPT_FLOAT:
780  str = "float";
781  break;
782  case OPT_STRING:
783  str = "string";
784  break;
785  case OPT_ENUM_INT:
786  str = "enum";
787  break;
788  default:
789  assert(0); // Local programming error only
790  }
791  return str;
792 }
793 
794 
795 } // end namespace Teuchos
796 
797 
798 #endif // TEUCHOS_COMMAND_LINE_PROCESSOR_HPP
Template classes for testing assertions at compile time.
Modified boost::any class for holding a templated value.
Provides std::map class for deficient platforms.
Thrown if –help was specified and throwExceptions==true.
Thrown if a parse std::exception occurs and throwExceptions==true.
Interface by which CommandLineProcessor may use TimeMonitor.
virtual void summarize(std::ostream &out=std::cout)=0
Summarize timings over all process(es) to the given output stream.
Thrown if an unrecognized option was found and throwExceptions==true.
Class that helps parse command line input arguments from (argc,argv[]) and set options.
bool throwExceptions() const
Returns true if an std::exception is thrown, there is a parse error, or help is printed.
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
EParseCommandLineReturn
Return value for CommandLineProcessor::parse(). Note: These enums are all given non-negative values s...
bool addOutputSetupOptions() const
Returns true options will be automatically added to setup Teuchos::VerboseObjectBase::getDefaultOStre...
bool recogniseAllOptions() const
Returns true if all options must be recognized by the parser.
If instantiated (for Test!=0) then this should not compile!
Simple wrapper class for raw pointers to single objects where no persisting relationship exists.
Smart reference counting pointer class for automatic garbage collection.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...