Explorar o código

method to enforce float

Patrick Brosi %!s(int64=2) %!d(string=hai) anos
pai
achega
ca166b3446
Modificáronse 2 ficheiros con 35 adicións e 0 borrados
  1. 32 0
      ConfigFileParser.cpp
  2. 3 0
      ConfigFileParser.h

+ 32 - 0
ConfigFileParser.cpp

@@ -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

+ 3 - 0
ConfigFileParser.h

@@ -78,6 +78,7 @@ class ConfigFileParser {
78 78
   const std::string& getStr(Sec sec, const Key& key) const;
79 79
   int getInt(Sec sec, const Key& key) const;
80 80
   double getDouble(Sec sec, const Key& key) const;
81
+  double getPosDouble(Sec sec, const Key& key) const;
81 82
   bool getBool(Sec sec, const Key& key) const;
82 83
 
83 84
   std::vector<std::string> getStrArr(Sec sec, const Key& key, char del) const;
@@ -102,6 +103,8 @@ class ConfigFileParser {
102 103
   std::string trim(const std::string& str) const;
103 104
   bool toBool(std::string str) const;
104 105
 
106
+  bool isFloat(const std::string& str) const;
107
+
105 108
   void updateVals(size_t sec, const KeyVals& kvs);
106 109
   std::string relPath(const std::string& file, std::string curFile) const;
107 110
 };