summaryrefslogtreecommitdiff
path: root/src/core/settings.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/settings.c')
-rw-r--r--src/core/settings.c131
1 files changed, 101 insertions, 30 deletions
diff --git a/src/core/settings.c b/src/core/settings.c
index 2296909e..4e0717cd 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -59,7 +59,7 @@ static SETTINGS_REC *settings_get(const char *key, SettingType type)
g_warning("settings_get(%s) : not found", key);
return NULL;
}
- if (type != -1 && rec->type != type) {
+ if (type != SETTING_TYPE_ANY && rec->type != type) {
g_warning("settings_get(%s) : invalid type", key);
return NULL;
}
@@ -77,7 +77,7 @@ settings_get_str_type(const char *key, SettingType type)
if (rec == NULL) return NULL;
node = iconfig_node_traverse("settings", FALSE);
- node = node == NULL ? NULL : config_node_section(node, rec->module, -1);
+ node = node == NULL ? NULL : iconfig_node_section(node, rec->module, -1);
return node == NULL ? rec->default_value.v_string :
config_node_get_str(node, key, rec->default_value.v_string);
@@ -85,7 +85,7 @@ settings_get_str_type(const char *key, SettingType type)
const char *settings_get_str(const char *key)
{
- return settings_get_str_type(key, -1);
+ return settings_get_str_type(key, SETTING_TYPE_ANY);
}
int settings_get_int(const char *key)
@@ -97,7 +97,7 @@ int settings_get_int(const char *key)
if (rec == NULL) return 0;
node = iconfig_node_traverse("settings", FALSE);
- node = node == NULL ? NULL : config_node_section(node, rec->module, -1);
+ node = node == NULL ? NULL : iconfig_node_section(node, rec->module, -1);
return node == NULL ? rec->default_value.v_int :
config_node_get_int(node, key, rec->default_value.v_int);
@@ -112,7 +112,7 @@ int settings_get_bool(const char *key)
if (rec == NULL) return FALSE;
node = iconfig_node_traverse("settings", FALSE);
- node = node == NULL ? NULL : config_node_section(node, rec->module, -1);
+ node = node == NULL ? NULL : iconfig_node_section(node, rec->module, -1);
return node == NULL ? rec->default_value.v_bool :
config_node_get_bool(node, key, rec->default_value.v_bool);
@@ -148,11 +148,36 @@ int settings_get_size(const char *key)
return str == NULL ? 0 : bytes;
}
+int settings_get_choice(const char *key)
+{
+ SETTINGS_REC *rec;
+ CONFIG_NODE *node;
+ char *str;
+ int index;
+
+ rec = settings_get(key, SETTING_TYPE_CHOICE);
+ if (rec == NULL) return -1;
+
+ node = iconfig_node_traverse("settings", FALSE);
+ node = node == NULL ? NULL : iconfig_node_section(node, rec->module, -1);
+
+ str = node == NULL ? rec->default_value.v_string :
+ config_node_get_str(node, key, rec->default_value.v_string);
+
+ if (str == NULL || (index = strarray_find(rec->choices, str)) < 0)
+ return rec->default_value.v_int;
+
+ return index;
+}
+
char *settings_get_print(SETTINGS_REC *rec)
{
char *value = NULL;
switch(rec->type) {
+ case SETTING_TYPE_CHOICE:
+ value = g_strdup(rec->choices[settings_get_choice(rec->key)]);
+ break;
case SETTING_TYPE_BOOLEAN:
value = g_strdup(settings_get_bool(rec->key) ? "ON" : "OFF");
break;
@@ -163,6 +188,7 @@ char *settings_get_print(SETTINGS_REC *rec)
case SETTING_TYPE_TIME:
case SETTING_TYPE_LEVEL:
case SETTING_TYPE_SIZE:
+ case SETTING_TYPE_ANY:
value = g_strdup(settings_get_str(rec->key));
break;
}
@@ -171,13 +197,31 @@ char *settings_get_print(SETTINGS_REC *rec)
static void settings_add(const char *module, const char *section,
const char *key, SettingType type,
- const SettingValue *default_value)
+ const SettingValue *default_value,
+ const char *choices)
{
SETTINGS_REC *rec;
+ char **choices_vec = NULL;
g_return_if_fail(key != NULL);
g_return_if_fail(section != NULL);
+ if (type == SETTING_TYPE_CHOICE) {
+ if (choices == NULL) {
+ g_warning("Trying to add setting '%s' with no choices.", key);
+ return;
+ }
+
+ choices_vec = g_strsplit(choices, ";", -1);
+
+ /* validate the default value */
+ if (default_value->v_int < 0 || default_value->v_int >= g_strv_length(choices_vec)) {
+ g_warning("Trying to add setting '%s' with an invalid default value.", key);
+ g_strfreev(choices_vec);
+ return;
+ }
+ }
+
rec = g_hash_table_lookup(settings, key);
if (rec != NULL) {
/* Already exists, make sure it's correct type */
@@ -196,6 +240,7 @@ static void settings_add(const char *module, const char *section,
rec->type = type;
rec->default_value = *default_value;
+ rec->choices = choices_vec;
g_hash_table_insert(settings, rec->key, rec);
}
}
@@ -207,7 +252,17 @@ void settings_add_str_module(const char *module, const char *section,
memset(&default_value, 0, sizeof(default_value));
default_value.v_string = g_strdup(def);
- settings_add(module, section, key, SETTING_TYPE_STRING, &default_value);
+ settings_add(module, section, key, SETTING_TYPE_STRING, &default_value, NULL);
+}
+
+void settings_add_choice_module(const char *module, const char *section,
+ const char *key, int def, const char *choices)
+{
+ SettingValue default_value;
+
+ memset(&default_value, 0, sizeof(default_value));
+ default_value.v_int = def;
+ settings_add(module, section, key, SETTING_TYPE_CHOICE, &default_value, choices);
}
void settings_add_int_module(const char *module, const char *section,
@@ -217,7 +272,7 @@ void settings_add_int_module(const char *module, const char *section,
memset(&default_value, 0, sizeof(default_value));
default_value.v_int = def;
- settings_add(module, section, key, SETTING_TYPE_INT, &default_value);
+ settings_add(module, section, key, SETTING_TYPE_INT, &default_value, NULL);
}
void settings_add_bool_module(const char *module, const char *section,
@@ -227,8 +282,7 @@ void settings_add_bool_module(const char *module, const char *section,
memset(&default_value, 0, sizeof(default_value));
default_value.v_bool = def;
- settings_add(module, section, key, SETTING_TYPE_BOOLEAN,
- &default_value);
+ settings_add(module, section, key, SETTING_TYPE_BOOLEAN, &default_value, NULL);
}
void settings_add_time_module(const char *module, const char *section,
@@ -238,7 +292,7 @@ void settings_add_time_module(const char *module, const char *section,
memset(&default_value, 0, sizeof(default_value));
default_value.v_string = g_strdup(def);
- settings_add(module, section, key, SETTING_TYPE_TIME, &default_value);
+ settings_add(module, section, key, SETTING_TYPE_TIME, &default_value, NULL);
}
void settings_add_level_module(const char *module, const char *section,
@@ -248,7 +302,7 @@ void settings_add_level_module(const char *module, const char *section,
memset(&default_value, 0, sizeof(default_value));
default_value.v_string = g_strdup(def);
- settings_add(module, section, key, SETTING_TYPE_LEVEL, &default_value);
+ settings_add(module, section, key, SETTING_TYPE_LEVEL, &default_value, NULL);
}
void settings_add_size_module(const char *module, const char *section,
@@ -258,14 +312,16 @@ void settings_add_size_module(const char *module, const char *section,
memset(&default_value, 0, sizeof(default_value));
default_value.v_string = g_strdup(def);
- settings_add(module, section, key, SETTING_TYPE_SIZE, &default_value);
+ settings_add(module, section, key, SETTING_TYPE_SIZE, &default_value, NULL);
}
static void settings_destroy(SETTINGS_REC *rec)
{
if (rec->type != SETTING_TYPE_INT &&
- rec->type != SETTING_TYPE_BOOLEAN)
+ rec->type != SETTING_TYPE_BOOLEAN &&
+ rec->type != SETTING_TYPE_CHOICE)
g_free(rec->default_value.v_string);
+ g_strfreev(rec->choices);
g_free(rec->module);
g_free(rec->section);
g_free(rec->key);
@@ -295,7 +351,7 @@ void settings_remove(const char *key)
static int settings_remove_hash(const char *key, SETTINGS_REC *rec,
const char *module)
{
- if (strcmp(rec->module, module) == 0) {
+ if (g_strcmp0(rec->module, module) == 0) {
settings_unref(rec, FALSE);
return TRUE;
}
@@ -324,7 +380,21 @@ static CONFIG_NODE *settings_get_node(const char *key)
}
node = iconfig_node_traverse("settings", TRUE);
- return config_node_section(node, rec->module, NODE_TYPE_BLOCK);
+ return iconfig_node_section(node, rec->module, NODE_TYPE_BLOCK);
+}
+
+gboolean settings_set_choice(const char *key, const char *value)
+{
+ SETTINGS_REC *rec;
+
+ rec = settings_get_record(key);
+
+ if (rec != NULL && strarray_find(rec->choices, value) < 0)
+ return FALSE;
+
+ settings_set_str(key, value);
+
+ return TRUE;
}
void settings_set_str(const char *key, const char *value)
@@ -342,7 +412,7 @@ void settings_set_bool(const char *key, int value)
iconfig_node_set_bool(settings_get_node(key), key, value);
}
-int settings_set_time(const char *key, const char *value)
+gboolean settings_set_time(const char *key, const char *value)
{
int msecs;
@@ -353,7 +423,7 @@ int settings_set_time(const char *key, const char *value)
return TRUE;
}
-int settings_set_level(const char *key, const char *value)
+gboolean settings_set_level(const char *key, const char *value)
{
int iserror;
@@ -365,7 +435,7 @@ int settings_set_level(const char *key, const char *value)
return TRUE;
}
-int settings_set_size(const char *key, const char *value)
+gboolean settings_set_size(const char *key, const char *value)
{
int size;
@@ -380,10 +450,10 @@ SettingType settings_get_type(const char *key)
{
SETTINGS_REC *rec;
- g_return_val_if_fail(key != NULL, -1);
+ g_return_val_if_fail(key != NULL, SETTING_TYPE_ANY);
rec = g_hash_table_lookup(settings, key);
- return rec == NULL ? -1 : rec->type;
+ return rec == NULL ? SETTING_TYPE_ANY : rec->type;
}
/* Get the record of the setting */
@@ -420,7 +490,7 @@ static void settings_clean_invalid_module(const char *module)
node = iconfig_node_traverse("settings", FALSE);
if (node == NULL) return;
- node = config_node_section(node, module, -1);
+ node = iconfig_node_section(node, module, -1);
if (node == NULL) return;
for (tmp = config_node_first(node->value); tmp != NULL; tmp = next) {
@@ -428,7 +498,7 @@ static void settings_clean_invalid_module(const char *module)
next = config_node_next(tmp);
set = g_hash_table_lookup(settings, subnode->key);
- if (set == NULL || strcmp(set->module, module) != 0)
+ if (set == NULL || g_strcmp0(set->module, module) != 0)
iconfig_node_remove(node, subnode);
}
}
@@ -458,7 +528,7 @@ static int backwards_compatibility(const char *module, CONFIG_NODE *node,
new_value = NULL; new_key = NULL; new_module = NULL;
/* fe-text term_type -> fe-common/core term_charset - for 0.8.10-> */
- if (strcmp(module, "fe-text") == 0) {
+ if (g_strcmp0(module, "fe-text") == 0) {
if (g_ascii_strcasecmp(node->key, "term_type") == 0 ||
/* kludge for cvs-version where term_charset was in fe-text */
g_ascii_strcasecmp(node->key, "term_charset") == 0) {
@@ -468,7 +538,7 @@ static int backwards_compatibility(const char *module, CONFIG_NODE *node,
g_strdup(node->value);
new_node = iconfig_node_traverse("settings", FALSE);
new_node = new_node == NULL ? NULL :
- config_node_section(new_node, new_module, -1);
+ iconfig_node_section(new_node, new_module, -1);
config_node_set_str(mainconfig, new_node,
new_key, new_value);
@@ -502,7 +572,7 @@ void settings_check_module(const char *module)
g_return_if_fail(module != NULL);
node = iconfig_node_traverse("settings", FALSE);
- node = node == NULL ? NULL : config_node_section(node, module, -1);
+ node = node == NULL ? NULL : iconfig_node_section(node, module, -1);
if (node == NULL) return;
errors = g_string_new(NULL);
@@ -515,12 +585,13 @@ void settings_check_module(const char *module)
for (; tmp != NULL; tmp = next) {
node = tmp->data;
next = config_node_next(tmp);
+ if (node->key == NULL) continue;
set = g_hash_table_lookup(settings, node->key);
if (backwards_compatibility(module, node, parent))
continue;
- if (set == NULL || strcmp(set->module, module) != 0) {
+ if (set == NULL || g_strcmp0(set->module, module) != 0) {
g_string_append_printf(errors, " %s", node->key);
count++;
}
@@ -548,9 +619,9 @@ void settings_check_module(const char *module)
static int settings_compare(SETTINGS_REC *v1, SETTINGS_REC *v2)
{
- int cmp = strcmp(v1->section, v2->section);
+ int cmp = g_strcmp0(v1->section, v2->section);
if (!cmp)
- cmp = strcmp(v1->key, v2->key);
+ cmp = g_strcmp0(v1->key, v2->key);
return cmp;
}
@@ -682,7 +753,7 @@ static void init_configfile(void)
if (stat(get_irssi_dir(), &statbuf) != 0) {
/* ~/.irssi not found, create it. */
- if (mkpath(get_irssi_dir(), 0700) != 0) {
+ if (g_mkdir_with_parents(get_irssi_dir(), 0700) != 0) {
g_error("Couldn't create %s directory", get_irssi_dir());
}
} else if (!S_ISDIR(statbuf.st_mode)) {