Browse Source

method to enforce float

Patrick Brosi 2 years ago
parent
commit
ca166b3446
2 changed files with 35 additions and 0 deletions
  1. 32 0
      ConfigFileParser.cpp
  2. 3 0
      ConfigFileParser.h

+ 32 - 0
ConfigFileParser.cpp

@@ -2,6 +2,8 @@
2
 // info@patrickbrosi.de
2
 // info@patrickbrosi.de
3
 
3
 
4
 #include <algorithm>
4
 #include <algorithm>
5
+#include <cmath>
6
+#include <cstdlib>
5
 #include <fstream>
7
 #include <fstream>
6
 #include <iostream>
8
 #include <iostream>
7
 #include <limits>
9
 #include <limits>
@@ -230,14 +232,37 @@ void ConfigFileParser::parse(std::istream& is, const std::string& path) {
230
 const std::string& ConfigFileParser::getStr(Sec sec, const Key& key) const {
232
 const std::string& ConfigFileParser::getStr(Sec sec, const Key& key) const {
231
   return _kvs[_secs.find(sec)->second].find(key)->second.val;
233
   return _kvs[_secs.find(sec)->second].find(key)->second.val;
232
 }
234
 }
235
+
233
 // _____________________________________________________________________________
236
 // _____________________________________________________________________________
234
 int ConfigFileParser::getInt(Sec sec, const Key& key) const {
237
 int ConfigFileParser::getInt(Sec sec, const Key& key) const {
235
   return atoi(_kvs[_secs.find(sec)->second].find(key)->second.val.c_str());
238
   return atoi(_kvs[_secs.find(sec)->second].find(key)->second.val.c_str());
236
 }
239
 }
240
+
237
 // _____________________________________________________________________________
241
 // _____________________________________________________________________________
238
 double ConfigFileParser::getDouble(Sec sec, const Key& key) const {
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
   return atof(_kvs[_secs.find(sec)->second].find(key)->second.val.c_str());
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
 bool ConfigFileParser::getBool(Sec sec, const Key& key) const {
267
 bool ConfigFileParser::getBool(Sec sec, const Key& key) const {
243
   return toBool(getStr(sec, key));
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
 std::string ConfigFileParser::relPath(const std::string& file,
403
 std::string ConfigFileParser::relPath(const std::string& file,
372
                                       std::string curF) const {
404
                                       std::string curF) const {
373
   // pass absolute paths through unchanged
405
   // pass absolute paths through unchanged

+ 3 - 0
ConfigFileParser.h

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