[augeas-devel] [PATCH] Add aug_label to retrieve the label from a path.
Raphaël Pinson
raphael.pinson at camptocamp.com
Wed Nov 7 09:18:18 UTC 2012
---
src/augeas.c | 30 ++++++++++++++++++++++++++++++
src/augeas.h | 17 +++++++++++++++++
src/augeas_sym.version | 1 +
src/augrun.c | 32 ++++++++++++++++++++++++++++++++
src/augtool.c | 2 +-
tests/test-api.c | 19 +++++++++++++++++++
6 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/src/augeas.c b/src/augeas.c
index 08901f2..830dbeb 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -766,6 +766,36 @@ int aug_get(const struct augeas *aug, const char *path, const char **value) {
return -1;
}
+int aug_label(const struct augeas *aug, const char *path, const char **label) {
+ struct pathx *p = NULL;
+ struct tree *match;
+ int r;
+
+ api_entry(aug);
+
+ p = pathx_aug_parse(aug, aug->origin, tree_root_ctx(aug), path, true);
+ ERR_BAIL(aug);
+
+ if (label != NULL)
+ *label = NULL;
+
+ r = pathx_find_one(p, &match);
+ ERR_BAIL(aug);
+ ERR_THROW(r > 1, aug, AUG_EMMATCH, "There are %d nodes matching %s",
+ r, path);
+
+ if (r == 1 && label != NULL)
+ *label = match->label;
+ free_pathx(p);
+
+ api_exit(aug);
+ return r;
+ error:
+ free_pathx(p);
+ api_exit(aug);
+ return -1;
+}
+
static void record_var_meta(struct augeas *aug, const char *name,
const char *expr) {
/* Record the definition of the variable */
diff --git a/src/augeas.h b/src/augeas.h
index fde3d09..8a44fa6 100644
--- a/src/augeas.h
+++ b/src/augeas.h
@@ -142,6 +142,23 @@ int aug_defnode(augeas *aug, const char *name, const char *expr,
*/
int aug_get(const augeas *aug, const char *path, const char **value);
+/* Function: aug_label
+ *
+ * Lookup the label associated with PATH. LABEL can be NULL, in which case
+ * it is ignored. If LABEL is not NULL, it is used to return a pointer to
+ * the value associated with PATH if PATH matches exactly one node. If PATH
+ * matches no nodes or more than one node, *LABEL is set to NULL.
+ *
+ * The string *LABEL must not be freed by the caller, and is valid as long
+ * as its node remains unchanged.
+ *
+ * Returns:
+ * 1 if there is exactly one node matching PATH, 0 if there is none,
+ * and a negative value if there is more than one node matching PATH, or if
+ * PATH is not a legal path expression.
+ */
+int aug_label(const augeas *aug, const char *path, const char **label);
+
/* Function: aug_set
*
* Set the value associated with PATH to VALUE. VALUE is copied into the
diff --git a/src/augeas_sym.version b/src/augeas_sym.version
index c56d443..1501801 100644
--- a/src/augeas_sym.version
+++ b/src/augeas_sym.version
@@ -58,4 +58,5 @@ AUGEAS_0.16.0 {
aug_text_retrieve;
aug_rename;
aug_transform;
+ aug_label;
} AUGEAS_0.15.0;
diff --git a/src/augrun.c b/src/augrun.c
index 28d6c63..2677484 100644
--- a/src/augrun.c
+++ b/src/augrun.c
@@ -842,6 +842,37 @@ static const struct command_def cmd_get_def = {
.help = "Get and print the value associated with PATH"
};
+static void cmd_label(struct command *cmd) {
+ const char *path = arg_value(cmd, "path");
+ const char *lbl;
+ int r;
+
+ r = aug_label(cmd->aug, path, &lbl);
+ ERR_RET(cmd);
+ fprintf(cmd->out, "%s", path);
+ if (r == 0) {
+ fprintf(cmd->out, " (o)\n");
+ } else if (lbl == NULL) {
+ fprintf(cmd->out, " (none)\n");
+ } else {
+ fprintf(cmd->out, " = %s\n", lbl);
+ }
+}
+
+static const struct command_opt_def cmd_label_opts[] = {
+ { .type = CMD_PATH, .name = "path", .optional = false,
+ .help = "get the label of this node" },
+ CMD_OPT_DEF_LAST
+};
+
+static const struct command_def cmd_label_def = {
+ .name = "label",
+ .opts = cmd_label_opts,
+ .handler = cmd_label,
+ .synopsis = "get the label of a node",
+ .help = "Get and print the label associated with PATH"
+};
+
static void cmd_print(struct command *cmd) {
const char *path = arg_value(cmd, "path");
@@ -1129,6 +1160,7 @@ static const struct command_grp_def cmd_grp_read_def = {
.commands = {
&cmd_dump_xml_def,
&cmd_get_def,
+ &cmd_label_def,
&cmd_ls_def,
&cmd_match_def,
&cmd_print_def,
diff --git a/src/augtool.c b/src/augtool.c
index 830082f..94d85f4 100644
--- a/src/augtool.c
+++ b/src/augtool.c
@@ -168,7 +168,7 @@ static char *readline_command_generator(const char *text, int state) {
// FIXME: expose somewhere under /augeas
static const char *const commands[] = {
"quit", "clear", "defnode", "defvar",
- "get", "ins", "load", "ls", "match",
+ "get", "label", "ins", "load", "ls", "match",
"mv", "rename", "print", "dump-xml", "rm", "save", "set", "setm",
"clearm", "span", "store", "retrieve", "transform",
"help", NULL };
diff --git a/tests/test-api.c b/tests/test-api.c
index e74a6db..eb4ffe1 100644
--- a/tests/test-api.c
+++ b/tests/test-api.c
@@ -44,6 +44,7 @@ static char *loadpath;
static void testGet(CuTest *tc) {
int r;
const char *value;
+ const char *label;
struct augeas *aug;
aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
@@ -73,6 +74,24 @@ static void testGet(CuTest *tc) {
CuAssertPtrEquals(tc, NULL, value);
CuAssertIntEquals(tc, AUG_EMMATCH, aug_error(aug));
+ /* aug_label returns 1 and the label if exactly one node matches */
+ r = aug_label(aug, "/augeas/version/save/*[1]", &label);
+ CuAssertIntEquals(tc, 1, r);
+ CuAssertPtrNotNull(tc, label);
+ CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
+
+ /* aug_label returns 0 and no label when no node matches */
+ r = aug_label(aug, "/augeas/version/save/*[ last() + 1 ]", &label);
+ CuAssertIntEquals(tc, 0, r);
+ CuAssertPtrEquals(tc, NULL, label);
+ CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
+
+ /* aug_label should return an error when multiple nodes match */
+ r = aug_label(aug, "/augeas/version/save/*", &label);
+ CuAssertIntEquals(tc, -1, r);
+ CuAssertPtrEquals(tc, NULL, label);
+ CuAssertIntEquals(tc, AUG_EMMATCH, aug_error(aug));
+
/* augeas should prepend context if relative path given */
r = aug_set(aug, "/augeas/context", "/augeas/version");
r = aug_get(aug, "save/*[1]", &value);
--
1.7.9.5
More information about the augeas-devel
mailing list