diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2018-01-03 22:29:17 +0100 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2018-01-03 22:29:17 +0100 |
commit | 1e57c2b3f6bd2a4f1756150e669eedffc29cf13d (patch) | |
tree | 01f22e47b85e556cd4fae4431f578f9c38bb12ca /lib | |
parent | Updated PKGBUILD (diff) | |
download | smolbote-1e57c2b3f6bd2a4f1756150e669eedffc29cf13d.tar.xz |
Fixed crash with Settings dialog
- User Configuration gets completely written, instead of being just
overrides
Diffstat (limited to 'lib')
-rw-r--r-- | lib/settings/CMakeLists.txt | 4 | ||||
-rw-r--r-- | lib/settings/configuration.cpp | 171 | ||||
-rw-r--r-- | lib/settings/configuration.h | 32 | ||||
-rw-r--r-- | lib/settings/settingsdialog.cpp | 1 |
4 files changed, 127 insertions, 81 deletions
diff --git a/lib/settings/CMakeLists.txt b/lib/settings/CMakeLists.txt index 983e8ca..26d8525 100644 --- a/lib/settings/CMakeLists.txt +++ b/lib/settings/CMakeLists.txt @@ -7,4 +7,8 @@ add_library(configuration settingsdialog.h settingsdialog.ui) +if (CLikeConfig) + target_compile_definitions(configuration PRIVATE C_LIKE_CONFIG) +endif (CLikeConfig) + target_link_libraries(configuration config++ Qt5::Widgets) 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); } diff --git a/lib/settings/configuration.h b/lib/settings/configuration.h index 1909eb8..b258cb3 100644 --- a/lib/settings/configuration.h +++ b/lib/settings/configuration.h @@ -25,9 +25,11 @@ public: ~Configuration(); bool readUserConfiguration(const std::string &path); + bool parse(const std::string &contents); bool writeUserConfiguration(const std::string &path); + bool writeIfNeeded(); - bool readDefaultConfiguration(const std::string &data); + bool parseDefaultConfiguration(const std::string &contents); std::vector<std::string> childrenSettings(const char *name = ""); std::vector<std::string> childrenGroups(const char *name = ""); @@ -38,14 +40,12 @@ public: std::optional<T> value(const char* path) const; template<typename T> - void setValue(std::string path, const T &val); + bool setValue(std::string path, const T &val); private: - libconfig::Config* getConfig(const char* path) const; - + bool changed = false; std::string m_userCfgPath; - libconfig::Config *m_userCfg; - libconfig::Config *m_defaultCfg; + libconfig::Config *m_userCfg, *m_defaultCfg; }; // replace ~ with home @@ -71,19 +71,19 @@ extern template std::optional<bool> Configuration::value<bool>(const char* path) extern template std::optional<std::string> Configuration::value<std::string>(const char* path) const; // Settings::setValue<> -extern template void Configuration::setValue<int>(std::string path, const int &val); -extern template void Configuration::setValue<unsigned int>(std::string path, const unsigned int &val); -extern template void Configuration::setValue<long>(std::string path, const long &val); -extern template void Configuration::setValue<unsigned long>(std::string path, const unsigned long &val); +extern template bool Configuration::setValue<int>(std::string path, const int &val); +extern template bool Configuration::setValue<unsigned int>(std::string path, const unsigned int &val); +extern template bool Configuration::setValue<long>(std::string path, const long &val); +extern template bool Configuration::setValue<unsigned long>(std::string path, const unsigned long &val); -extern template void Configuration::setValue<long long>(std::string path, const long long &val); -extern template void Configuration::setValue<unsigned long long>(std::string path, const unsigned long long &val); +extern template bool Configuration::setValue<long long>(std::string path, const long long &val); +extern template bool Configuration::setValue<unsigned long long>(std::string path, const unsigned long long &val); -extern template void Configuration::setValue<float>(std::string path, const float &val); -extern template void Configuration::setValue<double>(std::string path, const double &val); +extern template bool Configuration::setValue<float>(std::string path, const float &val); +extern template bool Configuration::setValue<double>(std::string path, const double &val); -extern template void Configuration::setValue<bool>(std::string path, const bool &val); +extern template bool Configuration::setValue<bool>(std::string path, const bool &val); -extern template void Configuration::setValue<std::string>(std::string path, const std::string &val); +extern template bool Configuration::setValue<std::string>(std::string path, const std::string &val); #endif // CONFIGURATION_H diff --git a/lib/settings/settingsdialog.cpp b/lib/settings/settingsdialog.cpp index 6de3894..9a589d6 100644 --- a/lib/settings/settingsdialog.cpp +++ b/lib/settings/settingsdialog.cpp @@ -11,7 +11,6 @@ #include "configuration.h" #include <QScrollArea> #include <QFormLayout> -#include <QHBoxLayout> #include <QLineEdit> #include <QToolButton> #include <QGroupBox> |