[augeas-devel] augeas: master - defnode: when creating new node, put it in the nodeset
David Lutterkort
lutter at fedoraproject.org
Fri Aug 7 00:21:49 UTC 2009
Gitweb: http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=a7ee31686ec24ef53eb85722c016a8c8902875be
Commit: a7ee31686ec24ef53eb85722c016a8c8902875be
Parent: 9cc90c45e35fb85b9c1a6af528b93371ebbd7426
Author: David Lutterkort <lutter at redhat.com>
AuthorDate: Thu Aug 6 17:09:26 2009 -0700
Committer: David Lutterkort <lutter at redhat.com>
CommitterDate: Thu Aug 6 17:09:26 2009 -0700
defnode: when creating new node, put it in the nodeset
When a new node is created, e.g. with 'defnode x "/foo[0 = 1]"' we used to
assign an empty nodeset to x. Now x will hold a reference to the newly
created node, even though the initial path expression would never match any
nodes.
* src/augeas.c (aug_defnode): call pathx_symtab_assign_tree after
creating a node
* src/pathx.c (pathx_symtab_assign_tree): new function to assign a single
tree node to a variable
* src/internal.h: declare pathx_symtab_assign_tree
* tests/test-xpath.c (test_defnode_nonexistent): test new behavior
---
src/augeas.c | 5 ++-
src/internal.h | 2 +
src/pathx.c | 71 +++++++++++++++++++++++++++++++++++++++++----------
tests/test-xpath.c | 7 ++++-
4 files changed, 68 insertions(+), 17 deletions(-)
diff --git a/src/augeas.c b/src/augeas.c
index 62339c5..b440803 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -410,10 +410,11 @@ int aug_defnode(augeas *aug, const char *name, const char *expr,
r = tree_set_value(tree, value);
if (r < 0)
goto done;
+ result = pathx_symtab_assign_tree(&(aug->symtab), name, tree);
+ } else {
+ result = pathx_symtab_define(&(aug->symtab), name, p);
}
- result = pathx_symtab_define(&(aug->symtab), name, p);
-
done:
free_pathx(p);
return result;
diff --git a/src/internal.h b/src/internal.h
index cc636ef..7f266b5 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -414,6 +414,8 @@ void free_pathx(struct pathx *path);
int pathx_symtab_init(struct pathx_symtab **symtab);
int pathx_symtab_define(struct pathx_symtab **symtab,
const char *name, struct pathx *px);
+int pathx_symtab_assign_tree(struct pathx_symtab **symtab, const char *name,
+ struct tree *tree);
int pathx_symtab_undefine(struct pathx_symtab **symtab, const char *name);
void pathx_symtab_remove_descendants(struct pathx *pathx,
const struct tree *tree);
diff --git a/src/pathx.c b/src/pathx.c
index d44aeb7..32d4aad 100644
--- a/src/pathx.c
+++ b/src/pathx.c
@@ -2248,9 +2248,36 @@ int pathx_symtab_init(struct pathx_symtab **symtab) {
return -1;
}
+static int pathx_symtab_set(struct pathx_symtab **symtab,
+ const char *name, struct value *v) {
+ int found = 0;
+
+ list_for_each(tab, *symtab) {
+ if (STREQ(tab->name, name)) {
+ release_value(tab->value);
+ free(tab->value);
+ tab->value = v;
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ struct pathx_symtab *new = NULL;
+
+ new = make_symtab(*symtab, name, v);
+ if (new == NULL)
+ goto error;
+ *symtab = new;
+ }
+ return 0;
+ error:
+ return -1;
+}
+
int pathx_symtab_define(struct pathx_symtab **symtab,
const char *name, struct pathx *px) {
- struct pathx_symtab *new;
+ int r;
struct value *value = NULL, *v = NULL;
value = pathx_eval(px);
@@ -2262,21 +2289,10 @@ int pathx_symtab_define(struct pathx_symtab **symtab,
*v = *value;
value->tag = T_BOOLEAN;
- list_for_each(tab, *symtab) {
- if (STREQ(tab->name, name)) {
- release_value(tab->value);
- free(tab->value);
- tab->value = v;
- goto done;
- }
- }
-
- new = make_symtab(*symtab, name, v);
- if (new == NULL)
+ r = pathx_symtab_set(symtab, name, v);
+ if (r < 0)
goto error;
- *symtab = new;
- done:
if (v->tag == T_NODESET)
return v->nodeset->used;
else
@@ -2302,6 +2318,33 @@ int pathx_symtab_undefine(struct pathx_symtab **symtab, const char *name) {
return 0;
}
+int pathx_symtab_assign_tree(struct pathx_symtab **symtab,
+ const char *name, struct tree *tree) {
+ struct value *v = NULL;
+ int r;
+
+ if (ALLOC(v) < 0)
+ goto error;
+
+ v->tag = T_NODESET;
+ if (ALLOC(v->nodeset) < 0)
+ goto error;
+ if (ALLOC_N(v->nodeset->nodes, 1) < 0)
+ goto error;
+ v->nodeset->used = 1;
+ v->nodeset->size = 1;
+ v->nodeset->nodes[0] = tree;
+
+ r = pathx_symtab_set(symtab, name, v);
+ if (r < 0)
+ goto error;
+ return 1;
+ error:
+ release_value(v);
+ free(v);
+ return -1;
+}
+
void pathx_symtab_remove_descendants(struct pathx *pathx,
const struct tree *tree) {
struct pathx_symtab *symtab = pathx->state->symtab;
diff --git a/tests/test-xpath.c b/tests/test-xpath.c
index 9a77e98..831e529 100644
--- a/tests/test-xpath.c
+++ b/tests/test-xpath.c
@@ -248,13 +248,18 @@ static int test_defnode_nonexistent(struct augeas *aug) {
int r, created;
printf("%-30s ... ", "defnode_nonexistent");
- r = aug_defnode(aug, "x", "/defnode/bar[. = 'foo']", "foo", &created);
+ r = aug_defnode(aug, "x", "/defnode/bar[0 = 1]", "foo", &created);
if (r != 1)
die("aug_defnode failed");
if (created != 1) {
fprintf(stderr, "defnode did not create a node\n");
goto fail;
}
+ r = aug_match(aug, "$x", NULL);
+ if (r != 1) {
+ fprintf(stderr, "$x must have exactly one entry, but has %d\n", r);
+ goto fail;
+ }
r = aug_defnode(aug, "x", "/defnode/bar", NULL, &created);
if (r != 1)
More information about the augeas-devel
mailing list