diff --git a/src/core/channels-setup.c b/src/core/channels-setup.c index ac9b1c23..62d43b2c 100644 --- a/src/core/channels-setup.c +++ b/src/core/channels-setup.c @@ -38,7 +38,7 @@ static void channel_setup_save(CHANNEL_SETUP_REC *channel) index = g_slist_index(setupchannels, channel); parentnode = iconfig_node_traverse("(channels", TRUE); - node = config_node_index(parentnode, index); + node = config_node_nth(parentnode, index); if (node == NULL) node = config_node_section(parentnode, NULL, NODE_TYPE_BLOCK); diff --git a/src/core/servers-setup.c b/src/core/servers-setup.c index 99f9f579..992f4e00 100644 --- a/src/core/servers-setup.c +++ b/src/core/servers-setup.c @@ -410,7 +410,7 @@ static void server_setup_save(SERVER_SETUP_REC *rec) index = g_slist_index(setupservers, rec); parentnode = iconfig_node_traverse("(servers", TRUE); - node = config_node_index(parentnode, index); + node = config_node_nth(parentnode, index); if (node == NULL) node = config_node_section(parentnode, NULL, NODE_TYPE_BLOCK); diff --git a/src/lib-config/get.c b/src/lib-config/get.c index 124d7101..e4c5cf07 100644 --- a/src/lib-config/get.c +++ b/src/lib-config/get.c @@ -41,8 +41,15 @@ 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_NODE *parent, const char *key, int new_type) +{ + return config_node_section_index(parent, key, -1, new_type); +} + +CONFIG_NODE *config_node_section_index(CONFIG_NODE *parent, const char *key, + int index, int new_type) { CONFIG_NODE *node; + int nindex; g_return_val_if_fail(parent != NULL, NULL); g_return_val_if_fail(is_node_list(parent), NULL); @@ -50,14 +57,22 @@ CONFIG_NODE *config_node_section(CONFIG_NODE *parent, const char *key, int new_t node = key == NULL ? NULL : config_node_find(parent, key); if (node != NULL) { g_return_val_if_fail(new_type == -1 || new_type == node->type, NULL); - return node; + nindex = g_slist_index(parent->value, node); + if (index >= 0 && nindex != index && + nindex <= g_slist_length(parent->value)) { + /* move it to wanted position */ + parent->value = g_slist_remove(parent->value, node); + parent->value = g_slist_insert(parent->value, node, index); + } + return node; } if (new_type == -1) return NULL; node = g_new0(CONFIG_NODE, 1); - parent->value = g_slist_append(parent->value, node); + parent->value = index < 0 ? g_slist_append(parent->value, node) : + g_slist_insert(parent->value, node, index); node->type = new_type; node->key = key == NULL ? NULL : g_strdup(key); @@ -294,7 +309,7 @@ char **config_node_get_list(CONFIG_NODE *node) } /* Returns n'th node from list. */ -CONFIG_NODE *config_node_index(CONFIG_NODE *node, int index) +CONFIG_NODE *config_node_nth(CONFIG_NODE *node, int index) { GSList *tmp; @@ -309,6 +324,21 @@ CONFIG_NODE *config_node_index(CONFIG_NODE *node, int index) return NULL; } +/* Returns index for given key */ +int config_node_index(CONFIG_NODE *parent, const char *key) +{ + CONFIG_NODE *node; + + g_return_val_if_fail(parent != NULL, -1); + g_return_val_if_fail(key != NULL, -1); + + node = config_node_find(parent, key); + if (node == NULL) + return -1; + + return g_slist_index(parent->value, node); +} + /* Returns the first non-comment node in list */ GSList *config_node_first(GSList *list) { diff --git a/src/lib-config/iconfig.h b/src/lib-config/iconfig.h index fc475f4e..7ef8d791 100644 --- a/src/lib-config/iconfig.h +++ b/src/lib-config/iconfig.h @@ -98,7 +98,9 @@ const char *config_list_find(CONFIG_REC *rec, const char *section, const char *k /* Like config_list_find(), but return node instead of it's value */ CONFIG_NODE *config_list_find_node(CONFIG_REC *rec, const char *section, const char *key, const char *value, const char *value_key); /* Returns n'th node from list. */ -CONFIG_NODE *config_node_index(CONFIG_NODE *node, int index); +CONFIG_NODE *config_node_nth(CONFIG_NODE *node, int index); +/* Returns index for given key */ +int config_node_index(CONFIG_NODE *parent, const char *key); /* Returns the first non-comment node in list */ GSList *config_node_first(GSList *list); @@ -116,6 +118,8 @@ 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_NODE *parent, const char *key, int new_type); +CONFIG_NODE *config_node_section_index(CONFIG_NODE *parent, const char *key, + int index, 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); diff --git a/src/lib-config/set.c b/src/lib-config/set.c index fdb358f9..6cfaa483 100644 --- a/src/lib-config/set.c +++ b/src/lib-config/set.c @@ -67,7 +67,7 @@ void config_node_list_remove(CONFIG_REC *rec, CONFIG_NODE *node, int index) g_return_if_fail(node != NULL); g_return_if_fail(is_node_list(node)); - child = config_node_index(node, index); + child = config_node_nth(node, index); if (child != NULL) config_node_remove(rec, node, child); }