core/vul/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 #include <vxl_config.h>
00024 
00025 //: forward declare all classes and their helper functions.
00026 class vul_arg_info_list;
00027 template <class T> class vul_arg;
00028 template <class T> void settype     (vul_arg<T> &);
00029 template <class T> void print_value (vcl_ostream &, vul_arg<T> const &);
00030 template <class T> int  parse       (vul_arg<T>*, char**);
00031 
00032 //: This is the base class for the templated vul_arg<T>s
00033 class vul_arg_base
00034 {
00035  protected:
00036    struct required_option_type {}; // see constructors of vul_arg
00037 
00038  public:
00039   static required_option_type is_required;
00040 
00041   static void parse_deprecated(int& argc, char **& argv,
00042                                bool warn_about_unrecognized_arguments = true);
00043   static void include_deprecated(vul_arg_info_list& l);
00044 
00045   static void add_to_current(vul_arg_base* a);
00046   static void set_help_option( char const*str);
00047   static void set_help_description( char const*str);
00048   static void set_help_precis( char const*str);
00049   static void display_usage(char const* msg = 0);
00050   static void display_usage_and_exit(char const* msg = 0);
00051 
00052   friend class vul_arg_info_list;
00053 
00054   char const* option();
00055   char const* help();
00056 
00057   //: Returns true if arg was set on the command line.
00058   bool set() const;
00059 
00060   virtual vcl_ostream& print_value(vcl_ostream&) = 0;
00061 
00062  public:   // Avoid errors on some compilers that don't follow
00063            // protected: directive correctly with type_
00064 
00065   //: Static text describing type of option (e.g. bool or double).
00066   char const *type_;
00067  protected:
00068   //: After parsing, true iff value was set on command line.
00069   bool set_;
00070   //: if true, this flag must be set on command line.
00071   bool required_;
00072   //: Option flag including "-" or "--".
00073   vcl_string option_;
00074   //: Description of argument.
00075   vcl_string help_;
00076 
00077   vul_arg_base(vul_arg_info_list& l, char const* option_string,
00078                char const*helpstring, bool required= false);
00079   vul_arg_base(char const* option_string, char const*helpstring, bool required= false);
00080   virtual ~vul_arg_base() {}
00081 
00082   virtual int parse(char ** argv) = 0;
00083 };
00084 
00085 //: parse command-line arguments
00086 // vul_arg_parse simplifies the parsing of command-line arguments by combining
00087 // the variables with the option specifications.  To get a variable, you
00088 // simply name it along with its flag, a help string, and an optional
00089 // default value:
00090 // \code
00091 //      vul_arg<double> threshold("-t", "Intensity threshold", 1.25);
00092 // \endcode
00093 // Repeat this for any other arguments and then ask the base class to parse
00094 // the lot:
00095 // \code
00096 //      vul_arg_parse(argc,argv);
00097 // \endcode
00098 //
00099 // Now parameters such as threshold above can be referred to and will have
00100 // either the default value or the one supplied on the command line.
00101 //
00102 // The big design decision here was whether or not the args should collect
00103 // themselves into a global pool, so that the static vul_arg_base::parse can
00104 // find them, or whether there should be a local argPool which is passed to
00105 // each arg in order that it may add itself.  That would give a syntax like
00106 // \code
00107 //      vul_arg_info_list args;
00108 //      vul_arg<double> threshold(args, "-t", 1.25);
00109 //                                ^^^^^ passing args in
00110 //      args.parse(argc, argv, true);
00111 // \endcode
00112 // The latter is "better" but the former is easier to use so I chose it.
00113 //
00114 // Added by Geoff: call to vul_arg_base::set_help_option("-?") means that a
00115 // program call with something like aprog -? will display usage info derived
00116 // from the argument list.  Note: default is -? but can be anything.
00117 //
00118 void vul_arg_parse(int& argc, char **& argv,
00119                    bool warn_about_unrecognized_arguments = true);
00120 
00121 //: Add an externally supplied list of args to the global list.
00122 void vul_arg_include(vul_arg_info_list& l);
00123 
00124 //: Print all args, and usage messages.
00125 void vul_arg_display_usage_and_exit(char const* msg = 0);
00126 
00127 //: parse command-line arguments
00128 template <class T>
00129 class vul_arg : public vul_arg_base
00130 {
00131  private:
00132   void settype() { ::settype(*this); }
00133  public:
00134   T value_;// public so we don't have to worry about templated friends.
00135 
00136   //: Construct a vul_arg<T> with command-line switch and default value.
00137   // Command line switch \a option_string, and default value
00138   // \a default_value.  Add this argument to the global
00139   // list of arguments that vul_arg_base::parse() uses when it eventually
00140   // gets the command line.
00141   //
00142   // If \a option_string is null, then the argument is assigned to the
00143   // first plain word in the command line (warning: this causes problems for
00144   // T=char *, but that just means that you have to have a help string if you
00145   // want a default... good)
00146   vul_arg(char const* option_string = 0,
00147           char const* helpstring = 0,
00148           T default_value = T()
00149          )
00150     : vul_arg_base(option_string,helpstring, false),
00151       value_(default_value) { settype(); }
00152 
00153   //: As above, but add the arg to the list \a l, on which \c parse() can be called later.
00154   vul_arg(vul_arg_info_list & l,
00155           char const * option_string = 0,
00156           char const * helpstring = 0,
00157           T default_value = T() )
00158     : vul_arg_base(l, option_string, helpstring, false),
00159       value_(default_value) { settype(); }
00160 
00161   //: Dummy parameter to be passed during construction. It sets a flag as required.
00162 
00163   //: Construct a vul_arg<T> that user must set in command line.
00164   // Note that a default value does not make sense.
00165   // Add this argument to the global list of arguments that
00166   // vul_arg_base::parse() uses when it eventually gets the command line.
00167   //
00168   // As in the previous constructors, if \a option_string is null, then the argument is assigned to the
00169   // first plain word in the command line. However, this constructor adds a new option, allowing us to declare
00170   // a non-null flag, which can appears anywhere, and that is REQUIRED.
00171   //
00172   // Note that the parameters are not optional. This interface has been chosen to ensure backward compatibility.
00173   // \seealso is_required
00174   vul_arg(char const* option_string,
00175           char const* helpstring,
00176           required_option_type /*dummy*/)
00177     : vul_arg_base(option_string,helpstring, true),
00178       value_(T()) { settype(); }
00179 
00180   //: As above, but add the arg to the list \a l, on which \c parse() can be called later.
00181   vul_arg(vul_arg_info_list & l,
00182           char const * option_string,
00183           char const * helpstring,
00184           required_option_type /*dummy*/ )
00185     : vul_arg_base(l, option_string, helpstring, true),
00186       value_(T()) { settype(); }
00187 
00188   //: return the arg's current value, whether the default or the one from the command line.
00189   T      & operator () () { return value_; }
00190   T const& operator () () const { return value_; }
00191   //operator T& () { return value_; }
00192 
00193   //: returns number of args chomped, or -1 on failure.
00194   int parse(char ** argv) { return ::parse(this, argv); }
00195 
00196   //: print
00197   vcl_ostream& print_value(vcl_ostream &s) {
00198     ::print_value(s, *this);
00199     return s; // << flush
00200   }
00201 };
00202 
00203 //: a helper for vul_arg::parse.
00204 // Users might need it if they wish to parse several command lines.
00205 //
00206 class vul_arg_info_list
00207 {
00208  public:
00209   enum autonomy {
00210     subset,
00211     all
00212   };
00213   //: Construct an empty vul_arg_info_list.
00214   vul_arg_info_list(autonomy autonomy__ = subset)
00215     : help_("-?"), // default help operator!
00216       verbose_(false), autonomy_(autonomy__) {}
00217 
00218   ~vul_arg_info_list() {}
00219 
00220   void add(vul_arg_base* arg);
00221   void parse(int& argc, char **& argv, bool warn_about_unrecognized_arguments);
00222   void include(vul_arg_info_list& l);
00223   void verbose(bool on) { verbose_ = on; }
00224 
00225   void set_help_option(char const* str);
00226 
00227   //: Set the (short) text used to describe the command
00228   void set_help_precis(char const* str) { command_precis_ = str; }
00229 
00230   //: Set the (possibly long) text used to document the command.
00231   // It is displayed at the end of the help page.
00232   void set_help_description(char const* str) { description_ = str; }
00233 
00234  public://protected:
00235   vcl_vector<vul_arg_base*> args_;
00236   vcl_string help_;
00237   vcl_string description_;
00238   vcl_string command_precis_;
00239   bool verbose_;
00240   autonomy autonomy_;
00241 
00242   void display_help( char const* progname= 0);
00243 
00244  private:
00245   // Disallow assigning to objects of this class:
00246   vul_arg_info_list(vul_arg_info_list const &) {}
00247   vul_arg_info_list& operator=(vul_arg_info_list const &) { return *this; }
00248 };
00249 
00250 #if defined(VCL_KAI) || defined(VCL_COMO) || defined(VCL_ICC)
00251 #define declare_specialization(T) \
00252 template<> void settype(vul_arg<T > &); \
00253 template<> void print_value(vcl_ostream &, vul_arg<T > const &); \
00254 template<> int  parse(vul_arg<T > *, char **)
00255 
00256 declare_specialization(bool);
00257 declare_specialization(int);
00258 declare_specialization(unsigned);
00259 declare_specialization(char*);
00260 declare_specialization(char const*);
00261 declare_specialization(float);
00262 declare_specialization(double);
00263 declare_specialization(vcl_list<int>);
00264 declare_specialization(vcl_vector<int>);
00265 declare_specialization(vcl_vector<unsigned>);
00266 declare_specialization(vcl_vector<double>);
00267 declare_specialization(vcl_string);
00268 
00269 #ifdef VXL_HAS_INT_64
00270 declare_specialization(vxl_int_64);
00271 #endif
00272 
00273 #undef declare_specialization
00274 #endif // VCL_KAI
00275 
00276 #endif // vul_arg_h_