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  ,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 
391  EParseCommandLineReturn parse(
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  OPT_LONG_LONG_INT,
425  OPT_DOUBLE, OPT_STRING, OPT_ENUM_INT };
426 
427  // RAB: 2003/10/10: Note: I had to move this out of the private section since
428  // the sun compiler (version 7) complained (rightly it now appears after looking
429  // up what the ISO/ANSI C++ standard says) about the declaration for opt_val_val_t
430  // not being able to access a private member of CommandLineProcessor.
431 
432 private:
433 
434  // /////////////////////////////////
435  // Private types
436 
437  // ToDo: RAB: 2004/05/25: Clean up these data structures and add
438  // support for a templated enum type. This will clean up usage
439  // quite a bit.
440 
441  //
442  struct opt_val_val_t {
443  opt_val_val_t():
444  opt_type(OPT_NONE),
445  required(false),
446  was_read(false)
447  {}
448  opt_val_val_t( EOptType opt_type_in, const any& opt_val_in, bool required_in )
449  :opt_type(opt_type_in),opt_val(opt_val_in),required(required_in),was_read(false)
450  {}
451  EOptType opt_type;
452  any opt_val; // Will be bool*, int*, double*, std::string* or a small int (for OPT_ENUM_INT)
453  bool required;
454  bool was_read;
455  };
456 
457  //
458  typedef Teuchos::map<std::string,opt_val_val_t> options_list_t;
459 
460  //
461  struct opt_doc_t {
462  opt_doc_t()
463  :opt_type(OPT_NONE)
464  {}
465  opt_doc_t(EOptType opt_type_in, const std::string& opt_name_in, const std::string& opt_name_false_in
466  ,const std::string &documentation_in, const any &default_val_in )
467  :opt_type(opt_type_in),opt_name(opt_name_in),opt_name_false(opt_name_false_in)
468  ,documentation(documentation_in),default_val(default_val_in)
469  {}
470  EOptType opt_type;
471  std::string opt_name;
472  std::string opt_name_false; // only for bool
473  std::string documentation;
474  any default_val;
475  };
476 
477  //
478  typedef std::vector<opt_doc_t> options_documentation_list_t;
479 
480  //
481  struct enum_opt_data_t {
482  enum_opt_data_t()
483  :enum_option_val(NULL), num_enum_opt_values(0)
484  {}
485  enum_opt_data_t(
486  int *_enum_option_val
487  ,const int _num_enum_opt_values
488  ,const int _enum_opt_values[]
489  ,const char* _enum_opt_names[]
490  )
491  :enum_option_val(_enum_option_val)
492  ,num_enum_opt_values(_num_enum_opt_values)
493  ,enum_opt_values(_enum_opt_values,_enum_opt_values+_num_enum_opt_values)
494  {
495  for( int k = 0; k < num_enum_opt_values; ++k )
496  enum_opt_names.push_back(std::string(_enum_opt_names[k]));
497  }
498  int *enum_option_val;
499  int num_enum_opt_values;
500  std::vector<int> enum_opt_values;
501  std::vector<std::string> enum_opt_names;
502  };
503 
504  //
505  typedef std::vector<enum_opt_data_t> enum_opt_data_list_t;
506 
507  // /////////////////////////////////
508  // Private data members
509 
510  bool throwExceptions_;
511  bool recogniseAllOptions_;
512  bool addOutputSetupOptions_;
513  std::string doc_string_;
514 
515  //use pragmas to disable some false positive warnings in windows sharedlib exports
516 #ifdef _MSC_VER
517 #pragma warning(push)
518 #pragma warning(disable:4251)
519 #endif
520  mutable options_list_t options_list_;
521  options_documentation_list_t options_documentation_list_;
522  enum_opt_data_list_t enum_opt_data_list_;
523 #ifdef _MSC_VER
524 #pragma warning(pop)
525 #endif
526 
527  bool output_all_front_matter_;
528  bool output_show_line_prefix_;
529  bool output_show_tab_count_;
530  bool output_show_proc_rank_;
531  int output_to_root_rank_only_;
532  bool print_rcpnode_statistics_on_exit_;
533  bool show_timer_summary_on_exit_;
534 
535  bool printed_timer_summary_;
536 
537  bool added_extra_output_setup_options_;
538  bool in_add_extra_output_setup_options_;
539 
540  static const bool output_all_front_matter_default_;
541  static const bool output_show_line_prefix_default_;
542  static const bool output_show_tab_count_default_;
543  static const bool output_show_proc_rank_default_;
544  static const int output_to_root_rank_only_default_;
545  static const bool print_rcpnode_statistics_on_exit_default_;
546  static const bool show_timer_summary_on_exit_default_;
547 
548  // /////////////////////////////////
549  // Private member functions
550 
551  // Set the extra output setup options
552  void add_extra_output_setup_options() const;
553 
554  // Set an integer enumeration option
555  void setEnumOption(
556  const char enum_option_name[]
557  ,int *enum_option_val
558  ,const int num_enum_opt_values
559  ,const int enum_opt_values[]
560  ,const char* enum_opt_names[]
561  ,const char documentation[]
562  ,const bool required
563  );
564 
565  // Set an enum int option
566  bool set_enum_value(
567  int argv_i
568  ,char* argv[]
569  ,const std::string &enum_opt_name
570  ,const int enum_id
571  ,const std::string &enum_str_val
572  ,std::ostream *errout
573  ) const;
574 
575  // Print the valid enum values
576  void print_enum_opt_names(
577  const int enum_id
578  ,std::ostream &out
579  ) const;
580 
581  // Return the name of the default value for an enum
582  std::string enum_opt_default_val_name(
583  const std::string &enum_name
584  ,const int enum_id
585  ,std::ostream *errout
586  ) const;
587 
588  // Return the index given and option value
589  int find_enum_opt_index(
590  const std::string &enum_opt_name
591  ,const int opt_value
592  ,const enum_opt_data_t &enum_data
593  ,std::ostream *errout
594  ) const;
595 
596  // Get the option and the value from an entry in argv[].
597  // Will return false if entry is not formated properly.
598  bool get_opt_val(
599  const char str[]
600  ,std::string *opt_name
601  ,std::string *opt_val_str // May be empty on return
602  ) const;
603 
604  // String for option type
605  std::string opt_type_str( EOptType ) const;
606 
607  // Print bad option
608  void print_bad_opt(
609  int argv_i
610  ,char* argv[]
611  ,std::ostream *errout
612  ) const;
613 
614 public: // Hidden implementation stuff that clients should never see
615 
651  public:
655  virtual void summarize(std::ostream &out=std::cout) = 0;
656  };
657 
658  static void setTimeMonitorSurrogate(const RCP<TimeMonitorSurrogate> &timeMonitorSurrogate);
659 
660  static RCP<TimeMonitorSurrogate> getTimeMonitorSurrogate();
661 
662 private:
663 
664  static RCP<TimeMonitorSurrogate>& getRawTimeMonitorSurrogate();
665 
666 }; // end class CommandLineProcessor
667 
668 
669 // /////////////////////////
670 // Inline members
671 
672 
673 // Behavior modes
674 
675 
676 inline
677 void CommandLineProcessor::throwExceptions( const bool & throwExceptions_in )
678 { throwExceptions_ = throwExceptions_in; }
679 
680 
681 inline
683 { return throwExceptions_; }
684 
685 
686 inline
687 void CommandLineProcessor::recogniseAllOptions( const bool & recogniseAllOptions_in )
688 { recogniseAllOptions_ = recogniseAllOptions_in; }
689 
690 
691 inline
693 { return recogniseAllOptions_; }
694 
695 
696 inline
697 void CommandLineProcessor::addOutputSetupOptions( const bool &addOutputSetupOptions_in )
698 { addOutputSetupOptions_ = addOutputSetupOptions_in; }
699 
700 
701 inline
703 { return addOutputSetupOptions_; }
704 
705 
706 template <class EType>
707 inline
709  const char enum_option_name[]
710  ,EType *enum_option_val
711  ,const int num_enum_opt_values
712  ,const EType enum_opt_values[]
713  ,const char* enum_opt_names[]
714  ,const char documentation[]
715  ,const bool required
716  )
717 {
718  // RAB: 2004/05/25: Every C++ implementation that I know of just
719  // represents enumerations as int's and therefore this will compile
720  // just fine. However, the ISO/ANSI C++ standard says that
721  // compilers are allowed to use a smaller storage type for an enum
722  // but must not require storage any larger than an 'int'. If the
723  // below compile-time assertion does not compile then we need to do
724  // something different but it will be a lot of work!
725  CompileTimeAssert<sizeof(int)-sizeof(EType)>();
726  //CompileTimeAssert<sizeof(int)-sizeof(EType)-1>(); // Uncomment to see compilation error
727  setEnumOption(
728  enum_option_name
729  ,reinterpret_cast<int*>(enum_option_val)
730  ,num_enum_opt_values
731  ,reinterpret_cast<const int*>(enum_opt_values)
732  ,enum_opt_names
733  ,documentation
734  ,required
735  );
736 }
737 
738 
739 inline
740 std::string CommandLineProcessor::opt_type_str( EOptType opt_type ) const
741 {
742  std::string str;
743  switch( opt_type ) {
744  case OPT_BOOL_TRUE:
745  str = "bool";
746  break;
747  case OPT_INT:
748  str = "int";
749  break;
750  case OPT_LONG_INT:
751  str = "long int";
752  break;
753  case OPT_SIZE_T:
754  str = "size_t";
755  break;
756  case OPT_LONG_LONG_INT:
757  str = "long long int";
758  break;
759  case OPT_DOUBLE:
760  str = "double";
761  break;
762  case OPT_STRING:
763  str = "string";
764  break;
765  case OPT_ENUM_INT:
766  str = "enum";
767  break;
768  default:
769  assert(0); // Local programming error only
770  }
771  return str;
772 }
773 
774 
775 } // end namespace Teuchos
776 
777 
778 #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 recogniseAllOptions() const
Returns true if all options must be recognized by the parser.
Thrown if an unrecognized option was found and throwExceptions==true.
bool addOutputSetupOptions() const
Returns true options will be automatically added to setup Teuchos::VerboseObjectBase::getDefaultOStre...
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.
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 throwExceptions() const
Returns true if an std::exception is thrown, there is a parse error, or help is printed.
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...