From 46ff73662cc94220c5ee962b591c8ee327de6f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 14 Jun 2016 03:02:36 +0200 Subject: Clean the Config module, use static things instead of a stupid singleton --- louloulibs/config/config.cpp | 66 +++++++++++++++----------------------------- louloulibs/config/config.hpp | 28 ++++++++----------- louloulibs/utils/reload.cpp | 4 +-- src/main.cpp | 22 +++++---------- tests/config.cpp | 10 +++---- 5 files changed, 48 insertions(+), 82 deletions(-) diff --git a/louloulibs/config/config.cpp b/louloulibs/config/config.cpp index c785632..967f581 100644 --- a/louloulibs/config/config.cpp +++ b/louloulibs/config/config.cpp @@ -6,22 +6,21 @@ #include std::string Config::filename{}; -bool Config::file_must_exist = false; +std::map Config::values{}; +std::vector Config::callbacks{}; std::string Config::get(const std::string& option, const std::string& def) { - Config* self = Config::instance().get(); - auto it = self->values.find(option); + auto it = Config::values.find(option); - if (it == self->values.end()) + if (it == Config::values.end()) return def; return it->second; } int Config::get_int(const std::string& option, const int& def) { - Config* self = Config::instance().get(); - std::string res = self->get(option, ""); + std::string res = Config::get(option, ""); if (!res.empty()) return atoi(res.c_str()); else @@ -30,65 +29,48 @@ int Config::get_int(const std::string& option, const int& def) void Config::set(const std::string& option, const std::string& value, bool save) { - Config* self = Config::instance().get(); - self->values[option] = value; + Config::values[option] = value; if (save) { - self->save_to_file(); - self->trigger_configuration_change(); + Config::save_to_file(); + Config::trigger_configuration_change(); } } void Config::connect(t_config_changed_callback callback) { - Config* self = Config::instance().get(); - self->callbacks.push_back(callback); + Config::callbacks.push_back(callback); } -void Config::close() +void Config::clear() { - Config* self = Config::instance().get(); - self->values.clear(); - Config::instance().reset(); + Config::values.clear(); } /** * Private methods */ - void Config::trigger_configuration_change() { std::vector::iterator it; - for (it = this->callbacks.begin(); it < this->callbacks.end(); ++it) + for (it = Config::callbacks.begin(); it < Config::callbacks.end(); ++it) (*it)(); } -std::unique_ptr& Config::instance() +bool Config::read_conf(const std::string& name) { - static std::unique_ptr instance; + if (!name.empty()) + Config::filename = name; - if (!instance) - { - instance = std::make_unique(); - instance->read_conf(); - } - return instance; -} - -bool Config::read_conf() -{ - std::ifstream file; - file.open(filename.data()); + std::ifstream file(Config::filename.data()); if (!file.is_open()) { - if (Config::file_must_exist) - { - perror(("Error while opening file " + filename + " for reading.").c_str()); - file.exceptions(std::ifstream::failbit); - } + perror(("Error while opening file " + filename + " for reading.").c_str()); return false; } + Config::clear(); + std::string line; size_t pos; std::string option; @@ -103,20 +85,18 @@ bool Config::read_conf() continue ; option = line.substr(0, pos); value = line.substr(pos+1); - this->values[option] = value; + Config::values[option] = value; } - return true; } -void Config::save_to_file() const +void Config::save_to_file() { - std::ofstream file(this->filename.data()); + std::ofstream file(Config::filename.data()); if (file.fail()) { std::cerr << "Could not save config file." << std::endl; return ; } - for (auto& it: this->values) + for (const auto& it: Config::values) file << it.first << "=" << it.second << '\n'; - file.close(); } diff --git a/louloulibs/config/config.hpp b/louloulibs/config/config.hpp index 72620c0..b46768e 100644 --- a/louloulibs/config/config.hpp +++ b/louloulibs/config/config.hpp @@ -60,38 +60,34 @@ public: * Destroy the instance, forcing it to be recreated (with potentially * different parameters) the next time it’s needed. */ - static void close(); + static void clear(); /** - * Set the value of the filename to use, before calling any method. + * Read the configuration file at the given path. */ - static std::string filename; + static bool read_conf(const std::string& name=""); /** - * Set to true if you want an exception to be raised if the file does not - * exist when reading it. + * Get the filename */ - static bool file_must_exist; + static const std::string& get_filename() + { return Config::filename; } private: /** - * Get the singleton instance - */ - static std::unique_ptr& instance(); - /** - * Read the configuration file at the given path. + * Set the value of the filename to use, before calling any method. */ - bool read_conf(); + static std::string filename; /** * Write all the config values into the configuration file */ - void save_to_file() const; + static void save_to_file(); /** * Call all the callbacks previously registered using connect(). * This is used to notify any class that a configuration change occured. */ - void trigger_configuration_change(); + static void trigger_configuration_change(); - std::map values; - std::vector callbacks; + static std::map values; + static std::vector callbacks; }; diff --git a/louloulibs/utils/reload.cpp b/louloulibs/utils/reload.cpp index 6600c75..bddfd86 100644 --- a/louloulibs/utils/reload.cpp +++ b/louloulibs/utils/reload.cpp @@ -3,9 +3,7 @@ void reload_process() { - // Closing the config will just force it to be reopened the next time - // a configuration option is needed - Config::close(); + Config::read_conf(); // Destroy the logger instance, to be recreated the next time a log // line needs to be written Logger::instance().reset(); diff --git a/src/main.cpp b/src/main.cpp index 226b400..cbec4a6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,7 +47,7 @@ static void sigint_handler(int sig, siginfo_t*, void*) { // We reset the SIGTERM or SIGINT (the one that didn't trigger this // handler) signal handler to its default value. This avoid calling this - // handler twice, if the process receive both signals in a quick + // handler twice, if the process receives both signals in a quick // succession. int sig_to_reset = (sig == SIGINT? SIGTERM: SIGINT); sigset_t mask; @@ -70,24 +70,16 @@ static void sigusr_handler(int, siginfo_t*, void*) int main(int ac, char** av) { - if (ac > 1) - Config::filename = av[1]; - else - Config::filename = xdg_config_path("biboumi.cfg"); + const std::string conf_filename = ac > 1 ? av[1] : xdg_config_path("biboumi.cfg"); + std::cerr << "Using configuration file: " << conf_filename << std::endl; - Config::file_must_exist = true; - std::cerr << "Using configuration file: " << Config::filename << std::endl; - - std::string password; - try { // The file must exist - password = Config::get("password", ""); - } - catch (const std::ios::failure& e) { + if (!Config::read_conf(conf_filename)) return config_help(""); - } - const std::string hostname = Config::get("hostname", ""); + + const std::string password = Config::get("password", ""); if (password.empty()) return config_help("password"); + const std::string hostname = Config::get("hostname", ""); if (hostname.empty()) return config_help("hostname"); diff --git a/tests/config.cpp b/tests/config.cpp index 346dea1..ddea151 100644 --- a/tests/config.cpp +++ b/tests/config.cpp @@ -4,18 +4,18 @@ TEST_CASE("Config basic") { - Config::filename = "test.cfg"; - Config::file_must_exist = false; + // Write a value in the config file + Config::read_conf("test.cfg"); Config::set("coucou", "bonjour", true); - Config::close(); + Config::clear(); bool error = false; try { - Config::file_must_exist = true; + CHECK(Config::read_conf()); CHECK(Config::get("coucou", "") == "bonjour"); CHECK(Config::get("does not exist", "default") == "default"); - Config::close(); + Config::clear(); } catch (const std::ios::failure& e) { -- cgit v1.2.3