about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/globals.cc22
-rw-r--r--src/libstore/globals.hh39
-rw-r--r--src/libutil/config.cc53
-rw-r--r--src/libutil/config.hh48
-rw-r--r--src/nix-daemon/nix-daemon.cc2
5 files changed, 90 insertions, 74 deletions
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 6b9d077469..3242ef9d63 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -73,7 +73,7 @@ unsigned int Settings::getDefaultCores()
 
 const string nixVersion = PACKAGE_VERSION;
 
-template<> void Setting<SandboxMode>::set(const std::string & str)
+template<> void BaseSetting<SandboxMode>::set(const std::string & str)
 {
     if (str == "true") value = smEnabled;
     else if (str == "relaxed") value = smRelaxed;
@@ -81,7 +81,7 @@ template<> void Setting<SandboxMode>::set(const std::string & str)
     else throw UsageError("option '%s' has invalid value '%s'", name, str);
 }
 
-template<> std::string Setting<SandboxMode>::to_string()
+template<> std::string BaseSetting<SandboxMode>::to_string()
 {
     if (value == smEnabled) return "true";
     else if (value == smRelaxed) return "relaxed";
@@ -89,27 +89,11 @@ template<> std::string Setting<SandboxMode>::to_string()
     else abort();
 }
 
-template<> void Setting<unsigned int, Settings::MaxBuildJobsTag>::set(const std::string & str)
+void MaxBuildJobsSetting::set(const std::string & str)
 {
     if (str == "auto") value = std::max(1U, std::thread::hardware_concurrency());
     else if (!string2Int(str, value))
         throw UsageError("configuration setting ‘%s’ should be ‘auto’ or an integer", name);
 }
 
-template<> std::string Setting<unsigned int, Settings::MaxBuildJobsTag>::to_string()
-{
-    return std::to_string(value);
-}
-
-template<> void Setting<bool, Settings::CaseHackTag>::set(const std::string & str)
-{
-    value = parseBool(str);
-    nix::useCaseHack = true;
-}
-
-template<> std::string Setting<bool, Settings::CaseHackTag>::to_string()
-{
-    return printBool(value);
-}
-
 }
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index d3ecaadb63..b4f44de2e6 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -13,6 +13,39 @@ typedef enum { smEnabled, smRelaxed, smDisabled } SandboxMode;
 
 extern bool useCaseHack; // FIXME
 
+struct CaseHackSetting : public BaseSetting<bool>
+{
+    CaseHackSetting(Config * options,
+        const std::string & name,
+        const std::string & description,
+        const std::set<std::string> & aliases = {})
+        : BaseSetting<bool>(useCaseHack, name, description, aliases)
+    {
+        options->addSetting(this);
+    }
+
+    void set(const std::string & str) override
+    {
+        BaseSetting<bool>::set(str);
+        nix::useCaseHack = true;
+    }
+};
+
+struct MaxBuildJobsSetting : public BaseSetting<unsigned int>
+{
+    MaxBuildJobsSetting(Config * options,
+        unsigned int def,
+        const std::string & name,
+        const std::string & description,
+        const std::set<std::string> & aliases = {})
+        : BaseSetting<unsigned int>(def, name, description, aliases)
+    {
+        options->addSetting(this);
+    }
+
+    void set(const std::string & str) override;
+};
+
 class Settings : public Config {
 
     unsigned int getDefaultCores();
@@ -66,8 +99,7 @@ public:
        the log to show if a build fails. */
     size_t logLines = 10;
 
-    struct MaxBuildJobsTag { };
-    Setting<unsigned int, MaxBuildJobsTag> maxBuildJobs{this, 1, "build-max-jobs",
+    MaxBuildJobsSetting maxBuildJobs{this, 1, "build-max-jobs",
         "Maximum number of parallel build jobs. \"auto\" means use number of cores."};
 
     Setting<unsigned int> buildCores{this, getDefaultCores(), "build-cores",
@@ -268,8 +300,7 @@ public:
     Setting<bool> enableImportFromDerivation{this, true, "allow-import-from-derivation",
         "Whether the evaluator allows importing the result of a derivation."};
 
-    struct CaseHackTag { };
-    Setting<bool, CaseHackTag> useCaseHack{this, nix::useCaseHack, "use-case-hack",
+    CaseHackSetting useCaseHack{this, "use-case-hack",
         "Whether to enable a Darwin-specific hack for dealing with file name collisions."};
 
     Setting<unsigned long> connectTimeout{this, 0, "connect-timeout",
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index bf13729971..72b6cf8068 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -111,83 +111,72 @@ AbstractSetting::AbstractSetting(
 {
 }
 
-template<> void Setting<std::string>::set(const std::string & str)
+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)
-{
-    return b ? "true" : "false";
-}
-
-
-template<> std::string Setting<bool>::to_string()
-{
-    return printBool(value);
-}
-
-template<> void Setting<Strings>::set(const std::string & str)
+template<> void BaseSetting<Strings>::set(const std::string & str)
 {
     value = tokenizeString<Strings>(str);
 }
 
-template<> std::string Setting<Strings>::to_string()
+template<> std::string BaseSetting<Strings>::to_string()
 {
     return concatStringsSep(" ", value);
 }
 
-template<> void Setting<StringSet>::set(const std::string & str)
+template<> void BaseSetting<StringSet>::set(const std::string & str)
 {
     value = tokenizeString<StringSet>(str);
 }
 
-template<> std::string Setting<StringSet>::to_string()
+template<> std::string BaseSetting<StringSet>::to_string()
 {
     return concatStringsSep(" ", value);
 }
 
-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>;
 
 void PathSetting::set(const std::string & str)
 {
diff --git a/src/libutil/config.hh b/src/libutil/config.hh
index 952bf04b8a..130f59e2bd 100644
--- a/src/libutil/config.hh
+++ b/src/libutil/config.hh
@@ -90,17 +90,12 @@ protected:
 
     virtual std::string to_string() = 0;
 
-    bool parseBool(const std::string & str);
-    std::string printBool(bool b);
-
     bool isOverriden() { return overriden; }
 };
 
-struct DefaultSettingTag { };
-
 /* A setting of type T. */
-template<typename T, typename Tag = DefaultSettingTag>
-class Setting : public AbstractSetting
+template<typename T>
+class BaseSetting : public AbstractSetting
 {
 protected:
 
@@ -108,23 +103,21 @@ protected:
 
 public:
 
-    Setting(Config * options,
-        const T & def,
+    BaseSetting(const T & def,
         const std::string & name,
         const std::string & description,
         const std::set<std::string> & aliases = {})
         : AbstractSetting(name, description, aliases)
         , value(def)
-    {
-        options->addSetting(this);
-    }
+    { }
 
     operator const T &() const { return value; }
     operator T &() { return value; }
     const T & get() const { return value; }
     bool operator ==(const T & v2) const { return value == v2; }
     bool operator !=(const T & v2) const { return value != v2; }
-    void operator =(const T & v) { value = v; }
+    void operator =(const T & v) { assign(v); }
+    virtual void assign(const T & v) { value = v; }
 
     void set(const std::string & str) override;
 
@@ -132,18 +125,35 @@ public:
 };
 
 template<typename T>
-std::ostream & operator <<(std::ostream & str, const Setting<T> & opt)
+std::ostream & operator <<(std::ostream & str, const BaseSetting<T> & opt)
 {
     str << (const T &) opt;
     return str;
 }
 
 template<typename T>
-bool operator ==(const T & v1, const Setting<T> & v2) { return v1 == (const T &) v2; }
+bool operator ==(const T & v1, const BaseSetting<T> & v2) { return v1 == (const T &) v2; }
+
+template<typename T>
+class Setting : public BaseSetting<T>
+{
+public:
+    Setting(Config * options,
+        const T & def,
+        const std::string & name,
+        const std::string & description,
+        const std::set<std::string> & aliases = {})
+        : BaseSetting<T>(def, name, description, aliases)
+    {
+        options->addSetting(this);
+    }
+
+    void operator =(const T & v) { this->assign(v); }
+};
 
 /* A special setting for Paths. These are automatically canonicalised
    (e.g. "/foo//bar/" becomes "/foo/bar"). */
-class PathSetting : public Setting<Path>
+class PathSetting : public BaseSetting<Path>
 {
     bool allowEmpty;
 
@@ -155,15 +165,17 @@ public:
         const std::string & name,
         const std::string & description,
         const std::set<std::string> & aliases = {})
-        : Setting<Path>(options, def, name, description, aliases)
+        : BaseSetting<Path>(def, name, description, aliases)
         , allowEmpty(allowEmpty)
     {
-        set(value);
+        options->addSetting(this);
     }
 
     void set(const std::string & str) override;
 
     Path operator +(const char * p) const { return value + p; }
+
+    void operator =(const Path & v) { this->assign(v); }
 };
 
 }
diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc
index 5c2641eac6..07ad0b45b3 100644
--- a/src/nix-daemon/nix-daemon.cc
+++ b/src/nix-daemon/nix-daemon.cc
@@ -440,7 +440,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
         settings.keepGoing = readInt(from);
         settings.tryFallback = readInt(from);
         verbosity = (Verbosity) readInt(from);
-        settings.maxBuildJobs = readInt(from);
+        settings.maxBuildJobs.assign(readInt(from));
         settings.maxSilentTime = readInt(from);
         settings.useBuildHook = readInt(from) != 0;
         settings.verboseBuild = lvlError == (Verbosity) readInt(from);