Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

vul_arg.h

Go to the documentation of this file.
00001 // This is core/vul/vul_arg.h
00002 #ifndef vul_arg_h_
00003 #define vul_arg_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief Command-line arguments
00010 // \author Andrew W. Fitzgibbon, Oxford RRG
00011 // \date   05 Feb 98
00012 //
00013 // \verbatim
00014 //  Modifications
00015 //   PDA (Manchester) 21/03/2001: Tidied up the documentation
00016 //   Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line
00017 // \endverbatim
00018 
00019 #include <vcl_vector.h>
00020 #include <vcl_string.h>
00021 #include <vcl_list.h>
00022 #include <vcl_iosfwd.h>
00023 
00024 //: forward declare all classes and their helper functions.
00025 class vul_arg_info_list;
00026 template <class T> class vul_arg;
00027 template <class T> void settype     (vul_arg<T> &);
00028 template <class T> void print_value (vcl_ostream &, vul_arg<T> const &);
00029 template <class T> int  parse       (vul_arg<T>*, char**);
00030 
00031 //: This is the base class for the templated vul_arg<T>s
00032 class vul_arg_base
00033 {
00034  public:
00035   static void parse_deprecated(int& argc, char **& argv,
00036                                bool warn_about_unrecognized_arguments = true);
00037   static void include_deprecated(vul_arg_info_list& l);
00038 
00039   static void add_to_current(vul_arg_base* a);
00040   static void set_help_option( char const*str);
00041   static void set_help_description( char const*str);
00042   static void set_help_precis( char const*str);
00043   static void display_usage(char const* msg = 0);
00044   static void display_usage_and_exit(char const* msg = 0);
00045 
00046   friend class vul_arg_info_list;
00047 
00048   char const* option();
00049   char const* help();
00050 
00051   //: Returns true if arg was set on the command line.
00052   bool set() const;
00053 
00054   virtual vcl_ostream& print_value(vcl_ostream&) = 0;
00055 
00056  public:   // Avoid errors on some compilers that don't follow
00057            // protected: directive correctly with type_
00058 
00059   //: Static text describing type of option (e.g. bool or double).
00060   char const *type_;
00061  protected:
00062   //: After parsing, true iff value was set on command line.
00063   bool set_;
00064   //: Option flag including "-" or "--".
00065   vcl_string option_;
00066   //: Description of argument.
00067   vcl_string help_;
00068 
00069   vul_arg_base(vul_arg_info_list& l, char const* option_string,
00070                char const*helpstring);
00071   vul_arg_base(char const* option_string, char const*helpstring);
00072   virtual ~vul_arg_base() {}
00073 
00074   virtual int parse(char ** argv) = 0;
00075 };
00076 
00077 //: parse command-line arguments
00078 // vul_arg_parse simplifies the parsing of command-line arguments by combining
00079 // the variables with the option specifications.  To get a variable, you
00080 // simply name it along with its flag, a help string, and an optional
00081 // default value:
00082 // \code
00083 //      vul_arg<double> threshold("-t", "Intensity threshold", 1.25);
00084 // \endcode
00085 // Repeat this for any other arguments and then ask the base class to parse
00086 // the lot:
00087 // \code
00088 //      vul_arg_parse(argc,argv);
00089 // \endcode
00090 //
00091 // Now parameters such as threshold above can be referred to and will have
00092 // either the default value or the one supplied on the command line.
00093 //
00094 // The big design decision here was whether or not the args should collect
00095 // themselves into a global pool, so that the static vul_arg_base::parse can
00096 // find them, or whether there should be a local argPool which is passed to
00097 // each arg in order that it may add itself.  That would give a syntax like
00098 // \code
00099 //      vul_arg_info_list args;
00100 //      vul_arg<double> threshold(args, "-t", 1.25);
00101 //                                ^^^^^ passing args in
00102 //      args.parse(argc, argv, true);
00103 // \endcode
00104 // The latter is "better" but the former is easier to use so I chose it.
00105 //
00106 // Added by Geoff: call to vul_arg_base::set_help_option("-?") means that a
00107 // program call with something like aprog -? will display usage info derived
00108 // from the argument list.  Note: default is -? but can be anything.
00109 //
00110 void vul_arg_parse(int& argc, char **& argv,
00111                    bool warn_about_unrecognized_arguments = true);
00112 
00113 //: Add an externally supplied list of args to the global list.
00114 void vul_arg_include(vul_arg_info_list& l);
00115 
00116 //: Print all args, and usage messages.
00117 void vul_arg_display_usage_and_exit(char const* msg = 0);
00118 
00119 //: parse command-line arguments
00120 template <class T>
00121 class vul_arg : public vul_arg_base
00122 {
00123  public:
00124   T value_;// public so we don't have to worry about templated friends.
00125 
00126   //: Construct an vul_arg<T> with command-line switch and default value.
00127   // Command line switch \a option_string, and default value
00128   // \a default_value.  Add this argument to the global
00129   // list of arguments that vul_arg_base::parse() uses when it eventually
00130   // gets the command line.
00131   //
00132   // If \a option_string is null, then the argument is assigned to the
00133   // first plain word in the command line (warning: this causes problems for
00134   // T=char *, but that just means that you have to have a help string if you
00135   // want a default... good)
00136   vul_arg(char const* option_string = 0,
00137           char const* helpstring = 0,
00138           T default_value = T())
00139     : vul_arg_base(option_string,helpstring),
00140       value_(default_value) { settype(); }
00141 
00142   //: As above, but add the arg to the list \a l, on which \c parse() can be called later.
00143   vul_arg(vul_arg_info_list & l,
00144           char const * option_string = 0,
00145           char const * helpstring = 0,
00146           T default_value = T())
00147     : vul_arg_base(l, option_string, helpstring),
00148       value_(default_value) { settype(); }
00149 
00150   //: return the arg's current value, whether the default or the one from the command line.
00151   T      & operator () () { return value_; }
00152   T const& operator () () const { return value_; }
00153   //operator T& () { return value_; }
00154 
00155   //: returns number of args chomped, or -1 on failure.
00156   int parse(char ** argv) { return ::parse(this, argv); }
00157 
00158   //: print
00159   vcl_ostream& print_value(vcl_ostream &s) {
00160     ::print_value(s, *this);
00161     return s; // << flush
00162   }
00163 
00164  private:
00165   void settype() { ::settype(*this); }
00166 };
00167 
00168 //: a helper for vul_arg::parse.
00169 // Users might need it if they wish to parse several command lines.
00170 //
00171 class vul_arg_info_list
00172 {
00173  public:
00174   enum autonomy {
00175     subset,
00176     all
00177   };
00178   //: Construct an empty vul_arg_info_list.
00179   vul_arg_info_list(autonomy autonomy__ = subset)
00180     : help_("-?"), // default help operator!
00181       verbose_(false), autonomy_(autonomy__) {}
00182 
00183   ~vul_arg_info_list() {}
00184 
00185   void add(vul_arg_base* arg);
00186   void parse(int& argc, char **& argv, bool warn_about_unrecognized_arguments);
00187   void include(vul_arg_info_list& l);
00188   void verbose(bool on) { verbose_ = on; }
00189 
00190   void set_help_option(char const* str);
00191 
00192   //: Set the (short) text used to describe the command
00193   void set_help_precis(char const* str) { command_precis_ = str; }
00194 
00195   //: Set the (possibly long) text used to document the command.
00196   // It is displayed at the end of the help page.
00197   void set_help_description(char const* str) { description_ = str; }
00198 
00199  public://protected:
00200   vcl_vector<vul_arg_base*> args_;
00201   vcl_string help_;
00202   vcl_string description_;
00203   vcl_string command_precis_;
00204   bool verbose_;
00205   autonomy autonomy_;
00206 
00207   void display_help( char const* progname= 0);
00208 
00209  private:
00210   vul_arg_info_list(vul_arg_info_list const &) {}
00211   void operator=(vul_arg_info_list const &) {}
00212 };
00213 
00214 #if defined(VCL_KAI) || defined(VCL_COMO) || defined(VCL_ICC)
00215 #define declare_specialization(T) \
00216 template<> void settype(vul_arg<T > &); \
00217 template<> void print_value(vcl_ostream &, vul_arg<T > const &); \
00218 template<> int  parse(vul_arg<T > *, char **)
00219 
00220 declare_specialization(bool);
00221 declare_specialization(int);
00222 declare_specialization(unsigned);
00223 declare_specialization(char*);
00224 declare_specialization(char const*);
00225 declare_specialization(float);
00226 declare_specialization(double);
00227 declare_specialization(vcl_list<int>);
00228 declare_specialization(vcl_vector<int>);
00229 declare_specialization(vcl_vector<unsigned>);
00230 declare_specialization(vcl_vector<double>);
00231 declare_specialization(vcl_string);
00232 
00233 #undef declare_specialization
00234 #endif // VCL_KAI
00235 
00236 #endif // vul_arg_h_

Generated on Thu Jan 10 14:41:00 2008 for core/vul by  doxygen 1.4.4