[augeas-devel] [PATCH 2 of 2] Add a call to move a subtree to the public API

David Lutterkort dlutter at redhat.com
Mon Jul 28 16:27:46 UTC 2008


6 files changed, 131 insertions(+), 1 deletion(-)
src/augeas.c           |   58 ++++++++++++++++++++++++++++++++++++++++++++++++
src/augeas.h           |   14 +++++++++++
src/augeas_sym.version |    1 
src/augtool.c          |   16 +++++++++++++
tests/Makefile.am      |    2 -
tests/test-mv.sh       |   41 +++++++++++++++++++++++++++++++++


# HG changeset patch
# User David Lutterkort <dlutter at redhat.com>
# Date 1217262238 25200
# Node ID 1fa780c4ddad4faa90415e67cc89bc89a237264d
# Parent  7a5e0853f47747bfd54359bccbb8769c6928967c
Add a call to move a subtree to the public API

diff -r 7a5e0853f477 -r 1fa780c4ddad src/augeas.c
--- a/src/augeas.c	Sat Jul 26 20:43:21 2008 -0700
+++ b/src/augeas.c	Mon Jul 28 09:23:58 2008 -0700
@@ -771,6 +771,64 @@
     return -1;
 }
 
+int aug_mv(struct augeas *aug, const char *src, const char *dst) {
+    struct tree *root = aug->tree;
+    struct path *s = make_path(root, src);
+    struct path *d = make_path(root, dst);
+    struct tree *ts, *td, *t;
+    int r, ret;
+
+    ret = -1;
+    if (s == NULL || d == NULL)
+        goto done;
+
+    r = path_find_one(s);
+    if (r != 1)
+        goto done;
+
+    r = path_find_one(d);
+    if (r == -1)
+        goto done;
+
+    if (r == 0) {
+        if (tree_create(root, d) == NULL)
+            goto done;
+    }
+
+    ts = last_segment(s)->tree;
+    for_each_segment(ds, d) {
+        /* Don't move SRC into its own descendent */
+        if (ds->tree == ts)
+            goto done;
+    }
+    td = last_segment(d)->tree;
+    free_tree(td->children);
+
+    td->children = ts->children;
+
+    free(td->value);
+    td->value = ts->value;
+
+    ts->value = NULL;
+    ts->children = NULL;
+
+
+    t = seg_parent(s, last_segment(s));
+    if (t == NULL) t = root;
+    list_remove(ts, t->children);
+
+    t->dirty = 1;
+    td->dirty = 1;
+
+    free_tree(ts);
+
+    ret = 0;
+ done:
+    free_path(s);
+    free_path(d);
+    return ret;
+}
+
 int aug_match(const struct augeas *aug, const char *pathin, char ***matches) {
     struct path *p = NULL;
     struct tree *tree;
diff -r 7a5e0853f477 -r 1fa780c4ddad src/augeas.h
--- a/src/augeas.h	Sat Jul 26 20:43:21 2008 -0700
+++ b/src/augeas.h	Mon Jul 28 09:23:58 2008 -0700
@@ -92,6 +92,20 @@
  */
 int aug_rm(augeas *aug, const char *path);
 
+/* Move the node SRC to DST. SRC must match exactly one node in the
+ * tree. DST must either match exactly one node in the tree, or may not
+ * exist yet. If DST exists already, it and all its descendants are
+ * deleted. If DST does not exist yet, it and all its missing ancestors are
+ * created.
+ *
+ * Note that the node SRC always becomes the node DST: when you move /a/b
+ * to /x, the node /a/b is now called /x, no matter whether /x existed
+ * initially or not.
+ *
+ * Return 0 on success and -1 on failure.
+ */
+int aug_mv(augeas *aug, const char *src, const char *dst);
+
 /* Return the number of matches of the path expression PATH in AUG. If
  * MATCHES is non-NULL, an array with the returned number of elements will
  * be allocated and filled with the paths of the matches. The caller must
diff -r 7a5e0853f477 -r 1fa780c4ddad src/augeas_sym.version
--- a/src/augeas_sym.version	Sat Jul 26 20:43:21 2008 -0700
+++ b/src/augeas_sym.version	Mon Jul 28 09:23:58 2008 -0700
@@ -6,6 +6,7 @@
       aug_set;
       aug_insert;
       aug_rm;
+      aug_mv;
       aug_ls;
       aug_match;
       aug_save;
diff -r 7a5e0853f477 -r 1fa780c4ddad src/augtool.c
--- a/src/augtool.c	Sat Jul 26 20:43:21 2008 -0700
+++ b/src/augtool.c	Mon Jul 28 09:23:58 2008 -0700
@@ -163,6 +163,16 @@
     printf(" %d\n", cnt);
 }
 
+static void cmd_mv(char *args[]) {
+    const char *src = cleanpath(args[0]);
+    const char *dst = cleanpath(args[1]);
+    int r;
+
+    r = aug_mv(aug, src, dst);
+    if (r == -1)
+        printf("Failed\n");
+}
+
 static void cmd_set(char *args[]) {
     const char *path = cleanpath(args[0]);
     const char *val = args[1];
@@ -309,6 +319,12 @@
     { "rm",  1, 1, cmd_rm, "rm <PATH>",
       "Delete PATH and all its children from the tree"
     },
+    { "mv", 2, 2, cmd_mv, "mv <SRC> <DST>",
+      "Move node SRC to DST. SRC must match exactly one node in the tree.\n"
+      "        DST must either match exactly one node in the tree, or may not\n"
+      "        exist yet. If DST exists already, it and all its descendants are\n"
+      "        deleted. If DST does not exist yet, it and all its missing \n"
+      "        ancestors are created." },
     { "set", 2, 2, cmd_set, "set <PATH> <VALUE>",
       "Associate VALUE with PATH. If PATH is not in the tree yet,\n"
       "        it and all its ancestors will be created. These new tree entries\n"
diff -r 7a5e0853f477 -r 1fa780c4ddad tests/Makefile.am
--- a/tests/Makefile.am	Sat Jul 26 20:43:21 2008 -0700
+++ b/tests/Makefile.am	Mon Jul 28 09:23:58 2008 -0700
@@ -10,7 +10,7 @@
 	libtool --mode=execute valgrind --quiet --leak-check=full ./fatest
 
 check_SCRIPTS=test-lenses.sh test-interpreter.sh test-get.sh \
-              test-put-symlink.sh test-save-empty.sh
+              test-put-symlink.sh test-save-empty.sh test-mv.sh
 
 EXTRA_DIST=augtest $(AUGTESTS) root \
 	   $(check_SCRIPTS) modules
diff -r 7a5e0853f477 -r 1fa780c4ddad tests/test-mv.sh
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mv.sh	Mon Jul 28 09:23:58 2008 -0700
@@ -0,0 +1,41 @@
+#! /bin/bash
+
+aug_mv() {
+(augtool -r /dev/null | grep -v '/augeas\|augtool' | tr '\n' ' ') <<EOF
+set /a/b/c value
+mv /a/b/c $1
+print
+EOF
+}
+
+assert_eq() {
+    msg=$1
+    if [ "$ACT" != "$EXP" ] ; then
+        echo "Failed: aug_mv $msg"
+        echo "Expected: <$EXP>"
+        echo "Actual  : <$ACT>"
+        exit 1
+    fi
+
+}
+
+ACT=$(aug_mv /x)
+EXP='/a /a/b /x = "value" '
+assert_eq /x
+
+ACT=$(aug_mv /x/y)
+EXP='/a /a/b /x /x/y = "value" '
+assert_eq /x/y
+
+ACT=$(aug_mv /a/x)
+EXP='/a /a/b /a/x = "value" '
+assert_eq /a/x
+
+# Check that we don't move into a descendant
+ACT=$(aug_mv /a/b/c/d)
+EXP='Failed /a /a/b /a/b/c = "value" /a/b/c/d '
+assert_eq /a/b/c/d
+
+ACT=$(aug_mv /a/b/d)
+EXP='/a /a/b /a/b/d = "value" '
+assert_eq /a/b/d




More information about the augeas-devel mailing list