From 378ebad1c8d7079b41319600f13c1c884d6c693a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 30 Jan 2013 22:37:17 +0100 Subject: ConfigData: use simple linked list instead of GSList --- src/ConfigData.cxx | 3 ++- src/ConfigData.hxx | 11 ++++++++--- src/ConfigFile.cxx | 23 ++++++++++++++++++----- src/ConfigGlobal.cxx | 41 ++++++++++------------------------------- 4 files changed, 38 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/ConfigData.cxx b/src/ConfigData.cxx index 7e16c0126..48e9612d4 100644 --- a/src/ConfigData.cxx +++ b/src/ConfigData.cxx @@ -32,10 +32,11 @@ extern "C" { #include config_param::config_param(const char *_value, int _line) - :value(g_strdup(_value)), line(_line) {} + :next(nullptr), value(g_strdup(_value)), line(_line) {} config_param::~config_param() { + delete next; g_free(value); } diff --git a/src/ConfigData.hxx b/src/ConfigData.hxx index 053cf3b39..f3e661b2b 100644 --- a/src/ConfigData.hxx +++ b/src/ConfigData.hxx @@ -25,7 +25,6 @@ #include "gcc.h" #ifdef __cplusplus -#include #include #include #include @@ -54,6 +53,12 @@ struct block_param { #endif struct config_param { + /** + * The next config_param with the same name. The destructor + * deletes the whole chain. + */ + struct config_param *next; + char *value; unsigned int line; @@ -67,7 +72,7 @@ struct config_param { bool used; config_param(int _line=-1) - :value(nullptr), line(_line), used(false) {} + :next(nullptr), value(nullptr), line(_line), used(false) {} gcc_nonnull_all config_param(const char *_value, int _line=-1); @@ -92,7 +97,7 @@ struct config_param { #ifdef __cplusplus struct ConfigData { - std::array params; + std::array params; }; #endif diff --git a/src/ConfigFile.cxx b/src/ConfigFile.cxx index d5b539e7a..695e7803e 100644 --- a/src/ConfigFile.cxx +++ b/src/ConfigFile.cxx @@ -137,6 +137,19 @@ config_read_block(FILE *fp, int *count, char *string, GError **error_r) } } +gcc_nonnull_all +static void +Append(config_param *&head, config_param *p) +{ + assert(p->next == nullptr); + + config_param **i = &head; + while (*i != nullptr) + i = &(*i)->next; + + *i = p; +} + static bool ReadConfigFile(ConfigData &config_data, FILE *fp, GError **error_r) { @@ -179,12 +192,12 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, GError **error_r) return false; } - const unsigned i = ParseConfigOptionName(name); + const unsigned i = unsigned(o); const ConfigTemplate &option = config_templates[i]; - GSList *¶ms = config_data.params[i]; + config_param *&head = config_data.params[i]; - if (params != NULL && !option.repeatable) { - param = (struct config_param *)params->data; + if (head != nullptr && !option.repeatable) { + param = head; g_set_error(error_r, config_quark(), 0, "config parameter \"%s\" is first defined " "on line %i and redefined on line %i\n", @@ -244,7 +257,7 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, GError **error_r) param = new config_param(value, count); } - params = g_slist_append(params, param); + Append(head, param); } return true; diff --git a/src/ConfigGlobal.cxx b/src/ConfigGlobal.cxx index 0c9af0563..9786690d0 100644 --- a/src/ConfigGlobal.cxx +++ b/src/ConfigGlobal.cxx @@ -39,20 +39,10 @@ extern "C" { static ConfigData config_data; -static void -config_param_free_callback(gpointer data, G_GNUC_UNUSED gpointer user_data) -{ - struct config_param *param = (struct config_param *)data; - - delete param; -} - void config_global_finish(void) { - for (auto i : config_data.params) { - g_slist_foreach(i, config_param_free_callback, NULL); - g_slist_free(i); - } + for (auto i : config_data.params) + delete i; } void config_global_init(void) @@ -66,10 +56,8 @@ ReadConfigFile(const Path &path, GError **error_r) } static void -config_param_check(gpointer data, G_GNUC_UNUSED gpointer user_data) +Check(const config_param *param) { - struct config_param *param = (struct config_param *)data; - if (!param->used) /* this whole config_param was not queried at all - the feature might be disabled at compile time? @@ -86,27 +74,18 @@ config_param_check(gpointer data, G_GNUC_UNUSED gpointer user_data) void config_global_check(void) { for (auto i : config_data.params) - g_slist_foreach(i, config_param_check, NULL); + for (const config_param *p = i; p != nullptr; p = p->next) + Check(p); } const struct config_param * config_get_next_param(ConfigOption option, const struct config_param * last) { - GSList *node = config_data.params[unsigned(option)]; - - if (last) { - node = g_slist_find(node, last); - if (node == NULL) - return NULL; - - node = g_slist_next(node); - } - - if (node == NULL) - return NULL; - - struct config_param *param = (struct config_param *)node->data; - param->used = true; + config_param *param = last != nullptr + ? last->next + : config_data.params[unsigned(option)]; + if (param != nullptr) + param->used = true; return param; } -- cgit v1.2.3