[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