[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