00001 #include "configfile.h"
00002 #include <string>
00003 #include <math.h>
00004 #include "exception.h"
00005 ConfigFile::ConfigFile()
00006 {
00007 numLines = 1;
00008 }
00009
00010
00011 ConfigFile::~ConfigFile()
00012 {
00013
00014 }
00015
00016
00021 void ConfigFile::readFile(string fileName)
00022 {
00023 m_currFile=fileName;
00024 std::string str;
00025 std::ifstream file(fileName.c_str());
00026 if (file.eof())
00027 return;
00028 if (file.fail())
00029 {
00030 throw new Exception("Config file \"%s\" not found\nQuitting",fileName.c_str());
00031 }
00032 while (!file.eof())
00033 {
00034 TokenId token = getToken(file);
00035 if (token == COMMENT)
00036 continue;
00037 if (token == KEY)
00038 {
00039
00040 std::string strKey = this->strToken;
00041
00042 if (getToken(file) != ASSIGN_OPERATOR)
00043 {
00044 throw new Exception("ConfigFile Error: Expect the assignment operator \"=\" at line %d",numLines);
00045
00046 }
00047
00048 TokenValue tk;
00049 tk.tokenId = getToken(file);
00050 if (tk.tokenId != STRING && tk.tokenId != NUMBER)
00051 {
00052 throw new Exception("ConfigFile Error: Expect a STRING or NUMBER at line %d",numLines);
00053
00054 }
00055 tk.value = strToken;
00056 keysMap[strKey]=tk;
00057 }
00058 else if (token == END_OF_FILE)
00059 return;
00060 else if (token == INVALID_TOKEN)
00061 {
00062 throw new Exception("ConfigFile Error: Invalid token found at line %d",numLines);
00063
00064 }
00065
00066 }
00067 file.close();
00068 }
00069
00075 ConfigFile::TokenId ConfigFile::getToken(std::ifstream &file)
00076 {
00077 int c;
00078 begin:
00079 c = file.get();
00080 if (isblank(c))
00081 goto begin;
00082 else if (c == '\n')
00083 {
00084 numLines++;
00085 goto begin;
00086 }
00087 else if (c == '#')
00088 {
00089 file.unget();
00090 file.getline(strToken,TOKEN_SIZE);
00091 numLines++;
00092 return COMMENT;
00093 }
00094 else if (c == '=')
00095 return ASSIGN_OPERATOR;
00096 else if (isalpha(c))
00097 {
00098 char *p = strToken;
00099 while ( (isalnum(c) || c == '_' ) && (p-strToken) < TOKEN_SIZE )
00100 {
00101 *p++ = c;
00102 c=file.get();
00103 }
00104 if (p - strToken == TOKEN_SIZE)
00105 {
00106 throw new Exception("ConfigFile Error: Token too large at line %d\n",numLines);
00107
00108 }
00109 *p='\0';
00110 file.unget();
00111 return KEY;
00112 }
00113 else if (c == '"')
00114 {
00115 char *p = strToken;
00116 c=file.get();
00117 while (c != '"' && ((p-strToken) < TOKEN_SIZE) && !file.eof())
00118 {
00119 *p++ = c;
00120 c=file.get();
00121 }
00122 if ( (p - strToken) == TOKEN_SIZE)
00123 {
00124 throw new Exception("ConfigFile Error: Token too large at line %d\n",numLines);
00125
00126 }
00127 if (file.eof())
00128 {
00129 throw new Exception("ConfigFile Error: Unexpected End of File, the string value is not closed in the right way\n");
00130
00131 }
00132 *p='\0';
00133 return STRING;
00134 }
00135 else if (isdigit(c) || c == '+' || c == '-')
00136 {
00137 double d;
00138 file.unget();
00139 file >> d;
00140 if (file.fail())
00141 {
00142 throw new Exception("ConfigFile Error: Invalid Number at line %d\n",numLines);
00143
00144 }
00145 sprintf(strToken,"%g",d);
00146 return NUMBER;
00147 }
00148 else if (c == EOF)
00149 return END_OF_FILE;
00150 else
00151 return INVALID_TOKEN;
00152 }
00153
00154
00155
00160 std::string ConfigFile::getString(std::string key)
00161 {
00162 if (keysMap.find(key) != keysMap.end())
00163 {
00164 TokenValue &tk = keysMap[key];
00165 if (tk.tokenId != STRING)
00166 {
00167 throw new Exception("ConfigFile Error: Key value %s is not a string\n",key.c_str());
00168
00169 }
00170 return tk.value;
00171 }
00172 else
00173 {
00174 throw new Exception("ConfigFile Error: Key value %s not found\n",key.c_str());
00175
00176 }
00177 return "";
00178 }
00179
00184 double ConfigFile::getDouble(std::string key)
00185 {
00186 if (keysMap.find(key) != keysMap.end())
00187 {
00188 TokenValue &tk = keysMap[key];
00189 if (tk.tokenId != NUMBER)
00190 {
00191 throw new Exception("ConfigFile Error: Key %s is not a NUMBER\n",key.c_str());
00192
00193 }
00194 return atof(tk.value.c_str());
00195 }
00196 else
00197 {
00198 throw new Exception("ConfigFile Error: Key %s not found\n",key.c_str());
00199
00200 }
00201 return NAN;
00202 }
00203
00204
00205 double ConfigFile::getDouble(string key,double def)
00206 {
00207 if (keysMap.find(key) != keysMap.end())
00208 {
00209 TokenValue &tk = keysMap[key];
00210 if (tk.tokenId != NUMBER)
00211 {
00212 throw new Exception("ConfigFile Error: Key %s is not a NUMBER\n",key.c_str());
00213
00214 }
00215 return atof(tk.value.c_str());
00216 }
00217 else
00218 {
00219 return def;
00220
00221 }
00222 return NAN;
00223
00224 }
00225
00226
00227
00228
00229
00235 int ConfigFile::getInt(string key)
00236 {
00237 return (int) getDouble(key);
00238 }
00239
00246 int ConfigFile::getInt(string key,int def)
00247 {
00248 if (isDefined(key))
00249 return (int) getDouble(key);
00250 else return def;
00251 }
00252
00253
00254
00255 unsigned ConfigFile::getUnsigned(string key)
00256 {
00257 double dd = getDouble(key);
00258 if (dd < 0)
00259 throw new Exception("ConfigFile Error: Expect an unsigned integer for the Key %s\n",key.c_str());
00260 return (unsigned) dd;
00261 }
00262
00263
00268 bool ConfigFile::isDefined(string key)
00269 {
00270 return (keysMap.find(key) != keysMap.end());
00271 }
00272
00273