From 1b5979ba100e935905f20a581fe33194dd3d01a7 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Fri, 18 Nov 2016 17:40:16 +0100 Subject: [PATCH] feat(config): Default reference values - Add fallback values to env/xrdb references: ${env:UNEXISTING:fallback value} ${xrdb:UNEXISTING:fallback value} - Replace ${BAR.key} with ${root.key} and display deprecation warning if the former is used --- examples/config | 2 +- examples/config.cmake | 2 +- include/components/config.hpp | 132 +++++++++++++++++++++------------- include/x11/xresources.hpp | 6 +- src/x11/xresources.cpp | 21 ++++-- 5 files changed, 101 insertions(+), 62 deletions(-) diff --git a/examples/config b/examples/config index d88231ec..7f4ed9d9 100644 --- a/examples/config +++ b/examples/config @@ -37,7 +37,7 @@ module-margin-left = 1 module-margin-right = 2 font-0 = fixed:pixelsize=10;0 -font-1 = unifont:size=6;-2 +font-1 = unifont:size=6:heavy;-2 font-2 = siji:pixelsize=10;0 modules-left = bspwm i3 mpd diff --git a/examples/config.cmake b/examples/config.cmake index ba154b61..6249a3bc 100644 --- a/examples/config.cmake +++ b/examples/config.cmake @@ -37,7 +37,7 @@ module-margin-left = 1 module-margin-right = 2 font-0 = fixed:pixelsize=10;0 -font-1 = unifont:size=6;-2 +font-1 = unifont:size=6:heavy;-2 font-2 = siji:pixelsize=10;0 modules-left = @MODULES_LEFT@ diff --git a/include/components/config.hpp b/include/components/config.hpp index eeaf4dc3..11a992a2 100644 --- a/include/components/config.hpp +++ b/include/components/config.hpp @@ -21,8 +21,7 @@ DEFINE_ERROR(key_error); class config { public: - explicit config(const logger& logger, const xresource_manager& xrm) - : m_logger(logger), m_xrm(xrm) {} + explicit config(const logger& logger, const xresource_manager& xrm) : m_logger(logger), m_xrm(xrm) {} void load(string file, string barname); string filepath() const; @@ -50,7 +49,7 @@ class config { auto str_val = m_ptree.get(build_path(section, key)); - return dereference_var(section, key, str_val, val.get()); + return dereference(section, key, str_val, val.get()); } /** @@ -62,8 +61,7 @@ class config { auto val = m_ptree.get_optional(build_path(section, key)); auto str_val = m_ptree.get_optional(build_path(section, key)); - return dereference_var( - section, key, str_val.get_value_or(""), val.get_value_or(default_value)); + return dereference(section, key, str_val.get_value_or(""), val.get_value_or(default_value)); } /** @@ -82,10 +80,9 @@ class config { vector vec; optional value; - while ((value = m_ptree.get_optional( - build_path(section, key) + "-" + to_string(vec.size()))) != boost::none) { + while ((value = m_ptree.get_optional(build_path(section, key) + "-" + to_string(vec.size()))) != boost::none) { auto str_val = m_ptree.get(build_path(section, key) + "-" + to_string(vec.size())); - vec.emplace_back(dereference_var(section, key, str_val, value.get())); + vec.emplace_back(dereference(section, key, str_val, value.get())); } if (vec.empty()) @@ -103,10 +100,9 @@ class config { vector vec; optional value; - while ((value = m_ptree.get_optional( - build_path(section, key) + "-" + to_string(vec.size()))) != boost::none) { + while ((value = m_ptree.get_optional(build_path(section, key) + "-" + to_string(vec.size()))) != boost::none) { auto str_val = m_ptree.get(build_path(section, key) + "-" + to_string(vec.size())); - vec.emplace_back(dereference_var(section, key, str_val, value.get())); + vec.emplace_back(dereference(section, key, str_val, value.get())); } if (vec.empty()) @@ -117,59 +113,93 @@ class config { protected: /** - * Find value of a config parameter defined as a reference - * variable using ${section.param} - * - * ${BAR.key} may be used to reference the current bar section - * ${self.key} may be used to reference the current section - * ${env:key} may be used to reference an environment variable - * ${xrdb:key} may be used to reference a variable in the X resource db + * Dereference value reference */ template - T dereference_var(string ref_section, string ref_key, string var, const T ref_val) const { - auto n = var.find("${"); - auto m = var.find("}"); + T dereference(string section, string key, string var, const T value) const { + if (var.substr(0, 2) != "${" || var.substr(var.length() - 1) != "}") { + return value; + } - if (n != 0 || m != var.length() - 1) - return ref_val; - - auto path = var.substr(2, m - 2); + auto path = var.substr(2, var.length() - 3); + size_t pos; if (path.find("env:") == 0) { - if (has_env(path.substr(4).c_str())) - return boost::lexical_cast(read_env(path.substr(4).c_str())); - return ref_val; + return dereference_env(path.substr(4), value); + } else if (path.find("xrdb:") == 0) { + return dereference_xrdb(path.substr(5), value); + } else if ((pos = path.find(".")) != string::npos) { + return dereference_local(path.substr(0, pos), path.substr(pos + 1)); + } else { + throw value_error("Invalid reference defined at [" + build_path(section, key) + "]"); } + } - if (path.find("xrdb:") == 0) { - if (std::is_same::value) - return boost::lexical_cast(m_xrm.get_string(path.substr(5))); - else if (std::is_same::value) - return boost::lexical_cast(m_xrm.get_float(path.substr(5))); - else if (std::is_same::value) - return boost::lexical_cast(m_xrm.get_int(path.substr(5))); - return ref_val; - } - - auto ref_path = build_path(ref_section, ref_key); - - if ((n = path.find(".")) == string::npos) - throw value_error("Invalid reference defined at [" + ref_path + "]"); - - auto section = path.substr(0, n); + /** + * Dereference local value reference defined using: + * ${root.key} + * ${self.key} + * ${section.key} + */ + template + T dereference_local(string section, string key) const { + if (section == "BAR") + m_logger.warn("${BAR.key} is deprecated. Use ${root.key} instead"); section = string_util::replace(section, "BAR", bar_section()); - section = string_util::replace(section, "self", ref_section); + section = string_util::replace(section, "root", bar_section()); + section = string_util::replace(section, "self", section); - auto key = path.substr(n + 1, path.length() - n - 1); - auto val = m_ptree.get_optional(build_path(section, key)); + auto path = build_path(section, key); + auto result = m_ptree.get_optional(path); - if (val == boost::none) - throw value_error("Unexisting reference defined at [" + ref_path + "]"); + if (result == boost::none) + throw value_error("Unexisting reference defined [" + path + "]"); - auto str_val = m_ptree.get(build_path(section, key)); + return dereference(section, key, m_ptree.get(path), result.get()); + } - return dereference_var(section, key, str_val, val.get()); + /** + * Dereference environment variable reference defined using: + * ${env:key} + * ${env:key:fallback value} + */ + template + T dereference_env(string var, T fallback) const { + size_t pos; + + if ((pos = var.find(":")) != string::npos) { + fallback = boost::lexical_cast(var.substr(pos + 1)); + var.erase(pos); + } + + if (has_env(var.c_str())) + return boost::lexical_cast(read_env(var.c_str())); + + return fallback; + } + + /** + * Dereference X resource db value defined using: + * ${xrdb:key} + * ${xrdb:key:fallback value} + */ + template + T dereference_xrdb(string var, T fallback) const { + size_t pos; + + if ((pos = var.find(":")) != string::npos) { + fallback = boost::lexical_cast(var.substr(pos + 1)); + var.erase(pos); + } + + if (std::is_same::value) + return boost::lexical_cast(m_xrm.get_string(var, boost::lexical_cast(fallback))); + else if (std::is_same::value) + return boost::lexical_cast(m_xrm.get_float(var, boost::lexical_cast(fallback))); + else if (std::is_same::value) + return boost::lexical_cast(m_xrm.get_int(var, boost::lexical_cast(fallback))); + return fallback; } private: diff --git a/include/x11/xresources.hpp b/include/x11/xresources.hpp index 3a52ff1c..a8ea14db 100644 --- a/include/x11/xresources.hpp +++ b/include/x11/xresources.hpp @@ -10,9 +10,9 @@ class xresource_manager { public: explicit xresource_manager(); - string get_string(string name) const; - float get_float(string name) const; - int get_int(string name) const; + string get_string(string name, string fallback = "") const; + float get_float(string name, float fallback = 0.0f) const; + int get_int(string name, int fallback = 0) const; protected: string load_value(string key, string res_type, size_t n) const; diff --git a/src/x11/xresources.cpp b/src/x11/xresources.cpp index fe42de72..c718c4eb 100644 --- a/src/x11/xresources.cpp +++ b/src/x11/xresources.cpp @@ -16,16 +16,25 @@ xresource_manager::xresource_manager() { return; } -string xresource_manager::get_string(string name) const { - return load_value(name, "String", 64); +string xresource_manager::get_string(string name, string fallback) const { + auto result = load_value(name, "String", 64); + if (result.empty()) + return fallback; + return result; } -float xresource_manager::get_float(string name) const { - return std::strtof(load_value(name, "String", 64).c_str(), 0); +float xresource_manager::get_float(string name, float fallback) const { + auto result = load_value(name, "String", 64); + if (result.empty()) + return fallback; + return strtof(result.c_str(), 0); } -int xresource_manager::get_int(string name) const { - return std::atoi(load_value(name, "String", 64).c_str()); +int xresource_manager::get_int(string name, int fallback) const { + auto result = load_value(name, "String", 64); + if (result.empty()) + return fallback; + return atoi(result.c_str()); } string xresource_manager::load_value(string key, string res_type, size_t n) const {