GetOpt.h

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB 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    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021    Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 
00025 #ifndef _EYEDB_GETOPT_H
00026 #define _EYEDB_GETOPT_H
00027 
00028 #include <string>
00029 #include <map>
00030 #include <iostream>
00031 #include <sstream>
00032 #include <iomanip>
00033 #include <vector>
00034 #include <unistd.h>
00035 
00036 // feel free to inherit from this class to define more precise type
00037 class OptionType {
00038 
00039 public:
00040   OptionType() { }
00041   OptionType(const std::string &name) : name(name) { }
00042   virtual bool checkValue(const std::string &value, const std::string &prog, std::ostream &err_os) const = 0;
00043 
00044   virtual const OptionType *clone() const = 0;
00045   const std::string getName() const {return name;}
00046 
00047   const std::string& getStringValue(const std::string &value) const {
00048     return value;
00049   }
00050 
00051   virtual std::string getDefaultValue() const {return "";}
00052 
00053   virtual ~OptionType() { }
00054 
00055 private:
00056   std::string name;
00057 };
00058 
00059 class OptionStringType : public OptionType {
00060 public:
00061   OptionStringType() : OptionType("string") { }
00062   virtual bool checkValue(const std::string &value, const std::string &prog, std::ostream &err_os) const { return true; }
00063 
00064   virtual const OptionType *clone() const {return new OptionStringType();}
00065 };
00066 
00067 class OptionIntType : public OptionType {
00068 public:
00069   OptionIntType() : OptionType("int") { }
00070 
00071   virtual bool checkValue(const std::string &value, const std::string &prog, std::ostream &err_os) const;
00072 
00073   int getIntValue(const std::string &value) const;
00074 
00075   virtual const OptionType *clone() const {return new OptionIntType();}
00076 };
00077 
00078 class OptionBoolType : public OptionType {
00079 public:
00080   OptionBoolType() : OptionType("bool") { }
00081 
00082   virtual bool checkValue(const std::string &value, const std::string &prog, std::ostream &err_os) const;
00083   bool getBoolValue(const std::string &value) const;
00084 
00085   virtual std::string getDefaultValue() const {return "true";}
00086 
00087   virtual const OptionType *clone() const {return new OptionBoolType();}
00088 };
00089 
00090 class OptionChoiceType : public OptionType {
00091 
00092 public:
00093   OptionChoiceType(const std::string &name,
00094                    const std::vector<std::string> &choice,
00095                    const std::string &defval = "") :
00096     OptionType(name), choice(choice), defval(defval) { }
00097 
00098   virtual bool checkValue(const std::string &value, const std::string &prog, std::ostream &err_os) const;
00099   virtual std::string getDefaultValue() const {return defval;}
00100 
00101   virtual const OptionType *clone() const {
00102     return new OptionChoiceType(getName(), choice, defval);
00103   }
00104 
00105 private:
00106   std::vector<std::string> choice;
00107   std::string defval;
00108 };
00109 
00110 class OptionValue {
00111 
00112 public:
00113   const OptionType *type;
00114 
00115   OptionValue() { type = 0; }
00116 
00117   OptionValue(const OptionType &_type, const std::string &_value) {
00118     set(_type, _value);
00119   }
00120 
00121   OptionValue(const OptionValue &ov) {
00122     type = 0;
00123     *this = ov;
00124   }
00125 
00126   OptionValue& operator=(const OptionValue &ov) {
00127     delete type;
00128     type = (ov.type ? ov.type->clone() : 0);
00129     value = ov.value;
00130     return *this;
00131   }
00132 
00133   void set(const OptionType &_type, const std::string &_value) {
00134     type = _type.clone();
00135     value = _value;
00136   }
00137 
00138   std::string value;
00139   bool def;
00140 
00141   ~OptionValue() {
00142     delete type;
00143   }
00144 };
00145 
00146 class OptionDesc {
00147 
00148 public:
00149   OptionDesc(const std::string &help = "",
00150              const std::string &value_name = "value") :
00151     value_name(value_name),
00152     help(help) { }
00153 
00154   std::string value_name;
00155   std::string help;
00156 };
00157 
00158 class Option {
00159 
00160 public:
00161   Option() : opt(0), flags(0), type(0) {}
00162 
00163   Option(char opt,
00164          const std::string &long_opt,
00165          const OptionType &type,
00166          unsigned int flags,
00167          const std::string &defval,
00168          const OptionDesc &optdesc = OptionDesc());
00169 
00170   Option(char opt, const std::string &long_opt,
00171          const OptionType &type = OptionBoolType(),
00172          unsigned int flags = 0,
00173          const OptionDesc &optdesc = OptionDesc());
00174 
00175   Option(char opt,
00176          const OptionType &type = OptionBoolType(),
00177          unsigned int flags = 0,
00178          const OptionDesc &optdesc = OptionDesc());
00179 
00180   Option(const std::string &long_opt,
00181          const OptionType &type = OptionBoolType(),
00182          unsigned int flags = 0,
00183          const OptionDesc &optdesc = OptionDesc());
00184 
00185   Option(char opt,
00186          const OptionType &type,
00187          unsigned int flags,
00188          const std::string &defval,
00189          const OptionDesc &optdesc = OptionDesc());
00190 
00191   Option(const std::string &long_opt,
00192          const OptionType &type,
00193          unsigned int flags,
00194          const std::string &defval,
00195          const OptionDesc &optdesc = OptionDesc());
00196 
00197   Option(const Option &o) {
00198     type = 0;
00199     *this = o;
00200   }
00201 
00202   Option& operator=(const Option &o) {
00203     delete type;
00204     type = (o.type ? o.type->clone() : 0);
00205     opt = o.opt;
00206     long_opt = o.long_opt;
00207     flags = o.flags;
00208     optdesc = o.optdesc;
00209     defval = o.defval;
00210     return *this;
00211   }
00212 
00213   enum {
00214     Mandatory = 0x1,
00215     MandatoryValue = 0x2,
00216     OptionalValue = 0x4,
00217 
00218     SetByDefault = 0x8,
00219 
00220     Usage = 0x100,
00221     Help = 0x200
00222   };
00223 
00224   char getOpt() const {return opt;}
00225   const std::string &getLongOpt() const {return long_opt;}
00226   const OptionType &getOptionType() const {return *type;}
00227   unsigned int getFlags() const {return flags;}
00228   const std::string &getDefaultValue() const {return defval;}
00229   const OptionDesc &getOptionDesc() const {return optdesc;}
00230 
00231   ~Option() { delete type; }
00232 
00233 private:
00234   char opt;
00235   std::string long_opt;
00236   const OptionType *type;
00237   unsigned int flags;
00238   OptionDesc optdesc;
00239   std::string defval;
00240 
00241   void init(char opt, const std::string &long_opt,
00242             const OptionType &type,
00243             unsigned int flags,
00244             const std::string &defval, const OptionDesc &optdesc);
00245 };
00246 
00247 class GetOpt {
00248 
00249 public:
00250   enum {
00251     SkipUnknownOption = 0x1,
00252     PurgeArgv = 0x2,
00253 
00254     DisplayUsageOnError = 0x10,
00255     DisplayHelpOnError = 0x20
00256   };
00257 
00258   GetOpt(const std::string &prog,
00259          unsigned int flags = PurgeArgv, std::ostream &err_os = std::cerr) :
00260     prog(prog), flags(flags), err_os(err_os), _maxlen(0) { }
00261 
00262   GetOpt(const std::string &prog,
00263          const std::vector<Option> &opts,
00264          unsigned int flags = PurgeArgv,
00265          std::ostream &err_os = std::cerr);
00266 
00267   GetOpt(const std::string &prog,
00268          const Option opts[], unsigned int opt_cnt,
00269          unsigned int flags = PurgeArgv,
00270          std::ostream &err_os = std::cerr);
00271 
00272   void add(const Option &opt);
00273 
00274   bool parse(int &argc, char *argv[]);
00275   bool parse(const std::string &prog, std::vector<std::string> &argv);
00276   
00277   void usage(const std::string &append = "\n",
00278              const std::string &prefix = "usage: ",
00279              std::ostream &os = std::cerr) const;
00280   void help(std::ostream &os = std::cerr, const std::string &indent = "  ") const;
00281 
00282   void helpLine(const std::string &option, const std::string &detail,
00283                 std::ostream &os = std::cerr, const std::string &indent = "  ") const;
00284 
00285   void displayOpt(const std::string &opt, const std::string &detail, std::ostream &os = std::cerr, const std::string &indent = "  ") const;
00286 
00287   static bool parseLongOpt(const std::string &arg, const std::string &opt,
00288                            std::string *value = 0);
00289 
00290   std::ostream &getErrorOS() {return err_os;}
00291 
00292   typedef std::map<std::string, OptionValue> Map;
00293   GetOpt::Map &getMap() {return map;}
00294 
00295   bool isset(const std::string &opt) const {return map.find(opt) != map.end();}
00296   const std::string &get(const std::string& opt) const {
00297     return (*map.find(opt)).second.value;
00298   }
00299 
00300   void adjustMaxLen(const std::string &opt);
00301   void adjustMaxLen(unsigned int maxlen);
00302 
00303 private:
00304   std::string prog;
00305   std::map<std::string, Option> opt_map, long_opt_map;
00306   std::vector<Option> opt_v;
00307   Map map;
00308   unsigned int flags;
00309   unsigned int add_map(const Option &opt, const std::string &value);
00310   void init_map(std::map<std::string, Option> &);
00311   unsigned int check_mandatory();
00312   std::ostream &err_os;
00313   unsigned int getMaxLen() const;
00314   void displayHelpOpt(const Option &opt, std::ostream &os) const;
00315   unsigned int _maxlen;
00316 };
00317 
00318 #endif

Generated on Mon Dec 22 18:15:55 2008 for eyedb by  doxygen 1.5.3