/* V_STRING -> V_TREE -> V_TREE */ static struct value *tree_rm_glue(struct info *info, struct value *path, struct value *tree) { // FIXME: This only works if TREE is not referenced more than once; // otherwise we'll have some pretty weird semantics, and would really // need to copy TREE first assert(path->tag == V_STRING); assert(tree->tag == V_TREE); struct pathx *p = NULL; struct value *result = NULL; if (pathx_parse(tree->origin, NULL, path->string->str, true, NULL, &p) != PATHX_NOERROR) { result = make_pathx_exn(ref(info), p); goto done; } if (tree_rm(p) == -1) { result = make_exn_value(ref(info), "Tree rm of %s failed", path->string->str); goto done; } result = ref(tree); done: free_pathx(p); return result; }
static struct value *tree_insert_glue(struct info *info, struct value *label, struct value *path, struct value *tree, int before) { // FIXME: This only works if TREE is not referenced more than once; // otherwise we'll have some pretty weird semantics, and would really // need to copy TREE first assert(label->tag == V_STRING); assert(path->tag == V_STRING); assert(tree->tag == V_TREE); int r; struct pathx *p = NULL; struct value *result = NULL; result = pathx_parse_glue(info, tree, path, &p); if (result != NULL) goto done; r = tree_insert(p, label->string->str, before); if (r != 0) { result = make_exn_value(ref(info), "Tree insert of %s at %s failed", label->string->str, path->string->str); goto done; } result = ref(tree); done: free_pathx(p); return result; }
/* V_STRING -> V_STRING -> V_TREE -> V_TREE */ static struct value *tree_set_glue(struct info *info, struct value *path, struct value *val, struct value *tree) { // FIXME: This only works if TREE is not referenced more than once; // otherwise we'll have some pretty weird semantics, and would really // need to copy TREE first assert(path->tag == V_STRING); assert(val->tag == V_STRING); assert(tree->tag == V_TREE); struct tree *fake = NULL; struct pathx *p = NULL; struct value *result = NULL; if (tree->origin->children == NULL) { tree->origin->children = make_tree(NULL, NULL, tree->origin, NULL); fake = tree->origin->children; } if (pathx_parse(tree->origin, NULL, path->string->str, true, NULL, &p) != PATHX_NOERROR) { result = make_pathx_exn(ref(info), p); goto done; } if (tree_set(p, val->string->str) == NULL) { result = make_exn_value(ref(info), "Tree set of %s to '%s' failed", path->string->str, val->string->str); goto done; } if (fake != NULL) { list_remove(fake, tree->origin->children); free_tree(fake); } result = ref(tree); done: free_pathx(p); return result; }