diff options
Diffstat (limited to 'src/libutil/config.cc')
-rw-r--r-- | src/libutil/config.cc | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/src/libutil/config.cc b/src/libutil/config.cc index eef01bde2..116dd6bfe 100644 --- a/src/libutil/config.cc +++ b/src/libutil/config.cc @@ -8,9 +8,18 @@ namespace nix { bool Config::set(const std::string & name, const std::string & value) { + bool append = false; auto i = _settings.find(name); - if (i == _settings.end()) return false; - i->second.setting->set(value); + if (i == _settings.end()) { + if (hasPrefix(name, "extra-")) { + i = _settings.find(std::string(name, 6)); + if (i == _settings.end() || !i->second.setting->isAppendable()) + return false; + append = true; + } else + return false; + } + i->second.setting->set(value, append); i->second.setting->overriden = true; return true; } @@ -181,6 +190,12 @@ void AbstractSetting::convertToArg(Args & args, const std::string & category) } template<typename T> +bool BaseSetting<T>::isAppendable() +{ + return false; +} + +template<typename T> void BaseSetting<T>::convertToArg(Args & args, const std::string & category) { args.addFlag({ @@ -190,9 +205,18 @@ void BaseSetting<T>::convertToArg(Args & args, const std::string & category) .labels = {"value"}, .handler = {[=](std::string s) { overriden = true; set(s); }}, }); + + if (isAppendable()) + args.addFlag({ + .longName = "extra-" + name, + .description = description, + .category = category, + .labels = {"value"}, + .handler = {[=](std::string s) { overriden = true; set(s, true); }}, + }); } -template<> void BaseSetting<std::string>::set(const std::string & str) +template<> void BaseSetting<std::string>::set(const std::string & str, bool append) { value = str; } @@ -203,7 +227,7 @@ template<> std::string BaseSetting<std::string>::to_string() const } template<typename T> -void BaseSetting<T>::set(const std::string & str) +void BaseSetting<T>::set(const std::string & str, bool append) { static_assert(std::is_integral<T>::value, "Integer required."); if (!string2Int(str, value)) @@ -217,7 +241,7 @@ std::string BaseSetting<T>::to_string() const return std::to_string(value); } -template<> void BaseSetting<bool>::set(const std::string & str) +template<> void BaseSetting<bool>::set(const std::string & str, bool append) { if (str == "true" || str == "yes" || str == "1") value = true; @@ -248,9 +272,16 @@ template<> void BaseSetting<bool>::convertToArg(Args & args, const std::string & }); } -template<> void BaseSetting<Strings>::set(const std::string & str) +template<> void BaseSetting<Strings>::set(const std::string & str, bool append) { - value = tokenizeString<Strings>(str); + auto ss = tokenizeString<Strings>(str); + if (!append) value.clear(); + for (auto & s : ss) value.push_back(std::move(s)); +} + +template<> bool BaseSetting<Strings>::isAppendable() +{ + return true; } template<> std::string BaseSetting<Strings>::to_string() const @@ -258,7 +289,7 @@ template<> std::string BaseSetting<Strings>::to_string() const return concatStringsSep(" ", value); } -template<> void BaseSetting<StringSet>::set(const std::string & str) +template<> void BaseSetting<StringSet>::set(const std::string & str, bool append) { value = tokenizeString<StringSet>(str); } @@ -268,9 +299,9 @@ template<> std::string BaseSetting<StringSet>::to_string() const return concatStringsSep(" ", value); } -template<> void BaseSetting<StringMap>::set(const std::string & str) +template<> void BaseSetting<StringMap>::set(const std::string & str, bool append) { - value.clear(); + if (!append) value.clear(); auto kvpairs = tokenizeString<Strings>(str); for (auto & s : kvpairs) { @@ -281,6 +312,11 @@ template<> void BaseSetting<StringMap>::set(const std::string & str) } } +template<> bool BaseSetting<StringMap>::isAppendable() +{ + return true; +} + template<> std::string BaseSetting<StringMap>::to_string() const { Strings kvstrs; @@ -301,7 +337,7 @@ template class BaseSetting<Strings>; template class BaseSetting<StringSet>; template class BaseSetting<StringMap>; -void PathSetting::set(const std::string & str) +void PathSetting::set(const std::string & str, bool append) { if (str == "") { if (allowEmpty) |