Rewrote parse_ini_file

Is now regex-based, and supports sections.
Sections are ignored by default, but can be used by calling
parse_ini_file with a second bool param: false.
Sections will become key prefixes, separated from keys with a dot.
This commit is contained in:
Bob Polis 2023-12-10 18:32:17 +01:00
parent 8a9a8f2811
commit 954fca9e56
2 changed files with 17 additions and 9 deletions

View File

@ -76,19 +76,27 @@ string sc::file_get_contents(const string& path)
return {buf.data(), static_cast<string::size_type>(file_len)}; return {buf.data(), static_cast<string::size_type>(file_len)};
} }
map<string, string> sc::parse_ini_file(const string& path) map<string, string> sc::parse_ini_file(const string& path, bool ignore_sections)
{ {
map<string, string> result; map<string, string> result;
string prefix;
string line; string line;
ifstream file {path}; ifstream file {path};
file.exceptions(/*ios::failbit |*/ ios::badbit); // it seems that getline() will set failbit when confronted with eof immediately file.exceptions(ios::badbit); // it seems that getline() will set failbit when confronted with eof immediately
while (getline(file, line)) { while (getline(file, line)) {
if (line[0] == '[') continue; if (line[0] == '#') continue; // ignore comments
vector<string> parts {split(line, "=")}; if (line[0] == '[') {
if (parts.size() > 1) { if (ignore_sections) continue;
string key {trim(parts[0])}; regex section {R"(^\[(.*)\])"};
string value {trim(parts[1], " \"")}; smatch m;
result[key] = value; if (regex_search(line, m, section)) {
prefix = string{m[1]} + '.';
}
}
regex key_value_pat {R"(^\s*(.*)\s*=\s*("?)(.*)\2)"};
smatch match;
if (regex_search(line, match, key_value_pat)) {
result[prefix + string{match[1]}] = match[3];
} }
} }
return result; return result;

View File

@ -44,7 +44,7 @@ namespace sc {
std::string file_get_contents (const std::string& path); std::string file_get_contents (const std::string& path);
std::map<std::string, std::string> parse_ini_file (const std::string& path); std::map<std::string, std::string> parse_ini_file (const std::string& path, bool ignore_sections = true);
void create_dir (const std::string& path, void create_dir (const std::string& path,
int mode = 0777); int mode = 0777);