mirror of
https://github.com/irssi/irssi.git
synced 2026-08-22 01:52:19 +02:00
Introduce variable filtering in the config files
Prepending a '&' to a quoted string makes the given string to be filtered trough an user-supplied function. Right now it does return the value as-is.
This commit is contained in:
parent
795301f679
commit
a9a3dba50d
5 changed files with 66 additions and 9 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ typedef struct _CONFIG_NODE CONFIG_NODE;
|
|||
typedef struct _CONFIG_REC CONFIG_REC;
|
||||
|
||||
struct _CONFIG_NODE {
|
||||
int type;
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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, " */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue