/* 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 *pathx_parse_glue(struct info *info, struct value *tree, struct value *path, struct pathx **p) { assert(path->tag == V_STRING); assert(tree->tag == V_TREE); if (pathx_parse(tree->origin, info->error, path->string->str, true, NULL, NULL, p) != PATHX_NOERROR) { return make_pathx_exn(ref(info), *p); } else { return NULL; } }
/* 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; }