aboutsummaryrefslogtreecommitdiff
path: root/lib/settings
diff options
context:
space:
mode:
Diffstat (limited to 'lib/settings')
-rw-r--r--lib/settings/configuration.cpp70
-rw-r--r--lib/settings/configuration.h11
-rw-r--r--lib/settings/settings.qbs1
3 files changed, 58 insertions, 24 deletions
diff --git a/lib/settings/configuration.cpp b/lib/settings/configuration.cpp
index 543ea60..9d53581 100644
--- a/lib/settings/configuration.cpp
+++ b/lib/settings/configuration.cpp
@@ -22,10 +22,18 @@
#include <libconfig.h++>
#include <sstream>
+using namespace libconfig;
+
Configuration::Configuration()
{
- m_userCfg = new libconfig::Config();
- m_defaultCfg = new libconfig::Config();
+ m_userCfg = new Config();
+#ifdef C_LIKE_CONFIG
+ m_userCfg->setOptions(Config::OptionSemicolonSeparators | Config::OptionOpenBraceOnSeparateLine);
+#endif
+ // fsync after writing and before closing
+ m_userCfg->setOption(Config::OptionFsync, true);
+
+ m_defaultCfg = new Config();
}
Configuration::~Configuration()
@@ -43,19 +51,30 @@ bool Configuration::readUserConfiguration(const std::string &path)
m_userCfgPath = path;
try {
m_userCfg->readFile(path.c_str());
- } catch (libconfig::FileIOException) {
+ } catch (FileIOException) {
return false;
- } catch (libconfig::ParseException) {
+ } catch (ParseException) {
return false;
}
return true;
}
+bool Configuration::writeUserConfiguration(const std::string &path)
+{
+ m_userCfgPath = path;
+ try {
+ m_userCfg->writeFile(path.c_str());
+ } catch (FileIOException) {
+ return false;
+ }
+ return true;
+}
+
bool Configuration::readDefaultConfiguration(const std::string &data)
{
try {
m_defaultCfg->readString(data);
- } catch(libconfig::ParseException) {
+ } catch(ParseException) {
return false;
}
return true;
@@ -64,7 +83,7 @@ bool Configuration::readDefaultConfiguration(const std::string &data)
std::vector<std::string> Configuration::children(const char* name)
{
std::vector<std::string> groupNames;
- const libconfig::Setting &root = m_defaultCfg->lookup(name);
+ const Setting &root = m_defaultCfg->lookup(name);
for(auto i = root.begin(); i != root.end(); ++i) {
groupNames.push_back(std::string(i->getName()));
@@ -76,23 +95,23 @@ std::vector<std::string> Configuration::children(const char* name)
template<typename T>
std::optional<T> Configuration::value(const char* path) const
{
- libconfig::Config *conf = getConfig(path);
+ Config *conf = getConfig(path);
if(conf == nullptr) {
return std::nullopt;
}
// setting was found
- const libconfig::Setting &setting = conf->lookup(path);
+ const Setting &setting = conf->lookup(path);
std::optional<T> r;
// cast depending on type
// type checks are done during compile time
switch (setting.getType()) {
- case libconfig::Setting::TypeNone:
+ case Setting::TypeNone:
r = std::nullopt;
break;
- case libconfig::Setting::TypeInt:
+ case Setting::TypeInt:
// int, unsigned int, long, unsigned long
if constexpr(std::is_same_v<T, std::string>) {
r = std::optional<std::string>(std::to_string(static_cast<int>(setting)));
@@ -103,7 +122,7 @@ std::optional<T> Configuration::value(const char* path) const
}
break;
- case libconfig::Setting::TypeInt64:
+ case Setting::TypeInt64:
// int, unsigned int; long long, unsigned long long
if constexpr(std::is_same_v<T, std::string>) {
r = std::optional<std::string>(std::to_string(static_cast<long long>(setting)));
@@ -114,7 +133,7 @@ std::optional<T> Configuration::value(const char* path) const
}
break;
- case libconfig::Setting::TypeFloat:
+ case Setting::TypeFloat:
// float, double
if constexpr(std::is_same_v<T, std::string>) {
r = std::optional<std::string>(std::to_string(static_cast<float>(setting)));
@@ -125,7 +144,7 @@ std::optional<T> Configuration::value(const char* path) const
}
break;
- case libconfig::Setting::TypeString:
+ case Setting::TypeString:
// const char*, std::string
if constexpr(std::is_same<T, std::string>::value) {
r = std::optional<std::string>(static_cast<const char*>(setting));
@@ -134,7 +153,7 @@ std::optional<T> Configuration::value(const char* path) const
}
break;
- case libconfig::Setting::TypeBoolean:
+ case Setting::TypeBoolean:
// bool
if constexpr(std::is_same<T, std::string>::value) {
r = std::optional<std::string>(static_cast<bool>(setting) ? "true" : "false");
@@ -145,15 +164,15 @@ std::optional<T> Configuration::value(const char* path) const
}
break;
- case libconfig::Setting::TypeGroup:
+ case Setting::TypeGroup:
r = std::nullopt;
break;
- case libconfig::Setting::TypeArray:
+ case Setting::TypeArray:
r = std::nullopt;
break;
- case libconfig::Setting::TypeList:
+ case Setting::TypeList:
r = std::nullopt;
break;
}
@@ -181,7 +200,7 @@ template<typename T>
void Configuration::setValue(std::string path, const T &val)
{
if(m_userCfg->exists(path)) {
- libconfig::Setting &setting = m_userCfg->lookup(path);
+ Setting &setting = m_userCfg->lookup(path);
// compiler complained about operator= not taking unsinged ints, longs and long longs
if constexpr(std::is_unsigned_v<T> && !std::is_same_v<T, bool>) {
setting = static_cast<typename std::make_signed_t<T>>(val);
@@ -197,8 +216,8 @@ void Configuration::setValue(std::string path, const T &val)
// this will error out if entry being added is not in the default config
std::istringstream p(path);
- libconfig::Setting *userSetting = &m_userCfg->getRoot();
- libconfig::Setting *defaultSetting = &m_defaultCfg->getRoot();
+ Setting *userSetting = &m_userCfg->getRoot();
+ Setting *defaultSetting = &m_defaultCfg->getRoot();
std::string i;
while (std::getline(p, i, '.')) {
@@ -232,7 +251,7 @@ template void Configuration::setValue<bool>(std::string path, const bool &val);
template void Configuration::setValue<std::string>(std::string path, const std::string &val);
-libconfig::Config *Configuration::getConfig(const char* path) const
+Config *Configuration::getConfig(const char* path) const
{
if(m_userCfg->exists(path)) {
return m_userCfg;
@@ -242,3 +261,12 @@ libconfig::Config *Configuration::getConfig(const char* path) const
return nullptr;
}
}
+
+std::string &patchHome(std::string &path, const std::string &home)
+{
+ const size_t location = path.find("~");
+ if(location != std::string::npos) {
+ return path.replace(location, 1, home);
+ }
+ return path;
+}
diff --git a/lib/settings/configuration.h b/lib/settings/configuration.h
index e0f1872..548b816 100644
--- a/lib/settings/configuration.h
+++ b/lib/settings/configuration.h
@@ -18,8 +18,8 @@
**
******************************************************************************/
-#ifndef SETTINGS_H
-#define SETTINGS_H
+#ifndef CONFIGURATION_H
+#define CONFIGURATION_H
#include <optional>
#include <vector>
@@ -36,6 +36,8 @@ public:
~Configuration();
bool readUserConfiguration(const std::string &path);
+ bool writeUserConfiguration(const std::string &path);
+
bool readDefaultConfiguration(const std::string &data);
std::vector<std::string> children(const char *name = "");
@@ -54,6 +56,9 @@ private:
libconfig::Config *m_defaultCfg;
};
+// replace ~ with home
+std::string& patchHome(std::string &path, const std::string &home);
+
// instantiate functions
// this needs to be done because the implementation is in the cpp file
@@ -89,4 +94,4 @@ extern template void Configuration::setValue<bool>(std::string path, const bool
extern template void Configuration::setValue<std::string>(std::string path, const std::string &val);
-#endif // SETTINGS_H
+#endif // CONFIGURATION_H
diff --git a/lib/settings/settings.qbs b/lib/settings/settings.qbs
index e49339f..77e97fb 100644
--- a/lib/settings/settings.qbs
+++ b/lib/settings/settings.qbs
@@ -8,6 +8,7 @@ Project {
Depends { name: "cpp" }
+ cpp.defines: "C_LIKE_CONFIG"
cpp.cxxLanguageVersion: "c++17"
files: [