|  | @@ -2,6 +2,8 @@
 | 
	
		
			
			| 2 | 2 |  // info@patrickbrosi.de
 | 
	
		
			
			| 3 | 3 |  
 | 
	
		
			
			| 4 | 4 |  #include <algorithm>
 | 
	
		
			
			|  | 5 | +#include <cmath>
 | 
	
		
			
			|  | 6 | +#include <cstdlib>
 | 
	
		
			
			| 5 | 7 |  #include <fstream>
 | 
	
		
			
			| 6 | 8 |  #include <iostream>
 | 
	
		
			
			| 7 | 9 |  #include <limits>
 | 
	
	
		
			
			|  | @@ -230,14 +232,37 @@ void ConfigFileParser::parse(std::istream& is, const std::string& path) {
 | 
	
		
			
			| 230 | 232 |  const std::string& ConfigFileParser::getStr(Sec sec, const Key& key) const {
 | 
	
		
			
			| 231 | 233 |    return _kvs[_secs.find(sec)->second].find(key)->second.val;
 | 
	
		
			
			| 232 | 234 |  }
 | 
	
		
			
			|  | 235 | +
 | 
	
		
			
			| 233 | 236 |  // _____________________________________________________________________________
 | 
	
		
			
			| 234 | 237 |  int ConfigFileParser::getInt(Sec sec, const Key& key) const {
 | 
	
		
			
			| 235 | 238 |    return atoi(_kvs[_secs.find(sec)->second].find(key)->second.val.c_str());
 | 
	
		
			
			| 236 | 239 |  }
 | 
	
		
			
			|  | 240 | +
 | 
	
		
			
			| 237 | 241 |  // _____________________________________________________________________________
 | 
	
		
			
			| 238 | 242 |  double ConfigFileParser::getDouble(Sec sec, const Key& key) const {
 | 
	
		
			
			|  | 243 | +  auto v = _kvs[_secs.find(sec)->second].find(key)->second;
 | 
	
		
			
			|  | 244 | +  if (!isFloat(v.val)) {
 | 
	
		
			
			|  | 245 | +    throw ParseExc(v.line, v.pos, "floating number for '" + key + "'",
 | 
	
		
			
			|  | 246 | +                   std::string("'") + v.val + "'", v.file);
 | 
	
		
			
			|  | 247 | +  }
 | 
	
		
			
			| 239 | 248 |    return atof(_kvs[_secs.find(sec)->second].find(key)->second.val.c_str());
 | 
	
		
			
			| 240 | 249 |  }
 | 
	
		
			
			|  | 250 | +
 | 
	
		
			
			|  | 251 | +// _____________________________________________________________________________
 | 
	
		
			
			|  | 252 | +double ConfigFileParser::getPosDouble(Sec sec, const Key& key) const {
 | 
	
		
			
			|  | 253 | +  auto v = _kvs[_secs.find(sec)->second].find(key)->second;
 | 
	
		
			
			|  | 254 | +  if (!isFloat(v.val)) {
 | 
	
		
			
			|  | 255 | +    throw ParseExc(v.line, v.pos, "positive floating number for '" + key + "'",
 | 
	
		
			
			|  | 256 | +                   std::string("'") + v.val + "'", v.file);
 | 
	
		
			
			|  | 257 | +  }
 | 
	
		
			
			|  | 258 | +  double d = atof(_kvs[_secs.find(sec)->second].find(key)->second.val.c_str());
 | 
	
		
			
			|  | 259 | +  if (d < 0) {
 | 
	
		
			
			|  | 260 | +    throw ParseExc(v.line, v.pos, "positive floating number for '" + key + "'",
 | 
	
		
			
			|  | 261 | +                   std::string("'") + v.val + "'", v.file);
 | 
	
		
			
			|  | 262 | +  }
 | 
	
		
			
			|  | 263 | +  return d;
 | 
	
		
			
			|  | 264 | +}
 | 
	
		
			
			|  | 265 | +
 | 
	
		
			
			| 241 | 266 |  // _____________________________________________________________________________
 | 
	
		
			
			| 242 | 267 |  bool ConfigFileParser::getBool(Sec sec, const Key& key) const {
 | 
	
		
			
			| 243 | 268 |    return toBool(getStr(sec, key));
 | 
	
	
		
			
			|  | @@ -368,6 +393,13 @@ void ConfigFileParser::updateVals(size_t sec, const KeyVals& kvs) {
 | 
	
		
			
			| 368 | 393 |  }
 | 
	
		
			
			| 369 | 394 |  
 | 
	
		
			
			| 370 | 395 |  // _____________________________________________________________________________
 | 
	
		
			
			|  | 396 | +bool ConfigFileParser::isFloat(const std::string& str) const {
 | 
	
		
			
			|  | 397 | +  char* l = 0;
 | 
	
		
			
			|  | 398 | +  auto v = std::strtod(str.c_str(), &l);
 | 
	
		
			
			|  | 399 | +  return l != str.c_str() && *l == 0 && v != HUGE_VAL;
 | 
	
		
			
			|  | 400 | +}
 | 
	
		
			
			|  | 401 | +
 | 
	
		
			
			|  | 402 | +// _____________________________________________________________________________
 | 
	
		
			
			| 371 | 403 |  std::string ConfigFileParser::relPath(const std::string& file,
 | 
	
		
			
			| 372 | 404 |                                        std::string curF) const {
 | 
	
		
			
			| 373 | 405 |    // pass absolute paths through unchanged
 |