[augeas-devel] [PATCH] Add aug_rename to rename node labels without moving them in the tree.

Raphaël Pinson raphael.pinson at camptocamp.com
Wed Aug 1 21:40:29 UTC 2012


---
 src/augeas.c           |   34 ++++++++++++++++++++++++++++++-
 src/augeas.h           |   12 ++++++++++-
 src/augeas_sym.version |    1 +
 src/augrun.c           |   33 ++++++++++++++++++++++++++++++
 src/augtool.c          |    2 +-
 tests/run.tests        |   52 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/test-api.c       |   29 +++++++++++++++++++++++++++
 tests/test-run.c       |    2 +-
 8 files changed, 161 insertions(+), 4 deletions(-)

diff --git a/src/augeas.c b/src/augeas.c
index 22ebd14..a2ffa03 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -78,7 +78,8 @@ static const char *const errcodes[] = {
     "Node has no span info",                            /* AUG_ENOSPAN */
     "Cannot move node into its descendant",             /* AUG_EMVDESC */
     "Failed to execute command",                        /* AUG_ECMDRUN */
-    "Invalid argument in function call"                 /* AUG_EBADARG */
+    "Invalid argument in function call",                /* AUG_EBADARG */
+    "Invalid label"                                     /* AUG_ELABEL */
 };
 
 static void tree_mark_dirty(struct tree *tree) {
@@ -1245,6 +1246,37 @@ int aug_mv(struct augeas *aug, const char *src, const char *dst) {
     return ret;
 }
 
+int aug_rename(struct augeas *aug, const char *src, const char *lbl) {
+    struct pathx *s = NULL;
+    struct tree *ts;
+    int ret;
+    int count = 0;
+
+    api_entry(aug);
+
+    ret = -1;
+    ERR_THROW(strchr(lbl, '/') != NULL, aug, AUG_ELABEL,
+              "Label %s contains a /", lbl);
+
+    s = pathx_aug_parse(aug, aug->origin, tree_root_ctx(aug), src, true);
+    ERR_BAIL(aug);
+
+    for (ts = pathx_first(s); ts != NULL; ts = pathx_next(s)) {
+        free(ts->label);
+        ts->label = strdup(lbl);
+        tree_mark_dirty(ts);
+        count ++;
+    }
+
+    free_pathx(s);
+    api_exit(aug);
+    return count;
+ error:
+    free_pathx(s);
+    api_exit(aug);
+    return ret;
+}
+
 int aug_match(const struct augeas *aug, const char *pathin, char ***matches) {
     struct pathx *p = NULL;
     struct tree *tree;
diff --git a/src/augeas.h b/src/augeas.h
index c49308b..7f7ac14 100644
--- a/src/augeas.h
+++ b/src/augeas.h
@@ -225,6 +225,15 @@ int aug_rm(augeas *aug, const char *path);
  */
 int aug_mv(augeas *aug, const char *src, const char *dst);
 
+/* Function: aug_rename
+ *
+ * Rename the label of all nodes matching SRC to LBL.
+ *
+ * Returns:
+ * The number of nodes renamed on success and -1 on failure.
+ */
+int aug_rename(augeas *aug, const char *src, const char *lbl);
+
 /* Function: aug_match
  *
  * Returns:
@@ -391,7 +400,8 @@ typedef enum {
     AUG_ENOSPAN,        /* No span for this node */
     AUG_EMVDESC,        /* Cannot move node into its descendant */
     AUG_ECMDRUN,        /* Failed to execute command */
-    AUG_EBADARG         /* Invalid argument in funcion call */
+    AUG_EBADARG,        /* Invalid argument in funcion call */
+    AUG_ELABEL          /* Invalid label */
 } aug_errcode_t;
 
 /* Return the error code from the last API call */
diff --git a/src/augeas_sym.version b/src/augeas_sym.version
index 5a6ddfc..eb53941 100644
--- a/src/augeas_sym.version
+++ b/src/augeas_sym.version
@@ -56,4 +56,5 @@ AUGEAS_0.16.0 {
     global:
       aug_text_store;
       aug_text_retrieve;
+      aug_rename;
 } AUGEAS_0.15.0;
diff --git a/src/augrun.c b/src/augrun.c
index 7895252..78ef414 100644
--- a/src/augrun.c
+++ b/src/augrun.c
@@ -580,6 +580,38 @@ static const struct command_def cmd_move_def = {
     .help = cmd_mv_help
 };
 
+static void cmd_rename(struct command *cmd) {
+    const char *src = arg_value(cmd, "src");
+    const char *lbl = arg_value(cmd, "lbl");
+    int cnt;
+
+    cnt = aug_rename(cmd->aug, src, lbl);
+    if (cnt < 0)
+        ERR_REPORT(cmd, AUG_ECMDRUN,
+                   "Renaming %s to %s failed", src, lbl);
+    if (! HAS_ERR(cmd))
+        fprintf(cmd->out, "rename : %s to %s %d\n", src, lbl, cnt);
+}
+
+static const struct command_opt_def cmd_rename_opts[] = {
+    { .type = CMD_PATH, .name = "src", .optional = false,
+      .help = "the tree to rename" },
+    { .type = CMD_STR, .name = "lbl", .optional = false,
+      .help = "the new label" },
+    CMD_OPT_DEF_LAST
+};
+
+static const char const cmd_rename_help[] =
+    "Rename the label of all nodes matching SRC to LBL.";
+
+static const struct command_def cmd_rename_def = {
+    .name = "rename",
+    .opts = cmd_rename_opts,
+    .handler = cmd_rename,
+    .synopsis = "rename a subtree label",
+    .help = cmd_rename_help
+};
+
 static void cmd_set(struct command *cmd) {
     const char *path = arg_value(cmd, "path");
     const char *val = arg_value(cmd, "value");
@@ -1088,6 +1120,7 @@ static const struct command_def const *commands[] = {
     &cmd_match_def,
     &cmd_mv_def,
     &cmd_move_def,
+    &cmd_rename_def,
     &cmd_print_def,
     &cmd_dump_xml_def,
     &cmd_rm_def,
diff --git a/src/augtool.c b/src/augtool.c
index ce4a8a3..bb0becc 100644
--- a/src/augtool.c
+++ b/src/augtool.c
@@ -167,7 +167,7 @@ static char *readline_command_generator(const char *text, int state) {
     static const char *const commands[] = {
         "quit", "clear", "defnode", "defvar",
         "get", "ins", "load", "ls", "match",
-        "mv", "print", "dump-xml", "rm", "save", "set", "setm",
+        "mv", "rename", "print", "dump-xml", "rm", "save", "set", "setm",
         "clearm", "span", "store", "retrieve", "help", NULL };
 
     static int current = 0;
diff --git a/tests/run.tests b/tests/run.tests
index 4f451a2..55effdb 100644
--- a/tests/run.tests
+++ b/tests/run.tests
@@ -213,6 +213,58 @@ prints
   /x/y/b/c = "value"
 
 #
+# test rename
+#
+test rename 1
+  rename /augeas/version version2
+prints
+  rename : /augeas/version to version2 1
+
+test rename-into-self 1
+  rename /augeas augeas
+prints
+  rename : /augeas to augeas 1
+
+test rename-tree1 3
+  set /a/b/c value
+  rename /a/b/c x
+  print /*[ label() != 'augeas' and label() != 'files']
+prints
+  rename : /a/b/c to x 1
+  /a
+  /a/b
+  /a/b/x = "value"
+
+test rename-tree2 4
+  set /a/b/c value
+  set /a/b/d value2
+  rename /a/b/c x
+  print /*[ label() != 'augeas' and label() != 'files']
+prints
+  rename : /a/b/c to x 1
+  /a
+  /a/b
+  /a/b/x = "value"
+  /a/b/d = "value2"
+
+test rename-multiple 4
+  set /a/b/d value
+  set /a/c/d value2
+  rename //d x
+  print /*[ label() != 'augeas' and label() != 'files']
+prints
+  rename : //d to x 2
+  /a
+  /a/b
+  /a/b/x = "value"
+  /a/c
+  /a/c/x = "value2"
+
+test rename-slash -1 ELABEL
+  set /a/b/c value
+  rename /a/b/c va/lue
+
+#
 # test set
 #
 test set-not-there 2
diff --git a/tests/test-api.c b/tests/test-api.c
index 5726540..e74a6db 100644
--- a/tests/test-api.c
+++ b/tests/test-api.c
@@ -416,6 +416,34 @@ static void testMv(CuTest *tc) {
 }
 
 
+static void testRename(CuTest *tc) {
+    struct augeas *aug;
+    int r;
+
+    aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
+    CuAssertPtrNotNull(tc, aug);
+
+    r = aug_set(aug, "/a/b/c", "value");
+    CuAssertRetSuccess(tc, r);
+
+    r = aug_rename(aug, "/a/b/c", "d");
+    CuAssertIntEquals(tc, 1, r);
+
+    r = aug_set(aug, "/a/e/d", "value2");
+    CuAssertRetSuccess(tc, r);
+
+    // Multiple rename
+    r = aug_rename(aug, "/a//d", "x");
+    CuAssertIntEquals(tc, 2, r);
+
+    // Label with a /
+    r = aug_rename(aug, "/a/e/x", "a/b");
+    CuAssertIntEquals(tc, -1, r);
+    CuAssertIntEquals(tc, AUG_ELABEL, aug_error(aug));
+
+    aug_close(aug);
+}
+
 static void testToXml(CuTest *tc) {
     struct augeas *aug;
     int r;
@@ -550,6 +578,7 @@ int main(void) {
     SUITE_ADD_TEST(suite, testDefNodeCreateMeta);
     SUITE_ADD_TEST(suite, testNodeInfo);
     SUITE_ADD_TEST(suite, testMv);
+    SUITE_ADD_TEST(suite, testRename);
     SUITE_ADD_TEST(suite, testToXml);
     SUITE_ADD_TEST(suite, testTextStore);
     SUITE_ADD_TEST(suite, testTextRetrieve);
diff --git a/tests/test-run.c b/tests/test-run.c
index ccaba76..e2d6bd9 100644
--- a/tests/test-run.c
+++ b/tests/test-run.c
@@ -49,7 +49,7 @@ static char *lensdir;
 static const char *const errtokens[] = {
     "NOERROR", "ENOMEM", "EINTERNAL", "EPATHX", "ENOMATCH",
     "EMMATCH", "ESYNTAX", "ENOLENS", "EMXFM", "ENOSPAN",
-    "EMVDESC", "ECMDRUN", "EBADARG"
+    "EMVDESC", "ECMDRUN", "EBADARG", "ELABEL"
 };
 
 struct test {
-- 
1.7.9.5




More information about the augeas-devel mailing list