85 lines
2.1 KiB
C++
85 lines
2.1 KiB
C++
|
|
#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<std::string, std::string> 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]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void OptionsBase::parse(const int argc, const char ** argv) {
|
|
std::unordered_map<std::string, std::string> kv;
|
|
|
|
std::string key, value, line;
|
|
|
|
for(int i = 0; i < argc; i++) {
|
|
line = std::string(argv[i]);
|
|
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]);
|
|
}
|
|
}
|
|
} |