13 #include "ansicolor.h"
16 #include "configreader.h"
19 static const bool Debug =
false;
36 bool FileExists(
const char *filename)
39 return(stat(filename,&st) == 0);
44 ConfigReader::SubTree::SubTree(
ConfigReader &c,
const char *base_exp)
48 errors_at_init = config->errors;
51 ConfigReader::SubTree::SubTree(SubTree &s,
const char *base_exp)
54 const char *sep = (base_exp[0]==
'[')?
"" :
".";
55 base.printf(
"%s%s%s",s.base(),sep,base_exp);
56 errors_at_init = config->errors;
59 const char *ConfigReader::SubTree::getFullExp(
const char *exp)
61 const char *sep = (exp[0]==
'[')?
"" :
".";
62 full.printf(
"%s%s%s",base(),sep,exp);
66 const char *ConfigReader::SubTree::getStr(
const char *exp,
67 const char *default_val)
69 return(config->getStr(getFullExp(exp),default_val));
72 bool ConfigReader::SubTree::getBool(
const char *exp,
bool &val)
74 return(config->getBool(getFullExp(exp),val));
77 bool ConfigReader::SubTree::getInt(
const char *exp,
int &val)
79 return(config->getInt(getFullExp(exp),val));
82 bool ConfigReader::SubTree::getUInt(
const char* exp,
unsigned int& val)
84 return(config->getUInt(getFullExp(exp),val));
87 bool ConfigReader::SubTree::getReal(
const char *exp,
float &val)
89 return(config->getReal(getFullExp(exp),val));
92 bool ConfigReader::SubTree::getReal(
const char *exp,
double &val)
94 return(config->getReal(getFullExp(exp),val));
97 bool ConfigReader::SubTree::getPosReal(
const char *exp,
float &val)
99 return(config->getPosReal(getFullExp(exp),val));
102 bool ConfigReader::SubTree::getPosReal(
const char *exp,
double &val)
104 return(config->getPosReal(getFullExp(exp),val));
107 bool ConfigReader::SubTree::getInt(
const char *exp,
int &val,
110 return(config->getInt(getFullExp(exp),val,_min,_max));
113 bool ConfigReader::SubTree::getReal(
const char *exp,
float &val,
114 float _min,
float _max)
116 return(config->getReal(getFullExp(exp),val,_min,_max));
119 bool ConfigReader::SubTree::getReal(
const char *exp,
double &val,
120 double _min,
double _max)
122 return(config->getReal(getFullExp(exp),val,_min,_max));
125 ConfigReader::FileHeader::FileHeader(
const FileHeader &fh)
127 filename = fh.filename;
134 ConfigReader::ConfigReader()
139 num_readfiles_calls = 0;
144 ConfigReader::ConfigReader(
const char* _path)
146 path = (
char*) malloc(strlen(_path)+1);
150 num_readfiles_calls = 0;
155 bool ConfigReader::initLua()
159 if(!L)
return(
false);
170 void ConfigReader::closeLua()
176 void ConfigReader::clearWatches()
178 for(
unsigned i=0; i<files.size(); i++){
179 files[i].watch.remove();
183 void ConfigReader::reset()
188 num_readfiles_calls = 0;
192 void ConfigReader::addFile(
const char *filename,
unsigned flags)
197 fh.filename.add(filename);
199 fh.filename = filename;
202 fh.watch.watch(watch_files,filename);
208 void ConfigReader::showError(
int err_code,
const char *filename)
210 if(err_code == 0)
return;
212 AnsiColor::SetFgColor(stderr,AnsiColor::Yellow);
213 AnsiColor::Bold(stderr);
217 case LUA_ERRFILE: err_str=
"File not found";
break;
218 case LUA_ERRSYNTAX: err_str=
"Syntax error";
break;
219 case LUA_ERRMEM: err_str=
"Memory allocation error";
break;
220 case LUA_ERRRUN: err_str=
"Runtime error";
break;
221 case LUA_ERRERR: err_str=
"Error running error handler";
break;
222 default: err_str=
"Uknown error";
225 int t = lua_gettop(L);
226 if(lua_isstring(L,t)){
227 const char *str = lua_tolstring(L,t,NULL);
228 fprintf(stderr,
"ConfigReader: %s\n",str);
231 fprintf(stderr,
"ConfigReader: %s: %s\n",filename,err_str);
233 AnsiColor::Reset(stderr);
236 bool ConfigReader::readFile(
const char *filename,
unsigned flags)
239 printf(
"ConfigReader: reading \"%s\"\n",filename);
243 if((flags & Optional)!=0 && !FileExists(filename))
return(
true);
246 int ret = luaL_loadfile(L, filename);
248 showError(ret,filename);
251 ret = lua_pcall(L, 0, LUA_MULTRET, 0);
252 if(ret) showError(ret,filename);
260 bool ConfigReader::readFiles()
262 if(!L && !initLua())
return(
false);
268 for(
unsigned i=0; i<files.size(); i++){
269 FileHeader &fh = files[i];
270 if(fh.watch.isFileModified()){
271 fh.watch.rewatch(fh.filename());
273 if(!readFile(fh.filename(),fh.flags)){
278 if(ok) num_readfiles_calls++;
283 bool ConfigReader::isFileModified()
286 while(!modified && i<files.size()){
287 modified = files[i].watch.isFileModified();
304 void ConfigReader::eval(
const char *exp)
307 fexp.printf(
"_ans=(%s);",exp);
308 luaL_dostring(L,fexp());
309 lua_getglobal(L,
"_ans");
312 void ConfigReader::eval(
const char *exp0,
const char *exp1)
315 fexp.printf(
"_ans=(%s%s);",exp0,exp1);
316 luaL_dostring(L,fexp());
317 lua_getglobal(L,
"_ans");
320 const char *ConfigReader::getStr(
const char *exp,
const char *default_val)
324 const char *ret = NULL;
325 if(lua_isstring(L,-1)){
326 ret = lua_tostring(L,-1);
328 printf(
"ConfigReader: \"%s\" is not a string.\n",exp);
333 return(ret? ret : default_val);
336 bool ConfigReader::getBool(
const char *exp,
bool &val)
340 bool ok = lua_isboolean(L,-1);
342 val = (bool)lua_toboolean(L,-1);
344 printf(
"ConfigReader: \"%s\" is not a boolean.\n",exp);
352 bool ConfigReader::getInt(
const char *exp,
int &val)
356 bool ok = lua_isnumber(L,-1);
358 val = (int)rint(lua_tonumber(L,-1));
360 printf(
"ConfigReader: \"%s\" is not an integer.\n",exp);
368 bool ConfigReader::getUInt(
const char *exp,
unsigned int &val)
372 bool ok = lua_isnumber(L,-1);
374 val = (int)rint(lua_tonumber(L,-1));
376 printf(
"ConfigReader: \"%s\" is not an unsigned integer.\n",exp);
381 printf(
"ConfigReader: \"%s\" is not an integer.\n",exp);
389 bool ConfigReader::getReal(
const char *exp,
float &val)
393 bool ok = lua_isnumber(L,-1);
395 val = (float)lua_tonumber(L,-1);
397 printf(
"ConfigReader: \"%s\" is not a real number.\n",exp);
405 bool ConfigReader::getReal(
const char *exp,
double &val)
409 bool ok = lua_isnumber(L,-1);
411 val = (float)lua_tonumber(L,-1);
413 printf(
"ConfigReader: \"%s\" is not a real number.\n",exp);
421 bool ConfigReader::getInt(
const char *exp,
int &val,
int _min,
int _max)
423 if(!getInt(exp,val))
return(
false);
424 if(val<_min || val>_max){
425 printf(
"ConfigReader: %s=%d is out of range [%d,%d].\n",
427 val = bound(val,_min,_max);
434 bool ConfigReader::getPosReal(
const char *exp,
float &val)
436 if(!getReal(exp,val))
return(
false);
438 printf(
"ConfigReader: %s=%f is non-positive\n",exp,val);
446 bool ConfigReader::getPosReal(
const char *exp,
double &val)
449 if(!getReal(exp,val)){
450 printf(
"failure at %s\n",exp);
454 printf(
"ConfigReader: %s=%f is non-positive\n",exp,val);
462 bool ConfigReader::getReal(
const char *exp,
float &val,
float _min,
float _max)
464 if(!getReal(exp,val))
return(
false);
465 if(val<_min || val>_max){
466 printf(
"ConfigReader: %s=%f is out of range [%f,%f].\n",
468 val = bound(val,_min,_max);
475 bool ConfigReader::getReal(
const char *exp,
double &val,
double _min,
double _max)
477 if(!getReal(exp,val))
return(
false);
478 if(val<_min || val>_max){
479 printf(
"ConfigReader: %s=%f is out of range [%f,%f].\n",
481 val = bound(val,_min,_max);
488 bool ConfigReader::set(
const char *name,
int val)
491 fexp.printf(
"%s=%d;",name,val);
492 luaL_dostring(L,fexp());
495 return(getInt(name,v) && v==val);
498 bool ConfigReader::set(
const char *name,
double val)
501 fexp.printf(
"%s=%f;",name,val);
502 luaL_dostring(L,fexp());
505 return(getReal(name,v) && fabs(val-v)<1E-9);
508 void ConfigReader::addStandard()
511 addFile(
"config/common.cfg");
bool needUpdate(int &client_generation) const
int getGeneration() const
get generation count in terms of # of readFiles() updates