struct tconfig_block { char *key; char *value; struct tconfig_block *prev; struct tconfig_block *next; struct tconfig_block *parent; struct tconfig_block *child; }; void tconfig_merge(struct tconfig_block *src, struct tconfig_block *dst) { struct tconfig_block *tmp; int depth = 0; /* int wild_depth = -1; */ /* We want to start at the initial positions and traverse down from * there, copying the keys and values and subkeys maintaining current * order if it already exists. */ if (src == NULL || dst == NULL) return; while (src != NULL) { if (src->child != NULL) { tmp = dst; /* Make sure it's at the beginning */ while (tmp->prev != NULL) tmp = tmp->prev; while (tmp != NULL) { if (tmp->key != NULL) { if (!strcmp(src->key,tmp->key) && !strcmp(src->value,tmp->value)) { /* It's a match, merely attach to it */ dst = tmp->child; break; } } tmp = tmp->next; } if (tmp == NULL) { /* No matches, create they key/value parent node */ while (dst->next != NULL && dst->key != NULL) dst = dst->next; if (dst->key != NULL) { dst->next = tmalloc(sizeof(struct tconfig_block)); dst->next->prev = dst; dst->next->next = NULL; dst = dst->next; } dst->key = tstrdup(src->key); dst->value = tstrdup(src->value); dst->parent = NULL; dst->child = tmalloc(sizeof(struct tconfig_block)); dst->child->parent = dst; dst = dst->child; dst->key = NULL; dst->value = NULL; dst->child = NULL; dst->prev = NULL; dst->next = NULL; } depth++; src = src->child; } tmp = dst; /* Make sure it's at the beginning */ while (tmp->prev != NULL) tmp = tmp->prev; while (tmp != NULL) { if (tmp->key != NULL) { if (!strcmp(src->key,tmp->key) && !strcmp(src->value,tmp->value)) { /* Ignore dupes */ break; } } tmp = tmp->next; } if (tmp == NULL) { /* go to the end of the list */ while (dst->next != NULL && dst->key != NULL) dst = dst->next; if (dst->key != NULL) { dst->next = tmalloc(sizeof(struct tconfig_block)); dst->next->prev = dst; dst = dst->next; dst->next = NULL; dst->parent = NULL; dst->child = NULL; } dst->key = tstrdup(src->key); dst->value = tstrdup(src->value); dst->next = NULL; } while (src->next == NULL) { if (depth == 0) return; while (src->prev != NULL) src = src->prev; /* Do the same to dst */ while (dst->prev != NULL) dst = dst->prev; src = src->parent; dst = dst->parent; depth--; } src = src->next; } }