diff --git a/include/components/config.hpp b/include/components/config.hpp index 5f4a1acb..0981f8c0 100644 --- a/include/components/config.hpp +++ b/include/components/config.hpp @@ -24,9 +24,12 @@ DEFINE_ERROR(key_error); class config { public: + static constexpr const char* KEY_INHERIT{"inherit"}; + explicit config(const logger& logger, const xresource_manager& xrm) : m_logger(logger), m_xrm(xrm) {} void load(string file, string barname); + void copy_inherited(); string filepath() const; string bar_section() const; vector defined_bars() const; diff --git a/src/components/config.cpp b/src/components/config.cpp index a0e5d791..3b363c68 100644 --- a/src/components/config.cpp +++ b/src/components/config.cpp @@ -40,6 +40,47 @@ void config::load(string file, string barname) { m_logger.trace("config: Loaded %s", file); m_logger.trace("config: Current bar section: [%s]", bar_section()); + + copy_inherited(); +} + +/** + * Look for sections set up to inherit from a base section + * and copy the missing parameters + * + * [sub/seciton] + * inherit = base/section + */ +void config::copy_inherited() { + for (auto&& section : m_ptree) { + for (auto&& param : section.second) { + if (param.first.compare(KEY_INHERIT) == 0) { + // Find and validate parent section + auto inherit_section = param.second.get_value(); + + // Dereference value + inherit_section = dereference(section.first, param.first, inherit_section, inherit_section); + + if (inherit_section.empty()) { + throw value_error("[" + section.first + ".inherit] requires a value"); + } + auto base_section = m_ptree.get_child_optional(inherit_section); + if (!base_section || base_section.value().empty()) { + throw value_error("[" + section.first + ".inherit] points to an invalid section \"" + inherit_section + "\""); + } + + m_logger.trace("config: Copying missing params (sub=\"%s\", base=\"%s\")", section.first, inherit_section); + + // Iterate the the base and copy the parameters + // that hasn't been defined for the sub-section + for (auto&& base_param : *base_section) { + if (!section.second.get_child_optional(base_param.first)) { + section.second.put_child(base_param.first, base_param.second); + } + } + } + } + } } /**