diff --git a/src/core/settings.c b/src/core/settings.c index 4e0717cd..881a129e 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -703,6 +703,13 @@ int irssi_config_is_changed(const char *fname) config_last_checksum != file_checksum(fname)); } +static gboolean filter_stub(const char *key, const char *value, char **new_value) +{ + g_warning("Filtering %s in %s", value, key); + *new_value = (char *)value; + return TRUE; +} + static CONFIG_REC *parse_configfile(const char *fname) { CONFIG_REC *config; @@ -736,6 +743,8 @@ static CONFIG_REC *parse_configfile(const char *fname) config = config_open(NULL, -1); } + config_set_filter_function(filter_stub); + if (config->fname != NULL) config_parse(config); else diff --git a/src/lib-config/get.c b/src/lib-config/get.c index a83686fd..eca12610 100644 --- a/src/lib-config/get.c +++ b/src/lib-config/get.c @@ -20,6 +20,8 @@ #include "module.h" +static ConfigFilterFunc filter_func = NULL; + CONFIG_NODE *config_node_find(CONFIG_NODE *node, const char *key) { GSList *tmp; @@ -165,7 +167,7 @@ CONFIG_NODE *config_node_traverse(CONFIG_REC *rec, const char *section, int crea char *config_get_str(CONFIG_REC *rec, const char *section, const char *key, const char *def) { CONFIG_NODE *parent, *node; - char *path; + char *path, *value; g_return_val_if_fail(rec != NULL, (char *) def); g_return_val_if_fail(key != NULL, (char *) def); @@ -190,7 +192,18 @@ char *config_get_str(CONFIG_REC *rec, const char *section, const char *key, cons } } - return (node == NULL || !has_node_value(node)) ? (char *) def : node->value; + if (node == NULL || !has_node_value(node)) + { + return (char *)def; + } + + if (node->do_filter && filter_func) + { + return filter_func(key, node->value, &value) ? + value : (char *)def; + } + + return node->value; } int config_get_int(CONFIG_REC *rec, const char *section, const char *key, int def) @@ -216,12 +229,24 @@ int config_get_bool(CONFIG_REC *rec, const char *section, const char *key, int d char *config_node_get_str(CONFIG_NODE *parent, const char *key, const char *def) { CONFIG_NODE *node; + char *value; if (parent == NULL) return (char *) def; node = config_node_find(parent, key); - return (char *) ((node != NULL && has_node_value(node)) ? - node->value : def); + + if (node == NULL || !has_node_value(node)) + { + return (char *)def; + } + + if (node->do_filter && filter_func) + { + return filter_func(key, node->value, &value) ? + value : (char *)def; + } + + return node->value; } int config_node_get_int(CONFIG_NODE *parent, const char *key, int def) @@ -339,3 +364,8 @@ GSList *config_node_next(GSList *list) list = list->next; return config_node_first(list); } + +void config_set_filter_function(ConfigFilterFunc func) +{ + filter_func = func; +} diff --git a/src/lib-config/iconfig.h b/src/lib-config/iconfig.h index 9b6e5c1e..9211eb22 100644 --- a/src/lib-config/iconfig.h +++ b/src/lib-config/iconfig.h @@ -18,8 +18,9 @@ typedef struct _CONFIG_NODE CONFIG_NODE; typedef struct _CONFIG_REC CONFIG_REC; struct _CONFIG_NODE { - int type; - char *key; + int type : 8; + int do_filter : 1; + char *key; void *value; }; @@ -46,6 +47,10 @@ struct _CONFIG_NODE { */ +typedef gboolean (*ConfigFilterFunc)(const char *key, + const char *value, + char **new_value); + struct _CONFIG_REC { char *fname; int create_mode; @@ -72,6 +77,8 @@ CONFIG_REC *config_open(const char *fname, int create_mode); void config_close(CONFIG_REC *rec); /* Change file name of config file */ void config_change_file_name(CONFIG_REC *rec, const char *fname, int create_mode); +/* Set the default function to handle the variable filtering */ +void config_set_filter_function(ConfigFilterFunc func); /* Parse configuration file */ int config_parse(CONFIG_REC *rec); diff --git a/src/lib-config/parse.c b/src/lib-config/parse.c index c106fc46..cbb11163 100644 --- a/src/lib-config/parse.c +++ b/src/lib-config/parse.c @@ -131,7 +131,7 @@ static GTokenType config_parse_symbol(CONFIG_REC *rec, CONFIG_NODE *node) { CONFIG_NODE *newnode; GTokenType last_char; - int print_warning; + int print_warning, do_filter; char *key; g_return_val_if_fail(rec != NULL, G_TOKEN_ERROR); @@ -151,12 +151,21 @@ static GTokenType config_parse_symbol(CONFIG_REC *rec, CONFIG_NODE *node) config_parse_get_token(rec->scanner, node); } + do_filter = FALSE; + switch (rec->scanner->token) { + case '&': + /* substitute value */ + do_filter = TRUE; + config_parse_warn_missing(rec, node, G_TOKEN_STRING, TRUE); + g_assert(rec->scanner->token == G_TOKEN_STRING); case G_TOKEN_STRING: /* value */ - config_node_set_str(rec, node, key, rec->scanner->value.v_string); + newnode = config_node_set_str(rec, node, key, rec->scanner->value.v_string); g_free_not_null(key); + newnode->do_filter = do_filter; + print_warning = TRUE; if (node->type == NODE_TYPE_LIST) { /* if it's last item it doesn't need comma */ @@ -167,7 +176,6 @@ static GTokenType config_parse_symbol(CONFIG_REC *rec, CONFIG_NODE *node) config_parse_warn_missing(rec, node, last_char, print_warning); break; - case '{': /* block */ if (key == NULL && node->type != NODE_TYPE_LIST) diff --git a/src/lib-config/write.c b/src/lib-config/write.c index 37e51f09..4558e77a 100644 --- a/src/lib-config/write.c +++ b/src/lib-config/write.c @@ -142,6 +142,7 @@ static int config_write_node(CONFIG_REC *rec, CONFIG_NODE *node, int line_feeds) case NODE_TYPE_KEY: if (config_write_word(rec, node->key, FALSE) == -1 || config_write_str(rec, " = ") == -1 || + (node->do_filter && config_write_str(rec, "&") == -1) || config_write_word(rec, node->value, TRUE) == -1) return -1; break; @@ -212,6 +213,8 @@ static int config_node_get_length(CONFIG_REC *rec, CONFIG_NODE *node) case NODE_TYPE_KEY: /* "key = value; " */ len = 5 + strlen(node->key) + strlen(node->value); + /* optional '&' before the value */ + len += node->do_filter ? 1 : 0; break; case NODE_TYPE_VALUE: /* "value, " */