[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