Browse Source

xml: Compilable API for libxml2

Serj Kalichev 3 years ago
parent
commit
2dc39055a3

+ 80 - 188
configure.ac

@@ -114,26 +114,6 @@ AC_SEARCH_LIBS([faux_zmalloc], [faux],
 	)
 
 
-################################
-# Check for Lua support
-################################
-AC_ARG_WITH(lua,
-            [AS_HELP_STRING([--with-lua=DIR],
-                            [Build Lua ACTION plugin [default=no]])],
-            [use_lua=$withval],
-            [use_lua=no])
-AM_CONDITIONAL(WITH_LUA,test x$use_lua != xno)
-
-if test x$use_lua != xno; then
-    if test x$use_lua != xyes; then
-        CPPFLAGS="${CPPFLAGS} -I$use_lua/include"
-	LDFLAGS="${LDFLAGS} -L$use_lua/lib"
-    fi
-    LUA_VERSION="5.1"
-    AX_LUA_HEADERS()
-    AX_LUA_LIBS()
-fi
-
 
 ################################
 # Check for the roxml library
@@ -156,53 +136,6 @@ AC_ARG_WITH(libxml2,
             [use_libxml2=$withval],
             [use_libxml2=no])
 
-# select the default xml backend
-sel_xml_backends=""
-xml_backend=""
-found_xml_backend=""
-count_xml_backends=0
-if test "x$use_libxml2" != "xno"; then
-    sel_xml_backends="$sel_xml_backends libxml2"
-    xml_backend="libxml2"
-    count_xml_backends=$((count_xml_backends + 1))
-fi
-
-if test "x$use_roxml" != "xno"; then
-    sel_xml_backends="$sel_xml_backends roxml"
-    xml_backend="roxml"
-    count_xml_backends=$((count_xml_backends + 1))
-fi
-
-if test "x$use_expat" != "xno"; then
-    sel_xml_backends="$sel_xml_backends expat"
-    xml_backend="expat"
-    count_xml_backends=$((count_xml_backends + 1))
-fi
-
-if test $count_xml_backends -gt 1; then
-    AC_MSG_WARN([Multiple XML backend has been selected ($sel_xml_backends). I choose $xml_backend])
-fi
-
-if test "x$xml_backend" = "x"; then
-    xml_backend="auto"
-    AC_MSG_WARN([No XML backend has been selected: auto check])
-fi
-
-case x$xml_backend in
-    xroxml)
-        use_libxml2="no"
-        use_expat="no"
-        ;;
-    xlibxml2)
-        use_roxml="no"
-        use_expat="no"
-        ;;
-    xexpat)
-        use_libxml2="no"
-        use_roxml="no"
-        ;;
-esac
-
 XML_LDFLAGS=""
 XML_CFLAGS=""
 XML_LIBS=""
@@ -427,131 +360,66 @@ else
     AC_MSG_RESULT([no])
 fi
 
-if test "$xml_backend" = "libxml2" -o "$xml_backend" = "auto"; then
-    if test "$xml_backend" = "auto"; then
-        # on auto select, we try to detect the library
-        use_libxml2="yes"
-    fi
-    case x$use_libxml2 in
-      xyes)
-        # I would love to avoid using pkg-config (which may not be available on
-        # some compilation environment) but doing so really add a lot of
-        # complexity to the system, as the headers don't lie in a standard
-        # directory (they lie in a subdirectory of a standard include directory;
-        # not the same thing for configure scripts).
-        XML_CFLAGS="`pkg-config libxml-2.0 --cflags`"
-        XML_LDFLAGS="`pkg-config libxml-2.0 --libs-only-L`"
-        XML_LIBS="`pkg-config libxml-2.0 --libs-only-l`"
-        AC_CHECK_LIB([xml2],
-                     [xmlNewDoc],
-                     [libxml2_lib_found=yes],
-                     [libxml2_lib_found=no],
-                     [])
-        if test "x$libxml2_lib_found" != "xyes"; then
-            if test "$xml_backend" = "auto"; then
-                AC_MSG_WARN([cannot find libxml2 library])
-            else
-                AC_MSG_ERROR([cannot find libxml2 library])
-            fi
-        fi
-
-        # the header file is installed in a subdirectory of one of the standard
-        # include directory. This might prove to be a problem if the cross-
-        # compile environment is not complete enough (i.e. if it misses
-        # pkg-config, or if pkg-config returns wrong values). In most cases, the
-        # environment is likely to be OK so we will never hit any issue.
-        xml2_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $XML_CFLAGS"
-        AC_CHECK_HEADER([libxml/tree.h],
-                        [libxml2_h_found=yes],
-                        [libxml2_h_found=no],
-                        [/* force include check */])
-        CFLAGS="$xml2_CFLAGS"
-        if test "x$libxml2_h_found" != "xyes"; then
-            if test "$xml_backend" = "auto"; then
-                AC_MSG_WARN([cannot find libxml2 headers])
-            else
-                AC_MSG_ERROR([cannot find libxml2 headers])
-            fi
-        fi
-
-        AC_DEFINE([HAVE_LIB_LIBXML2],
-                  [],
-                  [libxml2-based XML backend])
-        xml_backend="found"
-        found_xml_backend="libxml2"
-        ;;
-      *)
-        # this is probably broken. We consider that the user supplied path is
-        # a non-standard path. But we're not going to check anything.
-        AC_MSG_WARN([--with-libxml2=DIR is probably broken, just trying])
-        XML_LDFLAGS="-L${use_libxml2}/lib"
-        XML_CFLAGS="-I${use_libxml2}/include/libxml2"
-        XML_LIBS="-lxml2"
-        AC_MSG_CHECKING([for libxml2 support])
-        AC_MSG_RESULT([yes])
-        AC_MSG_NOTICE([headers for libxml2 hopefully in ${use_libxml2}/include/libxml2])
-        AC_MSG_NOTICE([library libxml2 hopefully in ${use_libxml2}/lib])
-        AC_DEFINE([HAVE_LIB_LIBXML2],
-                  [],
-                  [libxml2-based XML backend])
-        xml_backend="found"
-        found_xml_backend="libxml2"
-        ;;
-    esac
-else
-    # not selected? We print a small message
-    AC_MSG_CHECKING([for libxml2 support])
-    AC_MSG_RESULT([no])
-fi
-
-if test "$xml_backend" != "found"; then
-    AC_MSG_ERROR([Failed to find a suitable XML backend])
-fi
 
-if test $count_xml_backends -eq 0; then
-    AC_MSG_NOTICE([I found a suitable XML backend: $found_xml_backend])
-fi
 
-# LIBXSLT
-AC_ARG_WITH(libxslt,
-            [AS_HELP_STRING([--with-libxslt=DIR],
-                            [Use libxslt as the XSLT transform engine [default=no]. Depend on libxml2 library.])],
-            [use_libxslt=$withval],
-            [use_libxslt=no])
+case x$use_libxml2 in
+
+	xno)
+	/bin/true
+	;;
+
+	xyes)
+	# I would love to avoid using pkg-config (which may not be available on
+	# some compilation environment) but doing so really add a lot of
+	# complexity to the system, as the headers don't lie in a standard
+	# directory (they lie in a subdirectory of a standard include directory;
+	# not the same thing for configure scripts).
+	LIBXML2_CFLAGS="`pkg-config libxml-2.0 --cflags`"
+	LIBXML2_LDFLAGS="`pkg-config libxml-2.0 --libs-only-L`"
+	LIBXML2_LIBS="`pkg-config libxml-2.0 --libs-only-l`"
+	AC_CHECK_LIB([xml2],
+		[xmlNewDoc],
+		[],
+		[AC_MSG_ERROR([cannot find libxml2 headers])],
+		[])
+	# the header file is installed in a subdirectory of one of the standard
+	# include directory. This might prove to be a problem if the cross-
+	# compile environment is not complete enough (i.e. if it misses
+	# pkg-config, or if pkg-config returns wrong values). In most cases, the
+	# environment is likely to be OK so we will never hit any issue.
+	saved_CFLAGS="$CFLAGS"
+	CFLAGS="$CFLAGS $LIBXML2_CFLAGS"
+	AC_CHECK_HEADER([libxml/tree.h],
+		[],
+		[AC_MSG_ERROR([cannot find libxml2 headers])],
+		[])
+	CFLAGS="$saved_CFLAGS"
+	AC_DEFINE([HAVE_LIB_LIBXML2],
+		[],
+		[libxml2-based XML backend])
+	;;
+
+	*)
+	# this is probably broken. We consider that the user supplied path is
+	# a non-standard path. But we're not going to check anything.
+	AC_MSG_WARN([--with-libxml2=DIR is probably broken, just trying])
+	LIBXML2_LDFLAGS="-L${use_libxml2}/lib"
+	LIBXML2_CFLAGS="-I${use_libxml2}/include/libxml2"
+	LIBXML2_LIBS="-lxml2"
+	AC_MSG_CHECKING([for libxml2 support])
+	AC_MSG_RESULT([yes])
+	AC_MSG_NOTICE([headers for libxml2 hopefully in ${use_libxml2}/include/libxml2])
+	AC_MSG_NOTICE([library libxml2 hopefully in ${use_libxml2}/lib])
+	AC_DEFINE([HAVE_LIB_LIBXML2],
+		[],
+		[libxml2-based XML backend])
+	;;
+esac
 
-if test "x$use_libxslt" != "xno" -a "$found_xml_backend" != "libxml2"; then
-    AC_MSG_ERROR([The libxml2 is necessary for libxslt])
-fi
+AC_SUBST(LIBXML2_LIBS)
+AC_SUBST(LIBXML2_LDFLAGS)
+AC_SUBST(LIBXML2_CFLAGS)
 
-################################
-# Check for the libxslt transform engine
-################################
-
-if test x$use_libxslt != xno; then
-	AC_CHECK_LIB([xslt], [xsltApplyStylesheet], [libxslt_lib_found=yes], [libxslt_lib_found=no])
-	if test "x$libxslt_lib_found" != "xyes"; then
-		AC_MSG_ERROR([Can't find an XSLT library])
-	fi
-	XSLT_CFLAGS="`pkg-config libxslt --cflags 2>/dev/null`"
-	XSLT_LDFLAGS="`pkg-config libxslt --libs-only-L 2>/dev/null`"
-	XSLT_LIBS="`pkg-config libxslt --libs-only-l 2>/dev/null`"
-	if test "x${XSLT_LIBS}" = "x"; then
-		XSLT_LIBS="-lxslt"
-	fi
-	XML_CFLAGS="${XML_CFLAGS} ${XSLT_CFLAGS}"
-	XML_LDFLAGS="${XML_LDFLAGS} ${XSLT_LDFLAGS}"
-	XML_LIBS="${XML_LIBS} ${XSLT_LIBS}"
-        AC_DEFINE([HAVE_LIB_LIBXSLT], [], [libxslt XML transform engine])
-fi
-
-################################
-# Common XML related subst
-################################
-
-AC_SUBST(XML_LIBS)
-AC_SUBST(XML_LDFLAGS)
-AC_SUBST(XML_CFLAGS)
 
 ################################
 # Search for network functions (like connect())
@@ -659,5 +527,29 @@ AC_SUBST([CLISH_PLUGIN_BUILTIN_DEFS])
 AC_SUBST([CLISH_PLUGIN_BUILTIN_LIBS])
 #AC_CONFIG_FILES([clish/plugin_builtin.c])
 
+
+################################
+# Check for Lua support
+################################
+AC_ARG_WITH(lua,
+            [AS_HELP_STRING([--with-lua=DIR],
+                            [Build Lua ACTION plugin [default=no]])],
+            [use_lua=$withval],
+            [use_lua=no])
+AM_CONDITIONAL(WITH_LUA,test x$use_lua != xno)
+
+if test x$use_lua != xno; then
+    if test x$use_lua != xyes; then
+        CPPFLAGS="${CPPFLAGS} -I$use_lua/include"
+	LDFLAGS="${LDFLAGS} -L$use_lua/lib"
+    fi
+    LUA_VERSION="5.1"
+    AX_LUA_HEADERS()
+    AX_LUA_LIBS()
+fi
+
+
+
+
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT

+ 7 - 5
klish/kdb/libxml2/Makefile.am

@@ -1,7 +1,9 @@
-lib_LTLIBRARIES += kdb-libxml2.la
-kdb_libxml2_la_SOURCES =
-kdb_libxml2_la_LDFLAGS = $(AM_LDFLAGS) $(VERSION_INFO)
+lib_LTLIBRARIES += libkdb-libxml2.la
+libkdb_libxml2_la_SOURCES =
+libkdb_libxml2_la_LDFLAGS = $(AM_LDFLAGS) $(LIBXML2_LDFLAGS) $(VERSION_INFO)
+libkdb_libxml2_la_LIBS = $(LIBXML2_LIBS)
+libkdb_libxml2_la_CFLAGS = $(AM_LDFLAGS) $(LIBXML2_CFLAGS)
 
-kdb_libxml2_la_SOURCES += \
+libkdb_libxml2_la_SOURCES += \
 	klish/kdb/xml-common/load.c \
-	klish/kdb/libxml2/kdb_api_libxml2.c
+	klish/kdb/libxml2/libxml2_api.c

+ 0 - 381
klish/kdb/libxml2/kdb_api_libxml2.c

@@ -1,381 +0,0 @@
-/*
- * ------------------------------------------------------
- * shell_roxml.c
- *
- * This file implements the means to read an XML encoded file 
- * and populate the CLI tree based on the contents. It implements
- * the clish_xml API using roxml
- * ------------------------------------------------------
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#if defined(HAVE_LIB_LIBXML2)
-#include <errno.h>
-#include <string.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include "xmlapi.h"
-
-#ifdef HAVE_LIB_LIBXSLT
-#include <libxslt/xslt.h>
-#include <libxslt/xsltInternals.h>
-#include <libxslt/transform.h>
-#include <libxslt/xsltutils.h>
-extern int xmlLoadExtDtdDefaultValue;
-
-/* dummy stuff ; really a xsltStylesheet */
-struct clish_xslt_s {
-	int dummy;
-};
-#endif
-
-/* dummy stuff ; really a xmlDoc */
-struct clish_xmldoc_s {
-	int dummy;
-};
-
-/* dummy stuff ; really a xmlNode */
-struct clish_xmlnode_s {
-	int dummy;
-};
-
-static inline xmlDoc *xmldoc_to_doc(clish_xmldoc_t *doc)
-{
-	return (xmlDoc*)doc;
-}
-
-static inline xmlNode *xmlnode_to_node(clish_xmlnode_t *node)
-{
-	return (xmlNode*)node;
-}
-
-static inline clish_xmldoc_t *doc_to_xmldoc(xmlDoc *node)
-{
-	return (clish_xmldoc_t*)node;
-}
-
-static inline clish_xmlnode_t *node_to_xmlnode(xmlNode *node)
-{
-	return (clish_xmlnode_t*)node;
-}
-
-/*
- * public interface
- */
-
-int clish_xmldoc_start(void)
-{
-#ifdef HAVE_LIB_LIBXSLT
-	/* The XSLT example contain these settings but I doubt 
-	 * it's really necessary.
-	 */
-/*	xmlSubstituteEntitiesDefault(1);
-	xmlLoadExtDtdDefaultValue = 1;
-*/
-#endif
-	return 0;
-}
-
-int clish_xmldoc_stop(void)
-{
-#ifdef HAVE_LIB_LIBXSLT
-	xsltCleanupGlobals();
-#endif
-	xmlCleanupParser();
-	return 0;
-}
-
-clish_xmldoc_t *clish_xmldoc_read(const char *filename)
-{
-	xmlDoc *doc;
-	doc = xmlReadFile(filename, NULL, 0);
-	return doc_to_xmldoc(doc);
-}
-
-void clish_xmldoc_release(clish_xmldoc_t *doc)
-{
-	if (doc)
-		xmlFreeDoc(xmldoc_to_doc(doc));
-}
-
-int clish_xmldoc_is_valid(clish_xmldoc_t *doc)
-{
-	return doc != NULL;
-}
-
-int clish_xmldoc_error_caps(clish_xmldoc_t *doc)
-{
-	doc = doc; // happy compiler
-	return CLISH_XMLERR_NOCAPS;
-}
-
-int clish_xmldoc_get_err_line(clish_xmldoc_t *doc)
-{
-	doc = doc; // happy compiler
-	return -1;
-}
-
-int clish_xmldoc_get_err_col(clish_xmldoc_t *doc)
-{
-	doc = doc; // happy compiler
-	return -1;
-}
-
-const char *clish_xmldoc_get_err_msg(clish_xmldoc_t *doc)
-{
-	doc = doc; // happy compiler
-	return "";
-}
-
-int clish_xmlnode_get_type(clish_xmlnode_t *node)
-{
-	if (node) {
-		xmlNode *n = xmlnode_to_node(node);
-		switch (n->type) {
-		case XML_ELEMENT_NODE: 
-			return CLISH_XMLNODE_ELM;
-		case XML_TEXT_NODE: 
-			return CLISH_XMLNODE_TEXT;
-		case XML_COMMENT_NODE: 
-			return CLISH_XMLNODE_COMMENT;
-		case XML_PI_NODE: 
-			return CLISH_XMLNODE_PI;
-		case XML_ATTRIBUTE_NODE: 
-			return CLISH_XMLNODE_ATTR;
-		default:
-			break;
-		}
-	}
-
-	return CLISH_XMLNODE_UNKNOWN;
-}
-
-clish_xmlnode_t *clish_xmldoc_get_root(clish_xmldoc_t *doc)
-{
-	if (doc) {
-		xmlNode *root = xmlDocGetRootElement(xmldoc_to_doc(doc));
-		return node_to_xmlnode(root);
-	}
-	return NULL;
-}
-
-clish_xmlnode_t *clish_xmlnode_parent(clish_xmlnode_t *node)
-{
-	if (node) {
-		xmlNode *n = xmlnode_to_node(node);
-		xmlNode *root = xmlDocGetRootElement(n->doc);
-		if (n != root)
-			return node_to_xmlnode(n->parent);
-	}
-	return NULL;
-}
-
-clish_xmlnode_t *clish_xmlnode_next_child(clish_xmlnode_t *parent, 
-					  clish_xmlnode_t *curchild)
-{
-	xmlNode *child;
-
-	if (!parent)
-		return NULL;
-
-	if (curchild) {
-		child = xmlnode_to_node(curchild)->next;
-	} else {
-		child = xmlnode_to_node(parent)->children;
-	}
-
-	return node_to_xmlnode(child);
-}
-
-char *clish_xmlnode_fetch_attr(clish_xmlnode_t *node,
-					  const char *attrname)
-{
-	xmlNode *n;
-
-	if (!node || !attrname)
-		return NULL;
-
-	n = xmlnode_to_node(node);
-
-	if (n->type == XML_ELEMENT_NODE) {
-		xmlAttr *a = n->properties;
-		while (a) {
-			if (strcmp((char*)a->name, attrname) == 0) {
-				if (a->children && a->children->content)
-					return (char *)a->children->content;
-				else
-					return NULL;
-			}
-			a = a->next;
-		}
-	}
-		
-	return NULL;
-}
-
-int clish_xmlnode_get_content(clish_xmlnode_t *node, char *content, 
-			      unsigned int *contentlen)
-{
-	xmlNode *n;
-	xmlNode *c;
-	unsigned int rlen = 0;
-
-	if (content && contentlen && *contentlen)
-		*content = 0;
-
-	if (!node || !content || !contentlen)
-		return -EINVAL;
-
-	if (*contentlen <= 1)
-		return -EINVAL;
-
-	*content = 0;
-	n = xmlnode_to_node(node);
-
-	/* first, get the content length */
-	c = n->children;
-	while (c) {
-		if ((c->type == XML_TEXT_NODE || c->type == XML_CDATA_SECTION_NODE)
-			&& !xmlIsBlankNode(c)) {
-			rlen += strlen((char*)c->content);
-		}
-		c = c->next;
-	}
-	++rlen;
-
-	if (rlen <= *contentlen) {
-		c = n->children;
-		while (c) {
-			if ((c->type == XML_TEXT_NODE || c->type == XML_CDATA_SECTION_NODE)
-				 && !xmlIsBlankNode(c)) {
-				strcat(content, (char*)c->content);
-			}
-			c = c->next;
-		}
-		return 0;
-	} else {
-		*contentlen = rlen;
-		return -E2BIG;
-	}
-}
-
-int clish_xmlnode_get_name(clish_xmlnode_t *node, char *name, 
-			    unsigned int *namelen)
-{
-	unsigned int rlen;
-	xmlNode *n;
-
-	if (name && namelen && *namelen)
-		*name = 0;
-
-	if (!node || !name || !namelen)
-		return -EINVAL;
-
-	if (*namelen <= 1)
-		return -EINVAL;
-
-	*name = 0;
-	n = xmlnode_to_node(node);
-	rlen = strlen((char*)n->name) + 1;
-	
-	if (rlen <= *namelen) {
-		snprintf(name, *namelen, "%s", (char*)n->name);
-		name[*namelen - 1] = '\0';
-		return 0;
-	} else {
-		*namelen = rlen;
-		return -E2BIG;
-	}
-}
-
-void clish_xmlnode_print(clish_xmlnode_t *node, FILE *out)
-{
-	xmlNode *n;
-	xmlAttr *a;
-
-	n = xmlnode_to_node(node);
-	if (n && n->name) {
-		fprintf(out, "<%s", (char*)n->name);
-		a = n->properties;
-		while (a) {
-			char *av = "";
-			if (a->children && a->children->content)
-				av = (char*)a->children->content;
-			fprintf(out, " %s='%s'", (char*)a->name, av);
-			a = a->next;
-		}
-		fprintf(out, ">");
-	}
-}
-
-void clish_xml_release(void *p)
-{
-	p = p; // happy compiler
-	/* do we allocate memory? not yet. */
-}
-
-#ifdef HAVE_LIB_LIBXSLT
-
-static inline xsltStylesheet *xslt_to_xsltStylesheet(clish_xslt_t *xslt)
-{
-	return (xsltStylesheet*)xslt;
-}
-
-static inline clish_xslt_t *xsltStylesheet_to_xslt(xsltStylesheet *xslt)
-{
-	return (clish_xslt_t*)xslt;
-}
-
-int clish_xslt_is_valid(clish_xslt_t *stylesheet)
-{
-	return stylesheet != NULL;
-}
-
-clish_xmldoc_t *clish_xslt_apply(clish_xmldoc_t *xmldoc, clish_xslt_t *stylesheet)
-{
-	xmlDoc *doc = xmldoc_to_doc(xmldoc);
-	xsltStylesheetPtr cur = xslt_to_xsltStylesheet(stylesheet);
-	xmlDoc *res;
-
-	if (!doc || !cur)
-		return doc_to_xmldoc(NULL);
-	res = xsltApplyStylesheet(cur, doc, NULL);
-
-	return doc_to_xmldoc(res);
-}
-
-clish_xslt_t *clish_xslt_read(const char *filename)
-{
-	xsltStylesheet* cur = NULL;
-
-	cur = xsltParseStylesheetFile((const xmlChar *)filename);
-
-	return xsltStylesheet_to_xslt(cur);
-}
-
-clish_xslt_t *clish_xslt_read_embedded(clish_xmldoc_t *xmldoc)
-{
-	xsltStylesheet* cur = NULL;
-	xmlDoc *doc = xmldoc_to_doc(xmldoc);
-
-	cur = xsltLoadStylesheetPI(doc);
-
-	return xsltStylesheet_to_xslt(cur);
-}
-
-void clish_xslt_release(clish_xslt_t *stylesheet)
-{
-	xsltStylesheet* cur = xslt_to_xsltStylesheet(stylesheet);
-
-	if (!cur)
-		return;
-	xsltFreeStylesheet(cur);
-}
-
-#endif /* HAVE_LIB_LIBXSLT */
-
-#endif /* HAVE_LIB_LIBXML2 */
-

+ 227 - 0
klish/kdb/libxml2/libxml2_api.c

@@ -0,0 +1,227 @@
+/** @file libxml2_api.c
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <faux/faux.h>
+#include <faux/str.h>
+#include <klish/kxml.h>
+
+
+int kxml_doc_start(void)
+{
+	return 0;
+}
+
+
+int kxml_doc_stop(void)
+{
+	xmlCleanupParser();
+	return 0;
+}
+
+
+kxml_doc_t *kxml_doc_read(const char *filename)
+{
+	xmlDoc *doc = NULL;
+
+	if (faux_str_is_empty(filename))
+		return NULL;
+
+	doc = xmlReadFile(filename, NULL, 0);
+
+	return (kxml_doc_t *)doc;
+}
+
+
+void kxml_doc_release(kxml_doc_t *doc)
+{
+	if (doc)
+		xmlFreeDoc((xmlDoc *)doc);
+}
+
+
+int kxml_doc_is_valid(const kxml_doc_t *doc)
+{
+	return (doc != NULL);
+}
+
+
+/*
+int kxml_doc_error_caps(kxml_doc_t *doc)
+{
+	doc = doc; // happy compiler
+	return kxmlERR_NOCAPS;
+}
+
+int kxml_doc_err_line(kxml_doc_t *doc)
+{
+	doc = doc; // happy compiler
+	return -1;
+}
+
+int kxml_doc_err_col(kxml_doc_t *doc)
+{
+	doc = doc; // happy compiler
+	return -1;
+}
+
+const char *kxml_doc_err_msg(kxml_doc_t *doc)
+{
+	doc = doc; // happy compiler
+	return "";
+}
+*/
+
+kxml_nodetype_e kxml_node_type(const kxml_node_t *node)
+{
+	if (!node)
+		return KXML_NODE_UNKNOWN;
+
+	switch (((xmlNode *)node)->type) {
+	case XML_ELEMENT_NODE:
+		return KXML_NODE_ELM;
+	case XML_TEXT_NODE:
+		return KXML_NODE_TEXT;
+	case XML_COMMENT_NODE:
+		return KXML_NODE_COMMENT;
+	case XML_PI_NODE:
+		return KXML_NODE_PI;
+	case XML_ATTRIBUTE_NODE:
+		return KXML_NODE_ATTR;
+	default:
+		break;
+	}
+
+	return KXML_NODE_UNKNOWN;
+}
+
+
+kxml_node_t *kxml_doc_root(const kxml_doc_t *doc)
+{
+	if (!doc)
+		return NULL;
+
+	return (kxml_node_t *)xmlDocGetRootElement((xmlDoc *)doc);
+}
+
+
+kxml_node_t *kxml_node_parent(const kxml_node_t *node)
+{
+	xmlNode *root = NULL;
+	xmlNode *n = (xmlNode *)node;
+
+	if (!n)
+		return NULL;
+
+	root = xmlDocGetRootElement(n->doc);
+	if (n != root)
+		return (kxml_node_t *)n->parent;
+
+	return NULL;
+}
+
+
+const kxml_node_t *kxml_node_next_child(const kxml_node_t *parent,
+	const kxml_node_t *curchild)
+{
+	xmlNode *child = NULL;
+
+	if (!parent)
+		return NULL;
+
+	if (curchild) {
+		child = ((xmlNode *)curchild)->next;
+	} else {
+		child = ((xmlNode *)parent)->children;
+	}
+
+	return (kxml_node_t *)child;
+}
+
+
+char *kxml_node_attr(const kxml_node_t *node, const char *attrname)
+{
+	xmlNode *n = (xmlNode *)node;
+	xmlAttr *a = NULL;
+
+	if (!node || !attrname)
+		return NULL;
+
+	if (n->type != XML_ELEMENT_NODE)
+		return NULL;
+
+	a = n->properties;
+	while (a) {
+		if (faux_str_casecmp((char *)a->name, attrname) == 0) {
+			if (a->children && a->children->content)
+				return (char *)a->children->content;
+			else
+				return NULL;
+		}
+		a = a->next;
+	}
+
+	return NULL;
+}
+
+
+void kxml_node_attr_free(char *str)
+{
+	str = str; // Happy compiler
+	// kxml_node_attr() doesn't allocate any memory
+	// so we don't need to free()
+}
+
+
+char *kxml_node_content(const kxml_node_t *node)
+{
+	xmlNode *n = (xmlNode *)node;
+	xmlNode *c = NULL;
+	char *content = NULL;
+
+	if (!n)
+		return NULL;
+
+	c = n->children;
+	while (c) {
+		if ((c->type == XML_TEXT_NODE || c->type == XML_CDATA_SECTION_NODE)
+			 && !xmlIsBlankNode(c)) {
+			faux_str_cat(&content, (char *)c->content);
+		}
+		c = c->next;
+	}
+
+	return content;
+}
+
+
+void kxml_node_content_free(char *str)
+{
+	if (!str)
+		return;
+
+	faux_str_free(str);
+}
+
+
+char *kxml_node_name(const kxml_node_t *node)
+{
+	xmlNode *n = (xmlNode *)node;
+
+	if (!node)
+		return NULL;
+
+	return (char *)n->name;
+}
+
+
+void kxml_node_name_free(char *str)
+{
+	str = str; // Happy compiler
+	// kxml_node_name() doesn't allocate any memory
+	// so we don't need to free()
+}

+ 0 - 12
klish/kdb/xml-common/load.c

@@ -33,17 +33,6 @@ static kxml_process_fn
 	process_plugin,
 	process_klish;
 
-/*	process_startup,
-	process_overview,
-	process_detail,
-	process_namespace,
-	process_config,
-	process_var,
-	process_wdog,
-	process_hotkey,
-	process_hook;
-*/
-
 // Different TAGs types
 typedef enum {
 	KTAG_NONE,
@@ -124,7 +113,6 @@ static bool_t process_node(const kxml_node_t *node, void *parent, faux_error_t *
 }
 
 
-
 static bool_t kxml_load_file(kscheme_t *scheme, const char *filename,
 	faux_error_t *error)
 {

+ 3 - 3
klish/kxml.h

@@ -45,12 +45,12 @@ void kxml_doc_release(kxml_doc_t *doc);
  *
  * Checks if a doc is valid (i.e. it loaded successfully).
  */
-int kxml_doc_is_valid(kxml_doc_t *doc);
+int kxml_doc_is_valid(const kxml_doc_t *doc);
 
 
 /** @brief Gets the document root.
  */
-kxml_node_t *kxml_doc_root(kxml_doc_t *doc);
+kxml_node_t *kxml_doc_root(const kxml_doc_t *doc);
 
 
 /** @brief Gets error description, when available.
@@ -76,7 +76,7 @@ typedef enum {
 
 /** @brief Gets the node type.
  */
-int kxml_node_type(const kxml_node_t *node);
+kxml_nodetype_e kxml_node_type(const kxml_node_t *node);
 
 
 /** @brief Gets the next child or NULL.