ConfigFile: split config_entry
The new struct ConfigOption is the compile-time description, and the global array "config_params" contains the actual values.
This commit is contained in:
parent
f2a3a37dff
commit
c5ea586882
@ -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[] = {
|
|||||||
{ "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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->params != NULL && !entry->repeatable) {
|
const ConfigOption &option = config_options[i];
|
||||||
param = (struct config_param *)entry->params->data;
|
GSList *¶ms = 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)
|
|||||||
|
|
||||||
/* 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)
|
|||||||
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)
|
|||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user