diff options
Diffstat (limited to 'src/config.cc')
| -rw-r--r-- | src/config.cc | 91 |
1 files changed, 49 insertions, 42 deletions
diff --git a/src/config.cc b/src/config.cc index 9824044..db42a7b 100644 --- a/src/config.cc +++ b/src/config.cc @@ -30,7 +30,7 @@ public: for (auto& dir : dirs) { std::string tmp_error; std::unordered_map<std::string,std::string> tmp_data; - if (load_file(Paths::join(dir, name_), &tmp_data, &tmp_error)) { + if (load_file(Paths::join(dir, name_), &tmp_data, &tmp_error, false)) { data.insert(tmp_data.begin(), tmp_data.end()); } else { if (good) { @@ -46,7 +46,7 @@ public: bool load_file(std::string const& filename) override { std::string error; std::unordered_map<std::string,std::string> data; - bool good = load_file(filename, &data, &error); + bool good = load_file(filename, &data, &error, true); return update(good, error, data); } @@ -105,59 +105,66 @@ private: static bool load_file(std::string const& filename, std::unordered_map<std::string, std::string>* data, - std::string* error) { + std::string* error, bool should_exist) { bool good = true; data->clear(); error->clear(); std::ifstream in(filename); - // Non existent file is not considered an error - if (in) { - std::string line; - uint32_t count = 0; - std::string key, value; - while (std::getline(in, line)) { - count++; - if (line.empty() || line[0] == '#') continue; - auto idx = line.find('='); - if (idx == 0 || idx == std::string::npos) { - std::stringstream ss; - if (idx == 0) { - ss << filename << ':' << count << ": Invalid line, starts with '='"; - } else { - ss << filename << ':' << count << ": Invalid line, no '=' found"; - } - *error = ss.str(); - good = false; - break; - } - size_t start = 0, end = idx; - key.assign(Strings::trim(line, start, end)); - if (data->count(key) > 0) { - std::stringstream ss; - ss << filename << ':' << count << ": '" << key << "' is already set"; - *error = ss.str(); - good = false; - break; - } - start = idx + 1; - end = line.size(); - Strings::trim(line, &start, &end); - if (line[start] == '"' && line[end - 1] == '"') { - value.assign(Strings::unquote(line, start, end)); + if (!in) { + if (should_exist) { + std::stringstream ss; + ss << "Unable to read: " << filename; + *error = ss.str(); + good = false; + } + return good; + } + + std::string line; + uint32_t count = 0; + std::string key, value; + while (std::getline(in, line)) { + count++; + if (line.empty() || line[0] == '#') continue; + auto idx = line.find('='); + if (idx == 0 || idx == std::string::npos) { + std::stringstream ss; + if (idx == 0) { + ss << filename << ':' << count << ": Invalid line, starts with '='"; } else { - value.assign(line.substr(start, end - start)); + ss << filename << ':' << count << ": Invalid line, no '=' found"; } - (*data)[key] = value; + *error = ss.str(); + good = false; + break; } - if (good && in.bad()) { + size_t start = 0, end = idx; + key.assign(Strings::trim(line, start, end)); + if (data->count(key) > 0) { std::stringstream ss; - ss << filename << ": I/O error: " << strerror(errno); + ss << filename << ':' << count << ": '" << key << "' is already set"; *error = ss.str(); good = false; + break; + } + start = idx + 1; + end = line.size(); + Strings::trim(line, &start, &end); + if (line[start] == '"' && line[end - 1] == '"') { + value.assign(Strings::unquote(line, start, end)); + } else { + value.assign(line.substr(start, end - start)); } - if (!good) data->clear(); + (*data)[key] = value; + } + if (good && in.bad()) { + std::stringstream ss; + ss << filename << ": I/O error: " << strerror(errno); + *error = ss.str(); + good = false; } + if (!good) data->clear(); return good; } |
