diff options
Diffstat (limited to 'src/lib-config')
-rw-r--r-- | src/lib-config/get.c | 36 | ||||
-rw-r--r-- | src/lib-config/iconfig.h | 14 | ||||
-rw-r--r-- | src/lib-config/parse.c | 21 | ||||
-rw-r--r-- | src/lib-config/set.c | 25 | ||||
-rw-r--r-- | src/lib-config/write.c | 7 |
5 files changed, 83 insertions, 20 deletions
diff --git a/src/lib-config/get.c b/src/lib-config/get.c index b5c3f42e..8ac3e667 100644 --- a/src/lib-config/get.c +++ b/src/lib-config/get.c @@ -40,11 +40,10 @@ CONFIG_NODE *config_node_find(CONFIG_NODE *node, const char *key) /* find the section from node - if not found create it unless new_type is -1. you can also specify in new_type if it's NODE_TYPE_LIST or NODE_TYPE_BLOCK */ -CONFIG_NODE *config_node_section(CONFIG_REC *rec, CONFIG_NODE *parent, const char *key, int new_type) +CONFIG_NODE *config_node_section(CONFIG_NODE *parent, const char *key, int new_type) { CONFIG_NODE *node; - g_return_val_if_fail(rec != NULL, NULL); g_return_val_if_fail(parent != NULL, NULL); g_return_val_if_fail(is_node_list(parent), NULL); @@ -91,7 +90,7 @@ CONFIG_NODE *config_node_traverse(CONFIG_REC *rec, const char *section, int crea is_list = **tmp == '('; if (create) new_type = is_list ? NODE_TYPE_LIST : NODE_TYPE_BLOCK; - node = config_node_section(rec, node, *tmp + is_list, new_type); + node = config_node_section(node, *tmp + is_list, new_type); if (node == NULL) return NULL; } g_strfreev(list); @@ -252,3 +251,34 @@ int config_node_get_keyvalue(CONFIG_NODE *node, const char *key, const char *val return -1; } + +/* Return all values from from the list `node' in a g_strsplit() array */ +char **config_node_get_list(CONFIG_NODE *node) +{ + GString *values; + GSList *tmp; + char **ret; + + g_return_val_if_fail(node != NULL, NULL); + g_return_val_if_fail(is_node_list(node), NULL); + + /* put values to string */ + values = g_string_new(NULL); + for (tmp = node->value; tmp != NULL; tmp = tmp->next) { + node = tmp->data; + + if (node->type == NODE_TYPE_VALUE) + g_string_sprintfa(values, "%s ", (char *) node->value); + } + + /* split the values to **str array */ + if (values->len == 0) + ret = NULL; + else { + g_string_truncate(values, values->len-1); + ret = g_strsplit(values->str, " ", -1); + } + + g_string_free(values, TRUE); + return ret; +} diff --git a/src/lib-config/iconfig.h b/src/lib-config/iconfig.h index bbee0f6e..320b0629 100644 --- a/src/lib-config/iconfig.h +++ b/src/lib-config/iconfig.h @@ -108,13 +108,17 @@ int config_set_bool(CONFIG_REC *rec, const char *section, const char *key, int v CONFIG_NODE *config_node_find(CONFIG_NODE *node, const char *key); /* Find the section from node - if not found create it unless new_type is -1. You can also specify in new_type if it's NODE_TYPE_LIST or NODE_TYPE_BLOCK */ -CONFIG_NODE *config_node_section(CONFIG_REC *rec, CONFIG_NODE *parent, const char *key, int new_type); +CONFIG_NODE *config_node_section(CONFIG_NODE *parent, const char *key, int new_type); /* Find the section with the whole path. Create the path if necessary `create' is TRUE. */ CONFIG_NODE *config_node_traverse(CONFIG_REC *rec, const char *section, int create); /* Get the value of keys `key' and `key_value' and put them to `ret_key' and `ret_value'. Returns -1 if not found. */ int config_node_get_keyvalue(CONFIG_NODE *node, const char *key, const char *value_key, char **ret_key, char **ret_value); +/* Return all values from from the list `node' in a g_strsplit() array */ +char **config_node_get_list(CONFIG_NODE *node); +/* Add all values in `array' to `node' */ +void config_node_add_list(CONFIG_NODE *node, char **array); char *config_node_get_str(CONFIG_NODE *parent, const char *key, const char *def); int config_node_get_int(CONFIG_NODE *parent, const char *key, int def); @@ -124,13 +128,15 @@ void config_node_set_str(CONFIG_NODE *parent, const char *key, const char *value void config_node_set_int(CONFIG_NODE *parent, const char *key, int value); void config_node_set_bool(CONFIG_NODE *parent, const char *key, int value); -/* add/change the value of the `key' */ +/* Add/change the value of the `key' */ void config_node_set_str(CONFIG_NODE *parent, const char *key, const char *value); -/* remove one node from block/list. +/* Remove one node from block/list. ..set_str() with value = NULL does the same. */ void config_node_remove(CONFIG_NODE *parent, CONFIG_NODE *node); +/* Remove n'th node from a list */ +void config_node_list_remove(CONFIG_NODE *node, int index); -/* clear the entire configuration */ +/* Clear the entire configuration */ void config_nodes_remove_all(CONFIG_REC *rec); #endif diff --git a/src/lib-config/parse.c b/src/lib-config/parse.c index 5171161c..25f9ccec 100644 --- a/src/lib-config/parse.c +++ b/src/lib-config/parse.c @@ -62,7 +62,7 @@ static void config_parse_get_token(GScanner *scanner, CONFIG_NODE *node) #undef g_strdup_printf /* This is free'd by GLib itself */ scanner->value.v_string = g_strdup_printf("%lu", scanner->value.v_int); #ifdef MEM_DEBUG -#define g_strdup_printf ig_strdup_printf +#define g_strdup_printf(a, b...) ig_strdup_printf(__FILE__, __LINE__, a, ##b) #endif } break; @@ -127,8 +127,10 @@ static int config_parse_symbol(CONFIG_REC *rec, CONFIG_NODE *node) key = g_strdup(rec->scanner->value.v_string); config_parse_get_token(rec->scanner, node); - if (rec->scanner->token != '=') + if (rec->scanner->token != '=') { + g_free(key); return '='; + } config_parse_get_token(rec->scanner, node); } @@ -155,7 +157,7 @@ static int config_parse_symbol(CONFIG_REC *rec, CONFIG_NODE *node) if (key == NULL && node->type != NODE_TYPE_LIST) return G_TOKEN_ERROR; - newnode = config_node_section(rec, node, key, NODE_TYPE_BLOCK); + newnode = config_node_section(node, key, NODE_TYPE_BLOCK); config_parse_loop(rec, newnode, '}'); g_free_not_null(key); @@ -170,7 +172,7 @@ static int config_parse_symbol(CONFIG_REC *rec, CONFIG_NODE *node) /* list */ if (key == NULL) return G_TOKEN_ERROR; - newnode = config_node_section(rec, node, key, NODE_TYPE_LIST); + newnode = config_node_section(node, key, NODE_TYPE_LIST); config_parse_loop(rec, newnode, ')'); g_free_not_null(key); @@ -197,17 +199,18 @@ static void config_parse_loop(CONFIG_REC *rec, CONFIG_NODE *node, int expect) g_return_if_fail(rec != NULL); g_return_if_fail(node != NULL); - do { + for (;;) { + config_parse_peek_token(rec->scanner, node); + if (rec->scanner->next_token == expect || + rec->scanner->next_token == G_TOKEN_EOF) break; + expected_token = config_parse_symbol(rec, node); if (expected_token != G_TOKEN_NONE) { if (expected_token == G_TOKEN_ERROR) expected_token = G_TOKEN_NONE; g_scanner_unexp_token(rec->scanner, expected_token, NULL, "symbol", NULL, NULL, TRUE); } - - config_parse_peek_token(rec->scanner, node); - } while (rec->scanner->next_token != expect && - rec->scanner->next_token != G_TOKEN_EOF); + } } static void config_parse_error_func(GScanner *scanner, char *message, int is_error) diff --git a/src/lib-config/set.c b/src/lib-config/set.c index 49457576..6748fce9 100644 --- a/src/lib-config/set.c +++ b/src/lib-config/set.c @@ -43,6 +43,22 @@ void config_node_remove(CONFIG_NODE *parent, CONFIG_NODE *node) g_free(node); } +/* Remove n'th node from a list */ +void config_node_list_remove(CONFIG_NODE *node, int index) +{ + GSList *tmp; + + g_return_if_fail(node != NULL); + g_return_if_fail(is_node_list(node)); + + for (tmp = node->value; tmp != NULL; tmp = tmp->next, index--) { + if (index == 0) { + config_node_remove(node, tmp->data); + break; + } + } +} + void config_nodes_remove_all(CONFIG_REC *rec) { g_return_if_fail(rec != NULL); @@ -120,3 +136,12 @@ int config_set_bool(CONFIG_REC *rec, const char *section, const char *key, int v { return config_set_str(rec, section, key, value ? "yes" : "no"); } + +/* Add all values in `array' to `node' */ +void config_node_add_list(CONFIG_NODE *node, char **array) +{ + char **tmp; + + for (tmp = array; *tmp != NULL; tmp++) + config_node_set_str(node, NULL, *tmp); +} diff --git a/src/lib-config/write.c b/src/lib-config/write.c index 30a41fd4..552600a7 100644 --- a/src/lib-config/write.c +++ b/src/lib-config/write.c @@ -76,7 +76,7 @@ static int config_has_specials(const char *text) g_return_val_if_fail(text != NULL, FALSE); while (*text != '\0') { - if ((unsigned char) *text <= 32 || *text == '"' || *text == '\\') + if (!isalnum((int) *text)) return TRUE; text++; } @@ -162,7 +162,7 @@ static int config_write_node(CONFIG_REC *rec, CONFIG_NODE *node, int line_feeds) case NODE_TYPE_BLOCK: /* key = { */ if (node->key != NULL) { - if (config_write_str(rec, node->key) == -1 || + if (config_write_word(rec, node->key, FALSE) == -1 || config_write_str(rec, " = ") == -1) return -1; } @@ -182,7 +182,7 @@ static int config_write_node(CONFIG_REC *rec, CONFIG_NODE *node, int line_feeds) case NODE_TYPE_LIST: /* key = ( */ if (node->key != NULL) { - if (config_write_str(rec, node->key) == -1 || + if (config_write_word(rec, node->key, FALSE) == -1 || config_write_str(rec, " = ") == -1) return -1; } @@ -327,7 +327,6 @@ int config_write(CONFIG_REC *rec, const char *fname, int create_mode) config_error(rec, errno == 0 ? "bug" : g_strerror(errno)); return -1; } - write(rec->handle, "\n", 1); close(rec->handle); rec->handle = -1; |