-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathConfigReader.cc
76 lines (61 loc) · 2.27 KB
/
ConfigReader.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <fstream>
#include <regex.h>
#include "ConfigReader.h"
#define SUBREGS 3
#define LINEBUF 256
ConfigReader::ConfigReader(const std::string &path) : sections() {
regex_t section_expr, value_expr;
regmatch_t match_info[SUBREGS];
std::ifstream cfgfile;
char linebuf[LINEBUF];
if (regcomp(§ion_expr, "^\\[(.+)\\]$", REG_EXTENDED))
throw "Failed to compile section regex.";
if (regcomp(&value_expr, "^ *([^= ]+) *= *(.*) *$", REG_EXTENDED))
throw "Failed to compile value regex.";
cfgfile.open(path.c_str());
if (cfgfile.rdstate() != std::ios_base::goodbit)
throw "Failed to open config file.";
while (!cfgfile.getline(linebuf, sizeof(linebuf)).eof()) {
if (!regexec(§ion_expr, linebuf, SUBREGS, match_info, 0)) {
sections.push_back(
std::string(linebuf + match_info[1].rm_so,
match_info[1].rm_eo - match_info[1].rm_so));
} else if (!regexec(&value_expr, linebuf, SUBREGS, match_info, 0)) {
sections.back().add(
std::string(linebuf + match_info[1].rm_so,
match_info[1].rm_eo - match_info[1].rm_so),
std::string(linebuf + match_info[2].rm_so,
match_info[2].rm_eo - match_info[2].rm_so));
}
}
cfgfile.close();
regfree(§ion_expr);
regfree(&value_expr);
}
std::list<ConfigReader::Section>::const_iterator ConfigReader::begin() const {
return sections.begin();
}
std::list<ConfigReader::Section>::const_iterator ConfigReader::end() const {
return sections.end();
}
const ConfigReader::Section &ConfigReader::get(const std::string &name) const {
for (const auto &elem : sections) {
if (elem.name() == name)
return elem;
}
throw "ERROR: invalid section name.";
}
/////////////// ConfigReader::Section ////////////////
ConfigReader::Section::Section(const std::string &name_)
: _name(name_), entries() {}
void ConfigReader::Section::add(const std::string &k, const std::string &v) {
entries.insert(std::make_pair(k, v));
}
const std::string &ConfigReader::Section::get(const std::string &key) const {
auto e = entries.find(key);
if (e != entries.end())
return e->second;
throw "ERROR: invalid key name.";
}
const std::string &ConfigReader::Section::name() const { return _name; }
/* vim: set sw=2 sts=2 : */