Rewrite config file parser

I noticed it didn't work correctly in some cases...
This commit is contained in:
sfan5 2020-03-27 19:32:30 +01:00
parent 04b9dffb11
commit ecc2b31f78
2 changed files with 32 additions and 50 deletions

View File

@ -10,7 +10,7 @@ inline std::string read_setting_default(const std::string &name, std::istream &i
{ {
try { try {
return read_setting(name, is); return read_setting(name, is);
} catch(std::runtime_error &e) { } catch(const std::runtime_error &e) {
return def; return def;
} }
} }

View File

@ -3,61 +3,43 @@
#include "util.h" #include "util.h"
inline std::string trim(const std::string &s) static inline std::string trim(const std::string &s)
{ {
size_t front = 0; auto isspace = [] (char c) -> bool { return c == ' ' || c == '\t' || c == '\r' || c == '\n'; };
while(s[front] == ' ' ||
s[front] == '\t' ||
s[front] == '\r' ||
s[front] == '\n'
)
++front;
size_t back = s.size(); size_t front = 0;
while(back > front && while(isspace(s[front]))
(s[back-1] == ' ' || ++front;
s[back-1] == '\t' || size_t back = s.size() - 1;
s[back-1] == '\r' || while(back > front && isspace(s[back]))
s[back-1] == '\n' --back;
)
)
--back;
return s.substr(front, back - front); return s.substr(front, back - front + 1);
} }
#define EOFCHECK() do { \
if (is.eof()) { \
std::ostringstream oss; \
oss << "Setting '" << name << "' not found."; \
throw std::runtime_error(oss.str()); \
} \
} while(0)
std::string read_setting(const std::string &name, std::istream &is) std::string read_setting(const std::string &name, std::istream &is)
{ {
char c; char linebuf[512];
char s[256]; while (is.good()) {
std::string nm, value; is.getline(linebuf, sizeof(linebuf));
next: for(char *p = linebuf; *p; p++) {
while((c = is.get()) == ' ' || c == '\t' || c == '\r' || c == '\n') if(*p != '#')
; continue;
EOFCHECK(); *p = '\0'; // Cut off at the first #
if(c == '#') // Ignore comments break;
is.ignore(0xffff, '\n'); }
EOFCHECK(); std::string line(linebuf);
s[0] = c; // The current char belongs to the name too
is.get(&s[1], 255, '='); auto pos = line.find('=');
is.ignore(1); // Jump over the = if (pos == std::string::npos)
EOFCHECK(); continue;
nm = trim(std::string(s)); auto key = trim(line.substr(0, pos));
is.get(s, 256, '\n'); if (key != name)
value = trim(std::string(s)); continue;
if(name == nm) return trim(line.substr(pos+1));
return value; }
else std::ostringstream oss;
goto next; oss << "Setting '" << name << "' not found";
throw std::runtime_error(oss.str());
} }
#undef EOFCHECK