Commit c5ea5868 authored by Max Kellermann's avatar Max Kellermann

ConfigFile: split config_entry

The new struct ConfigOption is the compile-time description, and the global array "config_params" contains the actual values.
parent f2a3a37d
...@@ -45,20 +45,13 @@ extern "C" { ...@@ -45,20 +45,13 @@ extern "C" {
#define CONF_COMMENT '#' #define CONF_COMMENT '#'
struct config_entry { struct ConfigOption {
const char *const name; const char *const name;
const bool repeatable; const bool repeatable;
const bool block; const bool block;
GSList *params;
constexpr config_entry(const char *_name,
bool _repeatable, bool _block)
:name(_name), repeatable(_repeatable), block(_block),
params(nullptr) {}
}; };
static struct config_entry config_entries[] = { static constexpr struct ConfigOption config_options[] = {
{ CONF_MUSIC_DIR, false, false }, { CONF_MUSIC_DIR, false, false },
{ CONF_PLAYLIST_DIR, false, false }, { CONF_PLAYLIST_DIR, false, false },
{ CONF_FOLLOW_INSIDE_SYMLINKS, false, false }, { CONF_FOLLOW_INSIDE_SYMLINKS, false, false },
...@@ -115,6 +108,8 @@ static struct config_entry config_entries[] = { ...@@ -115,6 +108,8 @@ static struct config_entry config_entries[] = {
{ "database", false, true }, { "database", false, true },
}; };
static GSList *config_params[G_N_ELEMENTS(config_options)];
static bool static bool
get_bool(const char *value, bool *value_r) get_bool(const char *value, bool *value_r)
{ {
...@@ -177,26 +172,22 @@ config_param_free_callback(gpointer data, G_GNUC_UNUSED gpointer user_data) ...@@ -177,26 +172,22 @@ config_param_free_callback(gpointer data, G_GNUC_UNUSED gpointer user_data)
config_param_free(param); config_param_free(param);
} }
static struct config_entry * static int
config_entry_get(const char *name) ConfigFindByName(const char *name)
{ {
for (unsigned i = 0; i < G_N_ELEMENTS(config_entries); ++i) { for (unsigned i = 0; i < G_N_ELEMENTS(config_options); ++i)
struct config_entry *entry = &config_entries[i]; if (strcmp(config_options[i].name, name) == 0)
if (strcmp(entry->name, name) == 0) return i;
return entry;
}
return NULL; return -1;
} }
void config_global_finish(void) void config_global_finish(void)
{ {
for (unsigned i = 0; i < G_N_ELEMENTS(config_entries); ++i) { for (unsigned i = 0; i < G_N_ELEMENTS(config_params); ++i) {
struct config_entry *entry = &config_entries[i]; g_slist_foreach(config_params[i],
g_slist_foreach(entry->params,
config_param_free_callback, NULL); config_param_free_callback, NULL);
g_slist_free(entry->params); g_slist_free(config_params[i]);
} }
} }
...@@ -226,11 +217,8 @@ config_param_check(gpointer data, G_GNUC_UNUSED gpointer user_data) ...@@ -226,11 +217,8 @@ config_param_check(gpointer data, G_GNUC_UNUSED gpointer user_data)
void config_global_check(void) void config_global_check(void)
{ {
for (unsigned i = 0; i < G_N_ELEMENTS(config_entries); ++i) { for (unsigned i = 0; i < G_N_ELEMENTS(config_params); ++i)
struct config_entry *entry = &config_entries[i]; g_slist_foreach(config_params[i], config_param_check, NULL);
g_slist_foreach(entry->params, config_param_check, NULL);
}
} }
void void
...@@ -356,7 +344,6 @@ ReadConfigFile(const Path &path, GError **error_r) ...@@ -356,7 +344,6 @@ ReadConfigFile(const Path &path, GError **error_r)
FILE *fp; FILE *fp;
char string[MAX_STRING_SIZE + 1]; char string[MAX_STRING_SIZE + 1];
int count = 0; int count = 0;
struct config_entry *entry;
struct config_param *param; struct config_param *param;
g_debug("loading file %s", path_utf8.c_str()); g_debug("loading file %s", path_utf8.c_str());
...@@ -394,8 +381,8 @@ ReadConfigFile(const Path &path, GError **error_r) ...@@ -394,8 +381,8 @@ ReadConfigFile(const Path &path, GError **error_r)
/* get the definition of that option, and check the /* get the definition of that option, and check the
"repeatable" flag */ "repeatable" flag */
entry = config_entry_get(name); int i = ConfigFindByName(name);
if (entry == NULL) { if (i < 0) {
g_set_error(error_r, config_quark(), 0, g_set_error(error_r, config_quark(), 0,
"unrecognized parameter in config file at " "unrecognized parameter in config file at "
"line %i: %s\n", count, name); "line %i: %s\n", count, name);
...@@ -403,8 +390,11 @@ ReadConfigFile(const Path &path, GError **error_r) ...@@ -403,8 +390,11 @@ ReadConfigFile(const Path &path, GError **error_r)
return false; return false;
} }
if (entry->params != NULL && !entry->repeatable) { const ConfigOption &option = config_options[i];
param = (struct config_param *)entry->params->data; GSList *&params = config_params[i];
if (params != NULL && !option.repeatable) {
param = (struct config_param *)params->data;
g_set_error(error_r, config_quark(), 0, g_set_error(error_r, config_quark(), 0,
"config parameter \"%s\" is first defined " "config parameter \"%s\" is first defined "
"on line %i and redefined on line %i\n", "on line %i and redefined on line %i\n",
...@@ -415,7 +405,7 @@ ReadConfigFile(const Path &path, GError **error_r) ...@@ -415,7 +405,7 @@ ReadConfigFile(const Path &path, GError **error_r)
/* now parse the block or the value */ /* now parse the block or the value */
if (entry->block) { if (option.block) {
/* it's a block, call config_read_block() */ /* it's a block, call config_read_block() */
if (*line != '{') { if (*line != '{') {
...@@ -470,7 +460,7 @@ ReadConfigFile(const Path &path, GError **error_r) ...@@ -470,7 +460,7 @@ ReadConfigFile(const Path &path, GError **error_r)
param = config_new_param(value, count); param = config_new_param(value, count);
} }
entry->params = g_slist_append(entry->params, param); params = g_slist_append(params, param);
} }
fclose(fp); fclose(fp);
...@@ -480,15 +470,13 @@ ReadConfigFile(const Path &path, GError **error_r) ...@@ -480,15 +470,13 @@ ReadConfigFile(const Path &path, GError **error_r)
const struct config_param * const struct config_param *
config_get_next_param(const char *name, const struct config_param * last) config_get_next_param(const char *name, const struct config_param * last)
{ {
struct config_entry *entry;
GSList *node;
struct config_param *param; struct config_param *param;
entry = config_entry_get(name); int i = ConfigFindByName(name);
if (entry == NULL) if (i < 0)
return NULL; return NULL;
node = entry->params; GSList *node = config_params[i];
if (last) { if (last) {
node = g_slist_find(node, last); node = g_slist_find(node, last);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment