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