Browse Source

Add lost new files

git-svn-id: https://klish.googlecode.com/svn/trunk@608 0eaa4687-2ee9-07dd-09d9-bcdd2d2dd5fb
Serj Kalichev 12 years ago
parent
commit
0696c4ea1e

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+autom4te.cache
+build
+

+ 14 - 11
bin/clish.cpp → bin/clish.c

@@ -1,8 +1,10 @@
-//-------------------------------------
-// clish.cpp
-//
-// A console client for libclish
-//-------------------------------------
+/*
+ * --------------------------------------
+ * clish.cpp
+ *
+ * A console client for libclish
+ * --------------------------------------
+ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -171,12 +173,13 @@ int main(int argc, char **argv)
 			istimeout = BOOL_TRUE;
 			timeout = atoi(optarg);
 			break;
-		case 'c':
-			char *str;
-			cmd = BOOL_TRUE;
-			quiet = BOOL_TRUE;
-			str = strdup(optarg);
-			lub_list_add(cmds, str);
+		case 'c': {
+				char *str;
+				cmd = BOOL_TRUE;
+				quiet = BOOL_TRUE;
+				str = strdup(optarg);
+				lub_list_add(cmds, str);
+			}
 			break;
 		case 'h':
 			help(0, argv[0]);

+ 337 - 0
clish/shell/shell_libxml2.c

@@ -0,0 +1,337 @@
+/*
+ * ------------------------------------------------------
+ * 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
+ * ------------------------------------------------------
+ */
+
+#include "config.h"
+
+#if defined(HAVE_LIB_LIBXML2)
+#include <errno.h>
+#include <string.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include "xmlapi.h"
+
+/* dummy stuff ; really a xmlDoc */
+struct clish_xmldoc_s {
+	int dummy;
+};
+
+/* dummy stuff ; really a xmlNode */
+struct clish_xmlnode_s {
+	int dummy;
+};
+
+/* dummy stuff ; really a xmlAttr */
+struct clish_xmlattr_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 xmlAttr *xmlattr_to_attr(clish_xmlattr_t *attr)
+{
+	return (xmlAttr*)attr;
+}
+
+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;
+}
+
+static inline clish_xmlattr_t *attr_to_xmlattr(xmlAttr *node)
+{
+	return (clish_xmlattr_t*)node;
+}
+
+/*
+ * public interface
+ */
+clish_xmldoc_t *clish_xmldoc_read(const char *filename)
+{
+	xmlDoc *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));
+		xmlCleanupParser();
+	}
+}
+
+int clish_xmldoc_is_valid(clish_xmldoc_t *doc)
+{
+	return doc != NULL;
+}
+
+int clish_xmldoc_error_caps(clish_xmldoc_t *doc)
+{
+	return CLISH_XMLERR_NOCAPS;
+}
+
+int clish_xmldoc_get_err_line(clish_xmldoc_t *doc)
+{
+	return -1;
+}
+
+int clish_xmldoc_get_err_col(clish_xmldoc_t *doc)
+{
+	return -1;
+}
+
+const char *clish_xmldoc_get_err_msg(clish_xmldoc_t *doc)
+{
+	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);
+}
+
+clish_xmlattr_t *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) {
+				return attr_to_xmlattr(a);
+			}
+			a = a->next;
+		}
+	}
+		
+	return NULL;
+}
+
+int clish_xmlattr_get_value(clish_xmlattr_t *attr, char *value, 
+			    unsigned int *valuelen)
+{
+	xmlAttr *a;
+
+	if (value && valuelen && *valuelen) 
+		*value = 0;
+
+	if (!attr || !value || !valuelen)
+		return -EINVAL;
+
+	if (*valuelen <= 1)
+		return -EINVAL;
+
+	*value = 0;
+	
+	a = xmlattr_to_attr(attr);
+	if (a->children && a->children->content) {
+		char *c = (char*)a->children->content;
+		int rlen = strlen(c) + 1;
+		if (rlen <= *valuelen) {
+			sprintf(value, "%s", c);
+			return 0;
+		} else {
+			*valuelen = rlen;
+			return -E2BIG;
+		}
+	}
+
+	return -EINVAL;
+}
+
+/* safer */
+void clish_xmlattr_get_value_noerr(clish_xmlattr_t *attr, char *value, 
+				   unsigned int valuelen)
+{
+	xmlAttr *a;
+
+	if (value && valuelen) 
+		*value = 0;
+
+	if (!attr || !value || valuelen <= 1)
+		return;
+
+	a = xmlattr_to_attr(attr);
+	if (a->children && a->children->content) {
+		char *c = (char*)a->children->content;
+		int rlen = strlen(c) + 1;
+		if (rlen <= valuelen) {
+			sprintf(value, "%s", c);
+		}
+	}
+}
+
+int clish_xmlnode_get_content(clish_xmlnode_t *node, char *content, 
+			      unsigned int *contentlen)
+{
+	xmlNode *n;
+	xmlNode *c;
+	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 && !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 && !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)
+{
+	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) {
+		sprintf(name, "%s", (char*)n->name);
+		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, ">");
+	}
+}
+
+#endif /* HAVE_LIB_LIBXML2 */
+

+ 370 - 0
clish/shell/shell_roxml.c

@@ -0,0 +1,370 @@
+/*
+ * ------------------------------------------------------
+ * 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
+ * ------------------------------------------------------
+ */
+
+#include "config.h"
+
+#if defined(HAVE_LIB_ROXML)
+#include <errno.h>
+#include <roxml.h>
+#include "xmlapi.h"
+
+/* dummy stuff ; really a node_t */
+struct clish_xmldoc_s {
+	int dummy;
+};
+
+/* dummy stuff ; really a node_t */
+struct clish_xmlnode_s {
+	int dummy;
+};
+
+/* dummy stuff ; really a node_t */
+struct clish_xmlattr_s {
+	int dummy;
+};
+
+static inline node_t *xmldoc_to_node(clish_xmldoc_t *doc)
+{
+	return (node_t*)doc;
+}
+
+static inline node_t *xmlnode_to_node(clish_xmlnode_t *node)
+{
+	return (node_t*)node;
+}
+
+static inline node_t *xmlattr_to_node(clish_xmlattr_t *attr)
+{
+	return (node_t*)attr;
+}
+
+static inline clish_xmldoc_t *node_to_xmldoc(node_t *node)
+{
+	return (clish_xmldoc_t*)node;
+}
+
+static inline clish_xmlnode_t *node_to_xmlnode(node_t *node)
+{
+	return (clish_xmlnode_t*)node;
+}
+
+static inline clish_xmlattr_t *node_to_xmlattr(node_t *node)
+{
+	return (clish_xmlattr_t*)node;
+}
+
+/*
+ * public interface
+ */
+clish_xmldoc_t *clish_xmldoc_read(const char *filename)
+{
+	node_t *doc = roxml_load_doc((char*)filename);
+	return node_to_xmldoc(doc);
+}
+
+void clish_xmldoc_release(clish_xmldoc_t *doc)
+{
+	if (doc) {
+		node_t *node = xmldoc_to_node(doc);
+		roxml_release(RELEASE_ALL);
+		roxml_close(node);
+	}
+}
+
+int clish_xmldoc_is_valid(clish_xmldoc_t *doc)
+{
+	return doc != NULL;
+}
+
+int clish_xmldoc_error_caps(clish_xmldoc_t *doc)
+{
+	return CLISH_XMLERR_NOCAPS;
+}
+
+int clish_xmldoc_get_err_line(clish_xmldoc_t *doc)
+{
+	return -1;
+}
+
+int clish_xmldoc_get_err_col(clish_xmldoc_t *doc)
+{
+	return -1;
+}
+
+const char *clish_xmldoc_get_err_msg(clish_xmldoc_t *doc)
+{
+	return "";
+}
+
+int clish_xmlnode_get_type(clish_xmlnode_t *node)
+{
+	if (node) {
+		int type = roxml_get_type(xmlnode_to_node(node));
+		switch (type) {
+		case ROXML_ELM_NODE: 
+			return CLISH_XMLNODE_ELM;
+		case ROXML_TXT_NODE: 
+			return CLISH_XMLNODE_TEXT;
+		case ROXML_CMT_NODE: 
+			return CLISH_XMLNODE_COMMENT;
+		case ROXML_PI_NODE: 
+			return CLISH_XMLNODE_PI;
+		case ROXML_ATTR_NODE: 
+			return CLISH_XMLNODE_ATTR;
+		default:
+			break;
+		}
+	}
+
+	return CLISH_XMLNODE_UNKNOWN;
+}
+
+clish_xmlnode_t *clish_xmldoc_get_root(clish_xmldoc_t *doc)
+{
+	if (doc) {
+		node_t *root = roxml_get_root(xmldoc_to_node(doc));
+		return node_to_xmlnode(root);
+	}
+	return NULL;
+}
+
+clish_xmlnode_t *clish_xmlnode_parent(clish_xmlnode_t *node)
+{
+	if (node) {
+		node_t *roxn = xmlnode_to_node(node);
+		node_t *root = roxml_get_root(roxn);
+		if (roxn != root)
+			return node_to_xmlnode(roxml_get_parent(roxn));
+	}
+	return NULL;
+}
+
+clish_xmlnode_t *clish_xmlnode_next_child(clish_xmlnode_t *parent, 
+					  clish_xmlnode_t *curchild)
+{
+	node_t *roxc;
+
+	if (!parent)
+		return NULL;
+
+	roxc = xmlnode_to_node(curchild);
+
+	if (roxc) {
+		return node_to_xmlnode(roxml_get_next_sibling(roxc));
+	} else {
+		node_t *roxp = xmlnode_to_node(parent);
+		node_t *child = NULL;
+		int count;
+
+		count = roxml_get_chld_nb(roxp);
+		if (count)
+			child = roxml_get_chld(roxp, NULL, 0);
+
+		return node_to_xmlnode(child);
+	}
+
+	return NULL;
+}
+
+clish_xmlattr_t *clish_xmlnode_fetch_attr(clish_xmlnode_t *node,
+					  const char *attrname)
+{
+	node_t *roxn;
+	node_t *attr;
+
+	if (!node || !attrname)
+		return NULL;
+
+	roxn = xmlnode_to_node(node);
+	attr = roxml_get_attr(roxn, (char*)attrname, 0);
+	return node_to_xmlattr(attr);
+}
+
+static int i_is_needle(char *src, const char *needle)
+{
+	int nlen = strlen(needle);
+	int slen = strlen(src);
+
+	if (slen >= nlen) {
+		if (strncmp(src, needle, nlen) == 0)
+			return 1;
+	}
+	return 0;
+}
+
+static void i_decode_and_copy(char *dst, char *src)
+{
+	while (*src) {
+		if (*src == '&') {
+			if (i_is_needle(src, "&lt;")) {
+				*dst++ = '<';
+				src += 4;
+			} else if (i_is_needle(src, "&gt;")) {
+				*dst++ = '>';
+				src += 4;
+			} else if (i_is_needle(src, "&amp;")) {
+				*dst++ = '&';
+				src += 5;
+			} else {
+				*dst++ = *src++;
+			}
+		} else {
+			*dst++ = *src++;
+		}
+	}
+	*dst++ = 0;
+}
+
+static int i_get_content(node_t *n, char *v, unsigned int *vl)
+{
+	char *c;
+	int len;
+
+	c = roxml_get_content(n, NULL, 0, NULL);
+	if (c) {
+		len = strlen(c) + 1;
+		if (len <= *vl) {
+			i_decode_and_copy(v, c);
+			roxml_release(c);
+			return 0;
+		} else {
+			*vl = len;
+			roxml_release(c);
+			return -E2BIG;
+		}
+	}
+	*vl = (unsigned int)-1;
+	return -ENOMEM;
+}
+
+int clish_xmlattr_get_value(clish_xmlattr_t *attr, char *value, 
+			    unsigned int *valuelen)
+{
+	if (value && valuelen && *valuelen) 
+		*value = 0;
+
+	if (!attr || !value || !valuelen)
+		return -EINVAL;
+
+	if (*valuelen <= 1)
+		return -EINVAL;
+
+	*value = 0;
+
+	return i_get_content(xmlattr_to_node(attr), value, valuelen);
+}
+
+/* safer */
+void clish_xmlattr_get_value_noerr(clish_xmlattr_t *attr, char *value, 
+				   unsigned int valuelen)
+{
+	char *c;
+
+	if (value && valuelen) 
+		*value = 0;
+
+	if (!attr || !value || valuelen <= 1)
+		return;
+
+	c = roxml_get_content(xmlattr_to_node(attr), NULL, 0, NULL);
+	if (strlen(c) + 1 <= valuelen) {
+		i_decode_and_copy(value, c);
+	}
+	roxml_release(c);
+}
+
+int clish_xmlnode_get_content(clish_xmlnode_t *node, char *content, 
+			      unsigned int *contentlen)
+{
+	if (content && contentlen && *contentlen)
+		*content = 0;
+
+	if (!node || !content || !contentlen)
+		return -EINVAL;
+
+	if (*contentlen <= 1)
+		return -EINVAL;
+
+	*content = 0;
+
+	return i_get_content(xmlnode_to_node(node), content, contentlen);
+}
+
+static int i_get_name(node_t *n, char *v, unsigned int *vl)
+{
+	char *c;
+	int len;
+
+	c = roxml_get_name(n, NULL, 0);
+	if (c) {
+		len = strlen(c) + 1;
+		if (len <= *vl) {
+			sprintf(v, "%s", c);
+			roxml_release(c);
+			return 0;
+		} else {
+			*vl = len;
+			roxml_release(c);
+			return -E2BIG;
+		}
+	}
+	*vl = (unsigned int)-1;
+	return -ENOMEM;
+}
+
+int clish_xmlnode_get_name(clish_xmlnode_t *node, char *name, 
+			    unsigned int *namelen)
+{
+	if (name && namelen && *namelen)
+		*name = 0;
+
+	if (!node || !name || !namelen)
+		return -EINVAL;
+
+	if (*namelen <= 1)
+		return -EINVAL;
+
+	*name = 0;
+
+	return i_get_name(xmlnode_to_node(node), name, namelen);
+}
+
+void clish_xmlnode_print(clish_xmlnode_t *node, FILE *out)
+{
+	node_t *roxn;
+	char *name;
+
+	roxn = xmlnode_to_node(node);
+	name = roxml_get_name(roxn, NULL, 0);
+	if (name) {
+		fprintf(out, "<%s", name);
+		roxml_release(name);
+		if (roxml_get_attr_nb(roxn)) {
+			int attr_count = roxml_get_attr_nb(roxn);
+			int attr_pos;
+			for (attr_pos = 0; attr_pos < attr_count; ++attr_pos) {
+				node_t *attr = roxml_get_attr(roxn, NULL, attr_pos);
+				char *n = roxml_get_name(attr, NULL, 0);
+				char *v = roxml_get_content(attr, NULL, 0, NULL);
+				if (n && v) {
+					fprintf(out, " %s='%s'", n, v);
+				}
+				if (v) 
+					roxml_release(v);
+				if (n) 
+					roxml_release(n);
+			}
+		}
+		fprintf(out, ">");
+	}
+}
+
+#endif /* HAVE_LIB_ROXML */
+

+ 0 - 767
clish/shell/shell_tinyxml.cpp

@@ -1,767 +0,0 @@
-////////////////////////////////////////
-// shell_tinyxml_read.cpp
-// 
-// This file implements the means to read an XML encoded file and populate the 
-// CLI tree based on the contents.
-////////////////////////////////////////
-extern "C" {
-#include "private.h"
-#include "lub/string.h"
-#include "lub/ctype.h"
-}
-/*lint +libh(tinyxml/tinyxml.h) Add this to the library file list */
-#include <stdlib.h>
-#include "tinyxml/tinyxml.h"
-#include <string.h>
-#include <assert.h>
-
-typedef void (PROCESS_FN) (clish_shell_t * instance,
-	TiXmlElement * element, void *parent);
-
-// Define a control block for handling the decode of an XML file
-typedef struct clish_xml_cb_s clish_xml_cb_t;
-struct clish_xml_cb_s {
-	const char *element;
-	PROCESS_FN *handler;
-};
-
-// forward declare the handler functions
-static PROCESS_FN
-	process_clish_module,
-	process_startup,
-	process_view,
-	process_command,
-	process_param,
-	process_action,
-	process_ptype,
-	process_overview,
-	process_detail,
-	process_namespace,
-	process_config,
-	process_var,
-	process_wdog;
-
-static clish_xml_cb_t xml_elements[] = {
-	{"CLISH_MODULE", process_clish_module},
-	{"STARTUP", process_startup},
-	{"VIEW", process_view},
-	{"COMMAND", process_command},
-	{"PARAM", process_param},
-	{"ACTION", process_action},
-	{"PTYPE", process_ptype},
-	{"OVERVIEW", process_overview},
-	{"DETAIL", process_detail},
-	{"NAMESPACE", process_namespace},
-	{"CONFIG", process_config},
-	{"VAR", process_var},
-	{"WATCHDOG", process_wdog},
-	{NULL, NULL}
-};
-
-///////////////////////////////////////
-// This function reads an element from the XML stream and processes it.
-///////////////////////////////////////
-static void process_node(clish_shell_t * shell, TiXmlNode * node, void *parent)
-{
-	switch (node->Type()) {
-	case TiXmlNode::DOCUMENT:
-		break;
-	case TiXmlNode::ELEMENT:
-		clish_xml_cb_t * cb;
-		for (cb = &xml_elements[0]; cb->element; cb++) {
-			if (0 == strcmp(node->Value(), cb->element)) {
-				TiXmlElement *element = (TiXmlElement *) node;
-#ifdef DEBUG
-				fprintf(stderr, "NODE:");
-				element->Print(stderr, 0);
-				fprintf(stderr, "\n***\n");
-#endif
-				// process the elements at this level
-				cb->handler(shell, element, parent);
-				break;
-			}
-		}
-		break;
-	case TiXmlNode::COMMENT:
-	case TiXmlNode::TEXT:
-	case TiXmlNode::DECLARATION:
-	case TiXmlNode::TYPECOUNT:
-	case TiXmlNode::UNKNOWN:
-	default:
-		break;
-	}
-}
-
-///////////////////////////////////////
-static void process_children(clish_shell_t * shell,
-	TiXmlElement * element, void *parent = NULL)
-{
-	for (TiXmlNode * node = element->FirstChild();
-		node; node = element->IterateChildren(node)) {
-		// Now deal with all the contained elements
-		process_node(shell, node, parent);
-	}
-}
-
-///////////////////////////////////////
-static void
-process_clish_module(clish_shell_t * shell, TiXmlElement * element, void *)
-{
-	// create the global view
-	if (!shell->global)
-		shell->global = clish_shell_find_create_view(shell,
-			"global", "");
-	process_children(shell, element, shell->global);
-}
-
-///////////////////////////////////////
-static void process_view(clish_shell_t * shell, TiXmlElement * element, void *)
-{
-	clish_view_t *view;
-	const char *name = element->Attribute("name");
-	const char *prompt = element->Attribute("prompt");
-	const char *depth = element->Attribute("depth");
-	const char *restore = element->Attribute("restore");
-	const char *access = element->Attribute("access");
-	bool allowed = true;
-
-	/* Check permissions */
-	if (access) {
-		allowed = false;
-		if (shell->client_hooks->access_fn)
-			allowed = shell->client_hooks->access_fn(shell, access)
-				? true : false;
-	}
-	if (!allowed)
-		return;
-
-	// re-use a view if it already exists
-	view = clish_shell_find_create_view(shell, name, prompt);
-
-	if (depth && (*depth != '\0') && (lub_ctype_isdigit(*depth))) {
-		unsigned res = atoi(depth);
-		clish_view__set_depth(view, res);
-	}
-
-	if (restore) {
-		if (!lub_string_nocasecmp(restore, "depth"))
-			clish_view__set_restore(view, CLISH_RESTORE_DEPTH);
-		else if (!lub_string_nocasecmp(restore, "view"))
-			clish_view__set_restore(view, CLISH_RESTORE_VIEW);
-		else
-			clish_view__set_restore(view, CLISH_RESTORE_NONE);
-	}
-
-	process_children(shell, element, view);
-}
-
-///////////////////////////////////////
-static void process_ptype(clish_shell_t * shell, TiXmlElement * element, void *)
-{
-	clish_ptype_method_e method;
-	clish_ptype_preprocess_e preprocess;
-	clish_ptype_t *ptype;
-
-	const char *name = element->Attribute("name");
-	const char *help = element->Attribute("help");
-	const char *pattern = element->Attribute("pattern");
-	const char *method_name = element->Attribute("method");
-	const char *preprocess_name = element->Attribute("preprocess");
-
-	assert(name);
-	assert(pattern);
-	method = clish_ptype_method_resolve(method_name);
-	preprocess = clish_ptype_preprocess_resolve(preprocess_name);
-	ptype = clish_shell_find_create_ptype(shell,
-		name, help, pattern, method, preprocess);
-	assert(ptype);
-}
-
-///////////////////////////////////////
-static void
-process_overview(clish_shell_t * shell, TiXmlElement * element, void *)
-{
-	// read the following text element
-	TiXmlNode *text = element->FirstChild();
-
-	if (text) {
-		assert(TiXmlNode::TEXT == text->Type());
-		// set the overview text for this view
-		assert(NULL == shell->overview);
-		// store the overview
-		shell->overview = lub_string_dup(text->Value());
-	}
-}
-
-////////////////////////////////////////
-static void
-process_command(clish_shell_t * shell, TiXmlElement * element, void *parent)
-{
-	clish_view_t *v = (clish_view_t *) parent;
-	clish_command_t *cmd = NULL;
-	bool allowed = true;
-	clish_command_t *old;
-	char *alias_name = NULL;
-	clish_view_t *alias_view = NULL;
-
-	const char *access = element->Attribute("access");
-	const char *name = element->Attribute("name");
-	const char *help = element->Attribute("help");
-	const char *view = element->Attribute("view");
-	const char *viewid = element->Attribute("viewid");
-	const char *escape_chars = element->Attribute("escape_chars");
-	const char *args_name = element->Attribute("args");
-	const char *args_help = element->Attribute("args_help");
-	const char *lock = element->Attribute("lock");
-	const char *interrupt = element->Attribute("interrupt");
-	const char *ref = element->Attribute("ref");
-
-	/* Check permissions */
-	if (access) {
-		allowed = false;
-		if (shell->client_hooks->access_fn)
-			allowed = shell->client_hooks->access_fn(shell, access)
-				? true : false;
-	}
-	if (!allowed)
-		return;
-
-	old = clish_view_find_command(v, name, BOOL_FALSE);
-	// check this command doesn't already exist
-	if (old) {
-		// flag the duplication then ignore further definition
-		printf("DUPLICATE COMMAND: %s\n",
-		       clish_command__get_name(old));
-		return;
-	}
-
-	assert(name);
-	assert(help);
-
-	/* Reference 'ref' field */
-	if (ref) {
-		char *saveptr;
-		const char *delim = "@";
-		char *view_name = NULL;
-		char *cmdn = NULL;
-		char *str = lub_string_dup(ref);
-
-		cmdn = strtok_r(str, delim, &saveptr);
-		if (!cmdn) {
-			printf("EMPTY REFERENCE COMMAND: %s\n", name);
-			lub_string_free(str);
-			return;
-		}
-		alias_name = lub_string_dup(cmdn);
-		view_name = strtok_r(NULL, delim, &saveptr);
-		if (!view_name)
-			alias_view = v;
-		else
-			alias_view = clish_shell_find_create_view(shell,
-				view_name, NULL);
-		lub_string_free(str);
-	}
-
-	/* create a command */
-	cmd = clish_view_new_command(v, name, help);
-	assert(cmd);
-	clish_command__set_pview(cmd, v);
-	/* define some specialist escape characters */
-	if (escape_chars)
-		clish_command__set_escape_chars(cmd, escape_chars);
-	if (args_name) {
-		/* define a "rest of line" argument */
-		clish_param_t *param;
-		clish_ptype_t *tmp = NULL;
-
-		assert(args_help);
-		tmp = clish_shell_find_ptype(shell, "internal_ARGS");
-		assert(tmp);
-		param = clish_param_new(args_name, args_help, tmp);
-		clish_command__set_args(cmd, param);
-	}
-	// define the view which this command changes to
-	if (view) {
-		clish_view_t *next = clish_shell_find_create_view(shell, view,
-			NULL);
-
-		// reference the next view
-		clish_command__set_view(cmd, next);
-	}
-	// define the view id which this command changes to
-	if (viewid)
-		clish_command__set_viewid(cmd, viewid);
-	/* lock field */
-	if (lock && (lub_string_nocasecmp(lock, "false") == 0))
-		clish_command__set_lock(cmd, BOOL_FALSE);
-	else
-		clish_command__set_lock(cmd, BOOL_TRUE);
-	/* interrupt field */
-	if (interrupt && (lub_string_nocasecmp(interrupt, "true") == 0))
-		clish_command__set_interrupt(cmd, BOOL_TRUE);
-	else
-		clish_command__set_interrupt(cmd, BOOL_FALSE);
-
-	/* Set alias */
-	if (alias_name) {
-		assert(!((alias_view == v) && (!strcmp(alias_name, name))));
-		clish_command__set_alias(cmd, alias_name);
-		assert(alias_view);
-		clish_command__set_alias_view(cmd, alias_view);
-		lub_string_free(alias_name);
-	}
-
-	process_children(shell, element, cmd);
-}
-
-///////////////////////////////////////
-static void
-process_startup(clish_shell_t * shell, TiXmlElement * element, void *parent)
-{
-	clish_view_t *v = (clish_view_t *) parent;
-	clish_command_t *cmd = NULL;
-	const char *view = element->Attribute("view");
-	const char *viewid = element->Attribute("viewid");
-	const char *default_shebang = element->Attribute("default_shebang");
-	const char *timeout = element->Attribute("timeout");
-	const char *lock = element->Attribute("lock");
-	const char *interrupt = element->Attribute("interrupt");
-
-	assert(!shell->startup);
-	assert(view);
-
-	/* create a command with NULL help */
-	cmd = clish_view_new_command(v, "startup", NULL);
-	clish_command__set_lock(cmd, BOOL_FALSE);
-
-	// define the view which this command changes to
-	clish_view_t *next = clish_shell_find_create_view(shell, view, NULL);
-	// reference the next view
-	clish_command__set_view(cmd, next);
-
-	// define the view id which this command changes to
-	if (viewid)
-		clish_command__set_viewid(cmd, viewid);
-
-	if (default_shebang)
-		clish_shell__set_default_shebang(shell, default_shebang);
-
-	if (timeout)
-		clish_shell__set_timeout(shell, atoi(timeout));
-
-	/* lock field */
-	if (lock && (lub_string_nocasecmp(lock, "false") == 0))
-		clish_command__set_lock(cmd, BOOL_FALSE);
-	else
-		clish_command__set_lock(cmd, BOOL_TRUE);
-
-	/* interrupt field */
-	if (interrupt && (lub_string_nocasecmp(interrupt, "true") == 0))
-		clish_command__set_interrupt(cmd, BOOL_TRUE);
-	else
-		clish_command__set_interrupt(cmd, BOOL_FALSE);
-
-	// remember this command
-	shell->startup = cmd;
-
-	process_children(shell, element, cmd);
-}
-
-///////////////////////////////////////
-static void
-process_param(clish_shell_t * shell, TiXmlElement * element, void *parent)
-{
-	clish_command_t *cmd = NULL;
-	clish_param_t *p_param = NULL;
-	if (0 == lub_string_nocasecmp(element->Parent()->Value(), "PARAM"))
-		p_param = (clish_param_t *)parent;
-	else
-		cmd = (clish_command_t *)parent;
-
-	if (cmd || p_param) {
-		assert((!cmd) || (cmd != shell->startup));
-		const char *name = element->Attribute("name");
-		const char *help = element->Attribute("help");
-		const char *ptype = element->Attribute("ptype");
-		const char *prefix = element->Attribute("prefix");
-		const char *defval = element->Attribute("default");
-		const char *mode = element->Attribute("mode");
-		const char *optional = element->Attribute("optional");
-		const char *order = element->Attribute("order");
-		const char *value = element->Attribute("value");
-		const char *hidden = element->Attribute("hidden");
-		const char *test = element->Attribute("test");
-		const char *completion = element->Attribute("completion");
-		clish_param_t *param;
-		clish_ptype_t *tmp = NULL;
-
-		// create a command
-		assert(name);
-		assert(help);
-		assert(ptype);
-		if (ptype && *ptype) {
-			tmp = clish_shell_find_create_ptype(shell, ptype,
-				NULL, NULL,
-				CLISH_PTYPE_REGEXP,
-				CLISH_PTYPE_NONE);
-			assert(tmp);
-		}
-		param = clish_param_new(name, help, tmp);
-
-		/* If prefix is set clish will emulate old optional
-		 * command syntax over newer optional command mechanism.
-		 * It will create nested PARAM.
-		 */
-		if (prefix) {
-			const char *ptype_name = "__SUBCOMMAND";
-			clish_param_t *opt_param = NULL;
-
-			/* Create a ptype for prefix-named subcommand that
-			 * will contain the nested optional parameter. The
-			 * name of ptype is hardcoded. It's not good but
-			 * it's only the service ptype.
-			 */
-			tmp = (clish_ptype_t *)lub_bintree_find(
-				&shell->ptype_tree, ptype_name);
-			if (!tmp)
-				tmp = clish_shell_find_create_ptype(shell,
-					ptype_name, "Option", "[^\\\\]+",
-					CLISH_PTYPE_REGEXP, CLISH_PTYPE_NONE);
-			assert(tmp);
-			opt_param = clish_param_new(prefix, help, tmp);
-			clish_param__set_mode(opt_param,
-				CLISH_PARAM_SUBCOMMAND);
-			clish_param__set_optional(opt_param, BOOL_TRUE);
-
-			if (test)
-				clish_param__set_test(opt_param, test);
-
-			if (cmd)
-				// add the parameter to the command
-				clish_command_insert_param(cmd, opt_param);
-			if (p_param)
-				// add the parameter to the param
-				clish_param_insert_param(p_param, opt_param);
-			/* Unset cmd and set parent param to opt_param */
-			cmd = NULL;
-			p_param = opt_param;
-		}
-
-		if (defval)
-			clish_param__set_default(param, defval);
-
-		if (hidden && (lub_string_nocasecmp(hidden, "true") == 0))
-			clish_param__set_hidden(param, BOOL_TRUE);
-		else
-			clish_param__set_hidden(param, BOOL_FALSE);
-
-		if (mode) {
-			if (!lub_string_nocasecmp(mode, "switch")) {
-				clish_param__set_mode(param,
-					CLISH_PARAM_SWITCH);
-				/* Force hidden attribute */
-				clish_param__set_hidden(param, BOOL_TRUE);
-			} else if (!lub_string_nocasecmp(mode, "subcommand"))
-				clish_param__set_mode(param,
-					CLISH_PARAM_SUBCOMMAND);
-			else
-				clish_param__set_mode(param,
-					CLISH_PARAM_COMMON);
-		}
-
-		if (optional && (lub_string_nocasecmp(optional, "true") == 0))
-			clish_param__set_optional(param, BOOL_TRUE);
-		else
-			clish_param__set_optional(param, BOOL_FALSE);
-
-		if (order && (lub_string_nocasecmp(order, "true") == 0))
-			clish_param__set_order(param, BOOL_TRUE);
-		else
-			clish_param__set_order(param, BOOL_FALSE);
-
-		if (value) {
-			clish_param__set_value(param, value);
-			/* Force mode to subcommand */
-			clish_param__set_mode(param,
-				CLISH_PARAM_SUBCOMMAND);
-		}
-
-		if (test && !prefix)
-			clish_param__set_test(param, test);
-		if (completion)
-			clish_param__set_completion(param, completion);
-
-		if (cmd)
-			// add the parameter to the command
-			clish_command_insert_param(cmd, param);
-		if (p_param)
-			// add the parameter to the param
-			clish_param_insert_param(p_param, param);
-
-		process_children(shell, element, param);
-	}
-}
-
-////////////////////////////////////////
-static void
-process_action(clish_shell_t * shell, TiXmlElement * element, void *parent)
-{
-	clish_action_t *action = NULL;
-	TiXmlNode *text = element->FirstChild();
-	const char *builtin = element->Attribute("builtin");
-	const char *shebang = element->Attribute("shebang");
-
-	if (!lub_string_nocasecmp(element->Parent()->Value(), "VAR"))
-		action = clish_var__get_action((clish_var_t *)parent);
-	else
-		action = clish_command__get_action((clish_command_t *)parent);
-	assert(action);
-
-	if (text) {
-		assert(TiXmlNode::TEXT == text->Type());
-		// store the action
-		clish_action__set_script(action, text->Value());
-	}
-	if (builtin)
-		clish_action__set_builtin(action, builtin);
-	if (shebang)
-		clish_action__set_shebang(action, shebang);
-}
-
-////////////////////////////////////////
-static void
-process_detail(clish_shell_t * shell, TiXmlElement * element, void *parent)
-{
-	clish_command_t *cmd = (clish_command_t *) parent;
-
-	// read the following text element
-	TiXmlNode *text = element->FirstChild();
-
-	if (cmd && text) {
-		assert(TiXmlNode::TEXT == text->Type());
-		// store the action
-		clish_command__set_detail(cmd, text->Value());
-	}
-}
-
-///////////////////////////////////////
-static void
-process_namespace(clish_shell_t * shell, TiXmlElement * element, void *parent)
-{
-	clish_view_t *v = (clish_view_t *) parent;
-	clish_nspace_t *nspace = NULL;
-
-	const char *view = element->Attribute("ref");
-	const char *prefix = element->Attribute("prefix");
-	const char *prefix_help = element->Attribute("prefix_help");
-	const char *help = element->Attribute("help");
-	const char *completion = element->Attribute("completion");
-	const char *context_help = element->Attribute("context_help");
-	const char *inherit = element->Attribute("inherit");
-	const char *access = element->Attribute("access");
-	bool allowed = true;
-
-	if (access) {
-		allowed = false;
-		if (shell->client_hooks->access_fn)
-			allowed = shell->client_hooks->access_fn(shell, access)
-				? true : false;
-	}
-	if (!allowed)
-		return;
-
-	assert(view);
-	clish_view_t *ref_view = clish_shell_find_create_view(shell,
-		view, NULL);
-	assert(ref_view);
-	/* Don't include itself without prefix */
-	if ((ref_view == v) && !prefix)
-		return;
-	nspace = clish_nspace_new(ref_view);
-	assert(nspace);
-	clish_view_insert_nspace(v, nspace);
-
-	if (prefix) {
-		clish_nspace__set_prefix(nspace, prefix);
-		if (prefix_help)
-			clish_nspace_create_prefix_cmd(nspace,
-				"prefix",
-				prefix_help);
-		else
-			clish_nspace_create_prefix_cmd(nspace,
-				"prefix",
-				"Prefix for the imported commands.");
-	}
-
-	if (help && (lub_string_nocasecmp(help, "true") == 0))
-		clish_nspace__set_help(nspace, BOOL_TRUE);
-	else
-		clish_nspace__set_help(nspace, BOOL_FALSE);
-
-	if (completion && (lub_string_nocasecmp(completion, "false") == 0))
-		clish_nspace__set_completion(nspace, BOOL_FALSE);
-	else
-		clish_nspace__set_completion(nspace, BOOL_TRUE);
-
-	if (context_help && (lub_string_nocasecmp(context_help, "true") == 0))
-		clish_nspace__set_context_help(nspace, BOOL_TRUE);
-	else
-		clish_nspace__set_context_help(nspace, BOOL_FALSE);
-
-	if (inherit && (lub_string_nocasecmp(inherit, "false") == 0))
-		clish_nspace__set_inherit(nspace, BOOL_FALSE);
-	else
-		clish_nspace__set_inherit(nspace, BOOL_TRUE);
-}
-
-////////////////////////////////////////
-static void
-process_config(clish_shell_t * shell, TiXmlElement * element, void *parent)
-{
-	clish_command_t *cmd = (clish_command_t *)parent;
-	clish_config_t *config;
-
-	if (!cmd)
-		return;
-	config = clish_command__get_config(cmd);
-
-	// read the following text element
-	const char *operation = element->Attribute("operation");
-	const char *priority = element->Attribute("priority");
-	const char *pattern = element->Attribute("pattern");
-	const char *file = element->Attribute("file");
-	const char *splitter = element->Attribute("splitter");
-	const char *seq = element->Attribute("sequence");
-	const char *unique = element->Attribute("unique");
-	const char *depth = element->Attribute("depth");
-
-	if (operation && !lub_string_nocasecmp(operation, "unset"))
-		clish_config__set_op(config, CLISH_CONFIG_UNSET);
-	else if (operation && !lub_string_nocasecmp(operation, "none"))
-		clish_config__set_op(config, CLISH_CONFIG_NONE);
-	else if (operation && !lub_string_nocasecmp(operation, "dump"))
-		clish_config__set_op(config, CLISH_CONFIG_DUMP);
-	else {
-		clish_config__set_op(config, CLISH_CONFIG_SET);
-		/* The priority if no clearly specified */
-		clish_config__set_priority(config, 0x7f00);
-	}
-
-	if (priority && (*priority != '\0')) {
-		long val = 0;
-		char *endptr;
-		unsigned short pri;
-
-		val = strtol(priority, &endptr, 0);
-		if (endptr == priority)
-			pri = 0;
-		else if (val > 0xffff)
-			pri = 0xffff;
-		else if (val < 0)
-			pri = 0;
-		else
-			pri = (unsigned short)val;
-		clish_config__set_priority(config, pri);
-	}
-
-	if (pattern)
-		clish_config__set_pattern(config, pattern);
-	else
-		clish_config__set_pattern(config, "^${__cmd}");
-
-	if (file)
-		clish_config__set_file(config, file);
-
-	if (splitter && (lub_string_nocasecmp(splitter, "false") == 0))
-		clish_config__set_splitter(config, BOOL_FALSE);
-	else
-		clish_config__set_splitter(config, BOOL_TRUE);
-
-	if (unique && (lub_string_nocasecmp(unique, "false") == 0))
-		clish_config__set_unique(config, BOOL_FALSE);
-	else
-		clish_config__set_unique(config, BOOL_TRUE);
-
-	if (seq)
-		clish_config__set_seq(config, seq);
-	else
-		/* The entries without sequence cannot be non-unique */
-		clish_config__set_unique(config, BOOL_TRUE);
-
-	if (depth)
-		clish_config__set_depth(config, depth);
-
-}
-
-///////////////////////////////////////
-static void process_var(clish_shell_t * shell, TiXmlElement * element, void *)
-{
-	clish_var_t *var = NULL;
-	const char *name = element->Attribute("name");
-	const char *dynamic = element->Attribute("dynamic");
-	const char *value = element->Attribute("value");
-
-	assert(name);
-	/* Check if this var doesn't already exist */
-	var = (clish_var_t *)lub_bintree_find(&shell->var_tree, name);
-	if (var) {
-		printf("DUPLICATE VAR: %s\n", name);
-		assert(!var);
-	}
-
-	/* Create var instance */
-	var = clish_var_new(name);
-	lub_bintree_insert(&shell->var_tree, var);
-
-	if (dynamic && (lub_string_nocasecmp(dynamic, "true") == 0))
-		clish_var__set_dynamic(var, BOOL_TRUE);
-
-	if (value)
-		clish_var__set_value(var, value);
-
-	process_children(shell, element, var);
-}
-
-///////////////////////////////////////
-static void process_wdog(clish_shell_t *shell,
-	TiXmlElement *element, void *parent)
-{
-	clish_view_t *v = (clish_view_t *)parent;
-	clish_command_t *cmd = NULL;
-
-	assert(!shell->wdog);
-
-	/* create a command with NULL help */
-	cmd = clish_view_new_command(v, "watchdog", NULL);
-	clish_command__set_lock(cmd, BOOL_FALSE);
-
-	/* Remember this command */
-	shell->wdog = cmd;
-
-	process_children(shell, element, cmd);
-}
-
-///////////////////////////////////////
-int clish_shell_xml_read(clish_shell_t * shell, const char *filename)
-{
-	int ret = -1;
-	TiXmlDocument doc;
-
-	// keep the white space 
-	TiXmlBase::SetCondenseWhiteSpace(false);
-
-	if (doc.LoadFile(filename)) {
-		TiXmlNode *child = 0;
-		while ((child = doc.IterateChildren(child))) {
-			process_node(shell, child, NULL);
-		}
-		ret = 0;
-	} else {
-		printf("Unable to open %s (%s at line %d, col %d)\n",
-		        filename, doc.ErrorDesc(),
-		        doc.ErrorRow(), doc.ErrorCol());
-	}
-	return ret;
-}
-
-///////////////////////////////////////

+ 1009 - 0
clish/shell/shell_xml.c

@@ -0,0 +1,1009 @@
+/*
+ * ------------------------------------------------------
+ * shell_xml.c
+ *
+ * This file implements the means to read an XML encoded file and populate the
+ * CLI tree based on the contents.
+ * ------------------------------------------------------
+ */
+#include "private.h"
+#include "xmlapi.h"
+#include "lub/string.h"
+#include "lub/ctype.h"
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+typedef void (PROCESS_FN) (clish_shell_t * instance,
+	clish_xmlnode_t * element, void *parent);
+
+/* Define a control block for handling the decode of an XML file */
+typedef struct clish_xml_cb_s clish_xml_cb_t;
+struct clish_xml_cb_s {
+	const char *element;
+	PROCESS_FN *handler;
+};
+
+/* forward declare the handler functions */
+static PROCESS_FN
+	process_clish_module,
+	process_startup,
+	process_view,
+	process_command,
+	process_param,
+	process_action,
+	process_ptype,
+	process_overview,
+	process_detail,
+	process_namespace,
+	process_config,
+	process_var,
+	process_wdog;
+
+static clish_xml_cb_t xml_elements[] = {
+	{"CLISH_MODULE", process_clish_module},
+	{"STARTUP", process_startup},
+	{"VIEW", process_view},
+	{"COMMAND", process_command},
+	{"PARAM", process_param},
+	{"ACTION", process_action},
+	{"PTYPE", process_ptype},
+	{"OVERVIEW", process_overview},
+	{"DETAIL", process_detail},
+	{"NAMESPACE", process_namespace},
+	{"CONFIG", process_config},
+	{"VAR", process_var},
+	{"WATCHDOG", process_wdog},
+	{NULL, NULL}
+};
+
+/*
+ * ------------------------------------------------------
+ * This function reads an element from the XML stream and processes it.
+ * ------------------------------------------------------
+ */
+static void process_node(clish_shell_t * shell, clish_xmlnode_t * node, void *parent)
+{
+	switch (clish_xmlnode_get_type(node)) {
+	case CLISH_XMLNODE_ELM: {
+			clish_xml_cb_t * cb;
+			char name[128];
+			unsigned int namelen = sizeof(name);
+			if (clish_xmlnode_get_name(node, name, &namelen) == 0) {
+				for (cb = &xml_elements[0]; cb->element; cb++) {
+					if (0 == strcmp(name, cb->element)) {
+#ifdef DEBUG
+						fprintf(stderr, "NODE:");
+						clish_xmlnode_print(node, stderr);
+						fprintf(stderr, "\n");
+#endif
+						/* process the elements at this level */
+						cb->handler(shell, node, parent);
+						break;
+					}
+				}
+			}
+			break;
+		}
+	case CLISH_XMLNODE_DOC:
+	case CLISH_XMLNODE_TEXT:
+	case CLISH_XMLNODE_ATTR:
+	case CLISH_XMLNODE_PI:
+	case CLISH_XMLNODE_COMMENT:
+	case CLISH_XMLNODE_DECL:
+	case CLISH_XMLNODE_UNKNOWN:
+	default:
+		break;
+	}
+}
+
+/* ------------------------------------------------------ */
+static void process_children(clish_shell_t * shell,
+	clish_xmlnode_t * element, void *parent)
+{
+	clish_xmlnode_t *node = NULL;
+
+	while ((node = clish_xmlnode_next_child(element, node)) != NULL) {
+		/* Now deal with all the contained elements */
+		process_node(shell, node, parent);
+	}
+}
+
+/* ------------------------------------------------------ */
+static void
+process_clish_module(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	// create the global view
+	if (!shell->global)
+		shell->global = clish_shell_find_create_view(shell,
+			"global", "");
+	process_children(shell, element, shell->global);
+}
+
+/* ------------------------------------------------------ */
+static void process_view(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	clish_view_t *view;
+	char name[128] = "";
+	char prompt[128] = "";
+	char depth[128] = "";
+	char restore[128] = "";
+	clish_xmlattr_t *a_name;
+	clish_xmlattr_t *a_prompt;
+	clish_xmlattr_t *a_depth;
+	clish_xmlattr_t *a_restore;
+	clish_xmlattr_t *a_access;
+	int allowed = 1;
+
+	a_name = clish_xmlnode_fetch_attr(element, "name");
+	a_prompt = clish_xmlnode_fetch_attr(element, "prompt");
+	a_depth = clish_xmlnode_fetch_attr(element, "depth");
+	a_restore = clish_xmlnode_fetch_attr(element, "restore");
+	a_access = clish_xmlnode_fetch_attr(element, "access");
+
+	/* Check permissions */
+	if (a_access) {
+		char access[128] = "";
+
+		allowed = 0;
+		clish_xmlattr_get_value_noerr(a_access, access, sizeof(access));
+		if (shell->client_hooks->access_fn)
+			allowed = shell->client_hooks->access_fn(shell, access);
+	}
+	if (!allowed)
+		return;
+
+	clish_xmlattr_get_value_noerr(a_name, name, sizeof(name));
+	clish_xmlattr_get_value_noerr(a_prompt, prompt, sizeof(prompt));
+
+	/* re-use a view if it already exists */
+	view = clish_shell_find_create_view(shell, name, prompt);
+
+	clish_xmlattr_get_value_noerr(a_depth, depth, sizeof(depth));
+
+	if (*depth && (lub_ctype_isdigit(*depth))) {
+		unsigned res = atoi(depth);
+		clish_view__set_depth(view, res);
+	}
+
+	clish_xmlattr_get_value_noerr(a_restore, restore, sizeof(restore));
+
+	if (*restore) {
+		if (!lub_string_nocasecmp(restore, "depth"))
+			clish_view__set_restore(view, CLISH_RESTORE_DEPTH);
+		else if (!lub_string_nocasecmp(restore, "view"))
+			clish_view__set_restore(view, CLISH_RESTORE_VIEW);
+		else
+			clish_view__set_restore(view, CLISH_RESTORE_NONE);
+	}
+
+	process_children(shell, element, view);
+}
+
+/* ------------------------------------------------------ */
+static void process_ptype(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	clish_ptype_method_e method;
+	clish_ptype_preprocess_e preprocess;
+	clish_ptype_t *ptype;
+
+	clish_xmlattr_t *a_name = clish_xmlnode_fetch_attr(element, "name");
+	clish_xmlattr_t *a_help = clish_xmlnode_fetch_attr(element, "help");
+	clish_xmlattr_t *a_pattern = clish_xmlnode_fetch_attr(element, "pattern");
+	clish_xmlattr_t *a_method_name = clish_xmlnode_fetch_attr(element, "method");
+	clish_xmlattr_t *a_preprocess_name =
+		clish_xmlnode_fetch_attr(element, "preprocess");
+
+	char name[128] = "";
+	char help[128] = "";
+	char pattern[128] = "";
+	char method_name[128] = "";
+	char preprocess_name[128] = "";
+
+	clish_xmlattr_get_value_noerr(a_name, name, sizeof(name));
+	clish_xmlattr_get_value_noerr(a_pattern, pattern, sizeof(pattern));
+
+	assert(*name);
+	assert(*pattern);
+
+	clish_xmlattr_get_value_noerr(a_method_name, method_name,
+		sizeof(method_name));
+
+	method = clish_ptype_method_resolve(method_name);
+
+	clish_xmlattr_get_value_noerr(a_preprocess_name, preprocess_name,
+		sizeof(preprocess_name));
+	clish_xmlattr_get_value_noerr(a_help, help, sizeof(help));
+
+	preprocess = clish_ptype_preprocess_resolve(preprocess_name);
+	ptype = clish_shell_find_create_ptype(shell,
+		name, help, pattern, method, preprocess);
+
+	assert(ptype);
+}
+
+/* ------------------------------------------------------ */
+static void
+process_overview(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	char *content = NULL;
+	unsigned int content_len = 2048;
+	int result;
+
+	/*
+	 * the code below faithfully assume that we'll be able fully store
+	 * the content of the node. If it's really, really big, we may have
+	 * an issue (but then, if it's that big, how the hell does it
+	 * already fits in allocated memory?)
+	 * Ergo, it -should- be safe.
+	 */
+	do {
+		content = (char*)realloc(content, content_len);
+		result = clish_xmlnode_get_content(element, content,
+			&content_len);
+	} while (result == -E2BIG);
+
+	if (result == 0 && content) {
+		/* set the overview text for this view */
+		assert(NULL == shell->overview);
+		/* store the overview */
+		shell->overview = lub_string_dup(content);
+	}
+
+	if (content)
+		free(content);
+}
+
+/* ------------------------------------------------------ */
+static void
+process_command(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	clish_view_t *v = (clish_view_t *) parent;
+	clish_command_t *cmd = NULL;
+	clish_command_t *old;
+	char *alias_name = NULL;
+	clish_view_t *alias_view = NULL;
+	int allowed = 1;
+
+	clish_xmlattr_t *a_access = clish_xmlnode_fetch_attr(element, "access");
+	clish_xmlattr_t *a_name = clish_xmlnode_fetch_attr(element, "name");
+	clish_xmlattr_t *a_help = clish_xmlnode_fetch_attr(element, "help");
+	clish_xmlattr_t *a_view = clish_xmlnode_fetch_attr(element, "view");
+	clish_xmlattr_t *a_viewid = clish_xmlnode_fetch_attr(element, "viewid");
+	clish_xmlattr_t *a_escape_chars = clish_xmlnode_fetch_attr(element, "escape_chars");
+	clish_xmlattr_t *a_args_name = clish_xmlnode_fetch_attr(element, "args");
+	clish_xmlattr_t *a_args_help = clish_xmlnode_fetch_attr(element, "args_help");
+	clish_xmlattr_t *a_lock = clish_xmlnode_fetch_attr(element, "lock");
+	clish_xmlattr_t *a_interrupt = clish_xmlnode_fetch_attr(element, "interrupt");
+	clish_xmlattr_t *a_ref = clish_xmlnode_fetch_attr(element, "ref");
+
+	char name[128];
+	char help[128];
+	char ref[128];
+	char view[128];
+	char viewid[128];
+	char lock[128];
+	char interrupt[128];
+	char escape_chars[128];
+	char args_name[128];
+
+	/* Check permissions */
+	if (a_access) {
+		char access[128];
+
+		allowed = 0;
+		clish_xmlattr_get_value_noerr(a_access, access, sizeof(access));
+
+		if (shell->client_hooks->access_fn)
+			allowed = shell->client_hooks->access_fn(shell, access);
+	}
+	if (!allowed)
+		return;
+
+	clish_xmlattr_get_value_noerr(a_name, name, sizeof(name));
+
+	/* check this command doesn't already exist */
+	old = clish_view_find_command(v, name, BOOL_FALSE);
+	if (old) {
+		/* flag the duplication then ignore further definition */
+		printf("DUPLICATE COMMAND: %s\n",
+		       clish_command__get_name(old));
+		return;
+	}
+
+	clish_xmlattr_get_value_noerr(a_help, help, sizeof(help));
+
+	assert(*name);
+	assert(*help);
+
+	clish_xmlattr_get_value_noerr(a_ref, ref, sizeof(ref));
+
+	/* Reference 'ref' field */
+	if (*ref) {
+		char *saveptr;
+		const char *delim = "@";
+		char *view_name = NULL;
+		char *cmdn = NULL;
+		char *str = lub_string_dup(ref);
+
+		cmdn = strtok_r(str, delim, &saveptr);
+		if (!cmdn) {
+			printf("EMPTY REFERENCE COMMAND: %s\n", name);
+			lub_string_free(str);
+			return;
+		}
+		alias_name = lub_string_dup(cmdn);
+		view_name = strtok_r(NULL, delim, &saveptr);
+		if (!view_name)
+			alias_view = v;
+		else
+			alias_view = clish_shell_find_create_view(shell,
+				view_name, NULL);
+		lub_string_free(str);
+	}
+
+	clish_xmlattr_get_value_noerr(a_escape_chars, escape_chars,
+		sizeof(escape_chars));
+	clish_xmlattr_get_value_noerr(a_args_name, args_name,
+		sizeof(args_name));
+
+	/* create a command */
+	cmd = clish_view_new_command(v, name, help);
+	assert(cmd);
+	clish_command__set_pview(cmd, v);
+	/* define some specialist escape characters */
+	if (*escape_chars)
+		clish_command__set_escape_chars(cmd, escape_chars);
+	if (*args_name) {
+		/* define a "rest of line" argument */
+		char args_help[128];
+		clish_param_t *param;
+		clish_ptype_t *tmp = NULL;
+
+		clish_xmlattr_get_value_noerr(a_args_help, args_help,
+			sizeof(args_help));
+
+		assert(*args_help);
+		tmp = clish_shell_find_ptype(shell, "internal_ARGS");
+		assert(tmp);
+		param = clish_param_new(args_name, args_help, tmp);
+		clish_command__set_args(cmd, param);
+	}
+
+	clish_xmlattr_get_value_noerr(a_view, view, sizeof(view));
+
+	/* define the view which this command changes to */
+	if (*view) {
+		clish_view_t *next = clish_shell_find_create_view(shell, view,
+			NULL);
+
+		/* reference the next view */
+		clish_command__set_view(cmd, next);
+	}
+
+	clish_xmlattr_get_value_noerr(a_viewid, viewid, sizeof(viewid));
+
+	/* define the view id which this command changes to */
+	if (*viewid)
+		clish_command__set_viewid(cmd, viewid);
+
+	/* lock field */
+	clish_xmlattr_get_value_noerr(a_lock, lock, sizeof(lock));
+	if (lub_string_nocasecmp(lock, "false") == 0)
+		clish_command__set_lock(cmd, BOOL_FALSE);
+	else
+		clish_command__set_lock(cmd, BOOL_TRUE);
+
+	/* interrupt field */
+	clish_xmlattr_get_value_noerr(a_interrupt, interrupt, sizeof(interrupt));
+	if (lub_string_nocasecmp(interrupt, "true") == 0)
+		clish_command__set_interrupt(cmd, BOOL_TRUE);
+	else
+		clish_command__set_interrupt(cmd, BOOL_FALSE);
+
+	/* Set alias */
+	if (alias_name) {
+		assert(!((alias_view == v) && (!strcmp(alias_name, name))));
+		clish_command__set_alias(cmd, alias_name);
+		assert(alias_view);
+		clish_command__set_alias_view(cmd, alias_view);
+		lub_string_free(alias_name);
+	}
+
+	process_children(shell, element, cmd);
+}
+
+/* ------------------------------------------------------ */
+static void
+process_startup(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	clish_view_t *v = (clish_view_t *) parent;
+	clish_command_t *cmd = NULL;
+	clish_xmlattr_t *a_view = clish_xmlnode_fetch_attr(element, "view");
+	clish_xmlattr_t *a_viewid = clish_xmlnode_fetch_attr(element, "viewid");
+	clish_xmlattr_t *a_default_shebang =
+		clish_xmlnode_fetch_attr(element, "default_shebang");
+	clish_xmlattr_t *a_timeout = clish_xmlnode_fetch_attr(element, "timeout");
+	clish_xmlattr_t *a_lock = clish_xmlnode_fetch_attr(element, "lock");
+	clish_xmlattr_t *a_interrupt = clish_xmlnode_fetch_attr(element, "interrupt");
+
+	char view[128];
+	char viewid[128];
+	char timeout[128];
+	char lock[128];
+	char interrupt[128];
+	char default_shebang[128];
+
+	assert(!shell->startup);
+
+	clish_xmlattr_get_value_noerr(a_view, view, sizeof(view));
+
+	assert(*view);
+
+	/* create a command with NULL help */
+	cmd = clish_view_new_command(v, "startup", NULL);
+	clish_command__set_lock(cmd, BOOL_FALSE);
+
+	/* define the view which this command changes to */
+	clish_view_t *next = clish_shell_find_create_view(shell, view, NULL);
+	/* reference the next view */
+	clish_command__set_view(cmd, next);
+
+	/* define the view id which this command changes to */
+	clish_xmlattr_get_value_noerr(a_viewid, viewid, sizeof(viewid));
+	if (*viewid)
+		clish_command__set_viewid(cmd, viewid);
+
+	clish_xmlattr_get_value_noerr(a_default_shebang, default_shebang,
+		sizeof(default_shebang));
+	if (*default_shebang)
+		clish_shell__set_default_shebang(shell, default_shebang);
+
+	clish_xmlattr_get_value_noerr(a_timeout, timeout, sizeof(timeout));
+	if (*timeout)
+		clish_shell__set_timeout(shell, atoi(timeout));
+
+	/* lock field */
+	clish_xmlattr_get_value_noerr(a_lock, lock, sizeof(lock));
+	if (lub_string_nocasecmp(lock, "false") == 0)
+		clish_command__set_lock(cmd, BOOL_FALSE);
+	else
+		clish_command__set_lock(cmd, BOOL_TRUE);
+
+	/* interrupt field */
+	clish_xmlattr_get_value_noerr(a_interrupt, interrupt, sizeof(interrupt));
+	if (lub_string_nocasecmp(interrupt, "true") == 0)
+		clish_command__set_interrupt(cmd, BOOL_TRUE);
+	else
+		clish_command__set_interrupt(cmd, BOOL_FALSE);
+
+	/* remember this command */
+	shell->startup = cmd;
+
+	process_children(shell, element, cmd);
+}
+
+/* ------------------------------------------------------ */
+static void
+process_param(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	clish_command_t *cmd = NULL;
+	clish_param_t *p_param = NULL;
+	clish_xmlnode_t *pelement;
+	char *pname;
+
+	pelement = clish_xmlnode_parent(element);
+	pname = clish_xmlnode_get_all_name(pelement);
+
+	if (pname && lub_string_nocasecmp(pname, "PARAM") == 0)
+		p_param = (clish_param_t *)parent;
+	else
+		cmd = (clish_command_t *)parent;
+
+	if (pname)
+		free(pname);
+
+	if (cmd || p_param) {
+		clish_xmlattr_t *a_name = clish_xmlnode_fetch_attr(element, "name");
+		clish_xmlattr_t *a_help = clish_xmlnode_fetch_attr(element, "help");
+		clish_xmlattr_t *a_ptype = clish_xmlnode_fetch_attr(element, "ptype");
+		clish_xmlattr_t *a_prefix = clish_xmlnode_fetch_attr(element, "prefix");
+		clish_xmlattr_t *a_defval = clish_xmlnode_fetch_attr(element, "default");
+		clish_xmlattr_t *a_mode = clish_xmlnode_fetch_attr(element, "mode");
+		clish_xmlattr_t *a_optional = clish_xmlnode_fetch_attr(element, "optional");
+		clish_xmlattr_t *a_order = clish_xmlnode_fetch_attr(element, "order");
+		clish_xmlattr_t *a_value = clish_xmlnode_fetch_attr(element, "value");
+		clish_xmlattr_t *a_hidden = clish_xmlnode_fetch_attr(element, "hidden");
+		clish_xmlattr_t *a_test = clish_xmlnode_fetch_attr(element, "test");
+		clish_xmlattr_t *a_completion = clish_xmlnode_fetch_attr(element, "completion");
+		clish_param_t *param;
+		clish_ptype_t *tmp = NULL;
+
+		char name[128];
+		char help[128];
+		char ptype[128];
+		char prefix[128];
+		char defval[128];
+		char mode[128];
+		char optional[128];
+		char order[128];
+		char value[128];
+		char hidden[128];
+		char test[128];
+		char completion[128];
+
+		assert((!cmd) || (cmd != shell->startup));
+
+		clish_xmlattr_get_value_noerr(a_name, name, sizeof(name));
+		clish_xmlattr_get_value_noerr(a_help, help, sizeof(help));
+		clish_xmlattr_get_value_noerr(a_ptype, ptype, sizeof(ptype));
+
+		/* create a command */
+		assert(*name);
+		assert(*help);
+		assert(*ptype);
+
+		if (*ptype) {
+			tmp = clish_shell_find_create_ptype(shell, ptype,
+				NULL, NULL,
+				CLISH_PTYPE_REGEXP,
+				CLISH_PTYPE_NONE);
+			assert(tmp);
+		}
+		param = clish_param_new(name, help, tmp);
+
+		/* If prefix is set clish will emulate old optional
+		 * command syntax over newer optional command mechanism.
+		 * It will create nested PARAM.
+		 */
+		clish_xmlattr_get_value_noerr(a_prefix, prefix, sizeof(prefix));
+		clish_xmlattr_get_value_noerr(a_test, test, sizeof(test));
+		if (*prefix) {
+			const char *ptype_name = "__SUBCOMMAND";
+			clish_param_t *opt_param = NULL;
+
+			/* Create a ptype for prefix-named subcommand that
+			 * will contain the nested optional parameter. The
+			 * name of ptype is hardcoded. It's not good but
+			 * it's only the service ptype.
+			 */
+			tmp = (clish_ptype_t *)lub_bintree_find(
+				&shell->ptype_tree, ptype_name);
+			if (!tmp)
+				tmp = clish_shell_find_create_ptype(shell,
+					ptype_name, "Option", "[^\\\\]+",
+					CLISH_PTYPE_REGEXP, CLISH_PTYPE_NONE);
+			assert(tmp);
+			opt_param = clish_param_new(prefix, help, tmp);
+			clish_param__set_mode(opt_param,
+				CLISH_PARAM_SUBCOMMAND);
+			clish_param__set_optional(opt_param, BOOL_TRUE);
+
+			if (*test)
+				clish_param__set_test(opt_param, test);
+
+			/* add the parameter to the command */
+			if (cmd)
+				clish_command_insert_param(cmd, opt_param);
+			/* add the parameter to the param */
+			if (p_param)
+				clish_param_insert_param(p_param, opt_param);
+			/* Unset cmd and set parent param to opt_param */
+			cmd = NULL;
+			p_param = opt_param;
+		}
+
+		clish_xmlattr_get_value_noerr(a_defval, defval, sizeof(defval));
+
+		if (*defval)
+			clish_param__set_default(param, defval);
+
+		clish_xmlattr_get_value_noerr(a_hidden, hidden, sizeof(hidden));
+		if (lub_string_nocasecmp(hidden, "true") == 0)
+			clish_param__set_hidden(param, BOOL_TRUE);
+		else
+			clish_param__set_hidden(param, BOOL_FALSE);
+
+		clish_xmlattr_get_value_noerr(a_mode, mode, sizeof(mode));
+		if (*mode) {
+			if (lub_string_nocasecmp(mode, "switch") == 0) {
+				clish_param__set_mode(param,
+					CLISH_PARAM_SWITCH);
+				/* Force hidden attribute */
+				clish_param__set_hidden(param, BOOL_TRUE);
+			} else if (lub_string_nocasecmp(mode, "subcommand") == 0)
+				clish_param__set_mode(param,
+					CLISH_PARAM_SUBCOMMAND);
+			else
+				clish_param__set_mode(param,
+					CLISH_PARAM_COMMON);
+		}
+
+		clish_xmlattr_get_value_noerr(a_optional, optional,
+			sizeof(optional));
+		if (lub_string_nocasecmp(optional, "true") == 0)
+			clish_param__set_optional(param, BOOL_TRUE);
+		else
+			clish_param__set_optional(param, BOOL_FALSE);
+
+		clish_xmlattr_get_value_noerr(a_order, order, sizeof(order));
+		if (lub_string_nocasecmp(order, "true") == 0)
+			clish_param__set_order(param, BOOL_TRUE);
+		else
+			clish_param__set_order(param, BOOL_FALSE);
+
+		clish_xmlattr_get_value_noerr(a_value, value, sizeof(value));
+		if (*value) {
+			clish_param__set_value(param, value);
+			/* Force mode to subcommand */
+			clish_param__set_mode(param,
+				CLISH_PARAM_SUBCOMMAND);
+		}
+
+		if (*test && !*prefix)
+			clish_param__set_test(param, test);
+
+		clish_xmlattr_get_value_noerr(a_completion, completion,
+			sizeof(completion));
+		if (*completion)
+			clish_param__set_completion(param, completion);
+
+		/* add the parameter to the command */
+		if (cmd)
+			clish_command_insert_param(cmd, param);
+
+		/* add the parameter to the param */
+		if (p_param)
+			clish_param_insert_param(p_param, param);
+
+		process_children(shell, element, param);
+	}
+}
+
+/* ------------------------------------------------------ */
+static void
+process_action(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	clish_action_t *action = NULL;
+	clish_xmlattr_t *a_builtin = clish_xmlnode_fetch_attr(element, "builtin");
+	clish_xmlattr_t *a_shebang = clish_xmlnode_fetch_attr(element, "shebang");
+	clish_xmlnode_t *pelement = clish_xmlnode_parent(element);
+	char *pname = clish_xmlnode_get_all_name(pelement);
+	char *text;
+	char builtin[128];
+	char shebang[128];
+
+	if (pname && lub_string_nocasecmp(pname, "VAR") == 0)
+		action = clish_var__get_action((clish_var_t *)parent);
+	else
+		action = clish_command__get_action((clish_command_t *)parent);
+	assert(action);
+
+	if (pname)
+		free(pname);
+
+	text = clish_xmlnode_get_all_content(element);
+
+	if (text && *text) {
+		/* store the action */
+		clish_action__set_script(action, text);
+	}
+	if (text)
+		free(text);
+
+	clish_xmlattr_get_value_noerr(a_builtin, builtin, sizeof(builtin));
+	clish_xmlattr_get_value_noerr(a_shebang, shebang, sizeof(shebang));
+
+	if (*builtin)
+		clish_action__set_builtin(action, builtin);
+	if (*shebang)
+		clish_action__set_shebang(action, shebang);
+}
+
+/* ------------------------------------------------------ */
+static void
+process_detail(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	clish_command_t *cmd = (clish_command_t *) parent;
+
+	/* read the following text element */
+	char *text = clish_xmlnode_get_all_content(element);
+
+	if (text && *text) {
+		/* store the action */
+		clish_command__set_detail(cmd, text);
+	}
+
+	if (text)
+		free(text);
+}
+
+/* ------------------------------------------------------ */
+static void
+process_namespace(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	clish_view_t *v = (clish_view_t *) parent;
+	clish_nspace_t *nspace = NULL;
+
+	clish_xmlattr_t *a_view = clish_xmlnode_fetch_attr(element, "ref");
+	clish_xmlattr_t *a_prefix = clish_xmlnode_fetch_attr(element, "prefix");
+	clish_xmlattr_t *a_prefix_help = clish_xmlnode_fetch_attr(element, "prefix_help");
+	clish_xmlattr_t *a_help = clish_xmlnode_fetch_attr(element, "help");
+	clish_xmlattr_t *a_completion = clish_xmlnode_fetch_attr(element, "completion");
+	clish_xmlattr_t *a_context_help = clish_xmlnode_fetch_attr(element, "context_help");
+	clish_xmlattr_t *a_inherit = clish_xmlnode_fetch_attr(element, "inherit");
+	clish_xmlattr_t *a_access = clish_xmlnode_fetch_attr(element, "access");
+
+	char view[128];
+	char prefix[128];
+
+	char help[128];
+	char completion[128];
+	char context_help[128];
+	char inherit[128];
+
+	int allowed = 1;
+
+	if (a_access) {
+		char access[128];
+		allowed = 0;
+		clish_xmlattr_get_value_noerr(a_access, access, sizeof(access));
+		if (shell->client_hooks->access_fn)
+			allowed = shell->client_hooks->access_fn(shell, access);
+	}
+	if (!allowed)
+		return;
+
+	clish_xmlattr_get_value_noerr(a_view, view, sizeof(view));
+	clish_xmlattr_get_value_noerr(a_prefix, prefix, sizeof(prefix));
+
+	assert(*view);
+	clish_view_t *ref_view = clish_shell_find_create_view(shell,
+		view, NULL);
+	assert(ref_view);
+	/* Don't include itself without prefix */
+	if ((ref_view == v) && !*prefix)
+		return;
+	nspace = clish_nspace_new(ref_view);
+	assert(nspace);
+	clish_view_insert_nspace(v, nspace);
+
+	if (*prefix) {
+		char prefix_help[128];
+
+		clish_nspace__set_prefix(nspace, prefix);
+		clish_xmlattr_get_value_noerr(a_prefix_help, prefix_help,
+			sizeof(prefix_help));
+		if (*prefix_help)
+			clish_nspace_create_prefix_cmd(nspace,
+				"prefix",
+				prefix_help);
+		else
+			clish_nspace_create_prefix_cmd(nspace,
+				"prefix",
+				"Prefix for the imported commands.");
+	}
+
+	clish_xmlattr_get_value_noerr(a_help, help, sizeof(help));
+
+	if (lub_string_nocasecmp(help, "true") == 0)
+		clish_nspace__set_help(nspace, BOOL_TRUE);
+	else
+		clish_nspace__set_help(nspace, BOOL_FALSE);
+
+	clish_xmlattr_get_value_noerr(a_completion, completion,
+		sizeof(completion));
+
+	if (lub_string_nocasecmp(completion, "false") == 0)
+		clish_nspace__set_completion(nspace, BOOL_FALSE);
+	else
+		clish_nspace__set_completion(nspace, BOOL_TRUE);
+
+	clish_xmlattr_get_value_noerr(a_context_help, context_help,
+		sizeof(context_help));
+
+	if (lub_string_nocasecmp(context_help, "true") == 0)
+		clish_nspace__set_context_help(nspace, BOOL_TRUE);
+	else
+		clish_nspace__set_context_help(nspace, BOOL_FALSE);
+
+	clish_xmlattr_get_value_noerr(a_inherit, inherit, sizeof(inherit));
+
+	if (lub_string_nocasecmp(inherit, "false") == 0)
+		clish_nspace__set_inherit(nspace, BOOL_FALSE);
+	else
+		clish_nspace__set_inherit(nspace, BOOL_TRUE);
+}
+
+/* ------------------------------------------------------ */
+static void
+process_config(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	clish_command_t *cmd = (clish_command_t *)parent;
+	clish_config_t *config;
+
+	if (!cmd)
+		return;
+	config = clish_command__get_config(cmd);
+
+	/* read the following text element */
+	clish_xmlattr_t *a_operation = clish_xmlnode_fetch_attr(element, "operation");
+	clish_xmlattr_t *a_priority = clish_xmlnode_fetch_attr(element, "priority");
+	clish_xmlattr_t *a_pattern = clish_xmlnode_fetch_attr(element, "pattern");
+	clish_xmlattr_t *a_file = clish_xmlnode_fetch_attr(element, "file");
+	clish_xmlattr_t *a_splitter = clish_xmlnode_fetch_attr(element, "splitter");
+	clish_xmlattr_t *a_seq = clish_xmlnode_fetch_attr(element, "sequence");
+	clish_xmlattr_t *a_unique = clish_xmlnode_fetch_attr(element, "unique");
+	clish_xmlattr_t *a_depth = clish_xmlnode_fetch_attr(element, "depth");
+
+	char operation[128];
+	char priority[128];
+	char pattern[128];
+	char file[128];
+	char splitter[128];
+	char seq[128];
+	char unique[128];
+	char depth[128];
+
+	clish_xmlattr_get_value_noerr(a_operation, operation, sizeof(operation));
+
+	if (!lub_string_nocasecmp(operation, "unset"))
+		clish_config__set_op(config, CLISH_CONFIG_UNSET);
+	else if (!lub_string_nocasecmp(operation, "none"))
+		clish_config__set_op(config, CLISH_CONFIG_NONE);
+	else if (!lub_string_nocasecmp(operation, "dump"))
+		clish_config__set_op(config, CLISH_CONFIG_DUMP);
+	else {
+		clish_config__set_op(config, CLISH_CONFIG_SET);
+		/* The priority if no clearly specified */
+		clish_config__set_priority(config, 0x7f00);
+	}
+
+	clish_xmlattr_get_value_noerr(a_priority, priority, sizeof(priority));
+
+	if (*priority) {
+		long val = 0;
+		char *endptr;
+		unsigned short pri;
+
+		val = strtol(priority, &endptr, 0);
+		if (endptr == priority)
+			pri = 0;
+		else if (val > 0xffff)
+			pri = 0xffff;
+		else if (val < 0)
+			pri = 0;
+		else
+			pri = (unsigned short)val;
+		clish_config__set_priority(config, pri);
+	}
+
+	clish_xmlattr_get_value_noerr(a_pattern, pattern, sizeof(pattern));
+
+	if (*pattern)
+		clish_config__set_pattern(config, pattern);
+	else
+		clish_config__set_pattern(config, "^${__cmd}");
+
+	clish_xmlattr_get_value_noerr(a_file, file, sizeof(file));
+
+	if (*file)
+		clish_config__set_file(config, file);
+
+	clish_xmlattr_get_value_noerr(a_splitter, splitter, sizeof(splitter));
+
+	if (lub_string_nocasecmp(splitter, "false") == 0)
+		clish_config__set_splitter(config, BOOL_FALSE);
+	else
+		clish_config__set_splitter(config, BOOL_TRUE);
+
+	clish_xmlattr_get_value_noerr(a_unique, unique, sizeof(unique));
+
+	if (lub_string_nocasecmp(unique, "false") == 0)
+		clish_config__set_unique(config, BOOL_FALSE);
+	else
+		clish_config__set_unique(config, BOOL_TRUE);
+
+	clish_xmlattr_get_value_noerr(a_seq, seq, sizeof(seq));
+
+	if (*seq)
+		clish_config__set_seq(config, seq);
+	else
+		/* The entries without sequence cannot be non-unique */
+		clish_config__set_unique(config, BOOL_TRUE);
+
+	clish_xmlattr_get_value_noerr(a_depth, depth, sizeof(depth));
+
+	if (*depth)
+		clish_config__set_depth(config, depth);
+
+}
+
+/* ------------------------------------------------------ */
+static void process_var(clish_shell_t * shell, clish_xmlnode_t * element, void *parent)
+{
+	clish_var_t *var = NULL;
+	clish_xmlattr_t *a_name = clish_xmlnode_fetch_attr(element, "name");
+	clish_xmlattr_t *a_dynamic = clish_xmlnode_fetch_attr(element, "dynamic");
+	clish_xmlattr_t *a_value = clish_xmlnode_fetch_attr(element, "value");
+
+	char name[128];
+	char value[128];
+	char dynamic[128];
+
+	clish_xmlattr_get_value_noerr(a_name, name, sizeof(name));
+
+	assert(*name);
+	/* Check if this var doesn't already exist */
+	var = (clish_var_t *)lub_bintree_find(&shell->var_tree, name);
+	if (var) {
+		printf("DUPLICATE VAR: %s\n", name);
+		assert(!var);
+	}
+
+	/* Create var instance */
+	var = clish_var_new(name);
+	lub_bintree_insert(&shell->var_tree, var);
+
+	clish_xmlattr_get_value_noerr(a_dynamic, dynamic, sizeof(dynamic));
+
+	if (lub_string_nocasecmp(dynamic, "true") == 0)
+		clish_var__set_dynamic(var, BOOL_TRUE);
+
+	clish_xmlattr_get_value_noerr(a_value, value, sizeof(value));
+	if (*value)
+		clish_var__set_value(var, value);
+
+	process_children(shell, element, var);
+}
+
+/* ------------------------------------------------------ */
+static void process_wdog(clish_shell_t *shell,
+	clish_xmlnode_t *element, void *parent)
+{
+	clish_view_t *v = (clish_view_t *)parent;
+	clish_command_t *cmd = NULL;
+
+	assert(!shell->wdog);
+
+	/* create a command with NULL help */
+	cmd = clish_view_new_command(v, "watchdog", NULL);
+	clish_command__set_lock(cmd, BOOL_FALSE);
+
+	/* Remember this command */
+	shell->wdog = cmd;
+
+	process_children(shell, element, cmd);
+}
+
+/* ------------------------------------------------------ */
+int clish_shell_xml_read(clish_shell_t * shell, const char *filename)
+{
+	int ret = -1;
+	clish_xmldoc_t *doc;
+
+	doc = clish_xmldoc_read(filename);
+
+	if (clish_xmldoc_is_valid(doc)) {
+		clish_xmlnode_t *root = clish_xmldoc_get_root(doc);
+		process_node(shell, root, NULL);
+		ret = 0;
+	} else {
+		int errcaps = clish_xmldoc_error_caps(doc);
+		printf("Unable to open file '%s'", filename);
+		if ((errcaps & CLISH_XMLERR_LINE) == CLISH_XMLERR_LINE)
+			printf(", at line %d", clish_xmldoc_get_err_line(doc));
+		if ((errcaps & CLISH_XMLERR_COL) == CLISH_XMLERR_COL)
+			printf(", at column %d", clish_xmldoc_get_err_col(doc));
+		if ((errcaps & CLISH_XMLERR_DESC) == CLISH_XMLERR_DESC)
+			printf(", message is %s", clish_xmldoc_get_err_msg(doc));
+		printf("\n");
+	}
+
+	clish_xmldoc_release(doc);
+
+	return ret;
+}
+
+/* ------------------------------------------------------ */

+ 219 - 0
clish/shell/xmlapi.h

@@ -0,0 +1,219 @@
+/*
+ * xmlapi.h
+ * 
+ * private klish file: internal XML API
+ */
+
+#ifndef clish_xmlapi_included_h
+#define clish_xmlapi_included_h
+
+#include <stdlib.h>
+#include <errno.h>
+
+/* 
+ * XML document (opaque type) 
+ * The real type is defined by the selected external API
+ */
+typedef struct clish_xmldoc_s clish_xmldoc_t;
+
+/* 
+ * XML node (opaque type) 
+ * The real type is defined by the selected external API
+ */
+typedef struct clish_xmlnode_s clish_xmlnode_t;
+
+/* 
+ * XML attribute (opaque type) 
+ * The real type is defined by the selected external API
+ */
+typedef struct clish_xmlattr_s clish_xmlattr_t;
+
+/*
+ * read an XML document
+ */
+clish_xmldoc_t *clish_xmldoc_read(const char *filename);
+
+/*
+ * release a previously opened XML document
+ */
+void clish_xmldoc_release(clish_xmldoc_t *doc);
+
+/*
+ * check if a doc is valid (i.e. it loaded successfully)
+ */
+int clish_xmldoc_is_valid(clish_xmldoc_t *doc);
+
+/*
+ * XML implementation error capabilitiess
+ * The real capabilities is or'ed using the following
+ * constants
+ */
+typedef enum {
+	CLISH_XMLERR_NOCAPS 	= 0,
+	CLISH_XMLERR_LINE 	= 0x10,
+	CLISH_XMLERR_COL 	= 0x20,
+	CLISH_XMLERR_DESC 	= 0x40
+} clish_xmlerrcaps_t;
+
+/*
+ * does this specific implementation define any error?
+ * -> get the capabilities
+ */
+int clish_xmldoc_error_caps(clish_xmldoc_t *doc);
+
+typedef enum {
+	CLISH_XMLNODE_DOC,
+	CLISH_XMLNODE_ELM,
+	CLISH_XMLNODE_TEXT,
+	CLISH_XMLNODE_ATTR,
+	CLISH_XMLNODE_COMMENT,
+	CLISH_XMLNODE_PI,
+	CLISH_XMLNODE_DECL,
+	CLISH_XMLNODE_UNKNOWN,
+} clish_xmlnodetype_t;
+
+/*
+ * get error description, when available
+ */
+int clish_xmldoc_get_err_line(clish_xmldoc_t *doc);
+int clish_xmldoc_get_err_col(clish_xmldoc_t *doc);
+const char *clish_xmldoc_get_err_msg(clish_xmldoc_t *doc);
+
+/*
+ * get the node type
+ */
+int clish_xmlnode_get_type(clish_xmlnode_t *node);
+
+/*
+ * get the document root
+ */
+clish_xmlnode_t *clish_xmldoc_get_root(clish_xmldoc_t *doc);
+
+/*
+ * get the next child or NULL. If curchild is NULL, 
+ * then the function returns the first child. 
+ */
+clish_xmlnode_t *clish_xmlnode_next_child(
+	clish_xmlnode_t *parent, 
+	clish_xmlnode_t *curchild);
+
+/*
+ * get the parent node.
+ * returns NULL if node is the document root node.
+ */
+clish_xmlnode_t *clish_xmlnode_parent(clish_xmlnode_t *node);
+
+/*
+ * get the node name.
+ * neither name not namelen shall be NULL. *namelen is the length of the
+ * name buffer. If it's too small, we return -E2BIG and set *namelen to
+ * the minimum length value.
+ * returns < 0 on error. On error, name shall not be modified.
+ */
+int clish_xmlnode_get_name(
+	clish_xmlnode_t *node,
+	char *name, 
+	unsigned int *namelen);
+
+/*
+ * get the node name
+ * dynamically allocate the buffer (it must be freed once you don't need it
+ * anymore) that will contain all the content of the node.
+ * return NULL on error.
+ */
+static inline char* clish_xmlnode_get_all_name(clish_xmlnode_t *node)
+{
+	char *name = NULL; 
+	unsigned int nlen = 2048; 
+	int result;
+
+	do { 
+		name = (char*)realloc(name, nlen);
+		result = clish_xmlnode_get_name(node, name, &nlen);
+	} while (result == -E2BIG);
+
+	if (result < 0) {
+		free(name);
+		return NULL;
+	}
+
+	return name;
+}
+
+/*
+ * get the node content.
+ * neither content not contentlen shall be NULL. *contentlen is the length
+ * of the content buffer. If it's too small, we return -E2BIG and set
+ * *contentlen to the minimum length value (including space for the \0 
+ * character) so that two subsequent calls to this functions are going
+ * to succeed if the forst one failed because of a too small buffer.
+ * returns < 0 on error. On error, content shall not be modified.
+ */
+int clish_xmlnode_get_content(
+	clish_xmlnode_t *node,
+	char *content, 
+	unsigned int *contentlen);
+
+/*
+ * get the node content
+ * dynamically allocate the buffer (it must be freed once you don't need it
+ * anymore) that will contain all the content of the node.
+ * return NULL on error.
+ */
+static inline char* clish_xmlnode_get_all_content(clish_xmlnode_t *node)
+{
+	char *content = NULL; 
+	unsigned int clen = 2048; 
+	int result;
+
+	do { 
+		content = (char*)realloc(content, clen);
+		result = clish_xmlnode_get_content(node, content, &clen);
+	} while (result == -E2BIG);
+
+	if (result < 0) {
+		free(content);
+		return NULL;
+	}
+
+	return content;
+}
+
+/*
+ * get an attribute by name. May return NULL if the
+ * attribute is not found
+ */
+clish_xmlattr_t *clish_xmlnode_fetch_attr(
+	clish_xmlnode_t *node,
+	const char *attrname);
+
+/*
+ * get the attribute value.
+ * neither value not valuelen shall be NULL. *valuelen is the length
+ * of the value buffer. If it's too small, we return -E2BIG and set
+ * *valuelen to the minimum length value.
+ * returns < 0 on error. On error, value shall not be modified.
+ */
+int clish_xmlattr_get_value(
+	clish_xmlattr_t *attr,
+	char *value, 
+	unsigned int *valuelen);
+
+/*
+ * get the attribute value.
+ * value shall not be NULL, and valuelen shall not be 0. 
+ * On error, value is set to \0 when possible.
+ */
+void clish_xmlattr_get_value_noerr(
+	clish_xmlattr_t *attr,
+	char *value, 
+	unsigned int valuelen);
+
+#include <stdio.h> /* need for FILE */
+/*
+ * print an XML node to the out file
+ */
+void clish_xmlnode_print(clish_xmlnode_t *node, FILE *out);
+
+#endif /* clish_xmlapi_included_h */
+

+ 0 - 12
tinyxml/README

@@ -1,12 +0,0 @@
-/**
-\defgroup tinyxml "Tiny XML Library"
-@{
-
-This library provides a small footprint XML parsing facility. CLISH uses this
-in prefence to libxml2 as it is far more suited to embedded systems.
-
-Full documentation and details of this library can be found at
-http://www.grinninglizard.com/tinyxml/
-
-@}
-*/

+ 0 - 250
tinyxml/changes.txt

@@ -1,250 +0,0 @@
-Changes in version 1.0.1:
-- Fixed comment tags which were outputing as '<?--' instead of 
-  the correct '<!--'.
-- Implemented the Next and Prev methods of the TiXmlAttribute class.
-- Renamed 'LastAttribtute' to 'LastAttribute'
-- Fixed bad pointer to 'isspace' that could occur while parsing text.
-- Errors finding beginning and end of tags no longer throw it into an
-  infinite loop. (Hopefully.)
-
-Changes in version 1.0.2
-- Minor documentation fixes.
-
-Changes in version 1.0.3
-- After nodes are added to a document, they return a pointer
-  to the new node instead of a bool for success.
-- Elements can be constructed with a value, which is the
-  element name. Every element must have a value or it will be
-  invalid, but the code changes to enforce this are not fully
-  in place.
-
-Changes in version 1.1.0
-- Added the	TiXmlAttributeSet class to pull the attributes into
-  a seperate container.
-- Moved the doubly liked list out of XmlBase. Now XmlBase only
-  requires the Print() function and defines some utility functions.
-- Moved errors into a seperate file. (With the idea of internationalization
-  to the other latin-1 languages.)
-- Added the "NodeType"
-- Fixed white space parsing in text to conform with the standard. 
-  Basically, all white space becomes just one space.
-- Added the TiXmlDeclaration class to read xml declarations.
-
-Changes in version 1.2.0
-- Removed the factory. The factory was not really in the spirit 
-  of small and simple, confused the code, and was of limited value.
-- Added FirstChildElement and NextSiblingElement, because they
-  are such common functions.
-- Re-wrote the example to test and demonstrate more functionality.
-
-Changes in version 1.2.1
-- Fixed a bug where comments couldn't be inside elements.
-- Loading now clears out existing XML rather than appending.
-- Added the "Clear" method on a node to delete all its children.
-
-Changes in version 1.2.2
-- Fixed TiXmlAttribute::Previous actually returning "next." Thanks
-  to Rickard Troedsson for the bug fix.
-
-Changes in version 1.2.3
-- Added the TIXML prefix to the error strings to resolve conflicts
-  with #defines in OS headers. Thanks to Steve Lhomme.
-- Fixed a delete buf that should be a delete [] buf. 
-  Thanks to Ephi Sinowitz.
-
-Changes in version 1.2.4
-- ReplaceChild() was almost guarenteed to fail. Should be fixed,
-  thanks to Joe Smith. Joe also pointed out that the Print() functions
-  should take stream references: I agree, and would like to overload
-  the Print() method to take either format, but I don't want to do 
-  this in a dot release.
-- Some compilers seem to need an extra <ctype.h> include. Thanks
-  to Steve Lhomme for that.
-
-Changes in version 2.0.0 BETA
-- Made the ToXXX() casts safe if 'this' is null. 
-  When "LoadFile" is called with a filename, the value will correctly get set.
-  Thanks to Brian Yoder.
-- Fixed bug where isalpha() and isalnum() would get called with a negative value for 
-  high ascii numbers. Thanks to Alesky Aksenov.
-- Fixed some errors codes that were not getting set.
-- Made methods "const" that were not.
-- Added a switch to enable or disable the ignoring of white space. ( TiXmlDocument::SetIgnoreWhiteSpace() )
-- Greater standardization and code re-use in the parser.
-- Added a stream out operator.
-- Added a stream in operator.
-- Entity support, of predefined entites. &#x entities are untouched by input or output.
-- Improved text out formatting.
-- Fixed ReplaceChild bug, thanks to Tao Chen.
-
-Changes in version 2.0.1
-- Fixed hanging on loading a 0 length file. Thanks to Jeff Scozzafava.
-- Fixed crashing on InsertBeforeChild and InsertAfterChild. Also possibility of bad links being
-  created by same function. Thanks to Frank De prins.
-- Added missing licence text. Thanks to Lars Willemsens.
-- Added <ctype.h> include, at the suggestion of Steve Walters.
-
-Changes in version 2.1.0
-- Yves Berquin brings us the STL switch. The forum on SourceForge, and various emails to
-  me, have long debated all out STL vs. no STL at all. And now you can have it both ways.
-  TinyXml will compile either way.
-
-Changes in version 2.1.1
-- Compilation warnings.
-
-Changes in version 2.1.2
-- Uneeded code is not compiled in the STL case.
-- Changed headers so that STL can be turned on or off in tinyxml.h
-
-Changes in version 2.1.3
-- Fixed non-const reference in API; now uses a pointer.
-- Copy constructor of TiXmlString not checking for assignment to self.
-- Nimrod Cohen found a truly evil bug in the STL implementation that occurs
-  when a string is converted to a c_str and then assigned to self. Search for
-  STL_STRING_BUG for a full description. I'm asserting this is a Microsoft STL
-  bug, since &string and string.c_str() should never be the same. Nevertheless,
-  the code works around it.
-- Urivan Saaib pointed out a compiler conflict, where the C headers define
-  the isblank macro, which was wiping out the TiXmlString::isblank() method.
-  The method was unused and has been removed.
-
-Changes in version 2.1.4
-- Reworked the entity code. Entities were not correctly surving round trip input and output.
-  Will now automatically create entities for high ascii in output.
-
-Changes in version 2.1.5
-- Bug fix by kylotan : infinite loop on some input (tinyxmlparser.cpp rev 1.27)
-- Contributed by Ivica Aracic (bytelord) : 1 new VC++ project to compile versions as static libraries (tinyxml_lib.dsp), 
-  and an example usage in xmltest.dsp
-  (Patch request ID 678605)
-- A suggestion by Ronald Fenner Jr (dormlock) to add #include <istream> and <ostream> for Apple's Project Builder 
-  (Patch request ID 697642)
-- A patch from ohommes that allows to parse correctly dots in element names and attribute names
-  (Patch request 602600 and kylotan 701728)
-- A patch from  hermitgeek ( James ) and wasteland for improper error reporting
-- Reviewed by Lee, with the following changes:
-	- Got sick of fighting the STL/non-STL thing in the windows build. Broke
-	  them out as seperate projects.
-	- I have too long not included the dsw. Added.
-	- TinyXmlText had a protected Print. Odd.
-	- Made LinkEndChild public, with docs and appropriate warnings.
-	- Updated the docs.
-
-2.2.0
-- Fixed an uninitialized pointer in the TiXmlAttributes
-- Fixed STL compilation problem in MinGW (and gcc 3?) - thanks Brian Yoder for finding this one
-- Fixed a syntax error in TiXmlDeclaration - thanks Brian Yoder
-- Fletcher Dunn proposed and submitted new error handling that tracked the row and column. Lee
-  modified it to not have performance impact.
-- General cleanup suggestions from Fletcher Dunn.
-- In error handling, general errors will no longer clear the error state of specific ones.
-- Fix error in documentation : comments starting with "<?--" instead of "<!--" (thanks ion_pulse)
-- Added the TiXmlHandle. An easy, safe way to browse XML DOMs with less code.
-- Added QueryAttribute calls which have better error messaging. (Proposed by Fletcher Dunn)
-- Nodes and attributes can now print themselves to strings. (Yves suggestion)
-- Fixed bug where entities with one character would confuse parser. (Thanks Roman)
-
-2.2.1
-- Additional testing (no more bugs found to be fixed in this release)
-- Significant performance improvement to the cursor code.
-
-2.3.0
-- User Data are now defined in TiXmlBase instead of TiXmlNode
-- Character Entities are now UCS-2
-- Character Entities can be decimal or hexadecimal
-- UTF-8 conversion.
-- Fixed many, many bugs.
-
-2.3.1
-- Fixed bug in handling nulls embedded in the input.
-- Make UTF-8 parser tolerant of bad text encoding.
-- Added encoding detection. 
-- Many fixes and input from John-Philip Leonard Johansson (JP) and Ellers, 
-  including UTF-8 feedback, bug reports, and patches. Thanks!
-- Added version # constants - a suggestion from JP and Ellers.
-- [ 979180 ] Missing ; in entity reference, fix from Rob Laveaux.
-- Copy constructors and assignment have been a long time coming. Thanks to
-  Fokke and JP.
-
-2.3.2
-- Made the IsAlpha and IsAlphaNum much more tolerant of non-UTF-8 encodings. Thanks
-  Volker Boerchers for finding the issue.
-- Ran the program though the magnificent Valgrind - http://valgrind.kde.org - to check
-  for memory errors. Fixed some minor issues.
-
-2.3.3
-- Fixed crash when test program was run from incorrect directory.
-- Fixed bug 1070717 - empty document not returned correctly - thanks Katsuhisa Yuasa.
-- Bug 1079301 resolved - deprecated stdlib calls. Thanks Adrian Boeing.
-- Bug 1035218 fixed - documentation errors. Xunji Luo
-- Other bug fixes have accumulated and been fixed on the way as well; my apologies to
-  authors not credited!
-- Big fix / addition is to correctly return const values. TinyXml could basically
-  remove const in a method like this: TiXmlElement* Foo() const, where the returned element
-  was a pointer to internal data. That is now: const TiXmlElement* Foo() const and
-  TiXmlElement* Foo().
-
-2.3.4
-- Fixed additional const errors, thanks Kent Gibson.
-- Correctly re-enable warnings after tinyxml header. Thanks Cory Nelson.
-- Variety of type cleanup and warning fixes. Thanks Warren Stevens.
-- Cleaned up unneeded constructor calls in TinyString - thanks to Geoff Carlton and
-  the discussion group on sourceforge.
-
-2.4.0
-- Improved string class, thanks Tyge Lovset (whose name gets mangled in English - sorry)
-- Type cast compiler warning, thanks Rob van den Bogaard
-- Added GetText() convenience function. Thanks Ilya Parniuk & Andrew Ellers for input.
-- Many thanks to marlonism for finding an infinite loop in bad xml.
-- A patch to cleanup warnings from Robert Gebis.
-- Added ValueStr() to get the value of a node as a string.
-- TiXmlText can now parse and output as CDATA
-- Additional string improvement from James (z2895)
-- Removed extraneous 'const', thanks David Aldrich
-- First pass at switching to the "safe" stdlib functions. Many people have suggested and
-  pushed on this, but Warren Stevens put together the first proposal.
-- TinyXml now will do EOL normalization before parsing, consistent with the W3C XML spec.
-- Documents loaded with the UTF-8 BOM will now save with the UTF-8 BOM. Good suggestion 
-  from 'instructor_'
-- Ellers submitted his very popular tutorials, which have been added to the distribution.
-
-2.4.1
-- Fixed CDATA output formatting
-- Fixed memory allocators in TinyString to work with overloaded new/delete
-
-2.4.2
-- solosnake pointed out that TIXML_LOG causes problems on an XBOX. The definition in the header
-  was superflous and was moved inside of DEBUG_PARSING
-
-2.4.3
-- Fixed a test bug that caused a crash in 'xmltest'. TinyXML was fine, but it isn't good
-  to ship with a broken test suite.
-- Started converting some functions to not cast between std::string and const char* 
-  quite as often.
-- Added FILE* versions of the document loads - good suggestion from Wade Brainerd
-- Empty documents might not always return the errors they should. [1398915] Thanks to igor v.
-- Added some asserts for multiply adding a node, regardng bug [1391937] suggested by Paco Arjonilla.
-
-2.4.4
-- Bug find thanks to andre-gross found a memory leak that occured when a document failed to load.
-- Bug find (and good analysis) by VirtualJim who found a case where attribute parsing 
-  should be throwing an error and wasn't.
-- Steve Hyatt suggested the QueryValueAttribute method, which is now implemented.
-- DavidA identified a chunk of dead code.
-- Andrew Baxter sent in some compiler warnings that were good clean up points.
-
-2.5
-- Added the Visit() API. Many thanks to both Andrew Ellerton and John-Philip for all their
-  work, code, suggestion, and just general pushing that it should be done.
-- Removed existing streaming code and use TiXmlPrinter instead.
-- [ tinyxml-Bugs-1527079 ] Compile error in tinystr.cpp fixed, thanks to Paul Suggs
-- [ tinyxml-Bugs-1522890 ] SaveFile has no error checks fixed, thanks to Ivan Dobrokotov
-- Ivan Dobrokotov also reported redundant memory allocation in the Attribute() method, which
-  upon investigation was a mess. The attribute should now be fixed for both const char* and 
-  std::string, and the return types match the input parameters.
-- Feature [ 1511105 ] Make TiXmlComment constructor accept a string / char*, implemented.
-  Thanks to Karl Itschen for the feedback.
-- [ 1480108 ] Stream parsing fails when CDATA contains tags was found by Tobias Grimm, who also
-  submitted a test case and patch. A significant bug in CDATA streaming (operator>>) has now
-  been fixed.
-

+ 0 - 19
tinyxml/module.am

@@ -1,19 +0,0 @@
-## Process this file with automake to generate Makefile.in
-lib_LTLIBRARIES += libtinyxml.la
-
-nobase_include_HEADERS += \
-	tinyxml/tinystr.h \
-	tinyxml/tinyxml.h
-
-EXTRA_DIST += \
-	tinyxml/changes.txt \
-	tinyxml/readme.txt \
-	tinyxml/README
-
-libtinyxml_la_SOURCES = \
-	tinyxml/tinyxml.cpp \
-	tinyxml/tinyxmlerror.cpp \
-	tinyxml/tinyxmlparser.cpp \
-	tinyxml/tinystr.cpp
-
-libtinyxml_la_CXXFLAGS = @TINYXML_CXXFLAGS@

+ 0 - 530
tinyxml/readme.txt

@@ -1,530 +0,0 @@
-/** @mainpage
-
-<h1> TinyXML </h1>
-
-TinyXML is a simple, small, C++ XML parser that can be easily 
-integrated into other programs.
-
-<h2> What it does. </h2>
-	
-In brief, TinyXML parses an XML document, and builds from that a 
-Document Object Model (DOM) that can be read, modified, and saved.
-
-XML stands for "eXtensible Markup Language." It allows you to create 
-your own document markups. Where HTML does a very good job of marking 
-documents for browsers, XML allows you to define any kind of document 
-markup, for example a document that describes a "to do" list for an 
-organizer application. XML is a very structured and convenient format.
-All those random file formats created to store application data can 
-all be replaced with XML. One parser for everything.
-
-The best place for the complete, correct, and quite frankly hard to
-read spec is at <a href="http://www.w3.org/TR/2004/REC-xml-20040204/">
-http://www.w3.org/TR/2004/REC-xml-20040204/</a>. An intro to XML
-(that I really like) can be found at 
-<a href="http://skew.org/xml/tutorial/">http://skew.org/xml/tutorial</a>.
-
-There are different ways to access and interact with XML data.
-TinyXML uses a Document Object Model (DOM), meaning the XML data is parsed
-into a C++ objects that can be browsed and manipulated, and then 
-written to disk or another output stream. You can also construct an XML document 
-from scratch with C++ objects and write this to disk or another output
-stream.
-
-TinyXML is designed to be easy and fast to learn. It is two headers 
-and four cpp files. Simply add these to your project and off you go. 
-There is an example file - xmltest.cpp - to get you started. 
-
-TinyXML is released under the ZLib license, 
-so you can use it in open source or commercial code. The details
-of the license are at the top of every source file.
-
-TinyXML attempts to be a flexible parser, but with truly correct and
-compliant XML output. TinyXML should compile on any reasonably C++
-compliant system. It does not rely on exceptions or RTTI. It can be 
-compiled with or without STL support. TinyXML fully supports
-the UTF-8 encoding, and the first 64k character entities.
-
-
-<h2> What it doesn't do. </h2>
-
-TinyXML doesn't parse or use DTDs (Document Type Definitions) or XSLs
-(eXtensible Stylesheet Language.) There are other parsers out there 
-(check out www.sourceforge.org, search for XML) that are much more fully
-featured. But they are also much bigger, take longer to set up in
-your project, have a higher learning curve, and often have a more
-restrictive license. If you are working with browsers or have more
-complete XML needs, TinyXML is not the parser for you.
-
-The following DTD syntax will not parse at this time in TinyXML:
-
-@verbatim
-	<!DOCTYPE Archiv [
-	 <!ELEMENT Comment (#PCDATA)>
-	]>
-@endverbatim
-
-because TinyXML sees this as a !DOCTYPE node with an illegally 
-embedded !ELEMENT node. This may be addressed in the future.
-
-<h2> Tutorials. </h2>
-
-For the impatient, here is a tutorial to get you going. A great way to get started, 
-but it is worth your time to read this (very short) manual completely.
-
-- @subpage tutorial0
-
-<h2> Code Status.  </h2>
-
-TinyXML is mature, tested code. It is very stable. If you find
-bugs, please file a bug report on the sourceforge web site
-(www.sourceforge.net/projects/tinyxml). We'll get them straightened 
-out as soon as possible.
-
-There are some areas of improvement; please check sourceforge if you are
-interested in working on TinyXML.
-
-<h2> Related Projects </h2>
-
-TinyXML projects you may find useful! (Descriptions provided by the projects.)
-
-<ul>
-<li> <b>TinyXPath</b> (http://tinyxpath.sourceforge.net). TinyXPath is a small footprint 
-     XPath syntax decoder, written in C++.</li>
-<li> <b>TinyXML++</b> (http://code.google.com/p/ticpp/). TinyXML++ is a completely new 
-     interface to TinyXML that uses MANY of the C++ strengths. Templates, 
-	 exceptions, and much better error handling.</li>
-</ul>
-
-<h2> Features </h2>
-
-<h3> Using STL </h3>
-
-TinyXML can be compiled to use or not use STL. When using STL, TinyXML
-uses the std::string class, and fully supports std::istream, std::ostream,
-operator<<, and operator>>. Many API methods have both 'const char*' and
-'const std::string&' forms.
-
-When STL support is compiled out, no STL files are included whatsoever. All
-the string classes are implemented by TinyXML itself. API methods
-all use the 'const char*' form for input.
-
-Use the compile time #define:
-
-	TIXML_USE_STL
-
-to compile one version or the other. This can be passed by the compiler,
-or set as the first line of "tinyxml.h".
-
-Note: If compiling the test code in Linux, setting the environment
-variable TINYXML_USE_STL=YES/NO will control STL compilation. In the
-Windows project file, STL and non STL targets are provided. In your project,
-It's probably easiest to add the line "#define TIXML_USE_STL" as the first
-line of tinyxml.h.
-
-<h3> UTF-8 </h3>
-
-TinyXML supports UTF-8 allowing to manipulate XML files in any language. TinyXML
-also supports "legacy mode" - the encoding used before UTF-8 support and
-probably best described as "extended ascii".
-
-Normally, TinyXML will try to detect the correct encoding and use it. However,
-by setting the value of TIXML_DEFAULT_ENCODING in the header file, TinyXML
-can be forced to always use one encoding.
-
-TinyXML will assume Legacy Mode until one of the following occurs:
-<ol>
-	<li> If the non-standard but common "UTF-8 lead bytes" (0xef 0xbb 0xbf)
-		 begin the file or data stream, TinyXML will read it as UTF-8. </li>
-	<li> If the declaration tag is read, and it has an encoding="UTF-8", then
-		 TinyXML will read it as UTF-8. </li>
-	<li> If the declaration tag is read, and it has no encoding specified, then TinyXML will 
-		 read it as UTF-8. </li>
-	<li> If the declaration tag is read, and it has an encoding="something else", then TinyXML 
-		 will read it as Legacy Mode. In legacy mode, TinyXML will work as it did before. It's 
-		 not clear what that mode does exactly, but old content should keep working.</li>
-	<li> Until one of the above criteria is met, TinyXML runs in Legacy Mode.</li>
-</ol>
-
-What happens if the encoding is incorrectly set or detected? TinyXML will try
-to read and pass through text seen as improperly encoded. You may get some strange results or 
-mangled characters. You may want to force TinyXML to the correct mode.
-
-You may force TinyXML to Legacy Mode by using LoadFile( TIXML_ENCODING_LEGACY ) or
-LoadFile( filename, TIXML_ENCODING_LEGACY ). You may force it to use legacy mode all
-the time by setting TIXML_DEFAULT_ENCODING = TIXML_ENCODING_LEGACY. Likewise, you may 
-force it to TIXML_ENCODING_UTF8 with the same technique.
-
-For English users, using English XML, UTF-8 is the same as low-ASCII. You
-don't need to be aware of UTF-8 or change your code in any way. You can think
-of UTF-8 as a "superset" of ASCII.
-
-UTF-8 is not a double byte format - but it is a standard encoding of Unicode!
-TinyXML does not use or directly support wchar, TCHAR, or Microsoft's _UNICODE at this time. 
-It is common to see the term "Unicode" improperly refer to UTF-16, a wide byte encoding
-of unicode. This is a source of confusion.
-
-For "high-ascii" languages - everything not English, pretty much - TinyXML can
-handle all languages, at the same time, as long as the XML is encoded
-in UTF-8. That can be a little tricky, older programs and operating systems
-tend to use the "default" or "traditional" code page. Many apps (and almost all
-modern ones) can output UTF-8, but older or stubborn (or just broken) ones
-still output text in the default code page. 
-
-For example, Japanese systems traditionally use SHIFT-JIS encoding. 
-Text encoded as SHIFT-JIS can not be read by TinyXML. 
-A good text editor can import SHIFT-JIS and then save as UTF-8.
-
-The <a href="http://skew.org/xml/tutorial/">Skew.org link</a> does a great
-job covering the encoding issue.
-
-The test file "utf8test.xml" is an XML containing English, Spanish, Russian,
-and Simplified Chinese. (Hopefully they are translated correctly). The file
-"utf8test.gif" is a screen capture of the XML file, rendered in IE. Note that
-if you don't have the correct fonts (Simplified Chinese or Russian) on your
-system, you won't see output that matches the GIF file even if you can parse
-it correctly. Also note that (at least on my Windows machine) console output
-is in a Western code page, so that Print() or printf() cannot correctly display
-the file. This is not a bug in TinyXML - just an OS issue. No data is lost or 
-destroyed by TinyXML. The console just doesn't render UTF-8.
-
-
-<h3> Entities </h3>
-TinyXML recognizes the pre-defined "character entities", meaning special
-characters. Namely:
-
-@verbatim
-	&amp;	&
-	&lt;	<
-	&gt;	>
-	&quot;	"
-	&apos;	'
-@endverbatim
-
-These are recognized when the XML document is read, and translated to there
-UTF-8 equivalents. For instance, text with the XML of:
-
-@verbatim
-	Far &amp; Away
-@endverbatim
-
-will have the Value() of "Far & Away" when queried from the TiXmlText object,
-and will be written back to the XML stream/file as an ampersand. Older versions
-of TinyXML "preserved" character entities, but the newer versions will translate
-them into characters.
-
-Additionally, any character can be specified by its Unicode code point:
-The syntax "&#xA0;" or "&#160;" are both to the non-breaking space characher.
-
-<h3> Printing </h3>
-TinyXML can print output in several different ways that all have strengths and limitations.
-
-- Print( FILE* ). Output to a std-C stream, which includes all C files as well as stdout.
-	- "Pretty prints", but you don't have control over printing options.
-	- The output is streamed directly to the FILE object, so there is no memory overhead
-	  in the TinyXML code.
-	- used by Print() and SaveFile()
-
-- operator<<. Output to a c++ stream.
-	- Integrates with standart C++ iostreams.
-	- Outputs in "network printing" mode without line breaks. Good for network transmission
-	  and moving XML between C++ objects, but hard for a human to read.
-
-- TiXmlPrinter. Output to a std::string or memory buffer.
-	- API is less concise
-	- Future printing options will be put here.
-	- Printing may change slightly in future versions as it is refined and expanded.
-
-<h3> Streams </h3>
-With TIXML_USE_STL on TinyXML supports C++ streams (operator <<,>>) streams as well
-as C (FILE*) streams. There are some differences that you may need to be aware of.
-
-C style output:
-	- based on FILE*
-	- the Print() and SaveFile() methods
-
-	Generates formatted output, with plenty of white space, intended to be as 
-	human-readable as possible. They are very fast, and tolerant of ill formed 
-	XML documents. For example, an XML document that contains 2 root elements 
-	and 2 declarations, will still print.
-
-C style input:
-	- based on FILE*
-	- the Parse() and LoadFile() methods
-
-	A fast, tolerant read. Use whenever you don't need the C++ streams.
-
-C++ style output:
-	- based on std::ostream
-	- operator<<
-
-	Generates condensed output, intended for network transmission rather than
-	readability. Depending on your system's implementation of the ostream class,
-	these may be somewhat slower. (Or may not.) Not tolerant of ill formed XML:
-	a document should contain the correct one root element. Additional root level
-	elements will not be streamed out.
-
-C++ style input:
-	- based on std::istream
-	- operator>>
-
-	Reads XML from a stream, making it useful for network transmission. The tricky
-	part is knowing when the XML document is complete, since there will almost
-	certainly be other data in the stream. TinyXML will assume the XML data is
-	complete after it reads the root element. Put another way, documents that
-	are ill-constructed with more than one root element will not read correctly.
-	Also note that operator>> is somewhat slower than Parse, due to both 
-	implementation of the STL and limitations of TinyXML.
-
-<h3> White space </h3>
-The world simply does not agree on whether white space should be kept, or condensed.
-For example, pretend the '_' is a space, and look at "Hello____world". HTML, and 
-at least some XML parsers, will interpret this as "Hello_world". They condense white
-space. Some XML parsers do not, and will leave it as "Hello____world". (Remember
-to keep pretending the _ is a space.) Others suggest that __Hello___world__ should become
-Hello___world.
-
-It's an issue that hasn't been resolved to my satisfaction. TinyXML supports the
-first 2 approaches. Call TiXmlBase::SetCondenseWhiteSpace( bool ) to set the desired behavior.
-The default is to condense white space.
-
-If you change the default, you should call TiXmlBase::SetCondenseWhiteSpace( bool )
-before making any calls to Parse XML data, and I don't recommend changing it after
-it has been set.
-
-
-<h3> Handles </h3>
-
-Where browsing an XML document in a robust way, it is important to check
-for null returns from method calls. An error safe implementation can
-generate a lot of code like:
-
-@verbatim
-TiXmlElement* root = document.FirstChildElement( "Document" );
-if ( root )
-{
-	TiXmlElement* element = root->FirstChildElement( "Element" );
-	if ( element )
-	{
-		TiXmlElement* child = element->FirstChildElement( "Child" );
-		if ( child )
-		{
-			TiXmlElement* child2 = child->NextSiblingElement( "Child" );
-			if ( child2 )
-			{
-				// Finally do something useful.
-@endverbatim
-
-Handles have been introduced to clean this up. Using the TiXmlHandle class,
-the previous code reduces to:
-
-@verbatim
-TiXmlHandle docHandle( &document );
-TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
-if ( child2 )
-{
-	// do something useful
-@endverbatim
-
-Which is much easier to deal with. See TiXmlHandle for more information.
-
-
-<h3> Row and Column tracking </h3>
-Being able to track nodes and attributes back to their origin location
-in source files can be very important for some applications. Additionally,
-knowing where parsing errors occured in the original source can be very
-time saving.
-
-TinyXML can tracks the row and column origin of all nodes and attributes
-in a text file. The TiXmlBase::Row() and TiXmlBase::Column() methods return
-the origin of the node in the source text. The correct tabs can be 
-configured in TiXmlDocument::SetTabSize().
-
-
-<h2> Using and Installing </h2>
-
-To Compile and Run xmltest:
-
-A Linux Makefile and a Windows Visual C++ .dsw file is provided. 
-Simply compile and run. It will write the file demotest.xml to your 
-disk and generate output on the screen. It also tests walking the
-DOM by printing out the number of nodes found using different 
-techniques.
-
-The Linux makefile is very generic and runs on many systems - it 
-is currently tested on mingw and
-MacOSX. You do not need to run 'make depend'. The dependecies have been
-hard coded.
-
-<h3>Windows project file for VC6</h3>
-<ul>
-<li>tinyxml:		tinyxml library, non-STL </li>
-<li>tinyxmlSTL:		tinyxml library, STL </li>
-<li>tinyXmlTest:	test app, non-STL </li>
-<li>tinyXmlTestSTL: test app, STL </li>
-</ul>
-
-<h3>Makefile</h3>
-At the top of the makefile you can set:
-
-PROFILE, DEBUG, and TINYXML_USE_STL. Details (such that they are) are in
-the makefile.
-
-In the tinyxml directory, type "make clean" then "make". The executable
-file 'xmltest' will be created.
-
-
-
-<h3>To Use in an Application:</h3>
-
-Add tinyxml.cpp, tinyxml.h, tinyxmlerror.cpp, tinyxmlparser.cpp, tinystr.cpp, and tinystr.h to your
-project or make file. That's it! It should compile on any reasonably
-compliant C++ system. You do not need to enable exceptions or
-RTTI for TinyXML.
-
-
-<h2> How TinyXML works.  </h2>
-
-An example is probably the best way to go. Take:
-@verbatim
-	<?xml version="1.0" standalone=no>
-	<!-- Our to do list data -->
-	<ToDo>
-		<Item priority="1"> Go to the <bold>Toy store!</bold></Item>
-		<Item priority="2"> Do bills</Item>
-	</ToDo>
-@endverbatim
-
-Its not much of a To Do list, but it will do. To read this file 
-(say "demo.xml") you would create a document, and parse it in:
-@verbatim
-	TiXmlDocument doc( "demo.xml" );
-	doc.LoadFile();
-@endverbatim
-
-And its ready to go. Now lets look at some lines and how they 
-relate to the DOM.
-
-@verbatim
-<?xml version="1.0" standalone=no>
-@endverbatim
-
-	The first line is a declaration, and gets turned into the
-	TiXmlDeclaration class. It will be the first child of the
-	document node.
-	
-	This is the only directive/special tag parsed by by TinyXML.
-	Generally directive tags are stored in TiXmlUnknown so the 
-	commands wont be lost when it is saved back to disk.
-
-@verbatim
-<!-- Our to do list data -->
-@endverbatim
-
-	A comment. Will become a TiXmlComment object.
-
-@verbatim
-<ToDo>
-@endverbatim
-
-	The "ToDo" tag defines a TiXmlElement object. This one does not have 
-	any attributes, but does contain 2 other elements.
-
-@verbatim
-<Item priority="1"> 
-@endverbatim
-
-	Creates another TiXmlElement which is a child of the "ToDo" element. 
-	This element has 1 attribute, with the name "priority" and the value 
-	"1".
-
-@verbatim
-Go to the
-@endverbatim 
-
-	A TiXmlText. This is a leaf node and cannot contain other nodes. 
-	It is a child of the "Item" TiXmlElement.
-
-@verbatim
-<bold>
-@endverbatim
-
-	
-	Another TiXmlElement, this one a child of the "Item" element.
-
-Etc.
-
-Looking at the entire object tree, you end up with:
-@verbatim
-TiXmlDocument					"demo.xml"
-	TiXmlDeclaration			"version='1.0'" "standalone=no"
-	TiXmlComment				" Our to do list data"
-	TiXmlElement				"ToDo"
-		TiXmlElement			"Item" Attribtutes: priority = 1
-			TiXmlText			"Go to the "
-			TiXmlElement		"bold"
-				TiXmlText		"Toy store!"
-		TiXmlElement			"Item" Attributes: priority=2
-			TiXmlText			"Do bills"
-@endverbatim
-
-<h2> Documentation </h2>
-
-The documentation is build with Doxygen, using the 'dox' 
-configuration file.
-
-<h2> License </h2>
-
-TinyXML is released under the zlib license:
-
-This software is provided 'as-is', without any express or implied 
-warranty. In no event will the authors be held liable for any 
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any 
-purpose, including commercial applications, and to alter it and 
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must 
-not claim that you wrote the original software. If you use this 
-software in a product, an acknowledgment in the product documentation 
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and 
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source 
-distribution.
-
-<h2> References  </h2>
-
-The World Wide Web Consortium is the definitive standard body for 
-XML, and there web pages contain huge amounts of information. 
-
-The definitive spec: <a href="http://www.w3.org/TR/2004/REC-xml-20040204/">
-http://www.w3.org/TR/2004/REC-xml-20040204/</a>
-
-I also recommend "XML Pocket Reference" by Robert Eckstein and published by 
-OReilly...the book that got the whole thing started.
-
-<h2> Contributors, Contacts, and a Brief History </h2>
-
-Thanks very much to everyone who sends suggestions, bugs, ideas, and 
-encouragement. It all helps, and makes this project fun. A special thanks
-to the contributors on the web pages that keep it lively.
-
-So many people have sent in bugs and ideas, that rather than list here 
-we try to give credit due in the "changes.txt" file.
-
-TinyXML was originally written by Lee Thomason. (Often the "I" still
-in the documentation.) Lee reviews changes and releases new versions,
-with the help of Yves Berquin, Andrew Ellerton, and the tinyXml community.
-
-We appreciate your suggestions, and would love to know if you 
-use TinyXML. Hopefully you will enjoy it and find it useful. 
-Please post questions, comments, file bugs, or contact us at:
-
-www.sourceforge.net/projects/tinyxml
-
-Lee Thomason, Yves Berquin, Andrew Ellerton
-*/

+ 0 - 116
tinyxml/tinystr.cpp

@@ -1,116 +0,0 @@
-/*
-www.sourceforge.net/projects/tinyxml
-Original file by Yves Berquin.
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any
-purpose, including commercial applications, and to alter it and
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must
-not claim that you wrote the original software. If you use this
-software in a product, an acknowledgment in the product documentation
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-*/
-
-/*
- * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
- */
-
-
-#ifndef TIXML_USE_STL
-
-#include "tinystr.h"
-
-// Error value for find primitive
-const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
-
-
-// Null rep.
-TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, {'\0'} };
-
-
-void TiXmlString::reserve (size_type cap)
-{
-	if (cap > capacity())
-	{
-		TiXmlString tmp;
-		tmp.init(length(), cap);
-		memcpy(tmp.start(), data(), length());
-		swap(tmp);
-	}
-}
-
-
-TiXmlString& TiXmlString::assign(const char* str, size_type len)
-{
-	size_type cap = capacity();
-	if (len > cap || cap > 3*(len + 8))
-	{
-		TiXmlString tmp;
-		tmp.init(len);
-		memcpy(tmp.start(), str, len);
-		swap(tmp);
-	}
-	else
-	{
-		memmove(start(), str, len);
-		set_size(len);
-	}
-	return *this;
-}
-
-
-TiXmlString& TiXmlString::append(const char* str, size_type len)
-{
-	size_type newsize = length() + len;
-	if (newsize > capacity())
-	{
-		reserve (newsize + capacity());
-	}
-	memmove(finish(), str, len);
-	set_size(newsize);
-	return *this;
-}
-
-
-TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
-{
-	TiXmlString tmp;
-	tmp.reserve(a.length() + b.length());
-	tmp += a;
-	tmp += b;
-	return tmp;
-}
-
-TiXmlString operator + (const TiXmlString & a, const char* b)
-{
-	TiXmlString tmp;
-	TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
-	tmp.reserve(a.length() + b_len);
-	tmp += a;
-	tmp.append(b, b_len);
-	return tmp;
-}
-
-TiXmlString operator + (const char* a, const TiXmlString & b)
-{
-	TiXmlString tmp;
-	TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
-	tmp.reserve(a_len + b.length());
-	tmp.append(a, a_len);
-	tmp += b;
-	return tmp;
-}
-
-
-#endif	// TIXML_USE_STL

+ 0 - 319
tinyxml/tinystr.h

@@ -1,319 +0,0 @@
-/*
-www.sourceforge.net/projects/tinyxml
-Original file by Yves Berquin.
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any
-purpose, including commercial applications, and to alter it and
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must
-not claim that you wrote the original software. If you use this
-software in a product, an acknowledgment in the product documentation
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-*/
-
-/*
- * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
- *
- * - completely rewritten. compact, clean, and fast implementation.
- * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
- * - fixed reserve() to work as per specification.
- * - fixed buggy compares operator==(), operator<(), and operator>()
- * - fixed operator+=() to take a const ref argument, following spec.
- * - added "copy" constructor with length, and most compare operators.
- * - added swap(), clear(), size(), capacity(), operator+().
- */
-
-#ifndef TIXML_USE_STL
-
-#ifndef TIXML_STRING_INCLUDED
-#define TIXML_STRING_INCLUDED
-
-#include <assert.h>
-#include <string.h>
-
-/*	The support for explicit isn't that universal, and it isn't really
-	required - it is used to check that the TiXmlString class isn't incorrectly
-	used. Be nice to old compilers and macro it here:
-*/
-#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
-	// Microsoft visual studio, version 6 and higher.
-	#define TIXML_EXPLICIT explicit
-#elif defined(__GNUC__) && (__GNUC__ >= 3 )
-	// GCC version 3 and higher.s
-	#define TIXML_EXPLICIT explicit
-#else
-	#define TIXML_EXPLICIT
-#endif
-
-
-/*
-   TiXmlString is an emulation of a subset of the std::string template.
-   Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
-   Only the member functions relevant to the TinyXML project have been implemented.
-   The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
-   a string and there's no more room, we allocate a buffer twice as big as we need.
-*/
-class TiXmlString
-{
-  public :
-	// The size type used
-  	typedef size_t size_type;
-
-	// Error value for find primitive
-	static const size_type npos; // = -1;
-
-
-	// TiXmlString empty constructor
-	TiXmlString () : rep_(&nullrep_)
-	{
-	}
-
-	// TiXmlString copy constructor
-	TiXmlString ( const TiXmlString & copy) : rep_(0)
-	{
-		init(copy.length());
-		memcpy(start(), copy.data(), length());
-	}
-
-	// TiXmlString constructor, based on a string
-	TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
-	{
-		init( static_cast<size_type>( strlen(copy) ));
-		memcpy(start(), copy, length());
-	}
-
-	// TiXmlString constructor, based on a string
-	TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
-	{
-		init(len);
-		memcpy(start(), str, len);
-	}
-
-	// TiXmlString destructor
-	~TiXmlString ()
-	{
-		quit();
-	}
-
-	// = operator
-	TiXmlString& operator = (const char * copy)
-	{
-		return assign( copy, (size_type)strlen(copy));
-	}
-
-	// = operator
-	TiXmlString& operator = (const TiXmlString & copy)
-	{
-		return assign(copy.start(), copy.length());
-	}
-
-
-	// += operator. Maps to append
-	TiXmlString& operator += (const char * suffix)
-	{
-		return append(suffix, static_cast<size_type>( strlen(suffix) ));
-	}
-
-	// += operator. Maps to append
-	TiXmlString& operator += (char single)
-	{
-		return append(&single, 1);
-	}
-
-	// += operator. Maps to append
-	TiXmlString& operator += (const TiXmlString & suffix)
-	{
-		return append(suffix.data(), suffix.length());
-	}
-
-
-	// Convert a TiXmlString into a null-terminated char *
-	const char * c_str () const { return rep_->str; }
-
-	// Convert a TiXmlString into a char * (need not be null terminated).
-	const char * data () const { return rep_->str; }
-
-	// Return the length of a TiXmlString
-	size_type length () const { return rep_->size; }
-
-	// Alias for length()
-	size_type size () const { return rep_->size; }
-
-	// Checks if a TiXmlString is empty
-	bool empty () const { return rep_->size == 0; }
-
-	// Return capacity of string
-	size_type capacity () const { return rep_->capacity; }
-
-
-	// single char extraction
-	const char& at (size_type index) const
-	{
-		assert( index < length() );
-		return rep_->str[ index ];
-	}
-
-	// [] operator
-	char& operator [] (size_type index) const
-	{
-		assert( index < length() );
-		return rep_->str[ index ];
-	}
-
-	// find a char in a string. Return TiXmlString::npos if not found
-	size_type find (char lookup) const
-	{
-		return find(lookup, 0);
-	}
-
-	// find a char in a string from an offset. Return TiXmlString::npos if not found
-	size_type find (char tofind, size_type offset) const
-	{
-		if (offset >= length()) return npos;
-
-		for (const char* p = c_str() + offset; *p != '\0'; ++p)
-		{
-		   if (*p == tofind) return static_cast< size_type >( p - c_str() );
-		}
-		return npos;
-	}
-
-	void clear ()
-	{
-		//Lee:
-		//The original was just too strange, though correct:
-		//	TiXmlString().swap(*this);
-		//Instead use the quit & re-init:
-		quit();
-		init(0,0);
-	}
-
-	/*	Function to reserve a big amount of data when we know we'll need it. Be aware that this
-		function DOES NOT clear the content of the TiXmlString if any exists.
-	*/
-	void reserve (size_type cap);
-
-	TiXmlString& assign (const char* str, size_type len);
-
-	TiXmlString& append (const char* str, size_type len);
-
-	void swap (TiXmlString& other)
-	{
-		Rep* r = rep_;
-		rep_ = other.rep_;
-		other.rep_ = r;
-	}
-
-  private:
-
-	void init(size_type sz) { init(sz, sz); }
-	void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
-	char* start() const { return rep_->str; }
-	char* finish() const { return rep_->str + rep_->size; }
-
-	struct Rep
-	{
-		size_type size, capacity;
-		char str[1];
-	};
-
-	void init(size_type sz, size_type cap)
-	{
-		if (cap)
-		{
-			// Lee: the original form:
-			//	rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
-			// doesn't work in some cases of new being overloaded. Switching
-			// to the normal allocation, although use an 'int' for systems
-			// that are overly picky about structure alignment.
-			const size_type bytesNeeded = sizeof(Rep) + cap;
-			const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); 
-			rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
-
-			rep_->str[ rep_->size = sz ] = '\0';
-			rep_->capacity = cap;
-		}
-		else
-		{
-			rep_ = &nullrep_;
-		}
-	}
-
-	void quit()
-	{
-		if (rep_ != &nullrep_)
-		{
-			// The rep_ is really an array of ints. (see the allocator, above).
-			// Cast it back before delete, so the compiler won't incorrectly call destructors.
-			delete [] ( reinterpret_cast<int*>( rep_ ) );
-		}
-	}
-
-	Rep * rep_;
-	static Rep nullrep_;
-
-} ;
-
-
-inline bool operator == (const TiXmlString & a, const TiXmlString & b)
-{
-	return    ( a.length() == b.length() )				// optimization on some platforms
-	       && ( strcmp(a.c_str(), b.c_str()) == 0 );	// actual compare
-}
-inline bool operator < (const TiXmlString & a, const TiXmlString & b)
-{
-	return strcmp(a.c_str(), b.c_str()) < 0;
-}
-
-inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
-inline bool operator >  (const TiXmlString & a, const TiXmlString & b) { return b < a; }
-inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
-inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
-
-inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
-inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
-inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
-inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
-
-TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
-TiXmlString operator + (const TiXmlString & a, const char* b);
-TiXmlString operator + (const char* a, const TiXmlString & b);
-
-
-/*
-   TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
-   Only the operators that we need for TinyXML have been developped.
-*/
-class TiXmlOutStream : public TiXmlString
-{
-public :
-
-	// TiXmlOutStream << operator.
-	TiXmlOutStream & operator << (const TiXmlString & in)
-	{
-		*this += in;
-		return *this;
-	}
-
-	// TiXmlOutStream << operator.
-	TiXmlOutStream & operator << (const char * in)
-	{
-		*this += in;
-		return *this;
-	}
-
-} ;
-
-#endif	// TIXML_STRING_INCLUDED
-#endif	// TIXML_USE_STL

+ 0 - 1866
tinyxml/tinyxml.cpp

@@ -1,1866 +0,0 @@
-/*
-www.sourceforge.net/projects/tinyxml
-Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any
-purpose, including commercial applications, and to alter it and
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must
-not claim that you wrote the original software. If you use this
-software in a product, an acknowledgment in the product documentation
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-*/
-
-#include <ctype.h>
-
-#ifdef TIXML_USE_STL
-#include <sstream>
-#include <iostream>
-#endif
-
-#include "tinyxml.h"
-
-
-bool TiXmlBase::condenseWhiteSpace = true;
-
-void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
-{
-	int i=0;
-
-	while( i<(int)str.length() )
-	{
-		unsigned char c = (unsigned char) str[i];
-
-		if (    c == '&' 
-		     && i < ( (int)str.length() - 2 )
-			 && str[i+1] == '#'
-			 && str[i+2] == 'x' )
-		{
-			// Hexadecimal character reference.
-			// Pass through unchanged.
-			// &#xA9;	-- copyright symbol, for example.
-			//
-			// The -1 is a bug fix from Rob Laveaux. It keeps
-			// an overflow from happening if there is no ';'.
-			// There are actually 2 ways to exit this loop -
-			// while fails (error case) and break (semicolon found).
-			// However, there is no mechanism (currently) for
-			// this function to return an error.
-			while ( i<(int)str.length()-1 )
-			{
-				outString->append( str.c_str() + i, 1 );
-				++i;
-				if ( str[i] == ';' )
-					break;
-			}
-		}
-		else if ( c == '&' )
-		{
-			outString->append( entity[0].str, entity[0].strLength );
-			++i;
-		}
-		else if ( c == '<' )
-		{
-			outString->append( entity[1].str, entity[1].strLength );
-			++i;
-		}
-		else if ( c == '>' )
-		{
-			outString->append( entity[2].str, entity[2].strLength );
-			++i;
-		}
-		else if ( c == '\"' )
-		{
-			outString->append( entity[3].str, entity[3].strLength );
-			++i;
-		}
-		else if ( c == '\'' )
-		{
-			outString->append( entity[4].str, entity[4].strLength );
-			++i;
-		}
-		else if ( c < 32 )
-		{
-			// Easy pass at non-alpha/numeric/symbol
-			// Below 32 is symbolic.
-			char buf[ 32 ];
-			
-			#if defined(TIXML_SNPRINTF)		
-				TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
-			#else
-				sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
-			#endif		
-
-			//*ME:	warning C4267: convert 'size_t' to 'int'
-			//*ME:	Int-Cast to make compiler happy ...
-			outString->append( buf, (int)strlen( buf ) );
-			++i;
-		}
-		else
-		{
-			//char realc = (char) c;
-			//outString->append( &realc, 1 );
-			*outString += (char) c;	// somewhat more efficient function call.
-			++i;
-		}
-	}
-}
-
-
-TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
-{
-	parent = 0;
-	type = _type;
-	firstChild = 0;
-	lastChild = 0;
-	prev = 0;
-	next = 0;
-}
-
-
-TiXmlNode::~TiXmlNode()
-{
-	TiXmlNode* node = firstChild;
-	TiXmlNode* temp = 0;
-
-	while ( node )
-	{
-		temp = node;
-		node = node->next;
-		delete temp;
-	}	
-}
-
-
-void TiXmlNode::CopyTo( TiXmlNode* target ) const
-{
-	target->SetValue (value.c_str() );
-	target->userData = userData; 
-}
-
-
-void TiXmlNode::Clear()
-{
-	TiXmlNode* node = firstChild;
-	TiXmlNode* temp = 0;
-
-	while ( node )
-	{
-		temp = node;
-		node = node->next;
-		delete temp;
-	}	
-
-	firstChild = 0;
-	lastChild = 0;
-}
-
-
-TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
-{
-	assert( node->parent == 0 || node->parent == this );
-	assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
-
-	if ( node->Type() == TiXmlNode::DOCUMENT )
-	{
-		delete node;
-		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return 0;
-	}
-
-	node->parent = this;
-
-	node->prev = lastChild;
-	node->next = 0;
-
-	if ( lastChild )
-		lastChild->next = node;
-	else
-		firstChild = node;			// it was an empty list.
-
-	lastChild = node;
-	return node;
-}
-
-
-TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
-{
-	if ( addThis.Type() == TiXmlNode::DOCUMENT )
-	{
-		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return 0;
-	}
-	TiXmlNode* node = addThis.Clone();
-	if ( !node )
-		return 0;
-
-	return LinkEndChild( node );
-}
-
-
-TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
-{	
-	if ( !beforeThis || beforeThis->parent != this ) {
-		return 0;
-	}
-	if ( addThis.Type() == TiXmlNode::DOCUMENT )
-	{
-		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return 0;
-	}
-
-	TiXmlNode* node = addThis.Clone();
-	if ( !node )
-		return 0;
-	node->parent = this;
-
-	node->next = beforeThis;
-	node->prev = beforeThis->prev;
-	if ( beforeThis->prev )
-	{
-		beforeThis->prev->next = node;
-	}
-	else
-	{
-		assert( firstChild == beforeThis );
-		firstChild = node;
-	}
-	beforeThis->prev = node;
-	return node;
-}
-
-
-TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
-{
-	if ( !afterThis || afterThis->parent != this ) {
-		return 0;
-	}
-	if ( addThis.Type() == TiXmlNode::DOCUMENT )
-	{
-		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return 0;
-	}
-
-	TiXmlNode* node = addThis.Clone();
-	if ( !node )
-		return 0;
-	node->parent = this;
-
-	node->prev = afterThis;
-	node->next = afterThis->next;
-	if ( afterThis->next )
-	{
-		afterThis->next->prev = node;
-	}
-	else
-	{
-		assert( lastChild == afterThis );
-		lastChild = node;
-	}
-	afterThis->next = node;
-	return node;
-}
-
-
-TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
-{
-	if ( replaceThis->parent != this )
-		return 0;
-
-	TiXmlNode* node = withThis.Clone();
-	if ( !node )
-		return 0;
-
-	node->next = replaceThis->next;
-	node->prev = replaceThis->prev;
-
-	if ( replaceThis->next )
-		replaceThis->next->prev = node;
-	else
-		lastChild = node;
-
-	if ( replaceThis->prev )
-		replaceThis->prev->next = node;
-	else
-		firstChild = node;
-
-	delete replaceThis;
-	node->parent = this;
-	return node;
-}
-
-
-bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
-{
-	if ( removeThis->parent != this )
-	{	
-		assert( 0 );
-		return false;
-	}
-
-	if ( removeThis->next )
-		removeThis->next->prev = removeThis->prev;
-	else
-		lastChild = removeThis->prev;
-
-	if ( removeThis->prev )
-		removeThis->prev->next = removeThis->next;
-	else
-		firstChild = removeThis->next;
-
-	delete removeThis;
-	return true;
-}
-
-const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
-{
-	const TiXmlNode* node;
-	for ( node = firstChild; node; node = node->next )
-	{
-		if ( strcmp( node->Value(), _value ) == 0 )
-			return node;
-	}
-	return 0;
-}
-
-
-const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
-{
-	const TiXmlNode* node;
-	for ( node = lastChild; node; node = node->prev )
-	{
-		if ( strcmp( node->Value(), _value ) == 0 )
-			return node;
-	}
-	return 0;
-}
-
-
-const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
-{
-	if ( !previous )
-	{
-		return FirstChild();
-	}
-	else
-	{
-		assert( previous->parent == this );
-		return previous->NextSibling();
-	}
-}
-
-
-const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
-{
-	if ( !previous )
-	{
-		return FirstChild( val );
-	}
-	else
-	{
-		assert( previous->parent == this );
-		return previous->NextSibling( val );
-	}
-}
-
-
-const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 
-{
-	const TiXmlNode* node;
-	for ( node = next; node; node = node->next )
-	{
-		if ( strcmp( node->Value(), _value ) == 0 )
-			return node;
-	}
-	return 0;
-}
-
-
-const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
-{
-	const TiXmlNode* node;
-	for ( node = prev; node; node = node->prev )
-	{
-		if ( strcmp( node->Value(), _value ) == 0 )
-			return node;
-	}
-	return 0;
-}
-
-
-void TiXmlElement::RemoveAttribute( const char * name )
-{
-    #ifdef TIXML_USE_STL
-	TIXML_STRING str( name );
-	TiXmlAttribute* node = attributeSet.Find( str );
-	#else
-	TiXmlAttribute* node = attributeSet.Find( name );
-	#endif
-	if ( node )
-	{
-		attributeSet.Remove( node );
-		delete node;
-	}
-}
-
-const TiXmlElement* TiXmlNode::FirstChildElement() const
-{
-	const TiXmlNode* node;
-
-	for (	node = FirstChild();
-			node;
-			node = node->NextSibling() )
-	{
-		if ( node->ToElement() )
-			return node->ToElement();
-	}
-	return 0;
-}
-
-
-const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
-{
-	const TiXmlNode* node;
-
-	for (	node = FirstChild( _value );
-			node;
-			node = node->NextSibling( _value ) )
-	{
-		if ( node->ToElement() )
-			return node->ToElement();
-	}
-	return 0;
-}
-
-
-const TiXmlElement* TiXmlNode::NextSiblingElement() const
-{
-	const TiXmlNode* node;
-
-	for (	node = NextSibling();
-			node;
-			node = node->NextSibling() )
-	{
-		if ( node->ToElement() )
-			return node->ToElement();
-	}
-	return 0;
-}
-
-
-const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
-{
-	const TiXmlNode* node;
-
-	for (	node = NextSibling( _value );
-			node;
-			node = node->NextSibling( _value ) )
-	{
-		if ( node->ToElement() )
-			return node->ToElement();
-	}
-	return 0;
-}
-
-
-const TiXmlDocument* TiXmlNode::GetDocument() const
-{
-	const TiXmlNode* node;
-
-	for( node = this; node; node = node->parent )
-	{
-		if ( node->ToDocument() )
-			return node->ToDocument();
-	}
-	return 0;
-}
-
-
-TiXmlElement::TiXmlElement (const char * _value)
-	: TiXmlNode( TiXmlNode::ELEMENT )
-{
-	firstChild = lastChild = 0;
-	value = _value;
-}
-
-
-#ifdef TIXML_USE_STL
-TiXmlElement::TiXmlElement( const std::string& _value ) 
-	: TiXmlNode( TiXmlNode::ELEMENT )
-{
-	firstChild = lastChild = 0;
-	value = _value;
-}
-#endif
-
-
-TiXmlElement::TiXmlElement( const TiXmlElement& copy)
-	: TiXmlNode( TiXmlNode::ELEMENT )
-{
-	firstChild = lastChild = 0;
-	copy.CopyTo( this );	
-}
-
-
-void TiXmlElement::operator=( const TiXmlElement& base )
-{
-	ClearThis();
-	base.CopyTo( this );
-}
-
-
-TiXmlElement::~TiXmlElement()
-{
-	ClearThis();
-}
-
-
-void TiXmlElement::ClearThis()
-{
-	Clear();
-	while( attributeSet.First() )
-	{
-		TiXmlAttribute* node = attributeSet.First();
-		attributeSet.Remove( node );
-		delete node;
-	}
-}
-
-
-const char* TiXmlElement::Attribute( const char* name ) const
-{
-	const TiXmlAttribute* node = attributeSet.Find( name );
-	if ( node )
-		return node->Value();
-	return 0;
-}
-
-
-#ifdef TIXML_USE_STL
-const std::string* TiXmlElement::Attribute( const std::string& name ) const
-{
-	const TiXmlAttribute* node = attributeSet.Find( name );
-	if ( node )
-		return &node->ValueStr();
-	return 0;
-}
-#endif
-
-
-const char* TiXmlElement::Attribute( const char* name, int* i ) const
-{
-	const char* s = Attribute( name );
-	if ( i )
-	{
-		if ( s ) {
-			*i = atoi( s );
-		}
-		else {
-			*i = 0;
-		}
-	}
-	return s;
-}
-
-
-#ifdef TIXML_USE_STL
-const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
-{
-	const std::string* s = Attribute( name );
-	if ( i )
-	{
-		if ( s ) {
-			*i = atoi( s->c_str() );
-		}
-		else {
-			*i = 0;
-		}
-	}
-	return s;
-}
-#endif
-
-
-const char* TiXmlElement::Attribute( const char* name, double* d ) const
-{
-	const char* s = Attribute( name );
-	if ( d )
-	{
-		if ( s ) {
-			*d = atof( s );
-		}
-		else {
-			*d = 0;
-		}
-	}
-	return s;
-}
-
-
-#ifdef TIXML_USE_STL
-const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
-{
-	const std::string* s = Attribute( name );
-	if ( d )
-	{
-		if ( s ) {
-			*d = atof( s->c_str() );
-		}
-		else {
-			*d = 0;
-		}
-	}
-	return s;
-}
-#endif
-
-
-int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
-{
-	const TiXmlAttribute* node = attributeSet.Find( name );
-	if ( !node )
-		return TIXML_NO_ATTRIBUTE;
-	return node->QueryIntValue( ival );
-}
-
-
-#ifdef TIXML_USE_STL
-int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
-{
-	const TiXmlAttribute* node = attributeSet.Find( name );
-	if ( !node )
-		return TIXML_NO_ATTRIBUTE;
-	return node->QueryIntValue( ival );
-}
-#endif
-
-
-int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
-{
-	const TiXmlAttribute* node = attributeSet.Find( name );
-	if ( !node )
-		return TIXML_NO_ATTRIBUTE;
-	return node->QueryDoubleValue( dval );
-}
-
-
-#ifdef TIXML_USE_STL
-int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
-{
-	const TiXmlAttribute* node = attributeSet.Find( name );
-	if ( !node )
-		return TIXML_NO_ATTRIBUTE;
-	return node->QueryDoubleValue( dval );
-}
-#endif
-
-
-void TiXmlElement::SetAttribute( const char * name, int val )
-{	
-	char buf[64];
-	#if defined(TIXML_SNPRINTF)		
-		TIXML_SNPRINTF( buf, sizeof(buf), "%d", val );
-	#else
-		sprintf( buf, "%d", val );
-	#endif
-	SetAttribute( name, buf );
-}
-
-
-#ifdef TIXML_USE_STL
-void TiXmlElement::SetAttribute( const std::string& name, int val )
-{	
-   std::ostringstream oss;
-   oss << val;
-   SetAttribute( name, oss.str() );
-}
-#endif
-
-
-void TiXmlElement::SetDoubleAttribute( const char * name, double val )
-{	
-	char buf[256];
-	#if defined(TIXML_SNPRINTF)		
-		TIXML_SNPRINTF( buf, sizeof(buf), "%f", val );
-	#else
-		sprintf( buf, "%f", val );
-	#endif
-	SetAttribute( name, buf );
-}
-
-
-void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
-{
-    #ifdef TIXML_USE_STL
-	TIXML_STRING _name( cname );
-	TIXML_STRING _value( cvalue );
-	#else
-	const char* _name = cname;
-	const char* _value = cvalue;
-	#endif
-
-	TiXmlAttribute* node = attributeSet.Find( _name );
-	if ( node )
-	{
-		node->SetValue( _value );
-		return;
-	}
-
-	TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue );
-	if ( attrib )
-	{
-		attributeSet.Add( attrib );
-	}
-	else
-	{
-		TiXmlDocument* document = GetDocument();
-		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
-	}
-}
-
-
-#ifdef TIXML_USE_STL
-void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value )
-{
-	TiXmlAttribute* node = attributeSet.Find( name );
-	if ( node )
-	{
-		node->SetValue( _value );
-		return;
-	}
-
-	TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
-	if ( attrib )
-	{
-		attributeSet.Add( attrib );
-	}
-	else
-	{
-		TiXmlDocument* document = GetDocument();
-		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
-	}
-}
-#endif
-
-
-void TiXmlElement::Print( FILE* cfile, int depth ) const
-{
-	int i;
-	assert( cfile );
-	for ( i=0; i<depth; i++ ) {
-		fprintf( cfile, "    " );
-	}
-
-	fprintf( cfile, "<%s", value.c_str() );
-
-	const TiXmlAttribute* attrib;
-	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
-	{
-		fprintf( cfile, " " );
-		attrib->Print( cfile, depth );
-	}
-
-	// There are 3 different formatting approaches:
-	// 1) An element without children is printed as a <foo /> node
-	// 2) An element with only a text child is printed as <foo> text </foo>
-	// 3) An element with children is printed on multiple lines.
-	TiXmlNode* node;
-	if ( !firstChild )
-	{
-		fprintf( cfile, " />" );
-	}
-	else if ( firstChild == lastChild && firstChild->ToText() )
-	{
-		fprintf( cfile, ">" );
-		firstChild->Print( cfile, depth + 1 );
-		fprintf( cfile, "</%s>", value.c_str() );
-	}
-	else
-	{
-		fprintf( cfile, ">" );
-
-		for ( node = firstChild; node; node=node->NextSibling() )
-		{
-			if ( !node->ToText() )
-			{
-				fprintf( cfile, "\n" );
-			}
-			node->Print( cfile, depth+1 );
-		}
-		fprintf( cfile, "\n" );
-		for( i=0; i<depth; ++i ) {
-			fprintf( cfile, "    " );
-		}
-		fprintf( cfile, "</%s>", value.c_str() );
-	}
-}
-
-
-void TiXmlElement::CopyTo( TiXmlElement* target ) const
-{
-	// superclass:
-	TiXmlNode::CopyTo( target );
-
-	// Element class: 
-	// Clone the attributes, then clone the children.
-	const TiXmlAttribute* attribute = 0;
-	for(	attribute = attributeSet.First();
-	attribute;
-	attribute = attribute->Next() )
-	{
-		target->SetAttribute( attribute->Name(), attribute->Value() );
-	}
-
-	TiXmlNode* node = 0;
-	for ( node = firstChild; node; node = node->NextSibling() )
-	{
-		target->LinkEndChild( node->Clone() );
-	}
-}
-
-bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
-{
-	if ( visitor->VisitEnter( *this, attributeSet.First() ) ) 
-	{
-		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
-		{
-			if ( !node->Accept( visitor ) )
-				break;
-		}
-	}
-	return visitor->VisitExit( *this );
-}
-
-
-TiXmlNode* TiXmlElement::Clone() const
-{
-	TiXmlElement* clone = new TiXmlElement( Value() );
-	if ( !clone )
-		return 0;
-
-	CopyTo( clone );
-	return clone;
-}
-
-
-const char* TiXmlElement::GetText() const
-{
-	const TiXmlNode* child = this->FirstChild();
-	if ( child ) {
-		const TiXmlText* childText = child->ToText();
-		if ( childText ) {
-			return childText->Value();
-		}
-	}
-	return 0;
-}
-
-
-TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
-{
-	tabsize = 4;
-	useMicrosoftBOM = false;
-	ClearError();
-}
-
-TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
-{
-	tabsize = 4;
-	useMicrosoftBOM = false;
-	value = documentName;
-	ClearError();
-}
-
-
-#ifdef TIXML_USE_STL
-TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
-{
-	tabsize = 4;
-	useMicrosoftBOM = false;
-    value = documentName;
-	ClearError();
-}
-#endif
-
-
-TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT )
-{
-	copy.CopyTo( this );
-}
-
-
-void TiXmlDocument::operator=( const TiXmlDocument& copy )
-{
-	Clear();
-	copy.CopyTo( this );
-}
-
-
-bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
-{
-	// See STL_STRING_BUG below.
-	//StringToBuffer buf( value );
-
-	return LoadFile( Value(), encoding );
-}
-
-
-bool TiXmlDocument::SaveFile() const
-{
-	// See STL_STRING_BUG below.
-//	StringToBuffer buf( value );
-//
-//	if ( buf.buffer && SaveFile( buf.buffer ) )
-//		return true;
-//
-//	return false;
-	return SaveFile( Value() );
-}
-
-bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
-{
-	// There was a really terrifying little bug here. The code:
-	//		value = filename
-	// in the STL case, cause the assignment method of the std::string to
-	// be called. What is strange, is that the std::string had the same
-	// address as it's c_str() method, and so bad things happen. Looks
-	// like a bug in the Microsoft STL implementation.
-	// Add an extra string to avoid the crash.
-	TIXML_STRING filename( _filename );
-	value = filename;
-
-	// reading in binary mode so that tinyxml can normalize the EOL
-	FILE* file = fopen( value.c_str (), "rb" );	
-
-	if ( file )
-	{
-		bool result = LoadFile( file, encoding );
-		fclose( file );
-		return result;
-	}
-	else
-	{
-		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return false;
-	}
-}
-
-bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
-{
-	if ( !file ) 
-	{
-		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return false;
-	}
-
-	// Delete the existing data:
-	Clear();
-	location.Clear();
-
-	// Get the file size, so we can pre-allocate the string. HUGE speed impact.
-	long length = 0;
-	fseek( file, 0, SEEK_END );
-	length = ftell( file );
-	fseek( file, 0, SEEK_SET );
-
-	// Strange case, but good to handle up front.
-	if ( length == 0 )
-	{
-		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return false;
-	}
-
-	// If we have a file, assume it is all one big XML file, and read it in.
-	// The document parser may decide the document ends sooner than the entire file, however.
-	TIXML_STRING data;
-	data.reserve( length );
-
-	// Subtle bug here. TinyXml did use fgets. But from the XML spec:
-	// 2.11 End-of-Line Handling
-	// <snip>
-	// <quote>
-	// ...the XML processor MUST behave as if it normalized all line breaks in external 
-	// parsed entities (including the document entity) on input, before parsing, by translating 
-	// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
-	// a single #xA character.
-	// </quote>
-	//
-	// It is not clear fgets does that, and certainly isn't clear it works cross platform. 
-	// Generally, you expect fgets to translate from the convention of the OS to the c/unix
-	// convention, and not work generally.
-
-	/*
-	while( fgets( buf, sizeof(buf), file ) )
-	{
-		data += buf;
-	}
-	*/
-
-	char* buf = new char[ length+1 ];
-	buf[0] = 0;
-
-	if ( fread( buf, length, 1, file ) != 1 ) {
-		delete [] buf;
-		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return false;
-	}
-
-	const char* lastPos = buf;
-	const char* p = buf;
-
-	buf[length] = 0;
-	while( *p ) {
-		assert( p < (buf+length) );
-		if ( *p == 0xa ) {
-			// Newline character. No special rules for this. Append all the characters
-			// since the last string, and include the newline.
-			data.append( lastPos, (p-lastPos+1) );	// append, include the newline
-			++p;									// move past the newline
-			lastPos = p;							// and point to the new buffer (may be 0)
-			assert( p <= (buf+length) );
-		}
-		else if ( *p == 0xd ) {
-			// Carriage return. Append what we have so far, then
-			// handle moving forward in the buffer.
-			if ( (p-lastPos) > 0 ) {
-				data.append( lastPos, p-lastPos );	// do not add the CR
-			}
-			data += (char)0xa;						// a proper newline
-
-			if ( *(p+1) == 0xa ) {
-				// Carriage return - new line sequence
-				p += 2;
-				lastPos = p;
-				assert( p <= (buf+length) );
-			}
-			else {
-				// it was followed by something else...that is presumably characters again.
-				++p;
-				lastPos = p;
-				assert( p <= (buf+length) );
-			}
-		}
-		else {
-			++p;
-		}
-	}
-	// Handle any left over characters.
-	if ( p-lastPos ) {
-		data.append( lastPos, p-lastPos );
-	}		
-	delete [] buf;
-	buf = 0;
-
-	Parse( data.c_str(), 0, encoding );
-
-	if (  Error() )
-        return false;
-    else
-		return true;
-}
-
-
-bool TiXmlDocument::SaveFile( const char * filename ) const
-{
-	// The old c stuff lives on...
-	FILE* fp = fopen( filename, "w" );
-	if ( fp )
-	{
-		bool result = SaveFile( fp );
-		fclose( fp );
-		return result;
-	}
-	return false;
-}
-
-
-bool TiXmlDocument::SaveFile( FILE* fp ) const
-{
-	if ( useMicrosoftBOM ) 
-	{
-		const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
-		const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
-		const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
-
-		fputc( TIXML_UTF_LEAD_0, fp );
-		fputc( TIXML_UTF_LEAD_1, fp );
-		fputc( TIXML_UTF_LEAD_2, fp );
-	}
-	Print( fp, 0 );
-	return (ferror(fp) == 0);
-}
-
-
-void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
-{
-	TiXmlNode::CopyTo( target );
-
-	target->error = error;
-	target->errorDesc = errorDesc.c_str ();
-
-	TiXmlNode* node = 0;
-	for ( node = firstChild; node; node = node->NextSibling() )
-	{
-		target->LinkEndChild( node->Clone() );
-	}	
-}
-
-
-TiXmlNode* TiXmlDocument::Clone() const
-{
-	TiXmlDocument* clone = new TiXmlDocument();
-	if ( !clone )
-		return 0;
-
-	CopyTo( clone );
-	return clone;
-}
-
-
-void TiXmlDocument::Print( FILE* cfile, int depth ) const
-{
-	assert( cfile );
-	for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
-	{
-		node->Print( cfile, depth );
-		fprintf( cfile, "\n" );
-	}
-}
-
-
-bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
-{
-	if ( visitor->VisitEnter( *this ) )
-	{
-		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
-		{
-			if ( !node->Accept( visitor ) )
-				break;
-		}
-	}
-	return visitor->VisitExit( *this );
-}
-
-
-const TiXmlAttribute* TiXmlAttribute::Next() const
-{
-	// We are using knowledge of the sentinel. The sentinel
-	// have a value or name.
-	if ( next->value.empty() && next->name.empty() )
-		return 0;
-	return next;
-}
-
-/*
-TiXmlAttribute* TiXmlAttribute::Next()
-{
-	// We are using knowledge of the sentinel. The sentinel
-	// have a value or name.
-	if ( next->value.empty() && next->name.empty() )
-		return 0;
-	return next;
-}
-*/
-
-const TiXmlAttribute* TiXmlAttribute::Previous() const
-{
-	// We are using knowledge of the sentinel. The sentinel
-	// have a value or name.
-	if ( prev->value.empty() && prev->name.empty() )
-		return 0;
-	return prev;
-}
-
-/*
-TiXmlAttribute* TiXmlAttribute::Previous()
-{
-	// We are using knowledge of the sentinel. The sentinel
-	// have a value or name.
-	if ( prev->value.empty() && prev->name.empty() )
-		return 0;
-	return prev;
-}
-*/
-
-void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
-{
-	TIXML_STRING n, v;
-
-	PutString( name, &n );
-	PutString( value, &v );
-
-	if (value.find ('\"') == TIXML_STRING::npos) {
-		if ( cfile ) {
-		fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
-		}
-		if ( str ) {
-			(*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
-		}
-	}
-	else {
-		if ( cfile ) {
-		fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
-		}
-		if ( str ) {
-			(*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
-		}
-	}
-}
-
-
-int TiXmlAttribute::QueryIntValue( int* ival ) const
-{
-	if ( sscanf( value.c_str(), "%d", ival ) == 1 )
-		return TIXML_SUCCESS;
-	return TIXML_WRONG_TYPE;
-}
-
-int TiXmlAttribute::QueryDoubleValue( double* dval ) const
-{
-	if ( sscanf( value.c_str(), "%lf", dval ) == 1 )
-		return TIXML_SUCCESS;
-	return TIXML_WRONG_TYPE;
-}
-
-void TiXmlAttribute::SetIntValue( int _value )
-{
-	char buf [64];
-	#if defined(TIXML_SNPRINTF)		
-		TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
-	#else
-		sprintf (buf, "%d", _value);
-	#endif
-	SetValue (buf);
-}
-
-void TiXmlAttribute::SetDoubleValue( double _value )
-{
-	char buf [256];
-	#if defined(TIXML_SNPRINTF)		
-		TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value);
-	#else
-		sprintf (buf, "%lf", _value);
-	#endif
-	SetValue (buf);
-}
-
-int TiXmlAttribute::IntValue() const
-{
-	return atoi (value.c_str ());
-}
-
-double  TiXmlAttribute::DoubleValue() const
-{
-	return atof (value.c_str ());
-}
-
-
-TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT )
-{
-	copy.CopyTo( this );
-}
-
-
-void TiXmlComment::operator=( const TiXmlComment& base )
-{
-	Clear();
-	base.CopyTo( this );
-}
-
-
-void TiXmlComment::Print( FILE* cfile, int depth ) const
-{
-	assert( cfile );
-	for ( int i=0; i<depth; i++ )
-	{
-		fprintf( cfile,  "    " );
-	}
-	fprintf( cfile, "<!--%s-->", value.c_str() );
-}
-
-
-void TiXmlComment::CopyTo( TiXmlComment* target ) const
-{
-	TiXmlNode::CopyTo( target );
-}
-
-
-bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
-{
-	return visitor->Visit( *this );
-}
-
-
-TiXmlNode* TiXmlComment::Clone() const
-{
-	TiXmlComment* clone = new TiXmlComment();
-
-	if ( !clone )
-		return 0;
-
-	CopyTo( clone );
-	return clone;
-}
-
-
-void TiXmlText::Print( FILE* cfile, int depth ) const
-{
-	assert( cfile );
-	if ( cdata )
-	{
-		int i;
-		fprintf( cfile, "\n" );
-		for ( i=0; i<depth; i++ ) {
-			fprintf( cfile, "    " );
-		}
-		fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );	// unformatted output
-	}
-	else
-	{
-		TIXML_STRING buffer;
-		PutString( value, &buffer );
-		fprintf( cfile, "%s", buffer.c_str() );
-	}
-}
-
-
-void TiXmlText::CopyTo( TiXmlText* target ) const
-{
-	TiXmlNode::CopyTo( target );
-	target->cdata = cdata;
-}
-
-
-bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
-{
-	return visitor->Visit( *this );
-}
-
-
-TiXmlNode* TiXmlText::Clone() const
-{	
-	TiXmlText* clone = 0;
-	clone = new TiXmlText( "" );
-
-	if ( !clone )
-		return 0;
-
-	CopyTo( clone );
-	return clone;
-}
-
-
-TiXmlDeclaration::TiXmlDeclaration( const char * _version,
-									const char * _encoding,
-									const char * _standalone )
-	: TiXmlNode( TiXmlNode::DECLARATION )
-{
-	version = _version;
-	encoding = _encoding;
-	standalone = _standalone;
-}
-
-
-#ifdef TIXML_USE_STL
-TiXmlDeclaration::TiXmlDeclaration(	const std::string& _version,
-									const std::string& _encoding,
-									const std::string& _standalone )
-	: TiXmlNode( TiXmlNode::DECLARATION )
-{
-	version = _version;
-	encoding = _encoding;
-	standalone = _standalone;
-}
-#endif
-
-
-TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
-	: TiXmlNode( TiXmlNode::DECLARATION )
-{
-	copy.CopyTo( this );	
-}
-
-
-void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
-{
-	Clear();
-	copy.CopyTo( this );
-}
-
-
-void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
-{
-	if ( cfile ) fprintf( cfile, "<?xml " );
-	if ( str )	 (*str) += "<?xml ";
-
-	if ( !version.empty() ) {
-		if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
-		if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
-	}
-	if ( !encoding.empty() ) {
-		if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
-		if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
-	}
-	if ( !standalone.empty() ) {
-		if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
-		if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
-	}
-	if ( cfile ) fprintf( cfile, "?>" );
-	if ( str )	 (*str) += "?>";
-}
-
-
-void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
-{
-	TiXmlNode::CopyTo( target );
-
-	target->version = version;
-	target->encoding = encoding;
-	target->standalone = standalone;
-}
-
-
-bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
-{
-	return visitor->Visit( *this );
-}
-
-
-TiXmlNode* TiXmlDeclaration::Clone() const
-{	
-	TiXmlDeclaration* clone = new TiXmlDeclaration();
-
-	if ( !clone )
-		return 0;
-
-	CopyTo( clone );
-	return clone;
-}
-
-
-void TiXmlUnknown::Print( FILE* cfile, int depth ) const
-{
-	for ( int i=0; i<depth; i++ )
-		fprintf( cfile, "    " );
-	fprintf( cfile, "<%s>", value.c_str() );
-}
-
-
-void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
-{
-	TiXmlNode::CopyTo( target );
-}
-
-
-bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
-{
-	return visitor->Visit( *this );
-}
-
-
-TiXmlNode* TiXmlUnknown::Clone() const
-{
-	TiXmlUnknown* clone = new TiXmlUnknown();
-
-	if ( !clone )
-		return 0;
-
-	CopyTo( clone );
-	return clone;
-}
-
-
-TiXmlAttributeSet::TiXmlAttributeSet()
-{
-	sentinel.next = &sentinel;
-	sentinel.prev = &sentinel;
-}
-
-
-TiXmlAttributeSet::~TiXmlAttributeSet()
-{
-	assert( sentinel.next == &sentinel );
-	assert( sentinel.prev == &sentinel );
-}
-
-
-void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
-{
-    #ifdef TIXML_USE_STL
-	assert( !Find( TIXML_STRING( addMe->Name() ) ) );	// Shouldn't be multiply adding to the set.
-	#else
-	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
-	#endif
-
-	addMe->next = &sentinel;
-	addMe->prev = sentinel.prev;
-
-	sentinel.prev->next = addMe;
-	sentinel.prev      = addMe;
-}
-
-void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
-{
-	TiXmlAttribute* node;
-
-	for( node = sentinel.next; node != &sentinel; node = node->next )
-	{
-		if ( node == removeMe )
-		{
-			node->prev->next = node->next;
-			node->next->prev = node->prev;
-			node->next = 0;
-			node->prev = 0;
-			return;
-		}
-	}
-	assert( 0 );		// we tried to remove a non-linked attribute.
-}
-
-
-#ifdef TIXML_USE_STL
-const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
-{
-	for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
-	{
-		if ( node->name == name )
-			return node;
-	}
-	return 0;
-}
-
-/*
-TiXmlAttribute*	TiXmlAttributeSet::Find( const std::string& name )
-{
-	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
-	{
-		if ( node->name == name )
-			return node;
-	}
-	return 0;
-}
-*/
-#endif
-
-
-const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
-{
-	for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
-	{
-		if ( strcmp( node->name.c_str(), name ) == 0 )
-			return node;
-	}
-	return 0;
-}
-
-/*
-TiXmlAttribute*	TiXmlAttributeSet::Find( const char* name )
-{
-	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
-	{
-		if ( strcmp( node->name.c_str(), name ) == 0 )
-			return node;
-	}
-	return 0;
-}
-*/
-
-#ifdef TIXML_USE_STL	
-std::istream& operator>> (std::istream & in, TiXmlNode & base)
-{
-	TIXML_STRING tag;
-	tag.reserve( 8 * 1000 );
-	base.StreamIn( &in, &tag );
-
-	base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
-	return in;
-}
-#endif
-
-
-#ifdef TIXML_USE_STL	
-std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
-{
-	TiXmlPrinter printer;
-	printer.SetStreamPrinting();
-	base.Accept( &printer );
-	out << printer.Str();
-
-	return out;
-}
-
-
-std::string& operator<< (std::string& out, const TiXmlNode& base )
-{
-	TiXmlPrinter printer;
-	printer.SetStreamPrinting();
-	base.Accept( &printer );
-	out.append( printer.Str() );
-
-	return out;
-}
-#endif
-
-
-TiXmlHandle TiXmlHandle::FirstChild() const
-{
-	if ( node )
-	{
-		TiXmlNode* child = node->FirstChild();
-		if ( child )
-			return TiXmlHandle( child );
-	}
-	return TiXmlHandle( 0 );
-}
-
-
-TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
-{
-	if ( node )
-	{
-		TiXmlNode* child = node->FirstChild( value );
-		if ( child )
-			return TiXmlHandle( child );
-	}
-	return TiXmlHandle( 0 );
-}
-
-
-TiXmlHandle TiXmlHandle::FirstChildElement() const
-{
-	if ( node )
-	{
-		TiXmlElement* child = node->FirstChildElement();
-		if ( child )
-			return TiXmlHandle( child );
-	}
-	return TiXmlHandle( 0 );
-}
-
-
-TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
-{
-	if ( node )
-	{
-		TiXmlElement* child = node->FirstChildElement( value );
-		if ( child )
-			return TiXmlHandle( child );
-	}
-	return TiXmlHandle( 0 );
-}
-
-
-TiXmlHandle TiXmlHandle::Child( int count ) const
-{
-	if ( node )
-	{
-		int i;
-		TiXmlNode* child = node->FirstChild();
-		for (	i=0;
-				child && i<count;
-				child = child->NextSibling(), ++i )
-		{
-			// nothing
-		}
-		if ( child )
-			return TiXmlHandle( child );
-	}
-	return TiXmlHandle( 0 );
-}
-
-
-TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
-{
-	if ( node )
-	{
-		int i;
-		TiXmlNode* child = node->FirstChild( value );
-		for (	i=0;
-				child && i<count;
-				child = child->NextSibling( value ), ++i )
-		{
-			// nothing
-		}
-		if ( child )
-			return TiXmlHandle( child );
-	}
-	return TiXmlHandle( 0 );
-}
-
-
-TiXmlHandle TiXmlHandle::ChildElement( int count ) const
-{
-	if ( node )
-	{
-		int i;
-		TiXmlElement* child = node->FirstChildElement();
-		for (	i=0;
-				child && i<count;
-				child = child->NextSiblingElement(), ++i )
-		{
-			// nothing
-		}
-		if ( child )
-			return TiXmlHandle( child );
-	}
-	return TiXmlHandle( 0 );
-}
-
-
-TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
-{
-	if ( node )
-	{
-		int i;
-		TiXmlElement* child = node->FirstChildElement( value );
-		for (	i=0;
-				child && i<count;
-				child = child->NextSiblingElement( value ), ++i )
-		{
-			// nothing
-		}
-		if ( child )
-			return TiXmlHandle( child );
-	}
-	return TiXmlHandle( 0 );
-}
-
-
-bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
-{
-	return true;
-}
-
-bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
-{
-	return true;
-}
-
-bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
-{
-	DoIndent();
-	buffer += "<";
-	buffer += element.Value();
-
-	for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
-	{
-		buffer += " ";
-		attrib->Print( 0, 0, &buffer );
-	}
-
-	if ( !element.FirstChild() ) 
-	{
-		buffer += " />";
-		DoLineBreak();
-	}
-	else 
-	{
-		buffer += ">";
-		if (    element.FirstChild()->ToText()
-			  && element.LastChild() == element.FirstChild()
-			  && element.FirstChild()->ToText()->CDATA() == false )
-		{
-			simpleTextPrint = true;
-			// no DoLineBreak()!
-		}
-		else
-		{
-			DoLineBreak();
-		}
-	}
-	++depth;	
-	return true;
-}
-
-
-bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
-{
-	--depth;
-	if ( !element.FirstChild() ) 
-	{
-		// nothing.
-	}
-	else 
-	{
-		if ( simpleTextPrint )
-		{
-			simpleTextPrint = false;
-		}
-		else
-		{
-			DoIndent();
-		}
-		buffer += "</";
-		buffer += element.Value();
-		buffer += ">";
-		DoLineBreak();
-	}
-	return true;
-}
-
-
-bool TiXmlPrinter::Visit( const TiXmlText& text )
-{
-	if ( text.CDATA() )
-	{
-		DoIndent();
-		buffer += "<![CDATA[";
-		buffer += text.Value();
-		buffer += "]]>";
-		DoLineBreak();
-	}
-	else if ( simpleTextPrint )
-	{
-		buffer += text.Value();
-	}
-	else
-	{
-		DoIndent();
-		buffer += text.Value();
-		DoLineBreak();
-	}
-	return true;
-}
-
-
-bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
-{
-	DoIndent();
-	declaration.Print( 0, 0, &buffer );
-	DoLineBreak();
-	return true;
-}
-
-
-bool TiXmlPrinter::Visit( const TiXmlComment& comment )
-{
-	DoIndent();
-	buffer += "<!--";
-	buffer += comment.Value();
-	buffer += "-->";
-	DoLineBreak();
-	return true;
-}
-
-
-bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
-{
-	DoIndent();
-	buffer += "<";
-	buffer += unknown.Value();
-	buffer += ">";
-	DoLineBreak();
-	return true;
-}
-

+ 0 - 1776
tinyxml/tinyxml.h

@@ -1,1776 +0,0 @@
-/*
-www.sourceforge.net/projects/tinyxml
-Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any
-purpose, including commercial applications, and to alter it and
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must
-not claim that you wrote the original software. If you use this
-software in a product, an acknowledgment in the product documentation
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-*/
-
-
-#ifndef TINYXML_INCLUDED
-#define TINYXML_INCLUDED
-
-#ifdef _MSC_VER
-#pragma warning( push )
-#pragma warning( disable : 4530 )
-#pragma warning( disable : 4786 )
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-// Help out windows:
-#if defined( _DEBUG ) && !defined( DEBUG )
-#define DEBUG
-#endif
-
-#ifdef TIXML_USE_STL
-	#include <string>
- 	#include <iostream>
-	#include <sstream>
-	#define TIXML_STRING		std::string
-#else
-	#include "tinystr.h"
-	#define TIXML_STRING		TiXmlString
-#endif
-
-// Deprecated library function hell. Compilers want to use the
-// new safe versions. This probably doesn't fully address the problem,
-// but it gets closer. There are too many compilers for me to fully
-// test. If you get compilation troubles, undefine TIXML_SAFE
-#define TIXML_SAFE
-
-#ifdef TIXML_SAFE
-	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
-		// Microsoft visual studio, version 2005 and higher.
-		#define TIXML_SNPRINTF _snprintf_s
-		#define TIXML_SNSCANF  _snscanf_s
-	#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
-		// Microsoft visual studio, version 6 and higher.
-		//#pragma message( "Using _sn* functions." )
-		#define TIXML_SNPRINTF _snprintf
-		#define TIXML_SNSCANF  _snscanf
-	#elif defined(__GNUC__) && (__GNUC__ >= 3 )
-		// GCC version 3 and higher.s
-		//#warning( "Using sn* functions." )
-		#define TIXML_SNPRINTF snprintf
-		#define TIXML_SNSCANF  snscanf
-	#endif
-#endif	
-
-class TiXmlDocument;
-class TiXmlElement;
-class TiXmlComment;
-class TiXmlUnknown;
-class TiXmlAttribute;
-class TiXmlText;
-class TiXmlDeclaration;
-class TiXmlParsingData;
-
-const int TIXML_MAJOR_VERSION = 2;
-const int TIXML_MINOR_VERSION = 5;
-const int TIXML_PATCH_VERSION = 1;
-
-/*	Internal structure for tracking location of items 
-	in the XML file.
-*/
-struct TiXmlCursor
-{
-	TiXmlCursor()		{ Clear(); }
-	void Clear()		{ row = col = -1; }
-
-	int row;	// 0 based.
-	int col;	// 0 based.
-};
-
-
-/**
-	If you call the Accept() method, it requires being passed a TiXmlVisitor
-	class to handle callbacks. For nodes that contain other nodes (Document, Element)
-	you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
-	are simple called with Visit().
-
-	If you return 'true' from a Visit method, recursive parsing will continue. If you return
-	false, <b>no children of this node or its sibilings</b> will be Visited.
-
-	All flavors of Visit methods have a default implementation that returns 'true' (continue 
-	visiting). You need to only override methods that are interesting to you.
-
-	Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
-
-	You should never change the document from a callback.
-
-	@sa TiXmlNode::Accept()
-*/
-class TiXmlVisitor
-{
-public:
-	virtual ~TiXmlVisitor() {}
-
-	/// Visit a document.
-	virtual bool VisitEnter( const TiXmlDocument& doc )	{ return true; }
-	/// Visit a document.
-	virtual bool VisitExit( const TiXmlDocument& doc )	{ return true; }
-
-	/// Visit an element.
-	virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )	{ return true; }
-	/// Visit an element.
-	virtual bool VisitExit( const TiXmlElement& element )											{ return true; }
-
-	/// Visit a declaration
-	virtual bool Visit( const TiXmlDeclaration& declaration )		{ return true; }
-	/// Visit a text node
-	virtual bool Visit( const TiXmlText& text )						{ return true; }
-	/// Visit a comment node
-	virtual bool Visit( const TiXmlComment& comment )				{ return true; }
-	/// Visit an unknow node
-	virtual bool Visit( const TiXmlUnknown& unknown )				{ return true; }
-};
-
-// Only used by Attribute::Query functions
-enum 
-{ 
-	TIXML_SUCCESS,
-	TIXML_NO_ATTRIBUTE,
-	TIXML_WRONG_TYPE
-};
-
-
-// Used by the parsing routines.
-enum TiXmlEncoding
-{
-	TIXML_ENCODING_UNKNOWN,
-	TIXML_ENCODING_UTF8,
-	TIXML_ENCODING_LEGACY
-};
-
-const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
-
-/** TiXmlBase is a base class for every class in TinyXml.
-	It does little except to establish that TinyXml classes
-	can be printed and provide some utility functions.
-
-	In XML, the document and elements can contain
-	other elements and other types of nodes.
-
-	@verbatim
-	A Document can contain:	Element	(container or leaf)
-							Comment (leaf)
-							Unknown (leaf)
-							Declaration( leaf )
-
-	An Element can contain:	Element (container or leaf)
-							Text	(leaf)
-							Attributes (not on tree)
-							Comment (leaf)
-							Unknown (leaf)
-
-	A Decleration contains: Attributes (not on tree)
-	@endverbatim
-*/
-class TiXmlBase
-{
-	friend class TiXmlNode;
-	friend class TiXmlElement;
-	friend class TiXmlDocument;
-
-public:
-	TiXmlBase()	:	userData(0)		{}
-	virtual ~TiXmlBase()			{}
-
-	/**	All TinyXml classes can print themselves to a filestream
-		or the string class (TiXmlString in non-STL mode, std::string
-		in STL mode.) Either or both cfile and str can be null.
-		
-		This is a formatted print, and will insert 
-		tabs and newlines.
-		
-		(For an unformatted stream, use the << operator.)
-	*/
-	virtual void Print( FILE* cfile, int depth ) const = 0;
-
-	/**	The world does not agree on whether white space should be kept or
-		not. In order to make everyone happy, these global, static functions
-		are provided to set whether or not TinyXml will condense all white space
-		into a single space or not. The default is to condense. Note changing this
-		value is not thread safe.
-	*/
-	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
-
-	/// Return the current white space setting.
-	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
-
-	/** Return the position, in the original source file, of this node or attribute.
-		The row and column are 1-based. (That is the first row and first column is
-		1,1). If the returns values are 0 or less, then the parser does not have
-		a row and column value.
-
-		Generally, the row and column value will be set when the TiXmlDocument::Load(),
-		TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
-		when the DOM was created from operator>>.
-
-		The values reflect the initial load. Once the DOM is modified programmatically
-		(by adding or changing nodes and attributes) the new values will NOT update to
-		reflect changes in the document.
-
-		There is a minor performance cost to computing the row and column. Computation
-		can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
-
-		@sa TiXmlDocument::SetTabSize()
-	*/
-	int Row() const			{ return location.row + 1; }
-	int Column() const		{ return location.col + 1; }	///< See Row()
-
-	void  SetUserData( void* user )			{ userData = user; }	///< Set a pointer to arbitrary user data.
-	void* GetUserData()						{ return userData; }	///< Get a pointer to arbitrary user data.
-	const void* GetUserData() const 		{ return userData; }	///< Get a pointer to arbitrary user data.
-
-	// Table that returs, for a given lead byte, the total number of bytes
-	// in the UTF-8 sequence.
-	static const int utf8ByteTable[256];
-
-	virtual const char* Parse(	const char* p, 
-								TiXmlParsingData* data, 
-								TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
-
-	enum
-	{
-		TIXML_NO_ERROR = 0,
-		TIXML_ERROR,
-		TIXML_ERROR_OPENING_FILE,
-		TIXML_ERROR_OUT_OF_MEMORY,
-		TIXML_ERROR_PARSING_ELEMENT,
-		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
-		TIXML_ERROR_READING_ELEMENT_VALUE,
-		TIXML_ERROR_READING_ATTRIBUTES,
-		TIXML_ERROR_PARSING_EMPTY,
-		TIXML_ERROR_READING_END_TAG,
-		TIXML_ERROR_PARSING_UNKNOWN,
-		TIXML_ERROR_PARSING_COMMENT,
-		TIXML_ERROR_PARSING_DECLARATION,
-		TIXML_ERROR_DOCUMENT_EMPTY,
-		TIXML_ERROR_EMBEDDED_NULL,
-		TIXML_ERROR_PARSING_CDATA,
-		TIXML_ERROR_DOCUMENT_TOP_ONLY,
-
-		TIXML_ERROR_STRING_COUNT
-	};
-
-protected:
-
-	static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
-	inline static bool IsWhiteSpace( char c )		
-	{ 
-		return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
-	}
-	inline static bool IsWhiteSpace( int c )
-	{
-		if ( c < 256 )
-			return IsWhiteSpace( (char) c );
-		return false;	// Again, only truly correct for English/Latin...but usually works.
-	}
-
-	#ifdef TIXML_USE_STL
-	static bool	StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
-	static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
-	#endif
-
-	/*	Reads an XML name into the string provided. Returns
-		a pointer just past the last character of the name,
-		or 0 if the function has an error.
-	*/
-	static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
-
-	/*	Reads text. Returns a pointer past the given end tag.
-		Wickedly complex options, but it keeps the (sensitive) code in one place.
-	*/
-	static const char* ReadText(	const char* in,				// where to start
-									TIXML_STRING* text,			// the string read
-									bool ignoreWhiteSpace,		// whether to keep the white space
-									const char* endTag,			// what ends this text
-									bool ignoreCase,			// whether to ignore case in the end tag
-									TiXmlEncoding encoding );	// the current encoding
-
-	// If an entity has been found, transform it into a character.
-	static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
-
-	// Get a character, while interpreting entities.
-	// The length can be from 0 to 4 bytes.
-	inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
-	{
-		assert( p );
-		if ( encoding == TIXML_ENCODING_UTF8 )
-		{
-			*length = utf8ByteTable[ *((const unsigned char*)p) ];
-			assert( *length >= 0 && *length < 5 );
-		}
-		else
-		{
-			*length = 1;
-		}
-
-		if ( *length == 1 )
-		{
-			if ( *p == '&' )
-				return GetEntity( p, _value, length, encoding );
-			*_value = *p;
-			return p+1;
-		}
-		else if ( *length )
-		{
-			//strncpy( _value, p, *length );	// lots of compilers don't like this function (unsafe),
-												// and the null terminator isn't needed
-			for( int i=0; p[i] && i<*length; ++i ) {
-				_value[i] = p[i];
-			}
-			return p + (*length);
-		}
-		else
-		{
-			// Not valid text.
-			return 0;
-		}
-	}
-
-	// Puts a string to a stream, expanding entities as it goes.
-	// Note this should not contian the '<', '>', etc, or they will be transformed into entities!
-	static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
-
-	// Return true if the next characters in the stream are any of the endTag sequences.
-	// Ignore case only works for english, and should only be relied on when comparing
-	// to English words: StringEqual( p, "version", true ) is fine.
-	static bool StringEqual(	const char* p,
-								const char* endTag,
-								bool ignoreCase,
-								TiXmlEncoding encoding );
-
-	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
-
-	TiXmlCursor location;
-
-    /// Field containing a generic user pointer
-	void*			userData;
-	
-	// None of these methods are reliable for any language except English.
-	// Good for approximation, not great for accuracy.
-	static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
-	static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
-	inline static int ToLower( int v, TiXmlEncoding encoding )
-	{
-		if ( encoding == TIXML_ENCODING_UTF8 )
-		{
-			if ( v < 128 ) return tolower( v );
-			return v;
-		}
-		else
-		{
-			return tolower( v );
-		}
-	}
-	static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
-
-private:
-	TiXmlBase( const TiXmlBase& );				// not implemented.
-	void operator=( const TiXmlBase& base );	// not allowed.
-
-	struct Entity
-	{
-		const char*     str;
-		unsigned int	strLength;
-		char		    chr;
-	};
-	enum
-	{
-		NUM_ENTITY = 5,
-		MAX_ENTITY_LENGTH = 6
-
-	};
-	static Entity entity[ NUM_ENTITY ];
-	static bool condenseWhiteSpace;
-};
-
-
-/** The parent class for everything in the Document Object Model.
-	(Except for attributes).
-	Nodes have siblings, a parent, and children. A node can be
-	in a document, or stand on its own. The type of a TiXmlNode
-	can be queried, and it can be cast to its more defined type.
-*/
-class TiXmlNode : public TiXmlBase
-{
-	friend class TiXmlDocument;
-	friend class TiXmlElement;
-
-public:
-	#ifdef TIXML_USE_STL	
-
-	    /** An input stream operator, for every class. Tolerant of newlines and
-		    formatting, but doesn't expect them.
-	    */
-	    friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
-
-	    /** An output stream operator, for every class. Note that this outputs
-		    without any newlines or formatting, as opposed to Print(), which
-		    includes tabs and new lines.
-
-		    The operator<< and operator>> are not completely symmetric. Writing
-		    a node to a stream is very well defined. You'll get a nice stream
-		    of output, without any extra whitespace or newlines.
-		    
-		    But reading is not as well defined. (As it always is.) If you create
-		    a TiXmlElement (for example) and read that from an input stream,
-		    the text needs to define an element or junk will result. This is
-		    true of all input streams, but it's worth keeping in mind.
-
-		    A TiXmlDocument will read nodes until it reads a root element, and
-			all the children of that root element.
-	    */	
-	    friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
-
-		/// Appends the XML node or attribute to a std::string.
-		friend std::string& operator<< (std::string& out, const TiXmlNode& base );
-
-	#endif
-
-	/** The types of XML nodes supported by TinyXml. (All the
-			unsupported types are picked up by UNKNOWN.)
-	*/
-	enum NodeType
-	{
-		DOCUMENT,
-		ELEMENT,
-		COMMENT,
-		UNKNOWN,
-		TEXT,
-		DECLARATION,
-		TYPECOUNT
-	};
-
-	virtual ~TiXmlNode();
-
-	/** The meaning of 'value' changes for the specific type of
-		TiXmlNode.
-		@verbatim
-		Document:	filename of the xml file
-		Element:	name of the element
-		Comment:	the comment text
-		Unknown:	the tag contents
-		Text:		the text string
-		@endverbatim
-
-		The subclasses will wrap this function.
-	*/
-	const char *Value() const { return value.c_str (); }
-
-    #ifdef TIXML_USE_STL
-	/** Return Value() as a std::string. If you only use STL,
-	    this is more efficient than calling Value().
-		Only available in STL mode.
-	*/
-	const std::string& ValueStr() const { return value; }
-	#endif
-
-	/** Changes the value of the node. Defined as:
-		@verbatim
-		Document:	filename of the xml file
-		Element:	name of the element
-		Comment:	the comment text
-		Unknown:	the tag contents
-		Text:		the text string
-		@endverbatim
-	*/
-	void SetValue(const char * _value) { value = _value;}
-
-    #ifdef TIXML_USE_STL
-	/// STL std::string form.
-	void SetValue( const std::string& _value )	{ value = _value; }
-	#endif
-
-	/// Delete all the children of this node. Does not affect 'this'.
-	void Clear();
-
-	/// One step up the DOM.
-	TiXmlNode* Parent()							{ return parent; }
-	const TiXmlNode* Parent() const				{ return parent; }
-
-	const TiXmlNode* FirstChild()	const	{ return firstChild; }		///< The first child of this node. Will be null if there are no children.
-	TiXmlNode* FirstChild()					{ return firstChild; }
-	const TiXmlNode* FirstChild( const char * value ) const;			///< The first child of this node with the matching 'value'. Will be null if none found.
-	/// The first child of this node with the matching 'value'. Will be null if none found.
-	TiXmlNode* FirstChild( const char * _value ) {
-		// Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
-		// call the method, cast the return back to non-const.
-		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
-	}
-	const TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
-	TiXmlNode* LastChild()	{ return lastChild; }
-	
-	const TiXmlNode* LastChild( const char * value ) const;			/// The last child of this node matching 'value'. Will be null if there are no children.
-	TiXmlNode* LastChild( const char * _value ) {
-		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
-	}
-
-    #ifdef TIXML_USE_STL
-	const TiXmlNode* FirstChild( const std::string& _value ) const	{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
-	TiXmlNode* FirstChild( const std::string& _value )				{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
-	const TiXmlNode* LastChild( const std::string& _value ) const	{	return LastChild (_value.c_str ());	}	///< STL std::string form.
-	TiXmlNode* LastChild( const std::string& _value )				{	return LastChild (_value.c_str ());	}	///< STL std::string form.
-	#endif
-
-	/** An alternate way to walk the children of a node.
-		One way to iterate over nodes is:
-		@verbatim
-			for( child = parent->FirstChild(); child; child = child->NextSibling() )
-		@endverbatim
-
-		IterateChildren does the same thing with the syntax:
-		@verbatim
-			child = 0;
-			while( child = parent->IterateChildren( child ) )
-		@endverbatim
-
-		IterateChildren takes the previous child as input and finds
-		the next one. If the previous child is null, it returns the
-		first. IterateChildren will return null when done.
-	*/
-	const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
-	TiXmlNode* IterateChildren( TiXmlNode* previous ) {
-		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
-	}
-
-	/// This flavor of IterateChildren searches for children with a particular 'value'
-	const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
-	TiXmlNode* IterateChildren( const char * _value, TiXmlNode* previous ) {
-		return const_cast< TiXmlNode* >( const_cast< const TiXmlNode* >(this)->IterateChildren( _value, previous ) );
-	}
-
-    #ifdef TIXML_USE_STL
-	const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const	{	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
-	TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) {	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
-	#endif
-
-	/** Add a new node related to this. Adds a child past the LastChild.
-		Returns a pointer to the new object or NULL if an error occured.
-	*/
-	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
-
-
-	/** Add a new node related to this. Adds a child past the LastChild.
-
-		NOTE: the node to be added is passed by pointer, and will be
-		henceforth owned (and deleted) by tinyXml. This method is efficient
-		and avoids an extra copy, but should be used with care as it
-		uses a different memory model than the other insert functions.
-
-		@sa InsertEndChild
-	*/
-	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
-
-	/** Add a new node related to this. Adds a child before the specified child.
-		Returns a pointer to the new object or NULL if an error occured.
-	*/
-	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
-
-	/** Add a new node related to this. Adds a child after the specified child.
-		Returns a pointer to the new object or NULL if an error occured.
-	*/
-	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
-
-	/** Replace a child of this node.
-		Returns a pointer to the new object or NULL if an error occured.
-	*/
-	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
-
-	/// Delete a child of this node.
-	bool RemoveChild( TiXmlNode* removeThis );
-
-	/// Navigate to a sibling node.
-	const TiXmlNode* PreviousSibling() const			{ return prev; }
-	TiXmlNode* PreviousSibling()						{ return prev; }
-
-	/// Navigate to a sibling node.
-	const TiXmlNode* PreviousSibling( const char * ) const;
-	TiXmlNode* PreviousSibling( const char *_prev ) {
-		return const_cast< TiXmlNode* >( const_cast< const TiXmlNode* >(this)->PreviousSibling( _prev ) );
-	}
-
-    #ifdef TIXML_USE_STL
-	const TiXmlNode* PreviousSibling( const std::string& _value ) const	{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
-	TiXmlNode* PreviousSibling( const std::string& _value ) 			{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
-	const TiXmlNode* NextSibling( const std::string& _value) const		{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
-	TiXmlNode* NextSibling( const std::string& _value) 					{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
-	#endif
-
-	/// Navigate to a sibling node.
-	const TiXmlNode* NextSibling() const				{ return next; }
-	TiXmlNode* NextSibling()							{ return next; }
-
-	/// Navigate to a sibling node with the given 'value'.
-	const TiXmlNode* NextSibling( const char * ) const;
-	TiXmlNode* NextSibling( const char* _next ) {
-		return const_cast< TiXmlNode* >( const_cast< const TiXmlNode* >(this)->NextSibling( _next ) );
-	}
-
-	/** Convenience function to get through elements.
-		Calls NextSibling and ToElement. Will skip all non-Element
-		nodes. Returns 0 if there is not another element.
-	*/
-	const TiXmlElement* NextSiblingElement() const;
-	TiXmlElement* NextSiblingElement() {
-		return const_cast< TiXmlElement* >( const_cast< const TiXmlNode* >(this)->NextSiblingElement() );
-	}
-
-	/** Convenience function to get through elements.
-		Calls NextSibling and ToElement. Will skip all non-Element
-		nodes. Returns 0 if there is not another element.
-	*/
-	const TiXmlElement* NextSiblingElement( const char * ) const;
-	TiXmlElement* NextSiblingElement( const char *_next ) {
-		return const_cast< TiXmlElement* >( const_cast< const TiXmlNode* >(this)->NextSiblingElement( _next ) );
-	}
-
-    #ifdef TIXML_USE_STL
-	const TiXmlElement* NextSiblingElement( const std::string& _value) const	{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
-	TiXmlElement* NextSiblingElement( const std::string& _value)				{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
-	#endif
-
-	/// Convenience function to get through elements.
-	const TiXmlElement* FirstChildElement()	const;
-	TiXmlElement* FirstChildElement() {
-		return const_cast< TiXmlElement* >( const_cast< const TiXmlNode* >(this)->FirstChildElement() );
-	}
-
-	/// Convenience function to get through elements.
-	const TiXmlElement* FirstChildElement( const char * _value ) const;
-	TiXmlElement* FirstChildElement( const char * _value ) {
-		return const_cast< TiXmlElement* >( const_cast< const TiXmlNode* >(this)->FirstChildElement( _value ) );
-	}
-
-    #ifdef TIXML_USE_STL
-	const TiXmlElement* FirstChildElement( const std::string& _value ) const	{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
-	TiXmlElement* FirstChildElement( const std::string& _value )				{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
-	#endif
-
-	/** Query the type (as an enumerated value, above) of this node.
-		The possible types are: DOCUMENT, ELEMENT, COMMENT,
-								UNKNOWN, TEXT, and DECLARATION.
-	*/
-	int Type() const	{ return type; }
-
-	/** Return a pointer to the Document this node lives in.
-		Returns null if not in a document.
-	*/
-	const TiXmlDocument* GetDocument() const;
-	TiXmlDocument* GetDocument() {
-		return const_cast< TiXmlDocument* >( const_cast< const TiXmlNode* >(this)->GetDocument() );
-	}
-
-	/// Returns true if this node has no children.
-	bool NoChildren() const						{ return !firstChild; }
-
-	virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-	virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-	virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-	virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-	virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-	virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-
-	virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-	virtual TiXmlElement*           ToElement()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-	virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-	virtual TiXmlUnknown*           ToUnknown()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-	virtual TiXmlText*	            ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-	virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
-
-	/** Create an exact duplicate of this node and return it. The memory must be deleted
-		by the caller. 
-	*/
-	virtual TiXmlNode* Clone() const = 0;
-
-	/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the 
-		XML tree will be conditionally visited and the host will be called back
-		via the TiXmlVisitor interface.
-
-		This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
-		the XML for the callbacks, so the performance of TinyXML is unchanged by using this
-		interface versus any other.)
-
-		The interface has been based on ideas from:
-
-		- http://www.saxproject.org/
-		- http://c2.com/cgi/wiki?HierarchicalVisitorPattern 
-
-		Which are both good references for "visiting".
-
-		An example of using Accept():
-		@verbatim
-		TiXmlPrinter printer;
-		tinyxmlDoc.Accept( &printer );
-		const char* xmlcstr = printer.CStr();
-		@endverbatim
-	*/
-	virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
-
-protected:
-	TiXmlNode( NodeType _type );
-
-	// Copy to the allocated object. Shared functionality between Clone, Copy constructor,
-	// and the assignment operator.
-	void CopyTo( TiXmlNode* target ) const;
-
-	#ifdef TIXML_USE_STL
-	    // The real work of the input operator.
-	virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
-	#endif
-
-	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
-	TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
-
-	TiXmlNode*		parent;
-	NodeType		type;
-
-	TiXmlNode*		firstChild;
-	TiXmlNode*		lastChild;
-
-	TIXML_STRING	value;
-
-	TiXmlNode*		prev;
-	TiXmlNode*		next;
-
-private:
-	TiXmlNode( const TiXmlNode& );				// not implemented.
-	void operator=( const TiXmlNode& base );	// not allowed.
-};
-
-
-/** An attribute is a name-value pair. Elements have an arbitrary
-	number of attributes, each with a unique name.
-
-	@note The attributes are not TiXmlNodes, since they are not
-		  part of the tinyXML document object model. There are other
-		  suggested ways to look at this problem.
-*/
-class TiXmlAttribute : public TiXmlBase
-{
-	friend class TiXmlAttributeSet;
-
-public:
-	/// Construct an empty attribute.
-	TiXmlAttribute() : TiXmlBase()
-	{
-		document = 0;
-		prev = next = 0;
-	}
-
-	#ifdef TIXML_USE_STL
-	/// std::string constructor.
-	TiXmlAttribute( const std::string& _name, const std::string& _value )
-	{
-		name = _name;
-		value = _value;
-		document = 0;
-		prev = next = 0;
-	}
-	#endif
-
-	/// Construct an attribute with a name and value.
-	TiXmlAttribute( const char * _name, const char * _value )
-	{
-		name = _name;
-		value = _value;
-		document = 0;
-		prev = next = 0;
-	}
-
-	const char*		Name()  const		{ return name.c_str(); }		///< Return the name of this attribute.
-	const char*		Value() const		{ return value.c_str(); }		///< Return the value of this attribute.
-	#ifdef TIXML_USE_STL
-	const std::string& ValueStr() const	{ return value; }				///< Return the value of this attribute.
-	#endif
-	int				IntValue() const;									///< Return the value of this attribute, converted to an integer.
-	double			DoubleValue() const;								///< Return the value of this attribute, converted to a double.
-
-	// Get the tinyxml string representation
-	const TIXML_STRING& NameTStr() const { return name; }
-
-	/** QueryIntValue examines the value string. It is an alternative to the
-		IntValue() method with richer error checking.
-		If the value is an integer, it is stored in 'value' and 
-		the call returns TIXML_SUCCESS. If it is not
-		an integer, it returns TIXML_WRONG_TYPE.
-
-		A specialized but useful call. Note that for success it returns 0,
-		which is the opposite of almost all other TinyXml calls.
-	*/
-	int QueryIntValue( int* _value ) const;
-	/// QueryDoubleValue examines the value string. See QueryIntValue().
-	int QueryDoubleValue( double* _value ) const;
-
-	void SetName( const char* _name )	{ name = _name; }				///< Set the name of this attribute.
-	void SetValue( const char* _value )	{ value = _value; }				///< Set the value.
-
-	void SetIntValue( int _value );										///< Set the value from an integer.
-	void SetDoubleValue( double _value );								///< Set the value from a double.
-
-    #ifdef TIXML_USE_STL
-	/// STL std::string form.
-	void SetName( const std::string& _name )	{ name = _name; }	
-	/// STL std::string form.	
-	void SetValue( const std::string& _value )	{ value = _value; }
-	#endif
-
-	/// Get the next sibling attribute in the DOM. Returns null at end.
-	const TiXmlAttribute* Next() const;
-	TiXmlAttribute* Next() {
-		return const_cast< TiXmlAttribute* >( const_cast< const TiXmlAttribute* >(this)->Next() ); 
-	}
-
-	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
-	const TiXmlAttribute* Previous() const;
-	TiXmlAttribute* Previous() {
-		return const_cast< TiXmlAttribute* >( const_cast< const TiXmlAttribute* >(this)->Previous() ); 
-	}
-
-	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
-	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
-	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
-
-	/*	Attribute parsing starts: first letter of the name
-						 returns: the next char after the value end quote
-	*/
-	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
-
-	// Prints this Attribute to a FILE stream.
-	virtual void Print( FILE* cfile, int depth ) const {
-		Print( cfile, depth, 0 );
-	}
-	void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
-
-	// [internal use]
-	// Set the document pointer so the attribute can report errors.
-	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
-
-private:
-	TiXmlAttribute( const TiXmlAttribute& );				// not implemented.
-	void operator=( const TiXmlAttribute& base );	// not allowed.
-
-	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
-	TIXML_STRING name;
-	TIXML_STRING value;
-	TiXmlAttribute*	prev;
-	TiXmlAttribute*	next;
-};
-
-
-/*	A class used to manage a group of attributes.
-	It is only used internally, both by the ELEMENT and the DECLARATION.
-	
-	The set can be changed transparent to the Element and Declaration
-	classes that use it, but NOT transparent to the Attribute
-	which has to implement a next() and previous() method. Which makes
-	it a bit problematic and prevents the use of STL.
-
-	This version is implemented with circular lists because:
-		- I like circular lists
-		- it demonstrates some independence from the (typical) doubly linked list.
-*/
-class TiXmlAttributeSet
-{
-public:
-	TiXmlAttributeSet();
-	~TiXmlAttributeSet();
-
-	void Add( TiXmlAttribute* attribute );
-	void Remove( TiXmlAttribute* attribute );
-
-	const TiXmlAttribute* First()	const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
-	TiXmlAttribute* First()					{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
-	const TiXmlAttribute* Last() const		{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
-	TiXmlAttribute* Last()					{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
-
-	const TiXmlAttribute*	Find( const char* _name ) const;
-	TiXmlAttribute*	Find( const char* _name ) {
-		return const_cast< TiXmlAttribute* >( const_cast< const TiXmlAttributeSet* >(this)->Find( _name ) );
-	}
-	#ifdef TIXML_USE_STL
-	const TiXmlAttribute*	Find( const std::string& _name ) const;
-	TiXmlAttribute*	Find( const std::string& _name ) {
-		return const_cast< TiXmlAttribute* >( const_cast< const TiXmlAttributeSet* >(this)->Find( _name ) );
-	}
-
-	#endif
-
-private:
-	//*ME:	Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
-	//*ME:	this class must be also use a hidden/disabled copy-constructor !!!
-	TiXmlAttributeSet( const TiXmlAttributeSet& );	// not allowed
-	void operator=( const TiXmlAttributeSet& );	// not allowed (as TiXmlAttribute)
-
-	TiXmlAttribute sentinel;
-};
-
-
-/** The element is a container class. It has a value, the element name,
-	and can contain other elements, text, comments, and unknowns.
-	Elements also contain an arbitrary number of attributes.
-*/
-class TiXmlElement : public TiXmlNode
-{
-public:
-	/// Construct an element.
-	TiXmlElement (const char * in_value);
-
-	#ifdef TIXML_USE_STL
-	/// std::string constructor.
-	TiXmlElement( const std::string& _value );
-	#endif
-
-	TiXmlElement( const TiXmlElement& );
-
-	void operator=( const TiXmlElement& base );
-
-	virtual ~TiXmlElement();
-
-	/** Given an attribute name, Attribute() returns the value
-		for the attribute of that name, or null if none exists.
-	*/
-	const char* Attribute( const char* name ) const;
-
-	/** Given an attribute name, Attribute() returns the value
-		for the attribute of that name, or null if none exists.
-		If the attribute exists and can be converted to an integer,
-		the integer value will be put in the return 'i', if 'i'
-		is non-null.
-	*/
-	const char* Attribute( const char* name, int* i ) const;
-
-	/** Given an attribute name, Attribute() returns the value
-		for the attribute of that name, or null if none exists.
-		If the attribute exists and can be converted to an double,
-		the double value will be put in the return 'd', if 'd'
-		is non-null.
-	*/
-	const char* Attribute( const char* name, double* d ) const;
-
-	/** QueryIntAttribute examines the attribute - it is an alternative to the
-		Attribute() method with richer error checking.
-		If the attribute is an integer, it is stored in 'value' and 
-		the call returns TIXML_SUCCESS. If it is not
-		an integer, it returns TIXML_WRONG_TYPE. If the attribute
-		does not exist, then TIXML_NO_ATTRIBUTE is returned.
-	*/	
-	int QueryIntAttribute( const char* name, int* _value ) const;
-	/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
-	int QueryDoubleAttribute( const char* name, double* _value ) const;
-	/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
-	int QueryFloatAttribute( const char* name, float* _value ) const {
-		double d;
-		int result = QueryDoubleAttribute( name, &d );
-		if ( result == TIXML_SUCCESS ) {
-			*_value = (float)d;
-		}
-		return result;
-	}
-    #ifdef TIXML_USE_STL
-	/** Template form of the attribute query which will try to read the
-		attribute into the specified type. Very easy, very powerful, but
-		be careful to make sure to call this with the correct type.
-
-		@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
-	*/
-	template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
-	{
-		const TiXmlAttribute* node = attributeSet.Find( name );
-		if ( !node )
-			return TIXML_NO_ATTRIBUTE;
-
-		std::stringstream sstream( node->ValueStr() );
-		sstream >> *outValue;
-		if ( !sstream.fail() )
-			return TIXML_SUCCESS;
-		return TIXML_WRONG_TYPE;
-	}
-	#endif
-
-	/** Sets an attribute of name to a given value. The attribute
-		will be created if it does not exist, or changed if it does.
-	*/
-	void SetAttribute( const char* name, const char * _value );
-
-    #ifdef TIXML_USE_STL
-	const std::string* Attribute( const std::string& name ) const;
-	const std::string* Attribute( const std::string& name, int* i ) const;
-	const std::string* Attribute( const std::string& name, double* d ) const;
-	int QueryIntAttribute( const std::string& name, int* _value ) const;
-	int QueryDoubleAttribute( const std::string& name, double* _value ) const;
-
-	/// STL std::string form.
-	void SetAttribute( const std::string& name, const std::string& _value );
-	///< STL std::string form.
-	void SetAttribute( const std::string& name, int _value );
-	#endif
-
-	/** Sets an attribute of name to a given value. The attribute
-		will be created if it does not exist, or changed if it does.
-	*/
-	void SetAttribute( const char * name, int value );
-
-	/** Sets an attribute of name to a given value. The attribute
-		will be created if it does not exist, or changed if it does.
-	*/
-	void SetDoubleAttribute( const char * name, double value );
-
-	/** Deletes an attribute with the given name.
-	*/
-	void RemoveAttribute( const char * name );
-    #ifdef TIXML_USE_STL
-	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
-	#endif
-
-	const TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
-	TiXmlAttribute* FirstAttribute() 				{ return attributeSet.First(); }
-	const TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
-	TiXmlAttribute* LastAttribute()					{ return attributeSet.Last(); }
-
-	/** Convenience function for easy access to the text inside an element. Although easy
-		and concise, GetText() is limited compared to getting the TiXmlText child
-		and accessing it directly.
-	
-		If the first child of 'this' is a TiXmlText, the GetText()
-		returns the character string of the Text node, else null is returned.
-
-		This is a convenient method for getting the text of simple contained text:
-		@verbatim
-		<foo>This is text</foo>
-		const char* str = fooElement->GetText();
-		@endverbatim
-
-		'str' will be a pointer to "This is text". 
-		
-		Note that this function can be misleading. If the element foo was created from
-		this XML:
-		@verbatim
-		<foo><b>This is text</b></foo> 
-		@endverbatim
-
-		then the value of str would be null. The first child node isn't a text node, it is
-		another element. From this XML:
-		@verbatim
-		<foo>This is <b>text</b></foo> 
-		@endverbatim
-		GetText() will return "This is ".
-
-		WARNING: GetText() accesses a child node - don't become confused with the 
-				 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 
-				 safe type casts on the referenced node.
-	*/
-	const char* GetText() const;
-
-	/// Creates a new Element and returns it - the returned element is a copy.
-	virtual TiXmlNode* Clone() const;
-	// Print the Element to a FILE stream.
-	virtual void Print( FILE* cfile, int depth ) const;
-
-	/*	Attribtue parsing starts: next char past '<'
-						 returns: next char past '>'
-	*/
-	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
-
-	virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-	virtual TiXmlElement*           ToElement()	          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-
-	/** Walk the XML tree visiting this node and all of its children. 
-	*/
-	virtual bool Accept( TiXmlVisitor* visitor ) const;
-
-protected:
-
-	void CopyTo( TiXmlElement* target ) const;
-	void ClearThis();	// like clear, but initializes 'this' object as well
-
-	// Used to be public [internal use]
-	#ifdef TIXML_USE_STL
-	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
-	#endif
-	/*	[internal use]
-		Reads the "value" of the element -- another element, or text.
-		This should terminate with the current end tag.
-	*/
-	const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
-
-private:
-
-	TiXmlAttributeSet attributeSet;
-};
-
-
-/**	An XML comment.
-*/
-class TiXmlComment : public TiXmlNode
-{
-public:
-	/// Constructs an empty comment.
-	TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
-	/// Construct a comment from text.
-	TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) {
-		SetValue( _value );
-	}
-	TiXmlComment( const TiXmlComment& );
-	void operator=( const TiXmlComment& base );
-
-	virtual ~TiXmlComment()	{}
-
-	/// Returns a copy of this Comment.
-	virtual TiXmlNode* Clone() const;
-	// Write this Comment to a FILE stream.
-	virtual void Print( FILE* cfile, int depth ) const;
-
-	/*	Attribtue parsing starts: at the ! of the !--
-						 returns: next char past '>'
-	*/
-	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
-
-	virtual const TiXmlComment*  ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-	virtual TiXmlComment*  ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-
-	/** Walk the XML tree visiting this node and all of its children. 
-	*/
-	virtual bool Accept( TiXmlVisitor* visitor ) const;
-
-protected:
-	void CopyTo( TiXmlComment* target ) const;
-
-	// used to be public
-	#ifdef TIXML_USE_STL
-	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
-	#endif
-//	virtual void StreamOut( TIXML_OSTREAM * out ) const;
-
-private:
-
-};
-
-
-/** XML text. A text node can have 2 ways to output the next. "normal" output 
-	and CDATA. It will default to the mode it was parsed from the XML file and
-	you generally want to leave it alone, but you can change the output mode with 
-	SetCDATA() and query it with CDATA().
-*/
-class TiXmlText : public TiXmlNode
-{
-	friend class TiXmlElement;
-public:
-	/** Constructor for text element. By default, it is treated as 
-		normal, encoded text. If you want it be output as a CDATA text
-		element, set the parameter _cdata to 'true'
-	*/
-	TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
-	{
-		SetValue( initValue );
-		cdata = false;
-	}
-	virtual ~TiXmlText() {}
-
-	#ifdef TIXML_USE_STL
-	/// Constructor.
-	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
-	{
-		SetValue( initValue );
-		cdata = false;
-	}
-	#endif
-
-	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )	{ copy.CopyTo( this ); }
-	void operator=( const TiXmlText& base )							 	{ base.CopyTo( this ); }
-
-	// Write this text object to a FILE stream.
-	virtual void Print( FILE* cfile, int depth ) const;
-
-	/// Queries whether this represents text using a CDATA section.
-	bool CDATA() const				{ return cdata; }
-	/// Turns on or off a CDATA representation of text.
-	void SetCDATA( bool _cdata )	{ cdata = _cdata; }
-
-	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
-
-	virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-	virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-
-	/** Walk the XML tree visiting this node and all of its children. 
-	*/
-	virtual bool Accept( TiXmlVisitor* content ) const;
-
-protected :
-	///  [internal use] Creates a new Element and returns it.
-	virtual TiXmlNode* Clone() const;
-	void CopyTo( TiXmlText* target ) const;
-
-	bool Blank() const;	// returns true if all white space and new lines
-	// [internal use]
-	#ifdef TIXML_USE_STL
-	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
-	#endif
-
-private:
-	bool cdata;			// true if this should be input and output as a CDATA style text element
-};
-
-
-/** In correct XML the declaration is the first entry in the file.
-	@verbatim
-		<?xml version="1.0" standalone="yes"?>
-	@endverbatim
-
-	TinyXml will happily read or write files without a declaration,
-	however. There are 3 possible attributes to the declaration:
-	version, encoding, and standalone.
-
-	Note: In this version of the code, the attributes are
-	handled as special cases, not generic attributes, simply
-	because there can only be at most 3 and they are always the same.
-*/
-class TiXmlDeclaration : public TiXmlNode
-{
-public:
-	/// Construct an empty declaration.
-	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
-
-#ifdef TIXML_USE_STL
-	/// Constructor.
-	TiXmlDeclaration(	const std::string& _version,
-						const std::string& _encoding,
-						const std::string& _standalone );
-#endif
-
-	/// Construct.
-	TiXmlDeclaration(	const char* _version,
-						const char* _encoding,
-						const char* _standalone );
-
-	TiXmlDeclaration( const TiXmlDeclaration& copy );
-	void operator=( const TiXmlDeclaration& copy );
-
-	virtual ~TiXmlDeclaration()	{}
-
-	/// Version. Will return an empty string if none was found.
-	const char *Version() const			{ return version.c_str (); }
-	/// Encoding. Will return an empty string if none was found.
-	const char *Encoding() const		{ return encoding.c_str (); }
-	/// Is this a standalone document?
-	const char *Standalone() const		{ return standalone.c_str (); }
-
-	/// Creates a copy of this Declaration and returns it.
-	virtual TiXmlNode* Clone() const;
-	// Print this declaration to a FILE stream.
-	virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
-	virtual void Print( FILE* cfile, int depth ) const {
-		Print( cfile, depth, 0 );
-	}
-
-	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
-
-	virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-	virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-
-	/** Walk the XML tree visiting this node and all of its children. 
-	*/
-	virtual bool Accept( TiXmlVisitor* visitor ) const;
-
-protected:
-	void CopyTo( TiXmlDeclaration* target ) const;
-	// used to be public
-	#ifdef TIXML_USE_STL
-	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
-	#endif
-
-private:
-
-	TIXML_STRING version;
-	TIXML_STRING encoding;
-	TIXML_STRING standalone;
-};
-
-
-/** Any tag that tinyXml doesn't recognize is saved as an
-	unknown. It is a tag of text, but should not be modified.
-	It will be written back to the XML, unchanged, when the file
-	is saved.
-
-	DTD tags get thrown into TiXmlUnknowns.
-*/
-class TiXmlUnknown : public TiXmlNode
-{
-public:
-	TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )	{}
-	virtual ~TiXmlUnknown() {}
-
-	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )		{ copy.CopyTo( this ); }
-	void operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( this ); }
-
-	/// Creates a copy of this Unknown and returns it.
-	virtual TiXmlNode* Clone() const;
-	// Print this Unknown to a FILE stream.
-	virtual void Print( FILE* cfile, int depth ) const;
-
-	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
-
-	virtual const TiXmlUnknown*     ToUnknown()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-	virtual TiXmlUnknown*           ToUnknown()	    { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-
-	/** Walk the XML tree visiting this node and all of its children. 
-	*/
-	virtual bool Accept( TiXmlVisitor* content ) const;
-
-protected:
-	void CopyTo( TiXmlUnknown* target ) const;
-
-	#ifdef TIXML_USE_STL
-	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
-	#endif
-
-private:
-
-};
-
-
-/** Always the top level node. A document binds together all the
-	XML pieces. It can be saved, loaded, and printed to the screen.
-	The 'value' of a document node is the xml file name.
-*/
-class TiXmlDocument : public TiXmlNode
-{
-public:
-	/// Create an empty document, that has no name.
-	TiXmlDocument();
-	/// Create a document with a name. The name of the document is also the filename of the xml.
-	TiXmlDocument( const char * documentName );
-
-	#ifdef TIXML_USE_STL
-	/// Constructor.
-	TiXmlDocument( const std::string& documentName );
-	#endif
-
-	TiXmlDocument( const TiXmlDocument& copy );
-	void operator=( const TiXmlDocument& copy );
-
-	virtual ~TiXmlDocument() {}
-
-	/** Load a file using the current document value.
-		Returns true if successful. Will delete any existing
-		document data before loading.
-	*/
-	bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
-	/// Save a file using the current document value. Returns true if successful.
-	bool SaveFile() const;
-	/// Load a file using the given filename. Returns true if successful.
-	bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
-	/// Save a file using the given filename. Returns true if successful.
-	bool SaveFile( const char * filename ) const;
-	/** Load a file using the given FILE*. Returns true if successful. Note that this method
-		doesn't stream - the entire object pointed at by the FILE*
-		will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
-		file location. Streaming may be added in the future.
-	*/
-	bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
-	/// Save a file using the given FILE*. Returns true if successful.
-	bool SaveFile( FILE* ) const;
-
-	#ifdef TIXML_USE_STL
-	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
-	{
-//		StringToBuffer f( filename );
-//		return ( f.buffer && LoadFile( f.buffer, encoding ));
-		return LoadFile( filename.c_str(), encoding );
-	}
-	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
-	{
-//		StringToBuffer f( filename );
-//		return ( f.buffer && SaveFile( f.buffer ));
-		return SaveFile( filename.c_str() );
-	}
-	#endif
-
-	/** Parse the given null terminated block of xml data. Passing in an encoding to this
-		method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
-		to use that encoding, regardless of what TinyXml might otherwise try to detect.
-	*/
-	virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
-
-	/** Get the root element -- the only top level element -- of the document.
-		In well formed XML, there should only be one. TinyXml is tolerant of
-		multiple elements at the document level.
-	*/
-	const TiXmlElement* RootElement() const		{ return FirstChildElement(); }
-	TiXmlElement* RootElement()					{ return FirstChildElement(); }
-
-	/** If an error occurs, Error will be set to true. Also,
-		- The ErrorId() will contain the integer identifier of the error (not generally useful)
-		- The ErrorDesc() method will return the name of the error. (very useful)
-		- The ErrorRow() and ErrorCol() will return the location of the error (if known)
-	*/	
-	bool Error() const						{ return error; }
-
-	/// Contains a textual (english) description of the error if one occurs.
-	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
-
-	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
-		prefer the ErrorId, this function will fetch it.
-	*/
-	int ErrorId()	const				{ return errorId; }
-
-	/** Returns the location (if known) of the error. The first column is column 1, 
-		and the first row is row 1. A value of 0 means the row and column wasn't applicable
-		(memory errors, for example, have no row/column) or the parser lost the error. (An
-		error in the error reporting, in that case.)
-
-		@sa SetTabSize, Row, Column
-	*/
-	int ErrorRow()	{ return errorLocation.row+1; }
-	int ErrorCol()	{ return errorLocation.col+1; }	///< The column where the error occured. See ErrorRow()
-
-	/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
-		to report the correct values for row and column. It does not change the output
-		or input in any way.
-		
-		By calling this method, with a tab size
-		greater than 0, the row and column of each node and attribute is stored
-		when the file is loaded. Very useful for tracking the DOM back in to
-		the source file.
-
-		The tab size is required for calculating the location of nodes. If not
-		set, the default of 4 is used. The tabsize is set per document. Setting
-		the tabsize to 0 disables row/column tracking.
-
-		Note that row and column tracking is not supported when using operator>>.
-
-		The tab size needs to be enabled before the parse or load. Correct usage:
-		@verbatim
-		TiXmlDocument doc;
-		doc.SetTabSize( 8 );
-		doc.Load( "myfile.xml" );
-		@endverbatim
-
-		@sa Row, Column
-	*/
-	void SetTabSize( int _tabsize )		{ tabsize = _tabsize; }
-
-	int TabSize() const	{ return tabsize; }
-
-	/** If you have handled the error, it can be reset with this call. The error
-		state is automatically cleared if you Parse a new XML block.
-	*/
-	void ClearError()						{	error = false; 
-												errorId = 0; 
-												errorDesc = ""; 
-												errorLocation.row = errorLocation.col = 0; 
-												//errorLocation.last = 0; 
-											}
-
-	/** Write the document to standard out using formatted printing ("pretty print"). */
-	void Print() const						{ Print( stdout, 0 ); }
-
-	/* Write the document to a string using formatted printing ("pretty print"). This
-		will allocate a character array (new char[]) and return it as a pointer. The
-		calling code pust call delete[] on the return char* to avoid a memory leak.
-	*/
-	//char* PrintToMemory() const; 
-
-	/// Print this Document to a FILE stream.
-	virtual void Print( FILE* cfile, int depth = 0 ) const;
-	// [internal use]
-	void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
-
-	virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-	virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
-
-	/** Walk the XML tree visiting this node and all of its children. 
-	*/
-	virtual bool Accept( TiXmlVisitor* content ) const;
-
-protected :
-	// [internal use]
-	virtual TiXmlNode* Clone() const;
-	#ifdef TIXML_USE_STL
-	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
-	#endif
-
-private:
-	void CopyTo( TiXmlDocument* target ) const;
-
-	bool error;
-	int  errorId;
-	TIXML_STRING errorDesc;
-	int tabsize;
-	TiXmlCursor errorLocation;
-	bool useMicrosoftBOM;		// the UTF-8 BOM were found when read. Note this, and try to write.
-};
-
-
-/**
-	A TiXmlHandle is a class that wraps a node pointer with null checks; this is
-	an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
-	DOM structure. It is a separate utility class.
-
-	Take an example:
-	@verbatim
-	<Document>
-		<Element attributeA = "valueA">
-			<Child attributeB = "value1" />
-			<Child attributeB = "value2" />
-		</Element>
-	<Document>
-	@endverbatim
-
-	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
-	easy to write a *lot* of code that looks like:
-
-	@verbatim
-	TiXmlElement* root = document.FirstChildElement( "Document" );
-	if ( root )
-	{
-		TiXmlElement* element = root->FirstChildElement( "Element" );
-		if ( element )
-		{
-			TiXmlElement* child = element->FirstChildElement( "Child" );
-			if ( child )
-			{
-				TiXmlElement* child2 = child->NextSiblingElement( "Child" );
-				if ( child2 )
-				{
-					// Finally do something useful.
-	@endverbatim
-
-	And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
-	of such code. A TiXmlHandle checks for null	pointers so it is perfectly safe 
-	and correct to use:
-
-	@verbatim
-	TiXmlHandle docHandle( &document );
-	TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
-	if ( child2 )
-	{
-		// do something useful
-	@endverbatim
-
-	Which is MUCH more concise and useful.
-
-	It is also safe to copy handles - internally they are nothing more than node pointers.
-	@verbatim
-	TiXmlHandle handleCopy = handle;
-	@endverbatim
-
-	What they should not be used for is iteration:
-
-	@verbatim
-	int i=0; 
-	while ( true )
-	{
-		TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
-		if ( !child )
-			break;
-		// do something
-		++i;
-	}
-	@endverbatim
-
-	It seems reasonable, but it is in fact two embedded while loops. The Child method is 
-	a linear walk to find the element, so this code would iterate much more than it needs 
-	to. Instead, prefer:
-
-	@verbatim
-	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
-
-	for( child; child; child=child->NextSiblingElement() )
-	{
-		// do something
-	}
-	@endverbatim
-*/
-class TiXmlHandle
-{
-public:
-	/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
-	TiXmlHandle( TiXmlNode* _node )					{ this->node = _node; }
-	/// Copy constructor
-	TiXmlHandle( const TiXmlHandle& ref )			{ this->node = ref.node; }
-	TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
-
-	/// Return a handle to the first child node.
-	TiXmlHandle FirstChild() const;
-	/// Return a handle to the first child node with the given name.
-	TiXmlHandle FirstChild( const char * value ) const;
-	/// Return a handle to the first child element.
-	TiXmlHandle FirstChildElement() const;
-	/// Return a handle to the first child element with the given name.
-	TiXmlHandle FirstChildElement( const char * value ) const;
-
-	/** Return a handle to the "index" child with the given name. 
-		The first child is 0, the second 1, etc.
-	*/
-	TiXmlHandle Child( const char* value, int index ) const;
-	/** Return a handle to the "index" child. 
-		The first child is 0, the second 1, etc.
-	*/
-	TiXmlHandle Child( int index ) const;
-	/** Return a handle to the "index" child element with the given name. 
-		The first child element is 0, the second 1, etc. Note that only TiXmlElements
-		are indexed: other types are not counted.
-	*/
-	TiXmlHandle ChildElement( const char* value, int index ) const;
-	/** Return a handle to the "index" child element. 
-		The first child element is 0, the second 1, etc. Note that only TiXmlElements
-		are indexed: other types are not counted.
-	*/
-	TiXmlHandle ChildElement( int index ) const;
-
-	#ifdef TIXML_USE_STL
-	TiXmlHandle FirstChild( const std::string& _value ) const				{ return FirstChild( _value.c_str() ); }
-	TiXmlHandle FirstChildElement( const std::string& _value ) const		{ return FirstChildElement( _value.c_str() ); }
-
-	TiXmlHandle Child( const std::string& _value, int index ) const			{ return Child( _value.c_str(), index ); }
-	TiXmlHandle ChildElement( const std::string& _value, int index ) const	{ return ChildElement( _value.c_str(), index ); }
-	#endif
-
-	/** Return the handle as a TiXmlNode. This may return null.
-	*/
-	TiXmlNode* ToNode() const			{ return node; } 
-	/** Return the handle as a TiXmlElement. This may return null.
-	*/
-	TiXmlElement* ToElement() const		{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
-	/**	Return the handle as a TiXmlText. This may return null.
-	*/
-	TiXmlText* ToText() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
-	/** Return the handle as a TiXmlUnknown. This may return null.
-	*/
-	TiXmlUnknown* ToUnknown() const		{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
-
-	/** @deprecated use ToNode. 
-		Return the handle as a TiXmlNode. This may return null.
-	*/
-	TiXmlNode* Node() const			{ return ToNode(); } 
-	/** @deprecated use ToElement. 
-		Return the handle as a TiXmlElement. This may return null.
-	*/
-	TiXmlElement* Element() const	{ return ToElement(); }
-	/**	@deprecated use ToText()
-		Return the handle as a TiXmlText. This may return null.
-	*/
-	TiXmlText* Text() const			{ return ToText(); }
-	/** @deprecated use ToUnknown()
-		Return the handle as a TiXmlUnknown. This may return null.
-	*/
-	TiXmlUnknown* Unknown() const	{ return ToUnknown(); }
-
-private:
-	TiXmlNode* node;
-};
-
-
-/** Print to memory functionality. The TiXmlPrinter is useful when you need to:
-
-	-# Print to memory (especially in non-STL mode)
-	-# Control formatting (line endings, etc.)
-
-	When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
-	Before calling Accept() you can call methods to control the printing
-	of the XML document. After TiXmlNode::Accept() is called, the printed document can
-	be accessed via the CStr(), Str(), and Size() methods.
-
-	TiXmlPrinter uses the Visitor API.
-	@verbatim
-	TiXmlPrinter printer;
-	printer.SetIndent( "\t" );
-
-	doc.Accept( &printer );
-	fprintf( stdout, "%s", printer.CStr() );
-	@endverbatim
-*/
-class TiXmlPrinter : public TiXmlVisitor
-{
-public:
-	TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
-					 buffer(), indent( "    " ), lineBreak( "\n" ) {}
-
-	virtual bool VisitEnter( const TiXmlDocument& doc );
-	virtual bool VisitExit( const TiXmlDocument& doc );
-
-	virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
-	virtual bool VisitExit( const TiXmlElement& element );
-
-	virtual bool Visit( const TiXmlDeclaration& declaration );
-	virtual bool Visit( const TiXmlText& text );
-	virtual bool Visit( const TiXmlComment& comment );
-	virtual bool Visit( const TiXmlUnknown& unknown );
-
-	/** Set the indent characters for printing. By default 4 spaces
-		but tab (\t) is also useful, or null/empty string for no indentation.
-	*/
-	void SetIndent( const char* _indent )			{ indent = _indent ? _indent : "" ; }
-	/// Query the indention string.
-	const char* Indent()							{ return indent.c_str(); }
-	/** Set the line breaking string. By default set to newline (\n). 
-		Some operating systems prefer other characters, or can be
-		set to the null/empty string for no indenation.
-	*/
-	void SetLineBreak( const char* _lineBreak )		{ lineBreak = _lineBreak ? _lineBreak : ""; }
-	/// Query the current line breaking string.
-	const char* LineBreak()							{ return lineBreak.c_str(); }
-
-	/** Switch over to "stream printing" which is the most dense formatting without 
-		linebreaks. Common when the XML is needed for network transmission.
-	*/
-	void SetStreamPrinting()						{ indent = "";
-													  lineBreak = "";
-													}	
-	/// Return the result.
-	const char* CStr()								{ return buffer.c_str(); }
-	/// Return the length of the result string.
-	size_t Size()									{ return buffer.size(); }
-
-	#ifdef TIXML_USE_STL
-	/// Return the result.
-	const std::string& Str()						{ return buffer; }
-	#endif
-
-private:
-	void DoIndent()	{
-		for( int i=0; i<depth; ++i )
-			buffer += indent;
-	}
-	void DoLineBreak() {
-		buffer += lineBreak;
-	}
-
-	int depth;
-	bool simpleTextPrint;
-	TIXML_STRING buffer;
-	TIXML_STRING indent;
-	TIXML_STRING lineBreak;
-};
-
-
-#ifdef _MSC_VER
-#pragma warning( pop )
-#endif
-
-#endif
-

+ 0 - 53
tinyxml/tinyxmlerror.cpp

@@ -1,53 +0,0 @@
-/*
-www.sourceforge.net/projects/tinyxml
-Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
-
-This software is provided 'as-is', without any express or implied 
-warranty. In no event will the authors be held liable for any 
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any 
-purpose, including commercial applications, and to alter it and 
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must
-not claim that you wrote the original software. If you use this
-software in a product, an acknowledgment in the product documentation
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-*/
-
-#include "tinyxml.h"
-
-// The goal of the seperate error file is to make the first
-// step towards localization. tinyxml (currently) only supports
-// english error messages, but the could now be translated.
-//
-// It also cleans up the code a bit.
-//
-
-const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
-{
-	"No error",
-	"Error",
-	"Failed to open file",
-	"Memory allocation failed.",
-	"Error parsing Element.",
-	"Failed to read Element name",
-	"Error reading Element value.",
-	"Error reading Attributes.",
-	"Error: empty tag.",
-	"Error reading end tag.",
-	"Error parsing Unknown.",
-	"Error parsing Comment.",
-	"Error parsing Declaration.",
-	"Error document empty.",
-	"Error null (0) or unexpected EOF found in input stream.",
-	"Error parsing CDATA.",
-	"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
-};

+ 0 - 1606
tinyxml/tinyxmlparser.cpp

@@ -1,1606 +0,0 @@
-/*
-www.sourceforge.net/projects/tinyxml
-Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
-
-This software is provided 'as-is', without any express or implied 
-warranty. In no event will the authors be held liable for any 
-damages arising from the use of this software.
-
-Permission is granted to anyone to use this software for any 
-purpose, including commercial applications, and to alter it and 
-redistribute it freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must 
-not claim that you wrote the original software. If you use this
-software in a product, an acknowledgment in the product documentation
-would be appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and 
-must not be misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source 
-distribution.
-*/
-
-#include <ctype.h>
-#include <stddef.h>
-
-#include "tinyxml.h"
-
-//#define DEBUG_PARSER
-#if defined( DEBUG_PARSER )
-#	if defined( DEBUG ) && defined( _MSC_VER )
-#		include <windows.h>
-#		define TIXML_LOG OutputDebugString
-#	else
-#		define TIXML_LOG printf
-#	endif
-#endif
-
-// Note tha "PutString" hardcodes the same list. This
-// is less flexible than it appears. Changing the entries
-// or order will break putstring.	
-TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = 
-{
-	{ "&amp;",  5, '&' },
-	{ "&lt;",   4, '<' },
-	{ "&gt;",   4, '>' },
-	{ "&quot;", 6, '\"' },
-	{ "&apos;", 6, '\'' }
-};
-
-// Bunch of unicode info at:
-//		http://www.unicode.org/faq/utf_bom.html
-// Including the basic of this table, which determines the #bytes in the
-// sequence from the lead byte. 1 placed for invalid sequences --
-// although the result will be junk, pass it through as much as possible.
-// Beware of the non-characters in UTF-8:	
-//				ef bb bf (Microsoft "lead bytes")
-//				ef bf be
-//				ef bf bf 
-
-const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
-const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
-const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
-
-const int TiXmlBase::utf8ByteTable[256] = 
-{
-	//	0	1	2	3	4	5	6	7	8	9	a	b	c	d	e	f
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x00
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x10
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x20
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x30
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x40
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x50
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x60
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x70	End of ASCII range
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x80 0x80 to 0xc1 invalid
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x90 
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xa0 
-		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xb0 
-		1,	1,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xc0 0xc2 to 0xdf 2 byte
-		2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xd0
-		3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	// 0xe0 0xe0 to 0xef 3 byte
-		4,	4,	4,	4,	4,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1	// 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
-};
-
-
-void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
-{
-	const unsigned long BYTE_MASK = 0xBF;
-	const unsigned long BYTE_MARK = 0x80;
-	const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
-
-	if (input < 0x80) 
-		*length = 1;
-	else if ( input < 0x800 )
-		*length = 2;
-	else if ( input < 0x10000 )
-		*length = 3;
-	else if ( input < 0x200000 )
-		*length = 4;
-	else
-		{ *length = 0; return; }	// This code won't covert this correctly anyway.
-
-	output += *length;
-
-	// Scary scary fall throughs.
-	switch (*length) 
-	{
-		case 4:
-			--output; 
-			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
-			input >>= 6;
-		case 3:
-			--output; 
-			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
-			input >>= 6;
-		case 2:
-			--output; 
-			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
-			input >>= 6;
-		case 1:
-			--output; 
-			*output = (char)(input | FIRST_BYTE_MARK[*length]);
-	}
-}
-
-
-/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
-{
-	// This will only work for low-ascii, everything else is assumed to be a valid
-	// letter. I'm not sure this is the best approach, but it is quite tricky trying
-	// to figure out alhabetical vs. not across encoding. So take a very 
-	// conservative approach.
-
-//	if ( encoding == TIXML_ENCODING_UTF8 )
-//	{
-		if ( anyByte < 127 )
-			return isalpha( anyByte );
-		else
-			return 1;	// What else to do? The unicode set is huge...get the english ones right.
-//	}
-//	else
-//	{
-//		return isalpha( anyByte );
-//	}
-}
-
-
-/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
-{
-	// This will only work for low-ascii, everything else is assumed to be a valid
-	// letter. I'm not sure this is the best approach, but it is quite tricky trying
-	// to figure out alhabetical vs. not across encoding. So take a very 
-	// conservative approach.
-
-//	if ( encoding == TIXML_ENCODING_UTF8 )
-//	{
-		if ( anyByte < 127 )
-			return isalnum( anyByte );
-		else
-			return 1;	// What else to do? The unicode set is huge...get the english ones right.
-//	}
-//	else
-//	{
-//		return isalnum( anyByte );
-//	}
-}
-
-
-class TiXmlParsingData
-{
-	friend class TiXmlDocument;
-  public:
-	void Stamp( const char* now, TiXmlEncoding encoding );
-
-	const TiXmlCursor& Cursor()	{ return cursor; }
-
-  private:
-	// Only used by the document!
-	TiXmlParsingData( const char* start, int _tabsize, int row, int col )
-	{
-		assert( start );
-		stamp = start;
-		tabsize = _tabsize;
-		cursor.row = row;
-		cursor.col = col;
-	}
-
-	TiXmlCursor		cursor;
-	const char*		stamp;
-	int				tabsize;
-};
-
-
-void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
-{
-	assert( now );
-
-	// Do nothing if the tabsize is 0.
-	if ( tabsize < 1 )
-	{
-		return;
-	}
-
-	// Get the current row, column.
-	int row = cursor.row;
-	int col = cursor.col;
-	const char* p = stamp;
-	assert( p );
-
-	while ( p < now )
-	{
-		// Treat p as unsigned, so we have a happy compiler.
-		const unsigned char* pU = (const unsigned char*)p;
-
-		// Code contributed by Fletcher Dunn: (modified by lee)
-		switch (*pU) {
-			case 0:
-				// We *should* never get here, but in case we do, don't
-				// advance past the terminating null character, ever
-				return;
-
-			case '\r':
-				// bump down to the next line
-				++row;
-				col = 0;				
-				// Eat the character
-				++p;
-
-				// Check for \r\n sequence, and treat this as a single character
-				if (*p == '\n') {
-					++p;
-				}
-				break;
-
-			case '\n':
-				// bump down to the next line
-				++row;
-				col = 0;
-
-				// Eat the character
-				++p;
-
-				// Check for \n\r sequence, and treat this as a single
-				// character.  (Yes, this bizarre thing does occur still
-				// on some arcane platforms...)
-				if (*p == '\r') {
-					++p;
-				}
-				break;
-
-			case '\t':
-				// Eat the character
-				++p;
-
-				// Skip to next tab stop
-				col = (col / tabsize + 1) * tabsize;
-				break;
-
-			case TIXML_UTF_LEAD_0:
-				if ( encoding == TIXML_ENCODING_UTF8 )
-				{
-					if ( *(p+1) && *(p+2) )
-					{
-						// In these cases, don't advance the column. These are
-						// 0-width spaces.
-						if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
-							p += 3;	
-						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
-							p += 3;	
-						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
-							p += 3;	
-						else
-							{ p +=3; ++col; }	// A normal character.
-					}
-				}
-				else
-				{
-					++p;
-					++col;
-				}
-				break;
-
-			default:
-				if ( encoding == TIXML_ENCODING_UTF8 )
-				{
-					// Eat the 1 to 4 byte utf8 character.
-					int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
-					if ( step == 0 )
-						step = 1;		// Error case from bad encoding, but handle gracefully.
-					p += step;
-
-					// Just advance one column, of course.
-					++col;
-				}
-				else
-				{
-					++p;
-					++col;
-				}
-				break;
-		}
-	}
-	cursor.row = row;
-	cursor.col = col;
-	assert( cursor.row >= -1 );
-	assert( cursor.col >= -1 );
-	stamp = p;
-	assert( stamp );
-}
-
-
-const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
-{
-	if ( !p || !*p )
-	{
-		return 0;
-	}
-	if ( encoding == TIXML_ENCODING_UTF8 )
-	{
-		while ( *p )
-		{
-			const unsigned char* pU = (const unsigned char*)p;
-			
-			// Skip the stupid Microsoft UTF-8 Byte order marks
-			if (	*(pU+0)==TIXML_UTF_LEAD_0
-				 && *(pU+1)==TIXML_UTF_LEAD_1 
-				 && *(pU+2)==TIXML_UTF_LEAD_2 )
-			{
-				p += 3;
-				continue;
-			}
-			else if(*(pU+0)==TIXML_UTF_LEAD_0
-				 && *(pU+1)==0xbfU
-				 && *(pU+2)==0xbeU )
-			{
-				p += 3;
-				continue;
-			}
-			else if(*(pU+0)==TIXML_UTF_LEAD_0
-				 && *(pU+1)==0xbfU
-				 && *(pU+2)==0xbfU )
-			{
-				p += 3;
-				continue;
-			}
-
-			if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )		// Still using old rules for white space.
-				++p;
-			else
-				break;
-		}
-	}
-	else
-	{
-		while ( *p && (IsWhiteSpace( *p ) || (*p == '\n') || (*p =='\r')))
-			++p;
-	}
-
-	return p;
-}
-
-#ifdef TIXML_USE_STL
-/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
-{
-	for( ;; )
-	{
-		if ( !in->good() ) return false;
-
-		int c = in->peek();
-		// At this scope, we can't get to a document. So fail silently.
-		if ( !IsWhiteSpace( c ) || c <= 0 )
-			return true;
-
-		*tag += (char) in->get();
-	}
-}
-
-/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
-{
-	//assert( character > 0 && character < 128 );	// else it won't work in utf-8
-	while ( in->good() )
-	{
-		int c = in->peek();
-		if ( c == character )
-			return true;
-		if ( c <= 0 )		// Silent failure: can't get document at this scope
-			return false;
-
-		in->get();
-		*tag += (char) c;
-	}
-	return false;
-}
-#endif
-
-// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
-// "assign" optimization removes over 10% of the execution time.
-//
-const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
-{
-	// Oddly, not supported on some comilers,
-	//name->clear();
-	// So use this:
-	*name = "";
-	assert( p );
-
-	// Names start with letters or underscores.
-	// Of course, in unicode, tinyxml has no idea what a letter *is*. The
-	// algorithm is generous.
-	//
-	// After that, they can be letters, underscores, numbers,
-	// hyphens, or colons. (Colons are valid ony for namespaces,
-	// but tinyxml can't tell namespaces from names.)
-	if (    p && *p 
-		 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
-	{
-		const char* start = p;
-		while(		p && *p
-				&&	(		IsAlphaNum( (unsigned char ) *p, encoding ) 
-						 || *p == '_'
-						 || *p == '-'
-						 || *p == '.'
-						 || *p == ':' ) )
-		{
-			//(*name) += *p; // expensive
-			++p;
-		}
-		if ( p-start > 0 ) {
-			name->assign( start, p-start );
-		}
-		return p;
-	}
-	return 0;
-}
-
-const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
-{
-	// Presume an entity, and pull it out.
-    TIXML_STRING ent;
-	int i;
-	*length = 0;
-
-	if ( *(p+1) && *(p+1) == '#' && *(p+2) )
-	{
-		unsigned long ucs = 0;
-		ptrdiff_t delta = 0;
-		unsigned mult = 1;
-
-		if ( *(p+2) == 'x' )
-		{
-			// Hexadecimal.
-			if ( !*(p+3) ) return 0;
-
-			const char* q = p+3;
-			q = strchr( q, ';' );
-
-			if ( !q || !*q ) return 0;
-
-			delta = q-p;
-			--q;
-
-			while ( *q != 'x' )
-			{
-				if ( *q >= '0' && *q <= '9' )
-					ucs += mult * (*q - '0');
-				else if ( *q >= 'a' && *q <= 'f' )
-					ucs += mult * (*q - 'a' + 10);
-				else if ( *q >= 'A' && *q <= 'F' )
-					ucs += mult * (*q - 'A' + 10 );
-				else 
-					return 0;
-				mult *= 16;
-				--q;
-			}
-		}
-		else
-		{
-			// Decimal.
-			if ( !*(p+2) ) return 0;
-
-			const char* q = p+2;
-			q = strchr( q, ';' );
-
-			if ( !q || !*q ) return 0;
-
-			delta = q-p;
-			--q;
-
-			while ( *q != '#' )
-			{
-				if ( *q >= '0' && *q <= '9' )
-					ucs += mult * (*q - '0');
-				else 
-					return 0;
-				mult *= 10;
-				--q;
-			}
-		}
-		if ( encoding == TIXML_ENCODING_UTF8 )
-		{
-			// convert the UCS to UTF-8
-			ConvertUTF32ToUTF8( ucs, value, length );
-		}
-		else
-		{
-			*value = (char)ucs;
-			*length = 1;
-		}
-		return p + delta + 1;
-	}
-
-	// Now try to match it.
-	for( i=0; i<NUM_ENTITY; ++i )
-	{
-		if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
-		{
-			assert( strlen( entity[i].str ) == entity[i].strLength );
-			*value = entity[i].chr;
-			*length = 1;
-			return ( p + entity[i].strLength );
-		}
-	}
-
-	// So it wasn't an entity, its unrecognized, or something like that.
-	*value = *p;	// Don't put back the last one, since we return it!
-	//*length = 1;	// Leave unrecognized entities - this doesn't really work.
-					// Just writes strange XML.
-	return p+1;
-}
-
-
-bool TiXmlBase::StringEqual( const char* p,
-							 const char* tag,
-							 bool ignoreCase,
-							 TiXmlEncoding encoding )
-{
-	assert( p );
-	assert( tag );
-	if ( !p || !*p )
-	{
-		assert( 0 );
-		return false;
-	}
-
-	const char* q = p;
-
-	if ( ignoreCase )
-	{
-		while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
-		{
-			++q;
-			++tag;
-		}
-
-		if ( *tag == 0 )
-			return true;
-	}
-	else
-	{
-		while ( *q && *tag && *q == *tag )
-		{
-			++q;
-			++tag;
-		}
-
-		if ( *tag == 0 )		// Have we found the end of the tag, and everything equal?
-			return true;
-	}
-	return false;
-}
-
-const char* TiXmlBase::ReadText(	const char* p, 
-									TIXML_STRING * text, 
-									bool trimWhiteSpace, 
-									const char* endTag, 
-									bool caseInsensitive,
-									TiXmlEncoding encoding )
-{
-    *text = "";
-	if (    !trimWhiteSpace			// certain tags always keep whitespace
-		 || !condenseWhiteSpace )	// if true, whitespace is always kept
-	{
-		// Keep all the white space.
-		while (	   p && *p
-				&& !StringEqual( p, endTag, caseInsensitive, encoding )
-			  )
-		{
-			int len;
-			char cArr[4] = { 0, 0, 0, 0 };
-			p = GetChar( p, cArr, &len, encoding );
-			text->append( cArr, len );
-		}
-	}
-	else
-	{
-		bool whitespace = false;
-
-		// Remove leading white space:
-		p = SkipWhiteSpace( p, encoding );
-		while (	   p && *p
-				&& !StringEqual( p, endTag, caseInsensitive, encoding ) )
-		{
-			if ( *p == '\r' || *p == '\n' )
-			{
-				whitespace = true;
-				++p;
-			}
-			else if ( IsWhiteSpace( *p ) )
-			{
-				whitespace = true;
-				++p;
-			}
-			else
-			{
-				// If we've found whitespace, add it before the
-				// new character. Any whitespace just becomes a space.
-				if ( whitespace )
-				{
-					(*text) += ' ';
-					whitespace = false;
-				}
-				int len;
-				char cArr[4] = { 0, 0, 0, 0 };
-				p = GetChar( p, cArr, &len, encoding );
-				if ( len == 1 )
-					(*text) += cArr[0];	// more efficient
-				else
-					text->append( cArr, len );
-			}
-		}
-	}
-	if ( p ) 
-		p += strlen( endTag );
-	return p;
-}
-
-#ifdef TIXML_USE_STL
-
-void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
-{
-	// The basic issue with a document is that we don't know what we're
-	// streaming. Read something presumed to be a tag (and hope), then
-	// identify it, and call the appropriate stream method on the tag.
-	//
-	// This "pre-streaming" will never read the closing ">" so the
-	// sub-tag can orient itself.
-
-	if ( !StreamTo( in, '<', tag ) ) 
-	{
-		SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return;
-	}
-
-	while ( in->good() )
-	{
-		int tagIndex = (int) tag->length();
-		while ( in->good() && in->peek() != '>' )
-		{
-			int c = in->get();
-			if ( c <= 0 )
-			{
-				SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
-				break;
-			}
-			(*tag) += (char) c;
-		}
-
-		if ( in->good() )
-		{
-			// We now have something we presume to be a node of 
-			// some sort. Identify it, and call the node to
-			// continue streaming.
-			TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
-
-			if ( node )
-			{
-				node->StreamIn( in, tag );
-				bool isElement = node->ToElement() != 0;
-				delete node;
-				node = 0;
-
-				// If this is the root element, we're done. Parsing will be
-				// done by the >> operator.
-				if ( isElement )
-				{
-					return;
-				}
-			}
-			else
-			{
-				SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
-				return;
-			}
-		}
-	}
-	// We should have returned sooner.
-	SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
-}
-
-#endif
-
-const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
-{
-	ClearError();
-
-	// Parse away, at the document level. Since a document
-	// contains nothing but other tags, most of what happens
-	// here is skipping white space.
-	if ( !p || !*p )
-	{
-		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return 0;
-	}
-
-	// Note that, for a document, this needs to come
-	// before the while space skip, so that parsing
-	// starts from the pointer we are given.
-	location.Clear();
-	if ( prevData )
-	{
-		location.row = prevData->cursor.row;
-		location.col = prevData->cursor.col;
-	}
-	else
-	{
-		location.row = 0;
-		location.col = 0;
-	}
-	TiXmlParsingData data( p, TabSize(), location.row, location.col );
-	location = data.Cursor();
-
-	if ( encoding == TIXML_ENCODING_UNKNOWN )
-	{
-		// Check for the Microsoft UTF-8 lead bytes.
-		const unsigned char* pU = (const unsigned char*)p;
-		if (	*(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
-			 && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
-			 && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
-		{
-			encoding = TIXML_ENCODING_UTF8;
-			useMicrosoftBOM = true;
-		}
-	}
-
-    p = SkipWhiteSpace( p, encoding );
-	if ( !p )
-	{
-		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
-		return 0;
-	}
-
-	while ( p && *p )
-	{
-		TiXmlNode* node = Identify( p, encoding );
-		if ( node )
-		{
-			p = node->Parse( p, &data, encoding );
-			LinkEndChild( node );
-		}
-		else
-		{
-			break;
-		}
-
-		// Did we get encoding info?
-		if (    encoding == TIXML_ENCODING_UNKNOWN
-			 && node->ToDeclaration() )
-		{
-			TiXmlDeclaration* dec = node->ToDeclaration();
-			const char* enc = dec->Encoding();
-			assert( enc );
-
-			if ( *enc == 0 )
-				encoding = TIXML_ENCODING_UTF8;
-			else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
-				encoding = TIXML_ENCODING_UTF8;
-			else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
-				encoding = TIXML_ENCODING_UTF8;	// incorrect, but be nice
-			else 
-				encoding = TIXML_ENCODING_LEGACY;
-		}
-
-		p = SkipWhiteSpace( p, encoding );
-	}
-
-	// Was this empty?
-	if ( !firstChild ) {
-		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
-		return 0;
-	}
-
-	// All is well.
-	return p;
-}
-
-void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
-{	
-	// The first error in a chain is more accurate - don't set again!
-	if ( error )
-		return;
-
-	assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
-	error   = true;
-	errorId = err;
-	errorDesc = errorString[ errorId ];
-
-	errorLocation.Clear();
-	if ( pError && data )
-	{
-		data->Stamp( pError, encoding );
-		errorLocation = data->Cursor();
-	}
-}
-
-
-TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
-{
-	TiXmlNode* returnNode = 0;
-
-	p = SkipWhiteSpace( p, encoding );
-	if( !p || !*p || *p != '<' )
-	{
-		return 0;
-	}
-
-	TiXmlDocument* doc = GetDocument();
-	p = SkipWhiteSpace( p, encoding );
-
-	if ( !p || !*p )
-	{
-		return 0;
-	}
-
-	// What is this thing? 
-	// - Elements start with a letter or underscore, but xml is reserved.
-	// - Comments: <!--
-	// - Decleration: <?xml
-	// - Everthing else is unknown to tinyxml.
-	//
-
-	const char* xmlHeader = { "<?xml" };
-	const char* commentHeader = { "<!--" };
-	const char* dtdHeader = { "<!" };
-	const char* cdataHeader = { "<![CDATA[" };
-
-	if ( StringEqual( p, xmlHeader, true, encoding ) )
-	{
-		#ifdef DEBUG_PARSER
-			TIXML_LOG( "XML parsing Declaration\n" );
-		#endif
-		returnNode = new TiXmlDeclaration();
-	}
-	else if ( StringEqual( p, commentHeader, false, encoding ) )
-	{
-		#ifdef DEBUG_PARSER
-			TIXML_LOG( "XML parsing Comment\n" );
-		#endif
-		returnNode = new TiXmlComment();
-	}
-	else if ( StringEqual( p, cdataHeader, false, encoding ) )
-	{
-		#ifdef DEBUG_PARSER
-			TIXML_LOG( "XML parsing CDATA\n" );
-		#endif
-		TiXmlText* text = new TiXmlText( "" );
-		text->SetCDATA( true );
-		returnNode = text;
-	}
-	else if ( StringEqual( p, dtdHeader, false, encoding ) )
-	{
-		#ifdef DEBUG_PARSER
-			TIXML_LOG( "XML parsing Unknown(1)\n" );
-		#endif
-		returnNode = new TiXmlUnknown();
-	}
-	else if (    IsAlpha( *(p+1), encoding )
-			  || *(p+1) == '_' )
-	{
-		#ifdef DEBUG_PARSER
-			TIXML_LOG( "XML parsing Element\n" );
-		#endif
-		returnNode = new TiXmlElement( "" );
-	}
-	else
-	{
-		#ifdef DEBUG_PARSER
-			TIXML_LOG( "XML parsing Unknown(2)\n" );
-		#endif
-		returnNode = new TiXmlUnknown();
-	}
-
-	if ( returnNode )
-	{
-		// Set the parent, so it can report errors
-		returnNode->parent = this;
-	}
-	else
-	{
-		if ( doc )
-			doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
-	}
-	return returnNode;
-}
-
-#ifdef TIXML_USE_STL
-
-void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
-{
-	// We're called with some amount of pre-parsing. That is, some of "this"
-	// element is in "tag". Go ahead and stream to the closing ">"
-	while( in->good() )
-	{
-		int c = in->get();
-		if ( c <= 0 )
-		{
-			TiXmlDocument* document = GetDocument();
-			if ( document )
-				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
-			return;
-		}
-		(*tag) += (char) c ;
-		
-		if ( c == '>' )
-			break;
-	}
-
-	if ( tag->length() < 3 ) return;
-
-	// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
-	// If not, identify and stream.
-
-	if (    tag->at( tag->length() - 1 ) == '>' 
-		 && tag->at( tag->length() - 2 ) == '/' )
-	{
-		// All good!
-		return;
-	}
-	else if ( tag->at( tag->length() - 1 ) == '>' )
-	{
-		// There is more. Could be:
-		//		text
-		//		cdata text (which looks like another node)
-		//		closing tag
-		//		another node.
-		for ( ;; )
-		{
-			StreamWhiteSpace( in, tag );
-
-			// Do we have text?
-			if ( in->good() && in->peek() != '<' ) 
-			{
-				// Yep, text.
-				TiXmlText text( "" );
-				text.StreamIn( in, tag );
-
-				// What follows text is a closing tag or another node.
-				// Go around again and figure it out.
-				continue;
-			}
-
-			// We now have either a closing tag...or another node.
-			// We should be at a "<", regardless.
-			if ( !in->good() ) return;
-			assert( in->peek() == '<' );
-			int tagIndex = (int) tag->length();
-
-			bool closingTag = false;
-			bool firstCharFound = false;
-
-			for( ;; )
-			{
-				if ( !in->good() )
-					return;
-
-				int c = in->peek();
-				if ( c <= 0 )
-				{
-					TiXmlDocument* document = GetDocument();
-					if ( document )
-						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
-					return;
-				}
-				
-				if ( c == '>' )
-					break;
-
-				*tag += (char) c;
-				in->get();
-
-				// Early out if we find the CDATA id.
-				if ( c == '[' && tag->size() >= 9 )
-				{
-					size_t len = tag->size();
-					const char* start = tag->c_str() + len - 9;
-					if ( strcmp( start, "<![CDATA[" ) == 0 ) {
-						assert( !closingTag );
-						break;
-					}
-				}
-
-				if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
-				{
-					firstCharFound = true;
-					if ( c == '/' )
-						closingTag = true;
-				}
-			}
-			// If it was a closing tag, then read in the closing '>' to clean up the input stream.
-			// If it was not, the streaming will be done by the tag.
-			if ( closingTag )
-			{
-				if ( !in->good() )
-					return;
-
-				int c = in->get();
-				if ( c <= 0 )
-				{
-					TiXmlDocument* document = GetDocument();
-					if ( document )
-						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
-					return;
-				}
-				assert( c == '>' );
-				*tag += (char) c;
-
-				// We are done, once we've found our closing tag.
-				return;
-			}
-			else
-			{
-				// If not a closing tag, id it, and stream.
-				const char* tagloc = tag->c_str() + tagIndex;
-				TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
-				if ( !node )
-					return;
-				node->StreamIn( in, tag );
-				delete node;
-				node = 0;
-
-				// No return: go around from the beginning: text, closing tag, or node.
-			}
-		}
-	}
-}
-#endif
-
-const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
-{
-	p = SkipWhiteSpace( p, encoding );
-	TiXmlDocument* document = GetDocument();
-
-	if ( !p || !*p )
-	{
-		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
-		return 0;
-	}
-
-	if ( data )
-	{
-		data->Stamp( p, encoding );
-		location = data->Cursor();
-	}
-
-	if ( *p != '<' )
-	{
-		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
-		return 0;
-	}
-
-	p = SkipWhiteSpace( p+1, encoding );
-
-	// Read the name.
-	const char* pErr = p;
-
-    p = ReadName( p, &value, encoding );
-	if ( !p || !*p )
-	{
-		if ( document )	document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
-		return 0;
-	}
-
-    TIXML_STRING endTag ("</");
-	endTag += value;
-	endTag += ">";
-
-	// Check for and read attributes. Also look for an empty
-	// tag or an end tag.
-	while ( p && *p )
-	{
-		pErr = p;
-		p = SkipWhiteSpace( p, encoding );
-		if ( !p || !*p )
-		{
-			if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
-			return 0;
-		}
-		if ( *p == '/' )
-		{
-			++p;
-			// Empty tag.
-			if ( *p  != '>' )
-			{
-				if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );		
-				return 0;
-			}
-			return (p+1);
-		}
-		else if ( *p == '>' )
-		{
-			// Done with attributes (if there were any.)
-			// Read the value -- which can include other
-			// elements -- read the end tag, and return.
-			++p;
-			p = ReadValue( p, data, encoding );		// Note this is an Element method, and will set the error if one happens.
-			if ( !p || !*p )
-				return 0;
-
-			// We should find the end tag now
-			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
-			{
-				p += endTag.length();
-				return p;
-			}
-			else
-			{
-				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
-				return 0;
-			}
-		}
-		else
-		{
-			// Try to read an attribute:
-			TiXmlAttribute* attrib = new TiXmlAttribute();
-			if ( !attrib )
-			{
-				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
-				return 0;
-			}
-
-			attrib->SetDocument( document );
-			pErr = p;
-			p = attrib->Parse( p, data, encoding );
-
-			if ( !p || !*p )
-			{
-				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
-				delete attrib;
-				return 0;
-			}
-
-			// Handle the strange case of double attributes:
-			#ifdef TIXML_USE_STL
-			TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() );
-			#else
-			TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
-			#endif
-			if ( node )
-			{
-				node->SetValue( attrib->Value() );
-				delete attrib;
-				return 0;
-			}
-
-			attributeSet.Add( attrib );
-		}
-	}
-	return p;
-}
-
-
-const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
-{
-	TiXmlDocument* document = GetDocument();
-
-	// Read in text and elements in any order.
-	const char* pWithWhiteSpace = p;
-	p = SkipWhiteSpace( p, encoding );
-
-	while ( p && *p )
-	{
-		if ( *p != '<' )
-		{
-			// Take what we have, make a text element.
-			TiXmlText* textNode = new TiXmlText( "" );
-
-			if ( !textNode )
-			{
-				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding );
-				    return 0;
-			}
-
-			if ( TiXmlBase::IsWhiteSpaceCondensed() )
-			{
-				p = textNode->Parse( p, data, encoding );
-			}
-			else
-			{
-				// Special case: we want to keep the white space
-				// so that leading spaces aren't removed.
-				p = textNode->Parse( pWithWhiteSpace, data, encoding );
-			}
-
-			if ( !textNode->Blank() )
-				LinkEndChild( textNode );
-			else
-				delete textNode;
-		} 
-		else 
-		{
-			// We hit a '<'
-			// Have we hit a new element or an end tag? This could also be
-			// a TiXmlText in the "CDATA" style.
-			if ( StringEqual( p, "</", false, encoding ) )
-			{
-				return p;
-			}
-			else
-			{
-				TiXmlNode* node = Identify( p, encoding );
-				if ( node )
-				{
-					p = node->Parse( p, data, encoding );
-					LinkEndChild( node );
-				}				
-				else
-				{
-					return 0;
-				}
-			}
-		}
-		pWithWhiteSpace = p;
-		p = SkipWhiteSpace( p, encoding );
-	}
-
-	if ( !p )
-	{
-		if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
-	}	
-	return p;
-}
-
-
-#ifdef TIXML_USE_STL
-void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
-{
-	while ( in->good() )
-	{
-		int c = in->get();	
-		if ( c <= 0 )
-		{
-			TiXmlDocument* document = GetDocument();
-			if ( document )
-				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
-			return;
-		}
-		(*tag) += (char) c;
-
-		if ( c == '>' )
-		{
-			// All is well.
-			return;		
-		}
-	}
-}
-#endif
-
-
-const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
-{
-	TiXmlDocument* document = GetDocument();
-	p = SkipWhiteSpace( p, encoding );
-
-	if ( data )
-	{
-		data->Stamp( p, encoding );
-		location = data->Cursor();
-	}
-	if ( !p || !*p || *p != '<' )
-	{
-		if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
-		return 0;
-	}
-	++p;
-    value = "";
-
-	while ( p && *p && *p != '>' )
-	{
-		value += *p;
-		++p;
-	}
-
-	if ( !p )
-	{
-		if ( document )	document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
-	}
-	if ( *p == '>' )
-		return p+1;
-	return p;
-}
-
-#ifdef TIXML_USE_STL
-void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
-{
-	while ( in->good() )
-	{
-		int c = in->get();	
-		if ( c <= 0 )
-		{
-			TiXmlDocument* document = GetDocument();
-			if ( document )
-				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
-			return;
-		}
-
-		(*tag) += (char) c;
-
-		if ( c == '>' 
-			 && tag->at( tag->length() - 2 ) == '-'
-			 && tag->at( tag->length() - 3 ) == '-' )
-		{
-			// All is well.
-			return;		
-		}
-	}
-}
-#endif
-
-
-const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
-{
-	TiXmlDocument* document = GetDocument();
-	value = "";
-
-	p = SkipWhiteSpace( p, encoding );
-
-	if ( data )
-	{
-		data->Stamp( p, encoding );
-		location = data->Cursor();
-	}
-	const char* startTag = "<!--";
-	const char* endTag   = "-->";
-
-	if ( !StringEqual( p, startTag, false, encoding ) )
-	{
-		document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
-		return 0;
-	}
-	p += strlen( startTag );
-	p = ReadText( p, &value, false, endTag, false, encoding );
-	return p;
-}
-
-
-const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
-{
-	p = SkipWhiteSpace( p, encoding );
-	if ( !p || !*p ) return 0;
-
-//	int tabsize = 4;
-//	if ( document )
-//		tabsize = document->TabSize();
-
-	if ( data )
-	{
-		data->Stamp( p, encoding );
-		location = data->Cursor();
-	}
-	// Read the name, the '=' and the value.
-	const char* pErr = p;
-	p = ReadName( p, &name, encoding );
-	if ( !p || !*p )
-	{
-		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
-		return 0;
-	}
-	p = SkipWhiteSpace( p, encoding );
-	if ( !p || !*p || *p != '=' )
-	{
-		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
-		return 0;
-	}
-
-	++p;	// skip '='
-	p = SkipWhiteSpace( p, encoding );
-	if ( !p || !*p )
-	{
-		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
-		return 0;
-	}
-	
-	const char* end;
-	const char SINGLE_QUOTE = '\'';
-	const char DOUBLE_QUOTE = '\"';
-
-	if ( *p == SINGLE_QUOTE )
-	{
-		++p;
-		end = "\'";		// single quote in string
-		p = ReadText( p, &value, false, end, false, encoding );
-	}
-	else if ( *p == DOUBLE_QUOTE )
-	{
-		++p;
-		end = "\"";		// double quote in string
-		p = ReadText( p, &value, false, end, false, encoding );
-	}
-	else
-	{
-		// All attribute values should be in single or double quotes.
-		// But this is such a common error that the parser will try
-		// its best, even without them.
-		value = "";
-		while (    p && *p											// existence
-				&& !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r'	// whitespace
-				&& *p != '/' && *p != '>' )							// tag end
-		{
-			if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
-				// [ 1451649 ] Attribute values with trailing quotes not handled correctly
-				// We did not have an opening quote but seem to have a 
-				// closing one. Give up and throw an error.
-				if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
-				return 0;
-			}
-			value += *p;
-			++p;
-		}
-	}
-	return p;
-}
-
-#ifdef TIXML_USE_STL
-void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
-{
-	while ( in->good() )
-	{
-		int c = in->peek();	
-		if ( !cdata && (c == '<' ) ) 
-		{
-			return;
-		}
-		if ( c <= 0 )
-		{
-			TiXmlDocument* document = GetDocument();
-			if ( document )
-				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
-			return;
-		}
-
-		(*tag) += (char) c;
-		in->get();	// "commits" the peek made above
-
-		if ( cdata && c == '>' && tag->size() >= 3 ) {
-			size_t len = tag->size();
-			if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) {
-				// terminator of cdata.
-				return;
-			}
-		}    
-	}
-}
-#endif
-
-const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
-{
-	value = "";
-	TiXmlDocument* document = GetDocument();
-
-	if ( data )
-	{
-		data->Stamp( p, encoding );
-		location = data->Cursor();
-	}
-
-	const char* const startTag = "<![CDATA[";
-	const char* const endTag   = "]]>";
-
-	if ( cdata || StringEqual( p, startTag, false, encoding ) )
-	{
-		cdata = true;
-
-		if ( !StringEqual( p, startTag, false, encoding ) )
-		{
-			document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
-			return 0;
-		}
-		p += strlen( startTag );
-
-		// Keep all the white space, ignore the encoding, etc.
-		while (	   p && *p
-				&& !StringEqual( p, endTag, false, encoding )
-			  )
-		{
-			value += *p;
-			++p;
-		}
-
-		TIXML_STRING dummy; 
-		p = ReadText( p, &dummy, false, endTag, false, encoding );
-		return p;
-	}
-	else
-	{
-		bool ignoreWhite = true;
-
-		const char* end = "<";
-		p = ReadText( p, &value, ignoreWhite, end, false, encoding );
-		if ( p )
-			return p-1;	// don't truncate the '<'
-		return 0;
-	}
-}
-
-#ifdef TIXML_USE_STL
-void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
-{
-	while ( in->good() )
-	{
-		int c = in->get();
-		if ( c <= 0 )
-		{
-			TiXmlDocument* document = GetDocument();
-			if ( document )
-				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
-			return;
-		}
-		(*tag) += (char) c;
-
-		if ( c == '>' )
-		{
-			// All is well.
-			return;
-		}
-	}
-}
-#endif
-
-const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
-{
-	p = SkipWhiteSpace( p, _encoding );
-	// Find the beginning, find the end, and look for
-	// the stuff in-between.
-	TiXmlDocument* document = GetDocument();
-	if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
-	{
-		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
-		return 0;
-	}
-	if ( data )
-	{
-		data->Stamp( p, _encoding );
-		location = data->Cursor();
-	}
-	p += 5;
-
-	version = "";
-	encoding = "";
-	standalone = "";
-
-	while ( p && *p )
-	{
-		if ( *p == '>' )
-		{
-			++p;
-			return p;
-		}
-
-		p = SkipWhiteSpace( p, _encoding );
-		if ( StringEqual( p, "version", true, _encoding ) )
-		{
-			TiXmlAttribute attrib;
-			p = attrib.Parse( p, data, _encoding );		
-			version = attrib.Value();
-		}
-		else if ( StringEqual( p, "encoding", true, _encoding ) )
-		{
-			TiXmlAttribute attrib;
-			p = attrib.Parse( p, data, _encoding );		
-			encoding = attrib.Value();
-		}
-		else if ( StringEqual( p, "standalone", true, _encoding ) )
-		{
-			TiXmlAttribute attrib;
-			p = attrib.Parse( p, data, _encoding );		
-			standalone = attrib.Value();
-		}
-		else
-		{
-			// Read over whatever it is.
-			while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
-				++p;
-		}
-	}
-	return 0;
-}
-
-bool TiXmlText::Blank() const
-{
-	for ( unsigned i=0; i<value.length(); i++ )
-		if ( !IsWhiteSpace( value[i] ) )
-			return false;
-	return true;
-}
-