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