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