[augeas-devel] augeas: master - New API call aug_defnode and augtool command defnode
David Lutterkort
lutter at fedoraproject.org
Tue Mar 24 23:08:00 UTC 2009
Gitweb: http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=f7c35b0333ad3401395e9cd6254d059c4ec1dffe
Commit: f7c35b0333ad3401395e9cd6254d059c4ec1dffe
Parent: a6461b12d63144fe42d6108d2d8b802fdebbd472
Author: David Lutterkort <lutter at redhat.com>
AuthorDate: Mon Mar 23 18:42:37 2009 -0700
Committer: David Lutterkort <lutter at redhat.com>
CommitterDate: Tue Mar 24 16:04:24 2009 -0700
New API call aug_defnode and augtool command defnode
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 call.
---
src/augeas.c | 34 ++++++++++++++++++++++++++++++++++
src/augeas.h | 20 ++++++++++++++++++++
src/augeas_sym.version | 1 +
src/augtool.c | 24 ++++++++++++++++++++++++
src/internal.h | 3 ++-
tests/test-xpath.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
6 files changed, 123 insertions(+), 3 deletions(-)
diff --git a/src/augeas.c b/src/augeas.c
index 348184c..f239bfa 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -382,6 +382,40 @@ int aug_defvar(augeas *aug, const char *name, const char *expr) {
return result;
}
+int aug_defnode(augeas *aug, const char *name, const char *expr,
+ const char *value, int *created) {
+ struct pathx *p;
+ int result = -1;
+ int r, cr;
+ struct tree *tree;
+
+ if (expr == NULL)
+ return -1;
+ if (created == NULL)
+ created = &cr;
+
+ p = parse_user_pathx((struct augeas *) aug, false, expr);
+ if (p == NULL)
+ goto done;
+
+ r = pathx_expand_tree(p, &tree);
+ if (r < 0)
+ goto done;
+
+ *created = r > 0;
+ if (*created) {
+ r = tree_set_value(tree, value);
+ if (r < 0)
+ goto done;
+ }
+
+ result = pathx_symtab_define(&(aug->symtab), name, p);
+
+ done:
+ free_pathx(p);
+ return result;
+}
+
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 6b75a22..5a146f1 100644
--- a/src/augeas.h
+++ b/src/augeas.h
@@ -85,6 +85,26 @@ 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, VALUE) and NAME will be the nodeset containing
+ * that single node.
+ *
+ * If CREATED is non-NULL, it is set to 1 if a node was created, and 0 if
+ * it already existed.
+ *
+ * Returns -1 on error; on success, returns the number of nodes in the
+ * nodeset
+ */
+int aug_defnode(augeas *aug, const char *name, const char *expr,
+ const char *value, int *created);
+
/* 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..c4e90af 100644
--- a/src/augtool.c
+++ b/src/augtool.c
@@ -205,6 +205,22 @@ 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]);
+ const char *value = args[2];
+ int r;
+
+ /* Our simple minded line parser treats non-existant and empty values
+ * the same. We choose to take the empty string to mean NULL */
+ if (value != NULL && strlen(value) == 0)
+ value = NULL;
+ r = aug_defnode(aug, name, path, value, NULL);
+ if (r == -1)
+ printf ("Failed\n");
+ return r;
+}
+
static int cmd_clear(char *args[]) {
const char *path = cleanpath(args[0]);
int r;
@@ -408,6 +424,14 @@ 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, 3, cmd_defnode, "defnode <NAME> <EXPR> [<VALUE>]",
+ "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 and NAME will refer to it. If VALUE is given, this\n"
+ " is the same as 'set EXPR VALUE'; if VALUE is not given, the\n"
+ " node is created as if with '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..9a77e98 100644
--- a/tests/test-xpath.c
+++ b/tests/test-xpath.c
@@ -244,6 +244,43 @@ static int test_defvar_nonexistent(struct augeas *aug) {
return -1;
}
+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);
+ if (r != 1)
+ die("aug_defnode failed");
+ if (created != 1) {
+ fprintf(stderr, "defnode did not create a node\n");
+ goto fail;
+ }
+
+ r = aug_defnode(aug, "x", "/defnode/bar", NULL, &created);
+ if (r != 1)
+ die("aug_defnode failed");
+ if (created != 0) {
+ fprintf(stderr, "defnode created node again\n");
+ goto fail;
+ }
+
+ // FIXME: get values and compare them, too
+
+ r = aug_set(aug, "$x", "baz");
+ if (r != 0)
+ goto fail;
+
+ r = aug_match(aug, "$x", NULL);
+ 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;
@@ -256,10 +293,10 @@ static int run_tests(struct test *tests) {
if (aug == NULL)
die("aug_init");
r = aug_defvar(aug, "hosts", "/files/etc/hosts/*");
- if (r < 0)
+ if (r != 6)
die("aug_defvar $hosts");
r = aug_defvar(aug, "localhost", "'127.0.0.1'");
- if (r < 0)
+ if (r != 0)
die("aug_defvar $localhost");
list_for_each(t, tests) {
@@ -273,6 +310,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;
More information about the augeas-devel
mailing list