diff options
Diffstat (limited to 'src/libutil/config.cc')
-rw-r--r-- | src/libutil/config.cc | 100 |
1 files changed, 68 insertions, 32 deletions
diff --git a/src/libutil/config.cc b/src/libutil/config.cc index e7a810cec4d2..62c6433c741b 100644 --- a/src/libutil/config.cc +++ b/src/libutil/config.cc @@ -1,5 +1,6 @@ #include "config.hh" #include "args.hh" +#include "json.hh" namespace nix { @@ -9,6 +10,7 @@ void Config::set(const std::string & name, const std::string & value) if (i == _settings.end()) throw UsageError("unknown setting '%s'", name); i->second.setting->set(value); + i->second.setting->overriden = true; } void Config::addSetting(AbstractSetting * setting) @@ -22,6 +24,7 @@ void Config::addSetting(AbstractSetting * setting) auto i = initials.find(setting->name); if (i != initials.end()) { setting->set(i->second); + setting->overriden = true; initials.erase(i); set = true; } @@ -34,6 +37,7 @@ void Config::addSetting(AbstractSetting * setting) alias, setting->name); else { setting->set(i->second); + setting->overriden = true; initials.erase(i); set = true; } @@ -47,11 +51,11 @@ void Config::warnUnknownSettings() warn("unknown setting '%s'", i.first); } -StringMap Config::getSettings() +StringMap Config::getSettings(bool overridenOnly) { StringMap res; for (auto & opt : _settings) - if (!opt.second.isAlias) + if (!opt.second.isAlias && (!overridenOnly || opt.second.setting->overriden)) res.emplace(opt.first, opt.second.setting->to_string()); return res; } @@ -94,6 +98,23 @@ void Config::applyConfigFile(const Path & path, bool fatal) } catch (SysError &) { } } +void Config::resetOverriden() +{ + for (auto & s : _settings) + s.second.setting->overriden = false; +} + +void Config::toJSON(JSONObject & out) +{ + for (auto & s : _settings) + if (!s.second.isAlias) { + JSONObject out2(out.object(s.first)); + out2.attr("description", s.second.setting->description); + JSONPlaceholder out3(out2.placeholder("value")); + s.second.setting->toJSON(out3); + } +} + AbstractSetting::AbstractSetting( const std::string & name, const std::string & description, @@ -102,83 +123,98 @@ AbstractSetting::AbstractSetting( { } -template<> void Setting<std::string>::set(const std::string & str) +void AbstractSetting::toJSON(JSONPlaceholder & out) +{ + out.write(to_string()); +} + +template<typename T> +void BaseSetting<T>::toJSON(JSONPlaceholder & out) +{ + out.write(value); +} + +template<> void BaseSetting<std::string>::set(const std::string & str) { value = str; } -template<> std::string Setting<std::string>::to_string() +template<> std::string BaseSetting<std::string>::to_string() { return value; } -template<typename T, typename Tag> -void Setting<T, Tag>::set(const std::string & str) +template<typename T> +void BaseSetting<T>::set(const std::string & str) { static_assert(std::is_integral<T>::value, "Integer required."); if (!string2Int(str, value)) throw UsageError("setting '%s' has invalid value '%s'", name, str); } -template<typename T, typename Tag> -std::string Setting<T, Tag>::to_string() +template<typename T> +std::string BaseSetting<T>::to_string() { static_assert(std::is_integral<T>::value, "Integer required."); return std::to_string(value); } -bool AbstractSetting::parseBool(const std::string & str) +template<> void BaseSetting<bool>::set(const std::string & str) { if (str == "true" || str == "yes" || str == "1") - return true; + value = true; else if (str == "false" || str == "no" || str == "0") - return false; + value = false; else throw UsageError("Boolean setting '%s' has invalid value '%s'", name, str); } -template<> void Setting<bool>::set(const std::string & str) +template<> std::string BaseSetting<bool>::to_string() { - value = parseBool(str); + return value ? "true" : "false"; } -std::string AbstractSetting::printBool(bool b) +template<> void BaseSetting<Strings>::set(const std::string & str) { - return b ? "true" : "false"; + value = tokenizeString<Strings>(str); } - -template<> std::string Setting<bool>::to_string() +template<> std::string BaseSetting<Strings>::to_string() { - return printBool(value); + return concatStringsSep(" ", value); } -template<> void Setting<Strings>::set(const std::string & str) +template<> void BaseSetting<Strings>::toJSON(JSONPlaceholder & out) { - value = tokenizeString<Strings>(str); + JSONList list(out.list()); + for (auto & s : value) + list.elem(s); } -template<> std::string Setting<Strings>::to_string() +template<> void BaseSetting<StringSet>::set(const std::string & str) { - return concatStringsSep(" ", value); + value = tokenizeString<StringSet>(str); } -template<> void Setting<StringSet>::set(const std::string & str) +template<> std::string BaseSetting<StringSet>::to_string() { - value = tokenizeString<StringSet>(str); + return concatStringsSep(" ", value); } -template<> std::string Setting<StringSet>::to_string() +template<> void BaseSetting<StringSet>::toJSON(JSONPlaceholder & out) { - return concatStringsSep(" ", value); + JSONList list(out.list()); + for (auto & s : value) + list.elem(s); } -template class Setting<int>; -template class Setting<unsigned int>; -template class Setting<long>; -template class Setting<unsigned long>; -template class Setting<long long>; -template class Setting<unsigned long long>; +template class BaseSetting<int>; +template class BaseSetting<unsigned int>; +template class BaseSetting<long>; +template class BaseSetting<unsigned long>; +template class BaseSetting<long long>; +template class BaseSetting<unsigned long long>; +template class BaseSetting<bool>; void PathSetting::set(const std::string & str) { |