libConfiguration.h
Go to the documentation of this file.00001 #ifndef __LIBCONFIGURATION_H__
00002 #define __LIBCONFIGURATION_H__
00003
00004 #include "HashTable.h"
00005 #include "String.h"
00006
00007 class Configuration
00008 {
00009 static String g_sfl;
00010 static bool g_bRead;
00011 static HashSS g_h;
00012
00013 private:
00014 static bool IsWhitespace(char ch)
00015 {
00016 return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
00017 }
00018
00019 static void ReadConfigFile()
00020 {
00021 UD("READING CONFIGURATION FILE: %s", g_sfl.V());
00022 g_bRead = true;
00023
00024 FILE *pfl = fopen(g_sfl, "r");
00025 char s[4096];
00026 while (fgets(s, sizeof(s) - 1, pfl) != NULL)
00027 {
00028
00029 int nch = strlen(s) - 1;
00030 while (nch >= 0 && IsWhitespace(s[nch]))
00031 {
00032 nch--;
00033 }
00034 s[nch + 1] = 0;
00035
00036
00037 char sParam[4096];
00038 int cch;
00039 if (sscanf(s, " %4095s %n", sParam, &cch) == 1)
00040 {
00041 if (sParam[0] != '#')
00042 {
00043 String sKey = ConfigEvalString(sParam);
00044 String sVar = ConfigEvalString(&s[cch]);
00045 g_h.Set(sKey, sVar);
00046 }
00047 }
00048 }
00049 fclose(pfl);
00050 }
00051
00052 static String ConfigEvalStringInternal(const char *&pch) __attribute__((noinline))
00053 {
00054
00055 VectorOf<char> vecch;
00056 while (*pch != 0)
00057 {
00058 if (*pch == '{')
00059 {
00060 pch++;
00061 String sT = ConfigEvalStringInternal(pch);
00062 if (sT.V()[0] == '$')
00063 {
00064 sT = g_h.Get(String(&sT.V()[1]), "");
00065 }
00066 else if (sT.V()[0] == '+')
00067 {
00068 ASSERT(sT.V()[1] == '+');
00069 String sVal = g_h.Get(String(&sT.V()[2]), "");
00070 sVal = String(sVal.AsInt() + 1);
00071 g_h.Set(String(&sT.V()[2]), sVal);
00072 sT = sVal + "";
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 vecch.Append(sT.V(), sT.C());
00087 }
00088 else if (*pch == '}')
00089 {
00090 vecch.Append('\0');
00091 return String(vecch.V());
00092 }
00093 else
00094 {
00095 vecch.Append(*pch);
00096 }
00097 pch++;
00098 }
00099 vecch.Append('\0');
00100 return String(vecch.V());
00101 }
00102
00103 static String ConfigEvalString(const char *pch)
00104 {
00105 return ConfigEvalStringInternal(pch);
00106 }
00107
00108 public:
00109 static String Describe()
00110 {
00111 if (!g_bRead)
00112 {
00113 ReadConfigFile();
00114 }
00115
00116 String s;
00117 String sKey;
00118 String sVal;
00119
00120 forhash(sKey,sVal,g_h)
00121 {
00122 s+=_LINE + StringF("%60s",sKey.V()) + " := " + sVal + LINE_;
00123 }
00124
00125 return s;
00126 }
00127
00128 static void SetConfigFile(String sfl)
00129 {
00130 g_sfl = sfl;
00131 g_bRead = false;
00132 }
00133
00134 static String GetConfigFile()
00135 {
00136 return g_sfl;
00137 }
00138
00139 static const char* ConfigValue(const char *s, const char* sDefault)
00140 {
00141 if (!g_bRead)
00142 {
00143 ReadConfigFile();
00144 }
00145
00146 String sOut;
00147
00148 if (g_h.GetInto(s, &sOut))
00149 {
00150 return sOut;
00151 }
00152 return sDefault;
00153 }
00154
00155 static Real ConfigValue(const char *s, const double& rDefault)
00156 {
00157 if (!g_bRead)
00158 {
00159 ReadConfigFile();
00160 }
00161
00162 String sOut;
00163
00164 if (g_h.GetInto(s, &sOut))
00165 {
00166 return sOut.AsReal();
00167 }
00168 return rDefault;
00169 }
00170
00171 static Real ConfigValue(const char *s, const float& rDefault)
00172 {
00173 if (!g_bRead)
00174 {
00175 ReadConfigFile();
00176 }
00177
00178 String sOut;
00179
00180 if (g_h.GetInto(s, &sOut))
00181 {
00182 return sOut.AsReal();
00183 }
00184 return rDefault;
00185 }
00186
00187 static int ConfigValue(const char *s, const int& zDefault)
00188 {
00189 if (!g_bRead)
00190 {
00191 ReadConfigFile();
00192 }
00193
00194 String sOut;
00195
00196 if (g_h.GetInto(s, &sOut))
00197 {
00198 return sOut.AsInt();
00199 }
00200 return zDefault;
00201 }
00202
00203 static bool ConfigValue(const char *s, const bool& bDefault)
00204 {
00205 if (!g_bRead)
00206 {
00207 ReadConfigFile();
00208 }
00209
00210 String sOut;
00211
00212 if (g_h.GetInto(s, &sOut))
00213 {
00214 return sOut == "true" || sOut == "yes";
00215 }
00216 return bDefault;
00217 }
00218 };
00219
00220 inline void SetConfigFile(String sfl)
00221 {
00222 Configuration::SetConfigFile(sfl);
00223 }
00224
00225 inline String GetConfigFile()
00226 {
00227 return Configuration::GetConfigFile();
00228 }
00229
00230 inline String DescribeConfiguration()
00231 {
00232 return Configuration::Describe();
00233 }
00234
00235 inline const char* ConfigValue(const char *s, const char* tDefault)
00236 {
00237 return Configuration::ConfigValue(s, tDefault);
00238 }
00239 template<class T>
00240 inline T ConfigValue(const char *s, const T& tDefault)
00241 {
00242 return Configuration::ConfigValue(s, tDefault);
00243 }
00244
00245 #endif //__LIBCONFIGURATION_H__