static struct config_value *_clone_config_value(struct dm_pool *mem, const struct config_value *v) { struct config_value *new_cv; if (!v) return NULL; if (!(new_cv = _create_value(mem))) { log_error("Failed to clone config value."); return NULL; } new_cv->type = v->type; if (v->type == CFG_STRING) { if (!(new_cv->v.str = dm_pool_strdup(mem, v->v.str))) { log_error("Failed to clone config string value."); return NULL; } } else new_cv->v = v->v; if (v->next && !(new_cv->next = _clone_config_value(mem, v->next))) return_NULL; return new_cv; }
struct config_node *clone_config_node_with_mem(struct dm_pool *mem, const struct config_node *cn, int siblings) { struct config_node *new_cn; if (!cn) return NULL; if (!(new_cn = _create_node(mem))) { log_error("Failed to clone config node."); return NULL; } if ((cn->key && !(new_cn->key = dm_pool_strdup(mem, cn->key)))) { log_error("Failed to clone config node key."); return NULL; } if ((cn->v && !(new_cn->v = _clone_config_value(mem, cn->v))) || (cn->child && !(new_cn->child = clone_config_node_with_mem(mem, cn->child, 1))) || (siblings && cn->sib && !(new_cn->sib = clone_config_node_with_mem(mem, cn->sib, siblings)))) return_NULL; /* 'new_cn' released with mem pool */ return new_cn; }
static int _override_path(const char *path, struct dm_config_node *node, void *baton) { struct dm_config_tree *cft = baton; struct dm_config_node dummy, *target; dummy.child = cft->root; if (!(target = _find_or_make_node(cft->mem, &dummy, path))) return_0; if (!(target->v = _clone_config_value(cft->mem, node->v))) return_0; cft->root = dummy.child; return 1; }