00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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