#include "options.h" using namespace OptionLib; bool isValidKeyChar(char c) { return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '_' || c == '-'); } const std::string validateKey(const std::string &key) { for (char c : key) { if (!isValidKeyChar(c)) { throw std::invalid_argument("Options key contains invalid characters, must match [a-z0-9\\_\\-]"); } } return key; } __OptionBase::__OptionBase(const std::string &key) : key(validateKey(key)) {} void OptionsBase::registerOption(__OptionBase* opt) { options.push_back(opt); } const std::vector<__OptionBase*>& OptionsBase::getOptions() const { return options; } void OptionsBase::store(const std::string& filename, std::string) { std::ofstream file(filename); if(!comment.empty()) { file << "# " << comment << std::endl; } for (auto* opt : getOptions()) { file << opt->key << "="; opt->store(file); file << std::endl; } } void OptionsBase::read(const std::string& filename) { std::ifstream file(filename); std::unordered_map kv; std::string key, value, line; while (std::getline(file, line)) { if (line.size() < 1 || line[0] == '#') continue; // skip comment lines TODO make better auto pos = line.find('='); if (pos == std::string::npos) continue; // skip invalid lines std::string key = line.substr(0, pos); std::string value = line.substr(pos + 1); kv[key] = value; } for (auto* opt : getOptions()) { if (kv.count(opt->key)) { opt->setFromString(kv[opt->key]); } } }