00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _cvc3__command_line_flags_h_
00022 #define _cvc3__command_line_flags_h_
00023
00024 #include <sstream>
00025 #include <vector>
00026 #include <map>
00027 #include "command_line_exception.h"
00028 #include "debug.h"
00029
00030 namespace CVC3 {
00031
00032
00033 typedef enum {
00034 CLFLAG_NULL,
00035 CLFLAG_BOOL,
00036 CLFLAG_INT,
00037 CLFLAG_STRING,
00038 CLFLAG_STRVEC
00039 } CLFlagType;
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 class CLFlag {
00053 private:
00054
00055 CLFlagType d_tp;
00056
00057 union {
00058 bool b;
00059 int i;
00060 std::string* s;
00061 std::vector<std::pair<std::string,bool> >* sv;
00062 } d_data;
00063
00064 bool d_modified;
00065
00066 std::string d_help;
00067 public:
00068
00069 CLFlag(bool b, const std::string& help)
00070 : d_tp(CLFLAG_BOOL), d_modified(0), d_help(help)
00071 { d_data.b = b; }
00072
00073 CLFlag(int i, const std::string& help)
00074 : d_tp(CLFLAG_INT), d_modified(0), d_help(help)
00075 { d_data.i = i; }
00076
00077 CLFlag(const std::string& s, const std::string& help)
00078 : d_tp(CLFLAG_STRING), d_modified(0), d_help(help) {
00079 d_data.s = new std::string(s);
00080 }
00081
00082 CLFlag(const char* s, const std::string& help)
00083 : d_tp(CLFLAG_STRING), d_modified(0), d_help(help) {
00084 d_data.s = new std::string((char*)s);
00085 }
00086
00087 CLFlag(const std::vector<std::pair<std::string,bool> >& sv,
00088 const std::string& help)
00089 : d_tp(CLFLAG_STRVEC), d_modified(0), d_help(help) {
00090 d_data.sv = new std::vector<std::pair<std::string,bool> >(sv);
00091 }
00092
00093 CLFlag(): d_tp(CLFLAG_NULL), d_modified(0), d_help("Undefined flag") { }
00094
00095 CLFlag(const CLFlag& f)
00096 : d_tp(f.d_tp), d_modified(f.d_modified), d_help(f.d_help) {
00097 switch(d_tp) {
00098 case CLFLAG_STRING:
00099 d_data.s = new std::string(*f.d_data.s); break;
00100 case CLFLAG_STRVEC:
00101 d_data.sv = new std::vector<std::pair<std::string,bool> >(*f.d_data.sv); break;
00102 default: d_data = f.d_data;
00103 }
00104 }
00105
00106 ~CLFlag() {
00107 switch(d_tp) {
00108 case CLFLAG_STRING: delete d_data.s; break;
00109 case CLFLAG_STRVEC: delete d_data.sv; break;
00110 default: break;
00111 }
00112 }
00113
00114 CLFlag& operator=(const CLFlag& f) {
00115 if(this == &f) return *this;
00116
00117 if(d_tp == f.d_tp) {
00118 switch(d_tp) {
00119 case CLFLAG_STRING: *d_data.s = *f.d_data.s; break;
00120 case CLFLAG_STRVEC: *d_data.sv = *f.d_data.sv; break;
00121 default: d_data = f.d_data;
00122 }
00123 } else {
00124 switch(d_tp) {
00125 case CLFLAG_STRING: delete d_data.s; break;
00126 case CLFLAG_STRVEC: delete d_data.sv; break;
00127 default: break;
00128 }
00129 switch(f.d_tp) {
00130 case CLFLAG_STRING: d_data.s = new std::string(*f.d_data.s); break;
00131 case CLFLAG_STRVEC:
00132 d_data.sv=new std::vector<std::pair<std::string,bool> >(*f.d_data.sv);
00133 break;
00134 default: d_data = f.d_data;
00135 }
00136 }
00137 d_tp = f.d_tp;
00138 d_modified = f.d_modified;
00139 d_help = f.d_help;
00140 return *this;
00141 }
00142
00143
00144 CLFlag& operator=(bool b) {
00145 DebugAssert(d_tp == CLFLAG_BOOL, "");
00146 d_data.b = b;
00147 d_modified = true;
00148 return *this;
00149 }
00150
00151
00152 CLFlag& operator=(int i) {
00153 DebugAssert(d_tp == CLFLAG_INT, "");
00154 d_data.i = i;
00155 d_modified = true;
00156 return *this;
00157 }
00158
00159
00160 CLFlag& operator=(const std::string& s) {
00161 DebugAssert(d_tp == CLFLAG_STRING, "");
00162 *d_data.s = s;
00163 d_modified = true;
00164 return *this;
00165 }
00166
00167
00168 CLFlag& operator=(const char* s) {
00169 DebugAssert(d_tp == CLFLAG_STRING, "");
00170 *d_data.s = s;
00171 d_modified = true;
00172 return *this;
00173 }
00174
00175
00176
00177 CLFlag& operator=(const std::pair<std::string,bool>& p) {
00178 DebugAssert(d_tp == CLFLAG_STRVEC, "");
00179 d_data.sv->push_back(p);
00180 d_modified = true;
00181 return *this;
00182 }
00183
00184
00185 CLFlag& operator=(const std::vector<std::pair<std::string,bool> >& sv) {
00186 DebugAssert(d_tp == CLFLAG_STRVEC, "");
00187 *d_data.sv = sv;
00188 d_modified = true;
00189 return *this;
00190 }
00191
00192
00193 CLFlagType getType() const { return d_tp; }
00194
00195
00196 bool modified() const { return d_modified; }
00197
00198
00199
00200
00201
00202
00203 const bool& getBool() const {
00204 DebugAssert(d_tp == CLFLAG_BOOL, "CLFlag::getBool: not a boolean flag");
00205 return d_data.b;
00206 }
00207
00208 const int& getInt() const {
00209 DebugAssert(d_tp == CLFLAG_INT, "CLFlag::getInt: not an integer flag");
00210 return d_data.i;
00211 }
00212
00213 const std::string& getString() const {
00214 DebugAssert(d_tp == CLFLAG_STRING,
00215 "CLFlag::getString: not a string flag");
00216 return *d_data.s;
00217 }
00218
00219 const std::vector<std::pair<std::string,bool> >& getStrVec() const {
00220 DebugAssert(d_tp == CLFLAG_STRVEC,
00221 "CLFlag::getStrVec: not a string vector flag");
00222 return *d_data.sv;
00223 }
00224
00225 const std::string& getHelp() const {
00226 return d_help;
00227 }
00228
00229 };
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 class CLFlags {
00241 private:
00242 typedef std::map<std::string, CLFlag> CharMap;
00243 CharMap d_map;
00244
00245
00246
00247
00248
00249 CLFlag& getFlag0(const std::string& name) {
00250 DebugAssert(d_map.count(name) > 0,
00251 "getFlag0("+name+"): there are no flags with this name");
00252 return (*d_map.find(name)).second;
00253 }
00254 public:
00255
00256
00257 void addFlag(const std::string& name, const CLFlag& f) {
00258 d_map[name] = f;
00259 }
00260
00261 size_t countFlags(const std::string& name) const {
00262 size_t res(0), len(name.size());
00263 for(CharMap::const_iterator i=d_map.begin(), iend=d_map.end();
00264 i!=iend; ++i) {
00265 if(strncmp(name.c_str(), (*i).first.c_str(), len) == 0) res++;
00266 }
00267 return res;
00268 }
00269
00270 size_t countFlags(const std::string& name,
00271 std::vector<std::string>& names) const {
00272 size_t res(0), len(name.size());
00273 for(CharMap::const_iterator i=d_map.begin(), iend=d_map.end();
00274 i!=iend; ++i) {
00275 if(strncmp(name.c_str(), (*i).first.c_str(), len) == 0) {
00276 names.push_back((*i).first);
00277 res++;
00278 }
00279 }
00280 return res;
00281 }
00282
00283
00284 const CLFlag& getFlag(const std::string& name) const {
00285 DebugAssert(d_map.count(name) > 0,
00286 "getFlag("+name+"): there are no flags with this name");
00287 return (*d_map.find(name)).second;
00288 }
00289
00290 const CLFlag& operator[](const std::string& name) const {
00291 return getFlag(name);
00292 }
00293
00294
00295
00296 void setFlag(const std::string& name, const CLFlag& f) {
00297 CLFlag& oldF(getFlag0(name));
00298 DebugAssert(oldF.getType() == f.getType(),
00299 "setFlag("+name+"): flag type doesn't match");
00300 oldF = f;
00301 }
00302
00303
00304 void setFlag(const std::string& name, bool b) { getFlag0(name) = b; }
00305 void setFlag(const std::string& name, int i) { getFlag0(name) = i; }
00306 void setFlag(const std::string& name, const std::string& s)
00307 { getFlag0(name) = s; }
00308 void setFlag(const std::string& name, const char* s)
00309 { getFlag0(name) = s; }
00310 void setFlag(const std::string& name, const std::pair<std::string,bool>& p)
00311 { getFlag0(name) = p; }
00312 void setFlag(const std::string& name,
00313 const std::vector<std::pair<std::string,bool> >& sv)
00314 { getFlag0(name) = sv; }
00315
00316 };
00317
00318 }
00319
00320 #endif