Main Page   Class Hierarchy   Compound List   File List   Compound Members  

commandoptions.h

00001 // A -*- C++ -*- class for parsing command line options.
00002 //
00003 // Copyright (C) 2001  Ole Laursen <olau@hardworking.dk>
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Library General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Library General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Library General Public
00016 // License along with this library; if not, write to the
00017 // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018 // Boston, MA  02111-1307  USA.
00019 
00020 
00021 #ifndef COMMANDOPTIONS_HEADER
00022 #define COMMANDOPTIONS_HEADER
00023 
00024 #include <vector>
00025 #include <string>
00026 #include <exception>
00027 #include <sstream>
00028 
00095 class commandoptions
00096 {
00097 public:
00118   // register an option with pointer to variable, long and short argument names, a
00119   // description of the option and the name of the argument to the option
00120   template <typename T>
00121   void register_option(T &par, std::string long_name, char short_name,
00122                        std::string des, std::string arg_name)
00123   {
00124     option_table.push_back(option(new updater<T>(par), long_name, short_name, des, arg_name));
00125   }
00126 
00147   void register_flag(bool &par, std::string long_name, char short_name, std::string des)
00148   {
00149     flag_table.push_back(flag(par, long_name, short_name, des));
00150   }
00151 
00164   template <typename T>
00165   void register_argument(T &par, std::string name, std::string des)
00166   {
00167     argument_table.push_back(argument(new updater<T>(par), name, des));
00168   }
00169 
00175   void process_command_line(int argc, const char *argv[]);
00176 
00178   ~commandoptions()
00179   {
00180     // make sure dynamically allocated stuff is cleaned up
00181     for (std::vector<updaterbase *>::iterator it = clean_up_table.begin();
00182          it != clean_up_table.end(); ++it)
00183       delete (*it);
00184   }
00185 
00186 
00187 private:
00188   // member helpers
00189 
00193   std::string requirify(std::string s)
00194   {
00195     return '<' + s + '>';
00196   }
00197 
00201   std::string optionalify(std::string s)
00202   {
00203     return '[' + s + ']';
00204   }
00205 
00209   std::string strip_path(std::string s);
00210 
00213   void print_usage(std::string executable);
00216   void print_help(std::string executable);
00217 
00218   // private data structures
00219   // first a few classes for updating a variable from a stream
00220   class updaterbase
00221   {
00222   public:
00223     virtual bool update(std::string s) = 0;
00224   };
00225 
00226   template <typename T>
00227   class updater: public updaterbase
00228   {
00229   public:
00230     updater(T &par):
00231       var(par)
00232     {}
00233 
00234     // update the contained variable through reference - return false upon failure
00235     virtual bool update(std::string s)
00236     {
00237       std::istringstream is(s);
00238       is >> var;
00239       if (!is)
00240         return false;
00241       else
00242         return true;
00243     }
00244     
00245   private:
00246     T &var;
00247   };
00248 
00249   // a structure for keeping a command line option
00250   struct option 
00251   {
00252     updaterbase *par;
00253     std::string long_name, des, arg_name;
00254     char short_name;
00255 
00256     option(updaterbase *p, std::string ln, char sn, std::string d, std::string an):
00257       par(p), long_name(ln), des(d), arg_name(an), short_name(sn)
00258     {}
00259     option(const option &o):
00260       par(o.par), long_name(o.long_name), des(o.des), arg_name(o.arg_name), short_name(o.short_name)
00261     {}
00262   };
00263 
00264   // one for keeping a flag
00265   struct flag
00266   {
00267     bool *par;
00268     std::string long_name, des;
00269     char short_name;
00270     
00271     flag(bool &p, std::string ln, char sn, std::string d):
00272       par(&p), long_name(ln), des(d), short_name(sn)
00273     {}
00274   };
00275   
00276   // and one for keeping an argument
00277   struct argument
00278   {
00279     updaterbase *par;
00280     std::string name, des;
00281     
00282     argument(updaterbase *p, std::string n, std::string d):
00283       par(p), name(n), des(d)
00284     {}
00285     argument(const argument &a):
00286       par(a.par), name(a.name), des(a.des)
00287     {}
00288   };
00289 
00291   std::vector<option> option_table;
00293   std::vector<flag> flag_table;
00295   std::vector<argument> argument_table;
00297   typedef std::vector<option>::iterator option_iterator;
00299   typedef std::vector<flag>::iterator flag_iterator;
00301   typedef std::vector<argument>::iterator argument_iterator;
00302 
00303   std::vector<updaterbase *> clean_up_table;
00304 };
00305 
00306 template <> class commandoptions::updater<std::string>: public commandoptions::updaterbase
00307 {
00308 public:
00309   updater(std::string &par):
00310     var(par)
00311   {}
00312 
00313   // update the contained variable through reference - return false upon failure
00314   virtual bool update(std::string s)
00315   {
00316     var = s;
00317     return true;
00318   }
00319     
00320 private:
00321   std::string &var;
00322 };
00323   
00325 // an exception class
00326 class commandoptions_error: std::exception
00327 {
00328 public:
00331   commandoptions_error(std::string s) throw(): msg(s)
00332   {}
00334   ~commandoptions_error() throw()
00335   {}
00336 
00338   virtual const char *what() const throw()
00339   {
00340     return msg.c_str();
00341   }
00342 
00343 private:
00344   std::string msg;
00345 };
00346 
00347 
00348 #endif // COMMANDOPTIONS_HEADER

Generated on Wed Jan 23 17:53:15 2002 for rubik by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001