[augeas-devel] [PATCH] Add aug_to_xml public API call. Add print-xml command to augtool.

Raphaël Pinson raphink at gmail.com
Fri Mar 4 16:32:27 UTC 2011


---
 src/augeas.c           |  135 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/augeas.h           |   10 ++++
 src/augeas_sym.version |    5 ++
 src/augtool.c          |   29 ++++++++++
 4 files changed, 179 insertions(+), 0 deletions(-)

diff --git a/src/augeas.c b/src/augeas.c
index 41e649e..f2923e5 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <stdarg.h>
 #include <locale.h>
+#include <libxml/tree.h>
 
 /* Some popular labels that we use in /augeas */
 static const char *const s_augeas = "augeas";
@@ -1427,6 +1428,140 @@ int aug_print(const struct augeas *aug, FILE *out, const char *pathin) {
     return -1;
 }
 
+
+static int to_xml_one(xmlNodePtr elem, const struct tree *tree,
+                      const char *pathin) {
+    xmlNodePtr value;
+    xmlAttrPtr prop;
+
+    prop = xmlSetProp(elem, (xmlChar*) "label", (xmlChar*) tree->label);
+    if (prop == NULL)
+        goto error;
+
+    if (tree->span) {
+        prop = xmlSetProp(elem, (xmlChar*) "file",
+                          (xmlChar*) tree->span->filename->str);
+        if (prop == NULL)
+            goto error;
+    }
+
+    if (pathin != NULL) {
+        prop = xmlSetProp(elem, (xmlChar*) "path", (xmlChar*) pathin);
+        if (prop == NULL)
+            goto error;
+    }
+    if (tree->value != NULL) {
+        value = xmlNewTextChild(elem, NULL, (xmlChar*) "value",
+                                (xmlChar*) tree->value);
+        if (value == NULL)
+            goto error;
+    }
+    return 0;
+ error:
+    xmlFreeProp(prop);
+    return -1;
+}
+
+
+static int to_xml_rec(xmlNodePtr pnode, struct tree *start,
+                      const char *pathin) {
+    int r;
+    char *path, *ppath = NULL;
+    xmlNodePtr elem, nelem, added;
+
+    elem = xmlNewNode(NULL, (xmlChar*) "node");
+    if (elem == NULL)
+        goto error;
+    r = to_xml_one(elem, start, pathin);
+    if (r < 0)
+        goto error;
+
+    ppath = path_of_tree(start);
+    list_for_each(tree, start->children) {
+        if (TREE_HIDDEN(tree))
+            continue;
+        path = path_expand(tree, ppath);
+        if (path == NULL)
+            goto error;
+        nelem = xmlNewNode(NULL, (xmlChar*) "node");
+        if (nelem == NULL)
+            goto error;
+        r = to_xml_one(nelem, tree, NULL);
+        if (r < 0)
+            goto error;
+        r = to_xml_rec(elem, tree, NULL);
+        free(path);
+        path = NULL;
+        if (r < 0)
+            goto error;
+    }
+
+    added = xmlAddChild(pnode, elem);
+    if (added == NULL)
+        return -1;
+
+    free(ppath);
+    return 0;
+ error:
+    free(path);
+    free(ppath);
+    return -1;
+}
+
+
+static int tree_to_xml(struct pathx *p, xmlNode **xml, const char *pathin) {
+    char *path = NULL;
+    struct tree *tree;
+    xmlAttrPtr attr;
+    int r;
+
+    *xml = xmlNewNode(NULL, (xmlChar*) "augeas");
+    if (*xml == NULL)
+        goto error;
+    attr = xmlSetProp(*xml, (xmlChar*) "path", (xmlChar*) pathin);
+
+    for (tree = pathx_first(p); tree != NULL; tree = pathx_next(p)) {
+        if (TREE_HIDDEN(tree))
+            continue;
+        path = path_of_tree(tree);
+        if (path == NULL)
+            goto error;
+        r = to_xml_rec(*xml, tree, path);
+        if (r < 0)
+            goto error;
+        free(path);
+        path = NULL;
+    }
+    return 0;
+ error:
+    free(path);
+    return -1;
+}
+
+
+int aug_to_xml(struct augeas *aug, const char *pathin,
+               xmlNode **xmldoc) {
+    struct pathx *p;
+    int result;
+
+    api_entry(aug);
+
+    if (pathin == NULL || strlen(pathin) == 0) {
+        pathin = "/*";
+    }
+
+    p = pathx_aug_parse(aug, aug->origin, pathin, true);
+    ERR_BAIL(aug);
+    result = tree_to_xml(p, xmldoc, pathin);
+    free_pathx(p);
+    api_exit(aug);
+
+    return result;
+ error:
+    api_exit(aug);
+    return -1;
+}
+
 void aug_close(struct augeas *aug) {
     if (aug == NULL)
         return;
diff --git a/src/augeas.h b/src/augeas.h
index 813b7a6..77955b0 100644
--- a/src/augeas.h
+++ b/src/augeas.h
@@ -21,6 +21,7 @@
  */
 
 #include <stdio.h>
+#include <libxml/tree.h>
 
 #ifndef AUGEAS_H_
 #define AUGEAS_H_
@@ -298,6 +299,15 @@ int aug_load(augeas *aug);
  */
 int aug_print(const augeas *aug, FILE *out, const char *path);
 
+/* Function: aug_to_xml
+ *
+ * Turn the Augeas tree into a libxml2 xmlNodePtr structure.
+ *
+ * Returns:
+ * 0 on success, or a negative value on failure
+ */
+int aug_to_xml(augeas *aug, const char *path, xmlNode **xmldoc);
+
 /* Function: aug_close
  *
  * Close this Augeas instance and free any storage associated with
diff --git a/src/augeas_sym.version b/src/augeas_sym.version
index 3f065f1..d354dea 100644
--- a/src/augeas_sym.version
+++ b/src/augeas_sym.version
@@ -39,3 +39,8 @@ AUGEAS_0.12.0 {
     global:
       aug_span;
 } AUGEAS_0.11.0;
+
+AUGEAS_0.13.0 {
+    global:
+      aug_to_xml;
+} AUGEAS_0.12.0;
diff --git a/src/augtool.c b/src/augtool.c
index 8ee0920..6c7acd3 100644
--- a/src/augtool.c
+++ b/src/augtool.c
@@ -32,6 +32,7 @@
 #include <limits.h>
 #include <ctype.h>
 #include <locale.h>
+#include <libxml/tree.h>
 
 /* Global variables */
 
@@ -856,6 +857,33 @@ static const struct command_def cmd_print_def = {
     .help = "Print entries in the tree.  If PATH is given, printing starts there,\n otherwise the whole tree is printed"
 };
 
+static void cmd_print_xml(struct command *cmd) {
+    const char *path = arg_value(cmd, "path");
+    xmlNodePtr xmldoc;
+
+    aug_to_xml(aug, path, &xmldoc);
+    err_check(cmd);
+
+    xmlElemDump(stdout, NULL, xmldoc);
+    printf("\n");
+
+    xmlFreeNode(xmldoc);
+}
+
+static const struct command_opt_def cmd_print_xml_opts[] = {
+    { .type = CMD_PATH, .name = "path", .optional = true,
+      .help = "print this subtree" },
+    CMD_OPT_DEF_LAST
+};
+
+static const struct command_def cmd_print_xml_def = {
+    .name = "print-xml",
+    .opts = cmd_print_xml_opts,
+    .handler = cmd_print_xml,
+    .synopsis = "print a subtree as XML",
+    .help = "Export entries in the tree as XML.  If PATH is given, printing starts there,\n otherwise the whole tree is printed"
+};
+
 static void cmd_save(struct command *cmd) {
     int r;
     r = aug_save(aug);
@@ -1015,6 +1043,7 @@ static const struct command_def const *commands[] = {
     &cmd_match_def,
     &cmd_mv_def,
     &cmd_print_def,
+    &cmd_print_xml_def,
     &cmd_rm_def,
     &cmd_save_def,
     &cmd_set_def,
-- 
1.7.0.4




More information about the augeas-devel mailing list