about summary refs log tree commit diff
path: root/src/libutil/config.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/config.hh')
-rw-r--r--src/libutil/config.hh64
1 files changed, 45 insertions, 19 deletions
diff --git a/src/libutil/config.hh b/src/libutil/config.hh
index 6c8612f675c7..91962109100d 100644
--- a/src/libutil/config.hh
+++ b/src/libutil/config.hh
@@ -9,6 +9,8 @@ namespace nix {
 
 class Args;
 class AbstractSetting;
+class JSONPlaceholder;
+class JSONObject;
 
 /* A class to simplify providing configuration settings. The typical
    use is to inherit Config and add Setting<T> members:
@@ -51,9 +53,13 @@ public:
 
     void warnUnknownSettings();
 
-    StringMap getSettings();
+    StringMap getSettings(bool overridenOnly = false);
 
     void applyConfigFile(const Path & path, bool fatal = false);
+
+    void resetOverriden();
+
+    void toJSON(JSONObject & out);
 };
 
 class AbstractSetting
@@ -68,6 +74,8 @@ public:
 
     int created = 123;
 
+    bool overriden = false;
+
 protected:
 
     AbstractSetting(
@@ -78,7 +86,7 @@ protected:
     virtual ~AbstractSetting()
     {
         // Check against a gcc miscompilation causing our constructor
-        // not to run.
+        // not to run (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80431).
         assert(created == 123);
     }
 
@@ -86,15 +94,14 @@ protected:
 
     virtual std::string to_string() = 0;
 
-    bool parseBool(const std::string & str);
-    std::string printBool(bool b);
-};
+    virtual void toJSON(JSONPlaceholder & out);
 
-struct DefaultSettingTag { };
+    bool isOverriden() { return overriden; }
+};
 
 /* A setting of type T. */
-template<typename T, typename Tag = DefaultSettingTag>
-class Setting : public AbstractSetting
+template<typename T>
+class BaseSetting : public AbstractSetting
 {
 protected:
 
@@ -102,42 +109,59 @@ 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;
 
     std::string to_string() override;
+
+    void toJSON(JSONPlaceholder & out) override;
 };
 
 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;
 
@@ -149,15 +173,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); }
 };
 
 }