[augeas-devel] [PATCH] New API call aug_defnode and augtool command defnode
David Lutterkort
lutter at redhat.com
Tue Mar 24 01:47:05 UTC 2009
It's common that we want to define a variable to reference /foo/bar, and
create that node if it does not exist yet. aug_defnode bundles that
together into one convenient.
---
src/augeas.c | 23 +++++++++++++++++++++--
src/augeas.h | 15 +++++++++++++++
src/augeas_sym.version | 1 +
src/augtool.c | 17 +++++++++++++++++
src/internal.h | 3 ++-
tests/test-xpath.c | 28 ++++++++++++++++++++++++++++
6 files changed, 84 insertions(+), 3 deletions(-)
diff --git a/src/augeas.c b/src/augeas.c
index 8006883..83517d1 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -365,22 +365,41 @@ int aug_get(const struct augeas *aug, const char *path, const char **value) {
return r;
}
-int aug_defvar(augeas *aug, const char *name, const char *expr) {
+static int symtab_define(struct augeas *aug, const char *name,
+ const char *expr, bool expand_tree) {
struct pathx *p;
int r;
if (expr == NULL) {
r = pathx_symtab_undefine(&(aug->symtab), name);
} else {
+ struct tree *dummy;
+
p = parse_user_pathx((struct augeas *) aug, false, expr);
if (p == NULL)
- return -1;
+ goto done;
+ if (expand_tree) {
+ r = pathx_expand_tree(p, &dummy);
+ if (r < 0)
+ goto done;
+ }
r = pathx_symtab_define(&(aug->symtab), name, p);
}
+ done:
free_pathx(p);
return (r < 0) ? -1 : 0;
}
+int aug_defvar(augeas *aug, const char *name, const char *expr) {
+ return symtab_define(aug, name, expr, false);
+}
+
+int aug_defnode(augeas *aug, const char *name, const char *expr) {
+ if (expr == NULL)
+ return -1;
+ return symtab_define(aug, name, expr, true);
+}
+
struct tree *tree_set(struct pathx *p, const char *value) {
struct tree *tree;
int r;
diff --git a/src/augeas.h b/src/augeas.h
index be1ad65..67c0e27 100644
--- a/src/augeas.h
+++ b/src/augeas.h
@@ -83,6 +83,21 @@ augeas *aug_init(const char *root, const char *loadpath, unsigned int flags);
*/
int aug_defvar(augeas *aug, const char *name, const char *expr);
+/* Function: aug_defnode
+ *
+ * Define a variable NAME whose value is the result of evaluating EXPR,
+ * which must be non-NULL and evaluate to a nodeset. If a variable NAME
+ * already exists, its name will be replaced with the result of evaluating
+ * EXPR.
+ *
+ * If EXPR evaluates to an empty nodeset, a node is created, equivalent to
+ * calling AUG_SET(AUG, EXPR, NULL) and NAME will be the nodeset containing
+ * that single node.
+ *
+ * Returns 0 on success, -1 on error
+ */
+int aug_defnode(augeas *aug, const char *name, const char *expr);
+
/* Function: aug_get
*
* Lookup the value associated with PATH. VALUE can be NULL, in which case
diff --git a/src/augeas_sym.version b/src/augeas_sym.version
index f0c887e..0fdc03d 100644
--- a/src/augeas_sym.version
+++ b/src/augeas_sym.version
@@ -2,6 +2,7 @@
global:
aug_init;
aug_defvar;
+ aug_defnode;
aug_close;
aug_get;
aug_set;
diff --git a/src/augtool.c b/src/augtool.c
index 9b1d772..9d7365b 100644
--- a/src/augtool.c
+++ b/src/augtool.c
@@ -205,6 +205,17 @@ static int cmd_defvar(char *args[]) {
return r;
}
+static int cmd_defnode(char *args[]) {
+ const char *name = args[0];
+ const char *path = cleanpath(args[1]);
+ int r;
+
+ r = aug_defnode(aug, name, path);
+ if (r == -1)
+ printf ("Failed\n");
+ return r;
+}
+
static int cmd_clear(char *args[]) {
const char *path = cleanpath(args[0]);
int r;
@@ -408,6 +419,12 @@ static const struct command const commands[] = {
" variable can be used in path expressions as $NAME. Note that EXPR\n"
" is evaluated when the variable is defined, not when it is used."
},
+ { "defnode", 2, 2, cmd_defnode, "defnode <NAME> <EXPR>",
+ "Define the variable NAME to the result of evalutating EXPR, which\n"
+ " must be a nodeset. If no node matching EXPR exists yet, one\n"
+ " is created in the same way 'clear EXPR' would and NAME refers\n"
+ " to that node."
+ },
{ "help", 0, 0, cmd_help, "help",
"Print this help text"
},
diff --git a/src/internal.h b/src/internal.h
index 76d9c6d..060c95f 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -385,7 +385,8 @@ typedef enum {
PATHX_EINTERNAL,
PATHX_ETYPE,
PATHX_ENOVAR,
- PATHX_EEND
+ PATHX_EEND,
+ PATHX_ENONODES
} pathx_errcode_t;
struct pathx;
diff --git a/tests/test-xpath.c b/tests/test-xpath.c
index 9cfb8ab..710b875 100644
--- a/tests/test-xpath.c
+++ b/tests/test-xpath.c
@@ -244,6 +244,31 @@ static int test_defvar_nonexistent(struct augeas *aug) {
return -1;
}
+static int test_defnode_nonexistent(struct augeas *aug) {
+ int r;
+
+ printf("%-30s ... ", "defnode_nonexistent");
+ r = aug_defnode(aug, "x", "/defnode/bar");
+ if (r < 0)
+ die("aug_defnode failed");
+
+ r = aug_set(aug, "$x", "baz");
+ printf("\nset %d\n", r);
+ if (r != 0)
+ goto fail;
+
+ r = aug_match(aug, "$x", NULL);
+ printf("match %d\n", r);
+ if (r != 1)
+ goto fail;
+
+ printf("PASS\n");
+ return 0;
+ fail:
+ printf("FAIL\n");
+ return -1;
+}
+
static int run_tests(struct test *tests) {
char *lensdir;
struct augeas *aug = NULL;
@@ -273,6 +298,9 @@ static int run_tests(struct test *tests) {
if (test_defvar_nonexistent(aug) < 0)
result = EXIT_FAILURE;
+ if (test_defnode_nonexistent(aug) < 0)
+ result = EXIT_FAILURE;
+
aug_close(aug);
return result;
--
1.6.0.6
More information about the augeas-devel
mailing list