aboutsummaryrefslogtreecommitdiff
path: root/lib/settings/configuration.cpp
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2018-01-03 22:29:17 +0100
committerAqua-sama <aqua@iserlohn-fortress.net>2018-01-03 22:29:17 +0100
commit1e57c2b3f6bd2a4f1756150e669eedffc29cf13d (patch)
tree01f22e47b85e556cd4fae4431f578f9c38bb12ca /lib/settings/configuration.cpp
parentUpdated PKGBUILD (diff)
downloadsmolbote-1e57c2b3f6bd2a4f1756150e669eedffc29cf13d.tar.xz
Fixed crash with Settings dialog
- User Configuration gets completely written, instead of being just overrides
Diffstat (limited to 'lib/settings/configuration.cpp')
-rw-r--r--lib/settings/configuration.cpp171
1 files changed, 107 insertions, 64 deletions
diff --git a/lib/settings/configuration.cpp b/lib/settings/configuration.cpp
index 4603779..1fa1fbf 100644
--- a/lib/settings/configuration.cpp
+++ b/lib/settings/configuration.cpp
@@ -21,15 +21,14 @@ Configuration::Configuration()
// fsync after writing and before closing
m_userCfg->setOption(Config::OptionFsync, true);
+ // make sure the cfgPath is empty
+ m_userCfgPath = std::string();
+
m_defaultCfg = new Config();
}
Configuration::~Configuration()
{
- if(!m_userCfgPath.empty()) {
- m_userCfg->writeFile(m_userCfgPath.c_str());
- }
-
delete m_userCfg;
delete m_defaultCfg;
}
@@ -47,22 +46,42 @@ bool Configuration::readUserConfiguration(const std::string &path)
return true;
}
+bool Configuration::parse(const std::string &contents)
+{
+ try {
+ m_userCfg->readString(contents);
+ } catch (ParseException) {
+ return false;
+ }
+ return true;
+}
+
bool Configuration::writeUserConfiguration(const std::string &path)
{
m_userCfgPath = path;
try {
- m_userCfg->writeFile(path.c_str());
+ m_userCfg->writeFile(m_userCfgPath.c_str());
} catch (FileIOException) {
return false;
}
return true;
}
-bool Configuration::readDefaultConfiguration(const std::string &data)
+bool Configuration::writeIfNeeded()
{
try {
- m_defaultCfg->readString(data);
- } catch(ParseException) {
+ m_userCfg->writeFile(m_userCfgPath.c_str());
+ } catch (FileIOException) {
+ return false;
+ }
+ return true;
+}
+
+bool Configuration::parseDefaultConfiguration(const std::string &contents)
+{
+ try {
+ m_defaultCfg->readString(contents);
+ } catch (ParseException) {
return false;
}
return true;
@@ -71,7 +90,7 @@ bool Configuration::readDefaultConfiguration(const std::string &data)
std::vector<std::string> Configuration::childrenSettings(const char* name)
{
std::vector<std::string> groupNames;
- const Setting &root = m_defaultCfg->lookup(name);
+ const Setting &root = m_userCfg->lookup(name);
for(const Setting &setting : root) {
if(setting.getType() != Setting::TypeGroup) {
@@ -85,7 +104,7 @@ std::vector<std::string> Configuration::childrenSettings(const char* name)
std::vector<std::string> Configuration::childrenGroups(const char* name)
{
std::vector<std::string> groupNames;
- const Setting &root = m_defaultCfg->lookup(name);
+ const Setting &root = m_userCfg->lookup(name);
for(const Setting &setting : root) {
if(setting.getType() == Setting::TypeGroup) {
@@ -98,20 +117,45 @@ std::vector<std::string> Configuration::childrenGroups(const char* name)
void Configuration::resetValue(const char *path)
{
if(m_userCfg->exists(path)) {
- m_userCfg->getRoot().remove(path);
+ Setting &v = m_userCfg->lookup(path);
+ switch (v.getType()) {
+ case Setting::TypeNone:
+ break;
+ case Setting::TypeInt:
+ v = static_cast<int>(m_defaultCfg->lookup(path));
+ break;
+ case Setting::TypeInt64:
+ v = static_cast<long>(m_defaultCfg->lookup(path));
+ break;
+ case Setting::TypeFloat:
+ v = static_cast<double>(m_defaultCfg->lookup(path));
+ break;
+ case Setting::TypeString:
+ v = static_cast<const char *>(m_defaultCfg->lookup(path));
+ break;
+ case Setting::TypeBoolean:
+ v = static_cast<bool>(m_defaultCfg->lookup(path));
+ break;
+ case Setting::TypeGroup:
+ break;
+ case Setting::TypeArray:
+ break;
+ case Setting::TypeList:
+ break;
+ }
}
}
template<typename T>
std::optional<T> Configuration::value(const char* path) const
{
- Config *conf = getConfig(path);
- if(conf == nullptr) {
+ // if setting doesn't exist, give back a nullopt
+ if(!m_userCfg->exists(path)) {
return std::nullopt;
}
// setting was found
- const Setting &setting = conf->lookup(path);
+ const Setting &setting = m_userCfg->lookup(path);
std::optional<T> r;
// cast depending on type
@@ -207,7 +251,7 @@ template std::optional<bool> Configuration::value<bool>(const char* path) const;
template std::optional<std::string> Configuration::value<std::string>(const char* path) const;
template<typename T>
-void Configuration::setValue(std::string path, const T &val)
+bool Configuration::setValue(std::string path, const T &val)
{
if(m_userCfg->exists(path)) {
Setting &setting = m_userCfg->lookup(path);
@@ -215,70 +259,69 @@ void Configuration::setValue(std::string path, const T &val)
if constexpr(std::is_unsigned_v<T> && !std::is_same_v<T, bool>) {
setting = static_cast<typename std::make_signed_t<T>>(val);
} else if constexpr(std::is_same_v<T, std::string>) {
- setting = static_cast<std::string>(val).c_str();
+ switch (setting.getType()) {
+ case Setting::TypeNone:
+ break;
+
+ case Setting::TypeInt:
+ case Setting::TypeInt64:
+ setting = std::stoi(static_cast<std::string>(val));
+ break;
+
+ case Setting::TypeFloat:
+ setting = std::stod(static_cast<std::string>(val));
+ break;
+
+ case Setting::TypeString:
+ setting = static_cast<std::string>(val).c_str();
+ break;
+
+ case Setting::TypeBoolean:
+ if(static_cast<std::string>(val) == "true") {
+ setting = true;
+ } else if (static_cast<std::string>(val) == "false") {
+ setting = false;
+ }
+ break;
+
+ case Setting::TypeGroup:
+ break;
+ case Setting::TypeArray:
+ break;
+ case Setting::TypeList:
+ break;
+ }
+
} else {
setting = val;
}
- return;
- }
-
- // the entry doesn't exist, so we need to create it
- // libconfig can't create an entry from a path, we need to get its root, and then add it
-
- // this will error out if entry being added is not in the default config
-
- std::istringstream p(path);
- Setting *userSetting = &m_userCfg->getRoot();
- Setting *defaultSetting = &m_defaultCfg->getRoot();
-
- std::string i;
- while (std::getline(p, i, '.')) {
- defaultSetting = &defaultSetting->lookup(i);
- // check if user setting exists, if not, create it
- if(!userSetting->exists(i)) {
- userSetting = &userSetting->add(i, defaultSetting->getType());
- }
- }
- if constexpr(std::is_unsigned_v<T> && !std::is_same_v<T, bool>) {
- *userSetting = static_cast<typename std::make_signed_t<T>>(val);
- } else if constexpr(std::is_same_v<T, std::string>) {
- *userSetting = static_cast<std::string>(val).c_str();
- } else {
- *userSetting = val;
+ changed = true;
+ return true;
}
+ // the entry doesn't exist
+ return false;
}
-template void Configuration::setValue<int>(std::string path, const int &val);
-template void Configuration::setValue<unsigned int>(std::string path, const unsigned int &val);
-template void Configuration::setValue<long>(std::string path, const long &val);
-template void Configuration::setValue<unsigned long>(std::string path, const unsigned long &val);
-
-template void Configuration::setValue<long long>(std::string path, const long long &val);
-template void Configuration::setValue<unsigned long long>(std::string path, const unsigned long long &val);
+template bool Configuration::setValue<int>(std::string path, const int &val);
+template bool Configuration::setValue<unsigned int>(std::string path, const unsigned int &val);
+template bool Configuration::setValue<long>(std::string path, const long &val);
+template bool Configuration::setValue<unsigned long>(std::string path, const unsigned long &val);
-template void Configuration::setValue<float>(std::string path, const float &val);
-template void Configuration::setValue<double>(std::string path, const double &val);
+template bool Configuration::setValue<long long>(std::string path, const long long &val);
+template bool Configuration::setValue<unsigned long long>(std::string path, const unsigned long long &val);
-template void Configuration::setValue<bool>(std::string path, const bool &val);
+template bool Configuration::setValue<float>(std::string path, const float &val);
+template bool Configuration::setValue<double>(std::string path, const double &val);
-template void Configuration::setValue<std::string>(std::string path, const std::string &val);
+template bool Configuration::setValue<bool>(std::string path, const bool &val);
-Config *Configuration::getConfig(const char* path) const
-{
- if(m_userCfg->exists(path)) {
- return m_userCfg;
- } else if(m_defaultCfg->exists(path)) {
- return m_defaultCfg;
- } else {
- return nullptr;
- }
-}
+template bool Configuration::setValue<std::string>(std::string path, const std::string &val);
std::string &patchHome(std::string &path, const std::string &home)
{
- const size_t location = path.find("~");
+ const size_t location = path.find('~');
if(location != std::string::npos) {
return path.replace(location, 1, home);
}