[augeas-devel] [PATCH] Fix behavior of aug_defnode
lutter at redhat.com
lutter at redhat.com
Fri Aug 6 22:03:21 UTC 2010
From: David Lutterkort <lutter at redhat.com>
(1) Make sure that the definition of the variable is recorded under
/augeas/variables
(2) Do not report an error if the expression evaluates to a non-empty
nodeset
* src/augeas.c (aug_defvar): split creating metadata under
/augeas/variables into record_var_meta; (aug_defnode): do not return an
error when expr evaluates to nonempty node set; record variable
definition
* tests/test-api.c: add tests for defvar and defnode behavior
---
src/augeas.c | 51 ++++++++++++++++++--------
tests/test-api.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 138 insertions(+), 16 deletions(-)
diff --git a/src/augeas.c b/src/augeas.c
index d10966d..d2ef353 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -597,6 +597,24 @@ int aug_get(const struct augeas *aug, const char *path, const char **value) {
return -1;
}
+static void record_var_meta(struct augeas *aug, const char *name,
+ const char *expr) {
+ /* Record the definition of the variable */
+ struct tree *tree = tree_path_cr(aug->origin, 2, s_augeas, s_vars);
+ ERR_NOMEM(tree == NULL, aug);
+ if (expr == NULL) {
+ tree = tree_child(tree, name);
+ if (tree != NULL)
+ tree_unlink(tree);
+ } else {
+ tree = tree_child_cr(tree, name);
+ ERR_NOMEM(tree == NULL, aug);
+ tree_set_value(tree, expr);
+ }
+ error:
+ return;
+}
+
int aug_defvar(augeas *aug, const char *name, const char *expr) {
struct pathx *p = NULL;
int result = -1;
@@ -612,18 +630,8 @@ int aug_defvar(augeas *aug, const char *name, const char *expr) {
}
ERR_BAIL(aug);
- /* Record the definition of the variable */
- struct tree *tree = tree_path_cr(aug->origin, 2, s_augeas, s_vars);
- ERR_NOMEM(tree == NULL, aug);
- if (expr == NULL) {
- tree = tree_child(tree, name);
- if (tree != NULL)
- tree_unlink(tree);
- } else {
- tree = tree_child_cr(tree, name);
- ERR_NOMEM(tree == NULL, aug);
- tree_set_value(tree, expr);
- }
+ record_var_meta(aug, name, expr);
+ ERR_BAIL(aug);
error:
free_pathx(p);
api_exit(aug);
@@ -647,18 +655,29 @@ int aug_defnode(augeas *aug, const char *name, const char *expr,
p = pathx_aug_parse(aug, aug->origin, expr, false);
ERR_BAIL(aug);
- r = pathx_expand_tree(p, &tree);
- if (r < 0)
- goto done;
+ if (pathx_first(p) == NULL) {
+ r = pathx_expand_tree(p, &tree);
+ if (r < 0)
+ goto done;
+ *created = 1;
+ } else {
+ *created = 0;
+ }
- *created = r > 0;
if (*created) {
r = tree_set_value(tree, value);
if (r < 0)
goto done;
result = pathx_symtab_assign_tree(&(aug->symtab), name, tree);
+ char *e = path_of_tree(tree);
+ ERR_NOMEM(e == NULL, aug)
+ record_var_meta(aug, name, e);
+ free(e);
+ ERR_BAIL(aug);
} else {
result = pathx_symtab_define(&(aug->symtab), name, p);
+ record_var_meta(aug, name, expr);
+ ERR_BAIL(aug);
}
done:
diff --git a/tests/test-api.c b/tests/test-api.c
index eba109c..322f4a9 100644
--- a/tests/test-api.c
+++ b/tests/test-api.c
@@ -120,6 +120,106 @@ static void testSetM(CuTest *tc) {
r = aug_setm(aug, "/augeas/version/save/*", "mode[]", "invalid");
CuAssertIntEquals(tc, -1, r);
+
+ aug_close(aug);
+}
+
+/* Check that defining a variable leads to a corresponding entry in
+ * /augeas/variables and that that entry disappears when the variable is
+ * undefined */
+static void testDefVarMeta(CuTest *tc) {
+ int r;
+ struct augeas *aug;
+ static const char *const expr = "/augeas/version/save/mode";
+ const char *value;
+
+ aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
+ CuAssertPtrNotNull(tc, aug);
+ CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
+
+ r = aug_defvar(aug, "var", expr);
+ CuAssertIntEquals(tc, 4, r);
+
+ r = aug_match(aug, "/augeas/variables/*", NULL);
+ CuAssertIntEquals(tc, 1, r);
+
+ r = aug_get(aug, "/augeas/variables/var", &value);
+ CuAssertStrEquals(tc, expr, value);
+
+ r = aug_defvar(aug, "var", NULL);
+ CuAssertIntEquals(tc, 0, r);
+
+ r = aug_match(aug, "/augeas/variables/*", NULL);
+ CuAssertIntEquals(tc, 0, r);
+
+ aug_close(aug);
+}
+
+/* Check that defining a variable with defnode leads to a corresponding
+ * entry in /augeas/variables and that that entry disappears when the
+ * variable is undefined
+ */
+static void testDefNodeExistingMeta(CuTest *tc) {
+ int r, created;
+ struct augeas *aug;
+ static const char *const expr = "/augeas/version/save/mode";
+ const char *value;
+
+ aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
+ CuAssertPtrNotNull(tc, aug);
+ CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
+
+ r = aug_defnode(aug, "var", expr, "other", &created);
+ CuAssertIntEquals(tc, 4, r);
+ CuAssertIntEquals(tc, 0, created);
+
+ r = aug_match(aug, "/augeas/variables/*", NULL);
+ CuAssertIntEquals(tc, 1, r);
+
+ r = aug_get(aug, "/augeas/variables/var", &value);
+ CuAssertStrEquals(tc, expr, value);
+
+ r = aug_defvar(aug, "var", NULL);
+ CuAssertIntEquals(tc, 0, r);
+
+ r = aug_match(aug, "/augeas/variables/*", NULL);
+ CuAssertIntEquals(tc, 0, r);
+
+ aug_close(aug);
+}
+
+/* Check that defining a variable with defnode leads to a corresponding
+ * entry in /augeas/variables and that that entry disappears when the
+ * variable is undefined
+ */
+static void testDefNodeCreateMeta(CuTest *tc) {
+ int r, created;
+ struct augeas *aug;
+ static const char *const expr = "/augeas/version/save/mode[last()+1]";
+ static const char *const expr_can = "/augeas/version/save/mode[5]";
+ const char *value;
+
+ aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
+ CuAssertPtrNotNull(tc, aug);
+ CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
+
+ r = aug_defnode(aug, "var", expr, "other", &created);
+ CuAssertIntEquals(tc, 1, r);
+ CuAssertIntEquals(tc, 1, created);
+
+ r = aug_match(aug, "/augeas/variables/*", NULL);
+ CuAssertIntEquals(tc, 1, r);
+
+ r = aug_get(aug, "/augeas/variables/var", &value);
+ CuAssertStrEquals(tc, expr_can, value);
+
+ r = aug_defvar(aug, "var", NULL);
+ CuAssertIntEquals(tc, 0, r);
+
+ r = aug_match(aug, "/augeas/variables/*", NULL);
+ CuAssertIntEquals(tc, 0, r);
+
+ aug_close(aug);
}
int main(void) {
@@ -129,6 +229,9 @@ int main(void) {
SUITE_ADD_TEST(suite, testGet);
SUITE_ADD_TEST(suite, testSetM);
+ SUITE_ADD_TEST(suite, testDefVarMeta);
+ SUITE_ADD_TEST(suite, testDefNodeExistingMeta);
+ SUITE_ADD_TEST(suite, testDefNodeCreateMeta);
abs_top_srcdir = getenv("abs_top_srcdir");
if (abs_top_srcdir == NULL)
--
1.7.2.1
More information about the augeas-devel
mailing list