00001 #ifndef _config_H_
00002 #define _config_H_
00003 #include <std/strings.H>
00004 #include <std/config.H>
00005 #include "std/strstream.H" 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 class CONFIGmapbase {
00017    public:
00018       virtual ~CONFIGmapbase() {}
00019       virtual void remap(Cstr_ptr &newval) = 0;
00020 };
00021 
00022 class DllImpExp CONFIG {
00023  private:
00024           HASH<str_ptr> _entries;
00025    static CONFIG  *_config;
00026 
00027  public:
00028           void     read_file(istream &cfgfile);
00029 
00030                    CONFIG();
00031           void     add_config_line(Cstr_ptr &line);
00032           str_ptr *register_map  (Cstr_ptr &name, CONFIGmapbase *);
00033           void     unregister_map(Cstr_ptr &,     CONFIGmapbase *) {}
00034    static CONFIG  *mainconfig()       { if (!_config) _config = new CONFIG;
00035                                         return _config; }
00036    static void     init(int &argc, char **argv);
00037   
00038    
00039    
00040    static void     init_with_filenames(int &argc, char **argv);
00041 };
00042 
00043 template <class T>
00044 static inline
00045 bool
00046 decode_it(Cstr_ptr &str, T &v) {
00047    istrstream istr(**str);
00048    istr >> v;
00049    return !istr ? false : true;
00050 }
00051 
00052 static inline bool decode_it(Cstr_ptr &str, str_ptr &v) {v = str; return true;}
00053 extern DllImpExp void CONFIGmissing(Cstr_ptr &);
00054 
00055 #ifdef GLUEBASE_VER
00056 extern DllImpExp void CONFIGnotread(Cstr_ptr &);
00057 #endif
00058 
00059 template <class V>
00060 class CONFIGmap : public CONFIGmapbase {
00061    Cstr_ptr  n_;
00062    V        &v_;
00063  public:
00064    CONFIGmap(Cstr_ptr &name, V &variable, bool warn=true):n_(name),v_(variable)
00065    {
00066      str_ptr *ret = CONFIG::mainconfig()->register_map(n_, this);
00067      if (ret) {
00068        remap(*ret);  
00069      } else if (warn)
00070        CONFIGmissing(n_);
00071    }
00072   
00073    virtual ~CONFIGmap() { CONFIG::mainconfig()->unregister_map(n_, this); };
00074    virtual void remap(Cstr_ptr &myval) {
00075       if (!decode_it(myval, v_)) {
00076          cerr << "Garbled config file entry \"" << myval << "\" for  tag \""
00077               << n_ << "\".\n";
00078       }
00079    }
00080 };
00081 
00082 template <class V>
00083 class CONFIGget : public CONFIGmapbase {
00084   V        v_;
00085   Cstr_ptr n_;
00086 public:
00087   CONFIGget(Cstr_ptr &n, const V &dflt, bool warn=true)
00088     : v_(dflt), n_(n)
00089   { 
00090     str_ptr *ret = CONFIG::mainconfig()->register_map(n, this);
00091     if (ret) {
00092       remap(*ret);
00093     } else if (warn)
00094       CONFIGmissing(n);
00095   }
00096   
00097   virtual     ~CONFIGget()  { CONFIG::mainconfig()->unregister_map(n_, this); };
00098   
00099   V            operator *()           { return v_; }
00100   virtual void remap(Cstr_ptr &myval) {
00101     if (!decode_it(myval, v_)) {
00102       cerr << "Garbled config file entry \"" << myval
00103        << "\" for  tag \"" << n_ << "\".\n";
00104     }
00105   }
00106 };
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 #if (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x500) || \
00125     (defined(__GNUC__) && (__GNUC__ > 2 || \
00126                          (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)))
00127 #define QUOTED_STRING const char *
00128 #else
00129 #define QUOTED_STRING char *
00130 #endif
00131 inline str_ptr CONFIGval(QUOTED_STRING n, QUOTED_STRING dflt="", bool warn=true)
00132    { return *CONFIGget<str_ptr>(n,str_ptr(dflt),warn); }
00133 #if defined(WIN32) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x500)
00134    
00135 inline str_ptr CONFIGval(str_ptr &n, QUOTED_STRING dflt="", bool warn=true) 
00136    { return *CONFIGget<str_ptr>(n,str_ptr(dflt),warn); }
00137 #endif
00138 inline str_ptr CONFIGval(Cstr_ptr &n, QUOTED_STRING dflt="", bool warn=true) 
00139    { return *CONFIGget<str_ptr>(n,str_ptr(dflt),warn); }
00140 
00141 
00142 #ifdef _AIX
00143 template <class S, class V>
00144 V CONFIGval(S n, const V &dflt) 
00145    { return *CONFIGget<V>(n,dflt,true); }
00146 template <class S, class V>
00147 V CONFIGval(S n, const V &dflt, bool warn) 
00148    { return *CONFIGget<V>(n,dflt,warn); }
00149 #else
00150 template <class S, class V>
00151 V CONFIGval(S n, const V &dflt, bool warn=true) 
00152    { return *CONFIGget<V>(n,dflt,warn); }
00153 #endif
00154 
00155 inline str_ptr 
00156 CONFIGrecurse(Cstr_ptr &n, Cstr_ptr &dflt, bool warn=true)
00157 {
00158    str_ptr maps_to;
00159    if ((maps_to = CONFIGval(n, dflt, warn)) != dflt)
00160       return CONFIGrecurse(maps_to, maps_to, false);
00161    else
00162       return maps_to;
00163 }
00164 
00165 
00166 
00167 
00168 template <class V>
00169 inline V &
00170 CONFIGmapper(Cstr_ptr &name, V &var, const V &dflt)
00171 {
00172    var = dflt;
00173    new CONFIGmap<V>(name, var);
00174    return var;
00175 }
00176 
00177 #define CONFIG_DECLARE(VAR,DEFAULT) VAR = CONFIGmapper(str_ptr(#VAR), VAR, DEFAULT)
00178 
00179 #endif