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