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
This commit is contained in:
Michael Carlberg 2016-11-18 17:40:16 +01:00
parent 95ddb84406
commit 1b5979ba10
5 changed files with 101 additions and 62 deletions

View File

@ -37,7 +37,7 @@ module-margin-left = 1
module-margin-right = 2 module-margin-right = 2
font-0 = fixed:pixelsize=10;0 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 font-2 = siji:pixelsize=10;0
modules-left = bspwm i3 mpd modules-left = bspwm i3 mpd

View File

@ -37,7 +37,7 @@ module-margin-left = 1
module-margin-right = 2 module-margin-right = 2
font-0 = fixed:pixelsize=10;0 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 font-2 = siji:pixelsize=10;0
modules-left = @MODULES_LEFT@ modules-left = @MODULES_LEFT@

View File

@ -21,8 +21,7 @@ DEFINE_ERROR(key_error);
class config { class config {
public: public:
explicit config(const logger& logger, const xresource_manager& xrm) explicit config(const logger& logger, const xresource_manager& xrm) : m_logger(logger), m_xrm(xrm) {}
: m_logger(logger), m_xrm(xrm) {}
void load(string file, string barname); void load(string file, string barname);
string filepath() const; string filepath() const;
@ -50,7 +49,7 @@ class config {
auto str_val = m_ptree.get<string>(build_path(section, key)); auto str_val = m_ptree.get<string>(build_path(section, key));
return dereference_var<T>(section, key, str_val, val.get()); return dereference<T>(section, key, str_val, val.get());
} }
/** /**
@ -62,8 +61,7 @@ class config {
auto val = m_ptree.get_optional<T>(build_path(section, key)); auto val = m_ptree.get_optional<T>(build_path(section, key));
auto str_val = m_ptree.get_optional<string>(build_path(section, key)); auto str_val = m_ptree.get_optional<string>(build_path(section, key));
return dereference_var<T>( return dereference<T>(section, key, str_val.get_value_or(""), val.get_value_or(default_value));
section, key, str_val.get_value_or(""), val.get_value_or(default_value));
} }
/** /**
@ -82,10 +80,9 @@ class config {
vector<T> vec; vector<T> vec;
optional<T> value; optional<T> value;
while ((value = m_ptree.get_optional<T>( while ((value = m_ptree.get_optional<T>(build_path(section, key) + "-" + to_string(vec.size()))) != boost::none) {
build_path(section, key) + "-" + to_string(vec.size()))) != boost::none) {
auto str_val = m_ptree.get<string>(build_path(section, key) + "-" + to_string(vec.size())); auto str_val = m_ptree.get<string>(build_path(section, key) + "-" + to_string(vec.size()));
vec.emplace_back(dereference_var<T>(section, key, str_val, value.get())); vec.emplace_back(dereference<T>(section, key, str_val, value.get()));
} }
if (vec.empty()) if (vec.empty())
@ -103,10 +100,9 @@ class config {
vector<T> vec; vector<T> vec;
optional<T> value; optional<T> value;
while ((value = m_ptree.get_optional<T>( while ((value = m_ptree.get_optional<T>(build_path(section, key) + "-" + to_string(vec.size()))) != boost::none) {
build_path(section, key) + "-" + to_string(vec.size()))) != boost::none) {
auto str_val = m_ptree.get<string>(build_path(section, key) + "-" + to_string(vec.size())); auto str_val = m_ptree.get<string>(build_path(section, key) + "-" + to_string(vec.size()));
vec.emplace_back(dereference_var<T>(section, key, str_val, value.get())); vec.emplace_back(dereference<T>(section, key, str_val, value.get()));
} }
if (vec.empty()) if (vec.empty())
@ -117,59 +113,93 @@ class config {
protected: protected:
/** /**
* Find value of a config parameter defined as a reference * Dereference value 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
*/ */
template <typename T> template <typename T>
T dereference_var(string ref_section, string ref_key, string var, const T ref_val) const { T dereference(string section, string key, string var, const T value) const {
auto n = var.find("${"); if (var.substr(0, 2) != "${" || var.substr(var.length() - 1) != "}") {
auto m = var.find("}"); return value;
}
if (n != 0 || m != var.length() - 1) auto path = var.substr(2, var.length() - 3);
return ref_val; size_t pos;
auto path = var.substr(2, m - 2);
if (path.find("env:") == 0) { if (path.find("env:") == 0) {
if (has_env(path.substr(4).c_str())) return dereference_env<T>(path.substr(4), value);
return boost::lexical_cast<T>(read_env(path.substr(4).c_str())); } else if (path.find("xrdb:") == 0) {
return ref_val; return dereference_xrdb<T>(path.substr(5), value);
} else if ((pos = path.find(".")) != string::npos) {
return dereference_local<T>(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<string, T>::value) * Dereference local value reference defined using:
return boost::lexical_cast<T>(m_xrm.get_string(path.substr(5))); * ${root.key}
else if (std::is_same<float, T>::value) * ${self.key}
return boost::lexical_cast<T>(m_xrm.get_float(path.substr(5))); * ${section.key}
else if (std::is_same<int, T>::value) */
return boost::lexical_cast<T>(m_xrm.get_int(path.substr(5))); template <typename T>
return ref_val; T dereference_local(string section, string key) const {
} if (section == "BAR")
m_logger.warn("${BAR.key} is deprecated. Use ${root.key} instead");
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);
section = string_util::replace(section, "BAR", bar_section()); 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 path = build_path(section, key);
auto val = m_ptree.get_optional<T>(build_path(section, key)); auto result = m_ptree.get_optional<T>(path);
if (val == boost::none) if (result == boost::none)
throw value_error("Unexisting reference defined at [" + ref_path + "]"); throw value_error("Unexisting reference defined [" + path + "]");
auto str_val = m_ptree.get<string>(build_path(section, key)); return dereference<T>(section, key, m_ptree.get<string>(path), result.get());
}
return dereference_var<T>(section, key, str_val, val.get()); /**
* Dereference environment variable reference defined using:
* ${env:key}
* ${env:key:fallback value}
*/
template <typename T>
T dereference_env(string var, T fallback) const {
size_t pos;
if ((pos = var.find(":")) != string::npos) {
fallback = boost::lexical_cast<T>(var.substr(pos + 1));
var.erase(pos);
}
if (has_env(var.c_str()))
return boost::lexical_cast<T>(read_env(var.c_str()));
return fallback;
}
/**
* Dereference X resource db value defined using:
* ${xrdb:key}
* ${xrdb:key:fallback value}
*/
template <typename T>
T dereference_xrdb(string var, T fallback) const {
size_t pos;
if ((pos = var.find(":")) != string::npos) {
fallback = boost::lexical_cast<T>(var.substr(pos + 1));
var.erase(pos);
}
if (std::is_same<string, T>::value)
return boost::lexical_cast<T>(m_xrm.get_string(var, boost::lexical_cast<string>(fallback)));
else if (std::is_same<float, T>::value)
return boost::lexical_cast<T>(m_xrm.get_float(var, boost::lexical_cast<float>(fallback)));
else if (std::is_same<int, T>::value)
return boost::lexical_cast<T>(m_xrm.get_int(var, boost::lexical_cast<int>(fallback)));
return fallback;
} }
private: private:

View File

@ -10,9 +10,9 @@ class xresource_manager {
public: public:
explicit xresource_manager(); explicit xresource_manager();
string get_string(string name) const; string get_string(string name, string fallback = "") const;
float get_float(string name) const; float get_float(string name, float fallback = 0.0f) const;
int get_int(string name) const; int get_int(string name, int fallback = 0) const;
protected: protected:
string load_value(string key, string res_type, size_t n) const; string load_value(string key, string res_type, size_t n) const;

View File

@ -16,16 +16,25 @@ xresource_manager::xresource_manager() {
return; return;
} }
string xresource_manager::get_string(string name) const { string xresource_manager::get_string(string name, string fallback) const {
return load_value(name, "String", 64); auto result = load_value(name, "String", 64);
if (result.empty())
return fallback;
return result;
} }
float xresource_manager::get_float(string name) const { float xresource_manager::get_float(string name, float fallback) const {
return std::strtof(load_value(name, "String", 64).c_str(), 0); 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 { int xresource_manager::get_int(string name, int fallback) const {
return std::atoi(load_value(name, "String", 64).c_str()); 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 { string xresource_manager::load_value(string key, string res_type, size_t n) const {