void tconfig_merge(struct tconfig_block *src, struct tconfig_block *dst) { struct tconfig_block *tmp; int depth = 0; /* 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) return dst; else if (dst == NULL) return src; 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(tmp->key); dst->value = tstrdup(tmp->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; } depth++; src = src->child; continue; } if (src->next != 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)) { /* 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); } src = src->next; continue; } 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); } while (src->next == NULL) { while (src->parent == NULL) { src = src->prev; src = src->parent; depth--; if (depth == 0) break; } } src = src->next; } }