Release 0.2, 80% rewrite, nothing left intact ... Daniel
diff --git a/ChangeLog b/ChangeLog
index 811b39c..d31661e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Wed Aug 12 23:12:58 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+ * New release 0.2, removed the old xml_* files so that it's
+ coherent with the other CVS base (W3C), far better conformance
+ to standard, new namespaces, decent entities support, beginning
+ of a SAX-like interface. Nearly nothing left intact, even the
+ test examples ...
+
1998-07-30 Christopher Blizzard <blizzard@appliedtheory.com>
* .cvsignore: Add .deps dir
diff --git a/Makefile.am b/Makefile.am
index 02a6bd8..bbc78de 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,14 +5,18 @@
lib_LTLIBRARIES = libxml.la
libxml_la_SOURCES = \
- xml_entities.c \
- xml_parser.c \
- xml_tree.c
+ SAX.c \
+ entities.c \
+ error.c \
+ parser.c \
+ tester.c \
+ tree.c
+
include_HEADERS = \
- xml_entities.h \
- xml_parser.h \
- xml_tree.h
+ entities.h \
+ parser.h \
+ tree.h
DEPS = $(top_builddir)/libxml.la
LDADDS = $(top_builddir)/libxml.la @Z_LIBS@
diff --git a/Makefile.win b/Makefile.win
new file mode 100644
index 0000000..0d36057
--- /dev/null
+++ b/Makefile.win
@@ -0,0 +1,34 @@
+# This is a makefile for win32 systems (VC 5.0).
+# Christopher Blizzard
+# http://odin.appliedtheory.com/
+
+CC = cl
+CFLAGS = /c /GB /Gi /nologo /I. /DWIN32 /MT /Zi
+
+LD = link
+LDFLAGS = /DEBUG /NODEFAULTLIB:libc
+
+AR = lib
+
+all: xml.lib
+
+test: tester.exe
+
+SHARED_OBJS = entities.obj parser.obj tree.obj SAX.obj
+
+xml.lib: $(SHARED_OBJS)
+ $(AR) /out:xml.lib $(SHARED_OBJS)
+
+tester.obj: $(SHARED_OBJS)
+ $(CC) $(CFLAGS) tester.c /out:tester.obj
+
+tester.exe: tester.obj xml.lib
+ $(LD) $(LDFLAGS) /out:tester.exe tester.obj xml.lib
+
+clean:
+ -del /f $(SHARED_OBJS) tester.obj
+ -del /f tester.exe
+ -del /f xml.lib
+ -del /f *.pdb
+ -del /f *.idb
+ -del /f *.ilk
diff --git a/SAX.c b/SAX.c
new file mode 100644
index 0000000..17a8277
--- /dev/null
+++ b/SAX.c
@@ -0,0 +1,223 @@
+/*
+ * SAX.c : Default SAX handler to build a tree.
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include "tree.h"
+#include "parser.h"
+#include "error.h"
+
+/* #define DEBUG_SAX */
+
+/*
+ * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
+ */
+const CHAR *getPublicId(xmlParserCtxtPtr ctxt) {
+ return(NULL);
+}
+
+/*
+ * Return the system ID, basically URI or filename e.g.
+ * http://www.sgmlsource.com/dtds/memo.dtd
+ */
+const CHAR *getSystemId(xmlParserCtxtPtr ctxt) {
+ return(ctxt->input->filename);
+}
+
+/*
+ * Return the line number of the current parsing point.
+ */
+int getLineNumber(xmlParserCtxtPtr ctxt) {
+ return(ctxt->input->line);
+}
+/*
+ * Return the column number of the current parsing point.
+ */
+int getColumnNumber(xmlParserCtxtPtr ctxt) {
+ return(ctxt->input->col);
+}
+
+/*
+ * The default SAX Locator.
+ */
+
+xmlSAXLocator xmlDefaultSAXLocator = {
+ getPublicId, getSystemId, getLineNumber, getColumnNumber
+};
+
+/*
+ * Special entity resolver, better left to the parser, it has
+ * more context than the application layer.
+ */
+xmlParserInputPtr resolveEntity(xmlParserCtxtPtr ctxt,
+ const CHAR *publicId, const CHAR *systemId) {
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
+#endif
+ return(NULL);
+}
+
+/*
+ * What to do when a notation declaration has been parsed.
+ * TODO Not handled currently.
+ */
+void notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR *publicId, const CHAR *systemId) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
+#endif
+}
+
+/*
+ * What to do when an unparsed entity declaration is parsed
+ * TODO Create an Entity node.
+ */
+void unparsedEntityDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR *publicId, const CHAR *systemId,
+ const CHAR *notationName) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
+ name, publicId, systemId, notationName);
+#endif
+}
+
+/*
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ */
+void setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.setDocumentLocator()\n");
+#endif
+}
+
+/*
+ * called when the document start being processed.
+ */
+void startDocument(xmlParserCtxtPtr ctxt) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.startDocument()\n");
+#endif
+}
+
+/*
+ * called when the document end has been detected.
+ */
+void endDocument(xmlParserCtxtPtr ctxt) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.endDocument()\n");
+#endif
+}
+
+/*
+ * called when an opening tag has been processed.
+ * TODO We currently have a small pblm with the arguments ...
+ */
+void startElement(xmlParserCtxtPtr ctxt, const CHAR *name) {
+ xmlNodePtr parent;
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.startElement(%s)\n", name);
+#endif
+ if (ctxt->nodeNr < 2) return;
+ parent = ctxt->nodeTab[ctxt->nodeNr - 2];
+ if (parent != NULL)
+ xmlAddChild(parent, ctxt->node);
+
+}
+
+/*
+ * called when the end of an element has been detected.
+ */
+void endElement(xmlParserCtxtPtr ctxt, const CHAR *name) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.endElement(%s)\n", name);
+#endif
+}
+
+/*
+ * receiving some chars from the parser.
+ * Question: how much at a time ???
+ */
+void characters(xmlParserCtxtPtr ctxt, const CHAR *ch,
+ int start, int len) {
+ xmlNodePtr lastChild;
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.characters(%.30s, %d, %d)\n", ch, start, len);
+#endif
+ /*
+ * Handle the data if any. If there is no child
+ * add it as content, otherwise if the last child is text,
+ * concatenate it, else create a new node of type text.
+ */
+
+ lastChild = xmlGetLastChild(ctxt->node);
+ if (lastChild == NULL)
+ xmlNodeAddContentLen(ctxt->node, &ch[start], len);
+ else {
+ if (xmlNodeIsText(lastChild))
+ xmlTextConcat(lastChild, &ch[start], len);
+ else {
+ lastChild = xmlNewTextLen(&ch[start], len);
+ xmlAddChild(ctxt->node, lastChild);
+ }
+ }
+}
+
+/*
+ * receiving some ignorable whitespaces from the parser.
+ * Question: how much at a time ???
+ */
+void ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch,
+ int start, int len) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len);
+#endif
+}
+
+/*
+ * A processing instruction has beem parsed.
+ */
+void processingInstruction(xmlParserCtxtPtr ctxt, const CHAR *target,
+ const CHAR *data) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
+#endif
+}
+
+xmlSAXHandler xmlDefaultSAXHandler = {
+ resolveEntity,
+ notationDecl,
+ unparsedEntityDecl,
+ setDocumentLocator,
+ startDocument,
+ endDocument,
+ startElement,
+ endElement,
+ characters,
+ ignorableWhitespace,
+ processingInstruction,
+ xmlParserWarning,
+ xmlParserError,
+ xmlParserError,
+};
+
+void xmlDefaultSAXHandlerInit(void) {
+ xmlDefaultSAXHandler.resolveEntity = resolveEntity;
+ xmlDefaultSAXHandler.notationDecl = notationDecl;
+ xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
+ xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
+ xmlDefaultSAXHandler.startDocument = startDocument;
+ xmlDefaultSAXHandler.endDocument = endDocument;
+ xmlDefaultSAXHandler.startElement = startElement;
+ xmlDefaultSAXHandler.endElement = endElement;
+ xmlDefaultSAXHandler.characters = characters;
+ xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
+ xmlDefaultSAXHandler.processingInstruction = processingInstruction;
+ xmlDefaultSAXHandler.warning = xmlParserWarning;
+ xmlDefaultSAXHandler.error = xmlParserError;
+ xmlDefaultSAXHandler.fatalError = xmlParserError;
+}
diff --git a/TODO b/TODO
index 8fd623c..d8218bc 100644
--- a/TODO
+++ b/TODO
@@ -1,15 +1,11 @@
TODO for the XML parser:
-- Support for UTF-8 encoding
-- progressive parsing. Currently the parser uses a single
- string containing the full document. The good point is
- that there is no context associated with the parser, the
- full state is in the stack. The bad point is that such a
- recursive design is hard to make progressive ...
-- Better error handling, use a dedicated, overridable error
- handling function.
-- Keep track of line numbers for better error reporting.
+- Support for UTF-8 and UTF-16 encoding (Urgent !!!).
+- progressive parsing. The entity support is a first step toward
+ asbtraction of an input stream. A large part of the context is still
+ located on the stack, moving to a state machine and putting everyting
+ in the parsing context should provide an adequate solution.
- DOM support, instead of using a proprietary in memory
format for the document representation, the parser should
call a DOM API to actually build the resulting document.
@@ -17,14 +13,17 @@
representation of the document. Even better using RPC's
the parser can actually build the document in another
program.
-- finish the support for Entities.
- Support for Comments (bad, should be in ASAP, they are parsed
- but not stored).
-- Support for PI.
-- Support for CDATA.
+ but not stored), should be configurable.
+- Improve the support of entities on save (+SAX).
Done:
- C++ support : John Ehresman <jehresma@dsg.harvard.edu>
- Updated code to follow more recent specs, added compatibility flag
+- Better error handling, use a dedicated, overridable error
+ handling function.
+- Support for CDATA.
+- Keep track of line numbers for better error reporting.
+- Support for PI (SAX one).
$Id$
diff --git a/autogen.sh b/autogen.sh
index 0119b5c..69f0382 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -5,7 +5,7 @@
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
- echo "You must have autoconf installed to compile GLIB."
+ echo "You must have autoconf installed to compile gnome-xml."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
@@ -13,7 +13,7 @@
(libtool --version) < /dev/null > /dev/null 2>&1 || {
echo
- echo "You must have libtool installed to compile GLIB."
+ echo "You must have libtool installed to compile gnome-xml."
echo "Get ftp://alpha.gnu.org/gnu/libtool-1.0h.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
@@ -21,7 +21,7 @@
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
- echo "You must have automake installed to compile GLIB."
+ echo "You must have automake installed to compile gnome-xml."
echo "Get ftp://ftp.cygnus.com/pub/home/tromey/automake-1.2d.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
@@ -31,8 +31,8 @@
exit 1
fi
-test -f xml_entities.h || {
- echo "You must run this script in the top-level GLIB directory"
+test -f entities.h || {
+ echo "You must run this script in the top-level gnome-xml directory"
exit 1
}
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..758ca6d
--- /dev/null
+++ b/config.h
@@ -0,0 +1,62 @@
+/* config.h. Generated automatically by configure. */
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if you have the strftime function. */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you have the snprintf function. */
+#define HAVE_SNPRINTF 1
+
+/* Define if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strndup function. */
+#define HAVE_STRNDUP 1
+
+/* Define if you have the <ctype.h> header file. */
+#define HAVE_CTYPE_H 1
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define if you have the <ndir.h> header file. */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define if you have the <sys/dir.h> header file. */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/ndir.h> header file. */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <zlib.h> header file. */
+#define HAVE_ZLIB_H 1
diff --git a/configure.in b/configure.in
index 285c00c..4048bb9 100644
--- a/configure.in
+++ b/configure.in
@@ -1,8 +1,8 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.2)
-AC_INIT(xml_entities.h)
+AC_INIT(entities.h)
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(libxml, 0.10)
+AM_INIT_AUTOMAKE(libxml, 0.20)
dnl Checks for programs.
AC_PROG_CC
diff --git a/entities.c b/entities.c
new file mode 100644
index 0000000..47b7cfa
--- /dev/null
+++ b/entities.c
@@ -0,0 +1,426 @@
+/*
+ * entities.c : implementation for the XML entities handking
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+#include "entities.h"
+
+/*
+ * The XML predefined entities.
+ */
+
+struct xmlPredefinedEntityValue {
+ const char *name;
+ const char *value;
+};
+struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = {
+ { "lt", "<" },
+ { "gt", ">" },
+ { "apos", "'" },
+ { "quot", "\"" },
+ { "amp", "&" }
+};
+
+xmlEntitiesTablePtr xmlPredefinedEntities = NULL;
+
+/*
+ * A buffer used for converting entities to their equivalent and back.
+ */
+static int buffer_size = 0;
+static CHAR *buffer = NULL;
+
+void growBuffer(void) {
+ buffer_size *= 2;
+ buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
+ if (buffer == NULL) {
+ perror("realloc failed");
+ exit(1);
+ }
+}
+
+/*
+ * xmlFreeEntity : clean-up an entity record.
+ */
+
+void xmlFreeEntity(xmlEntityPtr entity) {
+ if (entity == NULL) return;
+
+ if (entity->name != NULL)
+ free((char *) entity->name);
+ if (entity->ExternalID != NULL)
+ free((char *) entity->ExternalID);
+ if (entity->SystemID != NULL)
+ free((char *) entity->SystemID);
+ if (entity->content != NULL)
+ free((char *) entity->content);
+ memset(entity, -1, sizeof(xmlEntity));
+}
+
+/*
+ * xmlAddDocEntity : register a new entity for an entities table.
+ *
+ * TODO !!! We should check here that the combination of type
+ * ExternalID and SystemID is valid.
+ */
+static void xmlAddEntity(xmlEntitiesTablePtr table, const CHAR *name, int type,
+ const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
+ int i;
+ xmlEntityPtr cur;
+ int len;
+
+ for (i = 0;i < table->nb_entities;i++) {
+ cur = &table->table[i];
+ if (!xmlStrcmp(cur->name, name)) {
+ /*
+ * The entity is already defined in this Dtd, the spec says to NOT
+ * override it ... Is it worth a Warning ??? !!!
+ */
+ return;
+ }
+ }
+ if (table->nb_entities >= table->max_entities) {
+ /*
+ * need more elements.
+ */
+ table->max_entities *= 2;
+ table->table = (xmlEntityPtr)
+ realloc(table->table, table->max_entities * sizeof(xmlEntity));
+ if (table->table) {
+ perror("realloc failed");
+ exit(1);
+ }
+ }
+ cur = &table->table[table->nb_entities];
+ cur->name = xmlStrdup(name);
+ for (len = 0;name[0] != 0;name++)len++;
+ cur->len = len;
+ cur->type = type;
+ if (ExternalID != NULL)
+ cur->ExternalID = xmlStrdup(ExternalID);
+ else
+ cur->ExternalID = NULL;
+ if (SystemID != NULL)
+ cur->SystemID = xmlStrdup(SystemID);
+ else
+ cur->SystemID = NULL;
+ if (content != NULL)
+ cur->content = xmlStrdup(content);
+ else
+ cur->content = NULL;
+ table->nb_entities++;
+}
+
+/*
+ * Set up xmlPredefinedEntities from xmlPredefinedEntityValues.
+ */
+void xmlInitializePredefinedEntities(void) {
+ int i;
+ CHAR name[50];
+ CHAR value[50];
+ const char *in;
+ CHAR *out;
+
+ if (xmlPredefinedEntities != NULL) return;
+
+ xmlPredefinedEntities = xmlCreateEntitiesTable();
+ for (i = 0;i < sizeof(xmlPredefinedEntityValues) /
+ sizeof(xmlPredefinedEntityValues[0]);i++) {
+ in = xmlPredefinedEntityValues[i].name;
+ out = &name[0];
+ for (;(*out++ = (CHAR) *in);)in++;
+ in = xmlPredefinedEntityValues[i].value;
+ out = &value[0];
+ for (;(*out++ = (CHAR) *in);)in++;
+ xmlAddEntity(xmlPredefinedEntities, (const CHAR *) &name[0],
+ XML_INTERNAL_GENERAL_ENTITY, NULL, NULL,
+ &value[0]);
+ }
+}
+
+
+/*
+ * xmlAddDtdEntity : register a new entity for this DTD.
+ */
+void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
+ const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
+ xmlEntitiesTablePtr table;
+
+ if (doc->dtd == NULL) {
+ fprintf(stderr, "xmlAddDtdEntity: document without Dtd !\n");
+ return;
+ }
+ table = (xmlEntitiesTablePtr) doc->dtd->entities;
+ if (table == NULL) {
+ table = xmlCreateEntitiesTable();
+ doc->dtd->entities = table;
+ }
+ xmlAddEntity(table, name, type, ExternalID, SystemID, content);
+}
+
+/*
+ * xmlAddDocEntity : register a new entity for this document.
+ */
+void xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
+ const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
+ xmlEntitiesTablePtr table;
+
+ table = (xmlEntitiesTablePtr) doc->entities;
+ if (table == NULL) {
+ table = xmlCreateEntitiesTable();
+ doc->entities = table;
+ }
+ xmlAddEntity(doc->entities, name, type, ExternalID, SystemID, content);
+}
+
+/*
+ * xmlGetDtdEntity : do an entity lookup in the Dtd entity hash table and
+ * returns the corrsponding entity, if found, NULL otherwise.
+ */
+xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name) {
+ int i;
+ xmlEntityPtr cur;
+ xmlEntitiesTablePtr table;
+
+ if ((doc->dtd != NULL) && (doc->dtd->entities != NULL)) {
+ table = (xmlEntitiesTablePtr) doc->dtd->entities;
+ for (i = 0;i < table->nb_entities;i++) {
+ cur = &table->table[i];
+ if (!xmlStrcmp(cur->name, name)) return(cur);
+ }
+ }
+ return(NULL);
+}
+
+/*
+ * xmlGetDocEntity : do an entity lookup in the document entity hash table and
+ * returns the corrsponding entity, otherwise a lookup is done
+ * in the predefined entities too.
+ */
+xmlEntityPtr xmlGetDocEntity(xmlDocPtr doc, const CHAR *name) {
+ int i;
+ xmlEntityPtr cur;
+ xmlEntitiesTablePtr table;
+
+ if (doc->entities != NULL) {
+ table = (xmlEntitiesTablePtr) doc->entities;
+ for (i = 0;i < table->nb_entities;i++) {
+ cur = &table->table[i];
+ if (!xmlStrcmp(cur->name, name)) return(cur);
+ }
+ }
+ if (xmlPredefinedEntities == NULL)
+ xmlInitializePredefinedEntities();
+ table = xmlPredefinedEntities;
+ for (i = 0;i < table->nb_entities;i++) {
+ cur = &table->table[i];
+ if (!xmlStrcmp(cur->name, name)) return(cur);
+ }
+
+ return(NULL);
+}
+
+/*
+ * xmlEncodeEntities : do a global encoding of a string, replacing the
+ * basic content with their entities form.
+ * TODO !!!! rewite !!!
+ */
+CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
+ const CHAR *cur = input;
+ CHAR *out = buffer;
+
+ if (buffer == NULL) {
+ buffer_size = 1000;
+ buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
+ if (buffer == NULL) {
+ perror("malloc failed");
+ exit(1);
+ }
+ out = buffer;
+ }
+ while (*cur != '\0') {
+ if (out - buffer > buffer_size - 100) {
+ int index = out - buffer;
+
+ growBuffer();
+ out = &buffer[index];
+ }
+
+ /*
+ * By default one have to encode at least '<', '>', '"' and '&' !
+ * One could try a better encoding using the entities defined and
+ * used as a compression code !!!.
+ */
+ if (*cur == '<') {
+ *out++ = '&';
+ *out++ = 'l';
+ *out++ = 't';
+ *out++ = ';';
+ } else if (*cur == '>') {
+ *out++ = '&';
+ *out++ = 'g';
+ *out++ = 't';
+ *out++ = ';';
+ } else if (*cur == '&') {
+ *out++ = '&';
+ *out++ = 'a';
+ *out++ = 'm';
+ *out++ = 'p';
+ *out++ = ';';
+ } else if (*cur == '"') {
+ *out++ = '&';
+ *out++ = 'q';
+ *out++ = 'u';
+ *out++ = 'o';
+ *out++ = 't';
+ *out++ = ';';
+ } else if (*cur == '\'') {
+ *out++ = '&';
+ *out++ = 'a';
+ *out++ = 'p';
+ *out++ = 'o';
+ *out++ = 's';
+ *out++ = ';';
+ } else {
+ /*
+ * default case, just copy !
+ */
+ *out++ = *cur;
+ }
+ cur++;
+ }
+ *out++ = 0;
+ return(buffer);
+}
+
+/*
+ * xmlCreateEntitiesTable : create and initialize an enmpty hash table
+ */
+xmlEntitiesTablePtr xmlCreateEntitiesTable(void) {
+ xmlEntitiesTablePtr ret;
+
+ ret = (xmlEntitiesTablePtr)
+ malloc(sizeof(xmlEntitiesTable));
+ if (ret == NULL) {
+ fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
+ sizeof(xmlEntitiesTable));
+ return(NULL);
+ }
+ ret->max_entities = XML_MIN_ENTITIES_TABLE;
+ ret->nb_entities = 0;
+ ret->table = (xmlEntityPtr )
+ malloc(ret->max_entities * sizeof(xmlEntity));
+ if (ret == NULL) {
+ fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
+ ret->max_entities * sizeof(xmlEntity));
+ free(ret);
+ return(NULL);
+ }
+ return(ret);
+}
+
+/*
+ * xmlFreeEntitiesTable : clean up and free an entities hash table.
+ */
+void xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
+ int i;
+
+ if (table == NULL) return;
+
+ for (i = 0;i < table->nb_entities;i++) {
+ xmlFreeEntity(&table->table[i]);
+ }
+ free(table->table);
+ free(table);
+}
+
+/*
+ * Dump the content of an entity table to the document output.
+ */
+void xmlDumpEntitiesTable(xmlEntitiesTablePtr table) {
+ int i;
+ xmlEntityPtr cur;
+
+ if (table == NULL) return;
+
+ for (i = 0;i < table->nb_entities;i++) {
+ cur = &table->table[i];
+ switch (cur->type) {
+ case XML_INTERNAL_GENERAL_ENTITY:
+ xmlBufferWriteChar("<!ENTITY ");
+ xmlBufferWriteCHAR(cur->name);
+ xmlBufferWriteChar(" \"");
+ xmlBufferWriteCHAR(cur->content);
+ xmlBufferWriteChar("\">\n");
+ break;
+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+ xmlBufferWriteChar("<!ENTITY ");
+ xmlBufferWriteCHAR(cur->name);
+ if (cur->ExternalID != NULL) {
+ xmlBufferWriteChar(" PUBLIC \"");
+ xmlBufferWriteCHAR(cur->ExternalID);
+ xmlBufferWriteChar("\" \"");
+ xmlBufferWriteCHAR(cur->SystemID);
+ xmlBufferWriteChar("\"");
+ } else {
+ xmlBufferWriteChar(" SYSTEM \"");
+ xmlBufferWriteCHAR(cur->SystemID);
+ xmlBufferWriteChar("\"");
+ }
+ xmlBufferWriteChar(">\n");
+ break;
+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+ xmlBufferWriteChar("<!ENTITY ");
+ xmlBufferWriteCHAR(cur->name);
+ if (cur->ExternalID != NULL) {
+ xmlBufferWriteChar(" PUBLIC \"");
+ xmlBufferWriteCHAR(cur->ExternalID);
+ xmlBufferWriteChar("\" \"");
+ xmlBufferWriteCHAR(cur->SystemID);
+ xmlBufferWriteChar("\"");
+ } else {
+ xmlBufferWriteChar(" SYSTEM \"");
+ xmlBufferWriteCHAR(cur->SystemID);
+ xmlBufferWriteChar("\"");
+ }
+ if (cur->content != NULL) { /* Should be true ! */
+ xmlBufferWriteChar(" NDATA ");
+ xmlBufferWriteCHAR(cur->content);
+ }
+ xmlBufferWriteChar(">\n");
+ break;
+ case XML_INTERNAL_PARAMETER_ENTITY:
+ xmlBufferWriteChar("<!ENTITY % ");
+ xmlBufferWriteCHAR(cur->name);
+ xmlBufferWriteChar(" \"");
+ xmlBufferWriteCHAR(cur->content);
+ xmlBufferWriteChar("\">\n");
+ break;
+ case XML_EXTERNAL_PARAMETER_ENTITY:
+ xmlBufferWriteChar("<!ENTITY % ");
+ xmlBufferWriteCHAR(cur->name);
+ if (cur->ExternalID != NULL) {
+ xmlBufferWriteChar(" PUBLIC \"");
+ xmlBufferWriteCHAR(cur->ExternalID);
+ xmlBufferWriteChar("\" \"");
+ xmlBufferWriteCHAR(cur->SystemID);
+ xmlBufferWriteChar("\"");
+ } else {
+ xmlBufferWriteChar(" SYSTEM \"");
+ xmlBufferWriteCHAR(cur->SystemID);
+ xmlBufferWriteChar("\"");
+ }
+ xmlBufferWriteChar(">\n");
+ break;
+ default:
+ fprintf(stderr,
+ "xmlDumpEntitiesTable: internal: unknown type %d\n",
+ cur->type);
+ }
+ }
+}
diff --git a/entities.h b/entities.h
new file mode 100644
index 0000000..0065245
--- /dev/null
+++ b/entities.h
@@ -0,0 +1,70 @@
+/*
+ * entities.h : interface for the XML entities handking
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_ENTITIES_H__
+#define __XML_ENTITIES_H__
+#include "parser.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XML_INTERNAL_GENERAL_ENTITY 1
+#define XML_EXTERNAL_GENERAL_PARSED_ENTITY 2
+#define XML_EXTERNAL_GENERAL_UNPARSED_ENTITY 3
+#define XML_INTERNAL_PARAMETER_ENTITY 4
+#define XML_EXTERNAL_PARAMETER_ENTITY 5
+
+/*
+ * An unit of storage for an entity, contains the string, the value
+ * and the linkind data needed for the linking in the hash table.
+ */
+
+typedef struct xmlEntity {
+ int type; /* The entity type */
+ int len; /* The lenght of the name */
+ const CHAR *name; /* Name of the entity */
+ const CHAR *ExternalID; /* External identifier for PUBLIC Entity */
+ const CHAR *SystemID; /* URI for a SYSTEM or PUBLIC Entity */
+ CHAR *content; /* The entity content or ndata if unparsed */
+} xmlEntity, *xmlEntityPtr;
+
+/*
+ * ALl entities are stored in a table there is one table per DTD
+ * and one extra per document.
+ */
+
+#define XML_MIN_ENTITIES_TABLE 32
+
+typedef struct xmlEntitiesTable {
+ int nb_entities; /* number of elements stored */
+ int max_entities; /* maximum number of elements */
+ xmlEntityPtr table; /* the table of entities */
+} xmlEntitiesTable, *xmlEntitiesTablePtr;
+
+/*
+ * External functions :
+ */
+
+extern void xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
+ const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
+ const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern xmlEntityPtr xmlGetDocEntity(xmlDocPtr doc, const CHAR *name);
+extern xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name);
+extern CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input);
+extern xmlEntitiesTablePtr xmlCreateEntitiesTable(void);
+extern void xmlFreeEntitiesTable(xmlEntitiesTablePtr table);
+extern void xmlDumpEntitiesTable(xmlEntitiesTablePtr table);
+
+#ifdef __cplusplus
+}
+#endif
+
+# endif /* __XML_ENTITIES_H__ */
diff --git a/error.c b/error.c
new file mode 100644
index 0000000..4c4bac5
--- /dev/null
+++ b/error.c
@@ -0,0 +1,93 @@
+/*
+ * error.c: module displaying errors
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "parser.h"
+
+/*
+ * Display and format error messages.
+ */
+void xmlParserError(xmlParserCtxtPtr ctxt, const char *msg, ...) {
+ const CHAR *cur, *base;
+ va_list args;
+ int n;
+
+ va_start(args, msg);
+ if (ctxt->input->filename)
+ fprintf(stderr, "%s:%d: ", ctxt->input->filename,
+ ctxt->input->line);
+ else
+ fprintf(stderr, "line %d: ", ctxt->input->line);
+
+ fprintf(stderr, "error: ");
+ vfprintf(stderr, msg, args);
+ va_end(ap);
+ cur = ctxt->input->cur;
+ base = ctxt->input->base;
+ while ((*cur == '\n') || (*cur == '\r')) {
+ cur--;
+ base--;
+ }
+ n = 0;
+ while ((n++ < 60) && (cur >= base) && (*cur != '\n') && (*cur != '\r'))
+ cur--;
+ if ((*cur == '\n') || (*cur == '\r')) cur++;
+ base = cur;
+ n = 0;
+ while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
+ fprintf(stderr, "%c", (unsigned char) *cur++);
+ n++;
+ }
+ fprintf(stderr, "\n");
+ cur = ctxt->input->cur;
+ while ((*cur == '\n') || (*cur == '\r'))
+ cur--;
+ n = 0;
+ while ((cur != base) && (n++ < 60)) {
+ fprintf(stderr, " ");
+ base++;
+ }
+ fprintf(stderr,"^\n");
+}
+
+/*
+ * Display and format error messages.
+ */
+void xmlParserWarning(xmlParserCtxtPtr ctxt, const char *msg, ...) {
+ const CHAR *cur, *base;
+ va_list args;
+ int n;
+
+ va_start(args, msg);
+ if (ctxt->input->filename)
+ fprintf(stderr, "%s:%d: ", ctxt->input->filename,
+ ctxt->input->line);
+ else
+ fprintf(stderr, "line %d: ", ctxt->input->line);
+
+ fprintf(stderr, "warning: ");
+ vfprintf(stderr, msg, args);
+ va_end(ap);
+ cur = ctxt->input->cur;
+ base = ctxt->input->base;
+ n = 0;
+ while ((n++ < 60) && (cur >= base) && (*cur != '\n') && (*cur != '\r'))
+ cur--;
+ if ((*cur != '\n') || (*cur != '\r')) cur++;
+ base = cur;
+ n = 0;
+ while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
+ fprintf(stderr, "%c", (unsigned char) *cur++);
+ n++;
+ }
+ fprintf(stderr, "\n");
+ cur = ctxt->input->cur;
+ n = 0;
+ while ((cur != base) && (n++ < 60)) {
+ fprintf(stderr, " ");
+ base++;
+ }
+ fprintf(stderr,"^\n");
+}
diff --git a/include/libxml/entities.h b/include/libxml/entities.h
new file mode 100644
index 0000000..0065245
--- /dev/null
+++ b/include/libxml/entities.h
@@ -0,0 +1,70 @@
+/*
+ * entities.h : interface for the XML entities handking
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_ENTITIES_H__
+#define __XML_ENTITIES_H__
+#include "parser.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XML_INTERNAL_GENERAL_ENTITY 1
+#define XML_EXTERNAL_GENERAL_PARSED_ENTITY 2
+#define XML_EXTERNAL_GENERAL_UNPARSED_ENTITY 3
+#define XML_INTERNAL_PARAMETER_ENTITY 4
+#define XML_EXTERNAL_PARAMETER_ENTITY 5
+
+/*
+ * An unit of storage for an entity, contains the string, the value
+ * and the linkind data needed for the linking in the hash table.
+ */
+
+typedef struct xmlEntity {
+ int type; /* The entity type */
+ int len; /* The lenght of the name */
+ const CHAR *name; /* Name of the entity */
+ const CHAR *ExternalID; /* External identifier for PUBLIC Entity */
+ const CHAR *SystemID; /* URI for a SYSTEM or PUBLIC Entity */
+ CHAR *content; /* The entity content or ndata if unparsed */
+} xmlEntity, *xmlEntityPtr;
+
+/*
+ * ALl entities are stored in a table there is one table per DTD
+ * and one extra per document.
+ */
+
+#define XML_MIN_ENTITIES_TABLE 32
+
+typedef struct xmlEntitiesTable {
+ int nb_entities; /* number of elements stored */
+ int max_entities; /* maximum number of elements */
+ xmlEntityPtr table; /* the table of entities */
+} xmlEntitiesTable, *xmlEntitiesTablePtr;
+
+/*
+ * External functions :
+ */
+
+extern void xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
+ const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
+ const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern xmlEntityPtr xmlGetDocEntity(xmlDocPtr doc, const CHAR *name);
+extern xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name);
+extern CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input);
+extern xmlEntitiesTablePtr xmlCreateEntitiesTable(void);
+extern void xmlFreeEntitiesTable(xmlEntitiesTablePtr table);
+extern void xmlDumpEntitiesTable(xmlEntitiesTablePtr table);
+
+#ifdef __cplusplus
+}
+#endif
+
+# endif /* __XML_ENTITIES_H__ */
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
new file mode 100644
index 0000000..a25e70a
--- /dev/null
+++ b/include/libxml/parser.h
@@ -0,0 +1,168 @@
+/*
+ * parser.h : constants and stuff related to the XML parser.
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_PARSER_H__
+#define __XML_PARSER_H__
+
+#include "tree.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Constants.
+ */
+#define XML_DEFAULT_VERSION "1.0"
+
+typedef struct xmlParserInput {
+ const char *filename; /* The file analyzed, if any */
+ const CHAR *base; /* Base of the array to parse */
+ const CHAR *cur; /* Current char being parsed */
+ int line; /* Current line */
+ int col; /* Current column */
+} xmlParserInput, *xmlParserInputPtr;
+
+typedef struct xmlParserNodeInfo {
+ const struct xmlNode* node;
+ /* Position & line # that text that created the node begins & ends on */
+ unsigned long begin_pos;
+ unsigned long begin_line;
+ unsigned long end_pos;
+ unsigned long end_line;
+} xmlParserNodeInfo;
+
+typedef struct xmlParserNodeInfoSeq {
+ unsigned long maximum;
+ unsigned long length;
+ xmlParserNodeInfo* buffer;
+} xmlParserNodeInfoSeq, *xmlParserNodeInfoSeqPtr;
+
+typedef struct xmlParserCtxt {
+ struct xmlSAXHandler *sax; /* The SAX handler */
+ xmlDocPtr doc; /* the document being built */
+
+ /* Input stream stack */
+ xmlParserInputPtr input; /* Current input stream */
+ int inputNr; /* Number of current input streams */
+ int inputMax; /* Max number of input streams */
+ xmlParserInputPtr *inputTab; /* stack of inputs */
+
+ /* Node analysis stack */
+ xmlNodePtr node; /* Current parsed Node */
+ int nodeNr; /* Depth of the parsing stack */
+ int nodeMax; /* Max depth of the parsing stack */
+ xmlNodePtr *nodeTab; /* array of nodes */
+
+ int record_info; /* Whether node info should be kept */
+ xmlParserNodeInfoSeq node_seq; /* info about each node parsed */
+} xmlParserCtxt, *xmlParserCtxtPtr;
+
+/*
+ * a SAX Locator.
+ */
+
+typedef struct xmlSAXLocator {
+ const CHAR *(*getPublicId)(xmlParserCtxtPtr ctxt);
+ const CHAR *(*getSystemId)(xmlParserCtxtPtr ctxt);
+ int (*getLineNumber)(xmlParserCtxtPtr ctxt);
+ int (*getColumnNumber)(xmlParserCtxtPtr ctxt);
+} xmlSAXLocator, *xmlSAXLocatorPtr;
+
+/*
+ * a SAX Exception.
+ */
+
+typedef xmlParserInputPtr (*resolveEntitySAXFunc) (xmlParserCtxtPtr ctxt,
+ const CHAR *publicId, const CHAR *systemId);
+typedef void (*notationDeclSAXFunc)(xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR *publicId, const CHAR *systemId);
+typedef void (*unparsedEntityDeclSAXFunc)(xmlParserCtxtPtr ctxt,
+ const CHAR *name, const CHAR *publicId,
+ const CHAR *systemId, const CHAR *notationName);
+typedef void (*setDocumentLocatorSAXFunc) (xmlParserCtxtPtr ctxt,
+ xmlSAXLocatorPtr loc);
+typedef void (*startDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef void (*endDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef void (*startElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
+typedef void (*endElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
+typedef void (*charactersSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *ch,
+ int start, int len);
+typedef void (*ignorableWhitespaceSAXFunc) (xmlParserCtxtPtr ctxt,
+ const CHAR *ch, int start, int len);
+typedef void (*processingInstructionSAXFunc) (xmlParserCtxtPtr ctxt,
+ const CHAR *target, const CHAR *data);
+typedef void (*warningSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+typedef void (*errorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+typedef void (*fatalErrorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+
+typedef struct xmlSAXHandler {
+ resolveEntitySAXFunc resolveEntity;
+ notationDeclSAXFunc notationDecl;
+ unparsedEntityDeclSAXFunc unparsedEntityDecl;
+ setDocumentLocatorSAXFunc setDocumentLocator;
+ startDocumentSAXFunc startDocument;
+ endDocumentSAXFunc endDocument;
+ startElementSAXFunc startElement;
+ endElementSAXFunc endElement;
+ charactersSAXFunc characters;
+ ignorableWhitespaceSAXFunc ignorableWhitespace;
+ processingInstructionSAXFunc processingInstruction;
+ warningSAXFunc warning;
+ errorSAXFunc error;
+ fatalErrorSAXFunc fatalError;
+} xmlSAXHandler, *xmlSAXHandlerPtr;
+
+/*
+ * Global variables: just the SAX interface tables we are looking for full
+ * reentrancy of the code !
+ */
+xmlSAXLocator xmlDefaultSAXLocator;
+xmlSAXHandler xmlDefaultSAXHandler;
+
+/*
+ * Interfaces
+ */
+extern int xmlParseDocument(xmlParserCtxtPtr ctxt);
+extern xmlDocPtr xmlParseDoc(CHAR *cur);
+extern xmlDocPtr xmlParseMemory(char *buffer, int size);
+extern xmlDocPtr xmlParseFile(const char *filename);
+extern CHAR *xmlStrdup(const CHAR *input);
+extern CHAR *xmlStrndup(const CHAR *input, int n);
+extern CHAR *xmlStrchr(const CHAR *str, CHAR val);
+extern int xmlStrcmp(const CHAR *str1, const CHAR *str2);
+extern int xmlStrncmp(const CHAR *str1, const CHAR *str2, int len);
+extern int xmlStrlen(const CHAR *str);
+extern CHAR *xmlStrcat(CHAR *cur, const CHAR *add);
+extern CHAR *xmlStrncat(CHAR *cur, const CHAR *add, int len);
+
+extern void xmlInitParserCtxt(xmlParserCtxtPtr ctx);
+extern void xmlClearParserCtxt(xmlParserCtxtPtr ctx);
+extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer,
+ const char* filename);
+
+extern void xmlParserError(xmlParserCtxtPtr ctxt, const char *msg, ...);
+
+extern const xmlParserNodeInfo* xmlParserFindNodeInfo(const xmlParserCtxt* c,
+ const xmlNode* node);
+extern void xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq);
+extern void xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq);
+unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
+ const xmlNode* node);
+extern void xmlParserAddNodeInfo(xmlParserCtxtPtr ctx,
+ const xmlParserNodeInfo* info);
+
+extern void xmlParserWarning(xmlParserCtxtPtr ctxt, const char *msg, ...);
+extern void xmlParserError(xmlParserCtxtPtr ctxt, const char *msg, ...);
+extern void xmlDefaultSAXHandlerInit(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_PARSER_H__ */
+
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
new file mode 100644
index 0000000..7a48a9b
--- /dev/null
+++ b/include/libxml/tree.h
@@ -0,0 +1,180 @@
+/*
+ * tree.h : describes the structures found in an tree resulting
+ * from an XML parsing.
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_TREE_H__
+#define __XML_TREE_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Type definitions
+ */
+#ifdef UNICODE
+typedef unsigned short CHAR;
+#else
+typedef unsigned char CHAR;
+#endif
+
+/*
+ * a DTD Notation definition
+ * TODO !!!!
+ */
+
+/*
+ * a DTD Attribute definition
+ * TODO !!!!
+ */
+
+/*
+ * a DTD Element definition.
+ */
+#define XML_ELEMENT_TYPE_EMPTY 1
+#define XML_ELEMENT_TYPE_ANY 2
+#define XML_ELEMENT_TYPE_MIXED 3
+#define XML_ELEMENT_TYPE_ELEMENT 4
+
+typedef struct xmlElement {
+ const CHAR *name; /* Element name */
+ int type; /* type (too simple, to extend ...) */
+ /* TODO !!! more needed */
+} xmlElement, *xmlElementPtr;
+
+/*
+ * An XML namespace.
+ * Note that prefix == NULL is valid, it defines the default namespace
+ * within the subtree (until overriden).
+ */
+
+#define XML_GLOBAL_NAMESPACE 1 /* old style global namespace */
+#define XML_LOCAL_NAMESPACE 2 /* new style local scoping */
+
+typedef struct xmlNs {
+ struct xmlNs *next; /* next Ns link for this node */
+ int type; /* global or local */
+ const CHAR *href; /* URL for the namespace */
+ const CHAR *prefix; /* prefix for the namespace */
+} xmlNs, *xmlNsPtr;
+
+/*
+ * An XML DtD, as defined by <!DOCTYPE.
+ */
+typedef struct xmlDtd {
+ const CHAR *name; /* Name of the DTD */
+ const CHAR *ExternalID; /* External identifier for PUBLIC DTD */
+ const CHAR *SystemID; /* URI for a SYSTEM or PUBLIC DTD */
+ void *elements; /* Hash table for elements if any */
+ void *entities; /* Hash table for entities if any */
+ /* struct xmlDtd *next; * next link for this document */
+} xmlDtd, *xmlDtdPtr;
+
+/*
+ * A attribute of an XML node.
+ */
+typedef struct xmlAttr {
+ struct xmlNode *node; /* attr->node link */
+ struct xmlAttr *next; /* parent->childs link */
+ const CHAR *name; /* the name of the property */
+ const CHAR *value; /* the value of the property */
+} xmlAttr, *xmlAttrPtr;
+
+/*
+ * A node in an XML tree.
+ */
+#define XML_TYPE_TEXT 1
+#define XML_TYPE_COMMENT 2
+#define XML_TYPE_ENTITY 3
+
+typedef struct xmlNode {
+ struct xmlNode *parent; /* child->parent link */
+ struct xmlNode *next; /* next sibling link */
+ struct xmlNode *childs; /* parent->childs link */
+ struct xmlAttr *properties; /* properties list */
+ int type; /* type number in the DTD */
+ const CHAR *name; /* the name of the node, or the entity */
+ xmlNs *ns; /* pointer to the associated namespace */
+ xmlNs *nsDef; /* namespace definitions on this node */
+ CHAR *content; /* the content */
+} xmlNode, *xmlNodePtr;
+
+/*
+ * An XML document.
+ */
+typedef struct xmlDoc {
+ char *name; /* name/filename/URI of the document */
+ const CHAR *version; /* the XML version string */
+ const CHAR *encoding; /* encoding, if any */
+ int standalone; /* standalone document (no external refs) */
+ struct xmlDtd *dtd; /* the document DTD if available */
+ struct xmlNs *oldNs; /* Global namespace, the old way */
+ void *entities; /* Hash table for general entities if any */
+ struct xmlNode *root; /* the document tree */
+} xmlDoc, *xmlDocPtr;
+
+/*
+ * Variables.
+ */
+extern xmlNsPtr baseDTD;
+extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
+extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
+
+/*
+ * Functions.
+ */
+extern xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *name,
+ const CHAR *ExternalID, const CHAR *SystemID);
+extern void xmlFreeDtd(xmlDtdPtr cur);
+extern xmlNsPtr xmlNewGlobalNs(xmlDocPtr doc, const CHAR *href, const CHAR *AS);
+extern xmlNsPtr xmlNewNs(xmlNodePtr node, const CHAR *href, const CHAR *AS);
+extern void xmlFreeNs(xmlNsPtr cur);
+extern xmlDocPtr xmlNewDoc(const CHAR *version);
+extern void xmlFreeDoc(xmlDocPtr cur);
+extern xmlAttrPtr xmlNewProp(xmlNodePtr node, const CHAR *name,
+ const CHAR *value);
+extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
+ const CHAR *value);
+extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
+extern void xmlFreePropList(xmlAttrPtr cur);
+extern void xmlFreeProp(xmlAttrPtr cur);
+extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content);
+extern xmlNodePtr xmlNewText(const CHAR *content);
+extern xmlNodePtr xmlNewTextLen(const CHAR *content, int len);
+extern xmlNodePtr xmlNewComment(CHAR *content);
+extern xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
+extern xmlNodePtr xmlGetLastChild(xmlNodePtr node);
+extern int xmlNodeIsText(xmlNodePtr node);
+extern void xmlTextConcat(xmlNodePtr node, const CHAR *content, int len);
+extern void xmlFreeNodeList(xmlNodePtr cur);
+extern void xmlFreeNode(xmlNodePtr cur);
+extern void xmlNodeSetContent(xmlNodePtr cur, const CHAR *content);
+extern void xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len);
+extern void xmlNodeAddContent(xmlNodePtr cur, const CHAR *content);
+extern void xmlNodeAddContentLen(xmlNodePtr cur, const CHAR *content, int len);
+extern xmlNsPtr xmlSearchNs(xmlDocPtr doc, xmlNodePtr node,
+ const CHAR *nameSpace);
+extern xmlNsPtr xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node,
+ const CHAR *href);
+extern void xmlSetNs(xmlNodePtr node, xmlNsPtr ns);
+extern xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
+ const CHAR *name, CHAR *content);
+
+extern void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size);
+extern void xmlDocDump(FILE *f, xmlDocPtr doc);
+extern void xmlBufferWriteCHAR(const CHAR *string);
+extern void xmlBufferWriteChar(const char *string);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_TREE_H__ */
+
diff --git a/parser.c b/parser.c
new file mode 100644
index 0000000..bb24dd5
--- /dev/null
+++ b/parser.c
@@ -0,0 +1,3334 @@
+/*
+ * parser.c : an XML 1.0 non-verifying parser
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifdef WIN32
+#define HAVE_FCNTL_H
+#include <io.h>
+#else
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h> /* for memset() only */
+#include <malloc.h>
+#include <sys/stat.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include "tree.h"
+#include "parser.h"
+#include "entities.h"
+
+/************************************************************************
+ * *
+ * Parser stacks related functions and macros *
+ * *
+ ************************************************************************/
+/*
+ * Generic function for accessing stacks in the Parser Context
+ */
+
+#define PUSH_AND_POP(type, name) \
+int name##Push(xmlParserCtxtPtr ctxt, type value) { \
+ if (ctxt->name##Nr >= ctxt->name##Max) { \
+ ctxt->name##Max *= 2; \
+ ctxt->name##Tab = (void *) realloc(ctxt->name##Tab, \
+ ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \
+ if (ctxt->name##Tab == NULL) { \
+ fprintf(stderr, "realloc failed !\n"); \
+ exit(1); \
+ } \
+ } \
+ ctxt->name##Tab[ctxt->name##Nr] = value; \
+ ctxt->name = value; \
+ return(ctxt->name##Nr++); \
+} \
+type name##Pop(xmlParserCtxtPtr ctxt) { \
+ if (ctxt->name##Nr <= 0) return(0); \
+ ctxt->name##Nr--; \
+ ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
+ return(ctxt->name); \
+} \
+
+PUSH_AND_POP(xmlParserInputPtr, input)
+PUSH_AND_POP(xmlNodePtr, node)
+
+/*************
+#define CUR (*(ctxt->input->cur) ? *(ctxt->input->cur) : xmlPopInput(ctxt))
+#define NEXT (((*(ctxt->input->cur) == '\n') ? \
+ (ctxt->input->line++, ctxt->input->col = 1) : \
+ (ctxt->input->col++)), ctxt->input->cur++)
+ *************/
+
+#define CUR (*ctxt->input->cur)
+#define NEXT ((*ctxt->input->cur) ? \
+ (((*(ctxt->input->cur) == '\n') ? \
+ (ctxt->input->line++, ctxt->input->col = 1) : \
+ (ctxt->input->col++)), ctxt->input->cur++) : \
+ (xmlPopInput(ctxt), ctxt->input->cur))
+
+#define CUR_PTR ctxt->input->cur
+
+#define NXT(val) ctxt->input->cur[(val)]
+
+#define SKIP(val) ctxt->input->cur += (val)
+#define SKIP_BLANKS \
+ while (IS_BLANK(*(ctxt->input->cur))) NEXT
+
+
+/*
+ * xmlPopInput: the current input pointed by ctxt->input came to an end
+ * pop it and return the next char.
+ *
+ * TODO A deallocation of the popped Input structure is needed
+ */
+CHAR xmlPopInput(xmlParserCtxtPtr ctxt) {
+ if (ctxt->inputNr == 1) return(0); /* End of main Input */
+ inputPop(ctxt);
+ return(CUR);
+}
+
+/*
+ * xmlPushInput: switch to a new input stream which is stacked on top
+ * of the previous one(s).
+ */
+void xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
+ if (input == NULL) return;
+ inputPush(ctxt, input);
+}
+
+/*
+ * Create a new input stream based on a memory buffer.
+ */
+void xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+ xmlParserInputPtr input;
+
+ if (entity == NULL) {
+ xmlParserError(ctxt,
+ "internal: xmlNewEntityInputStream entity = NULL\n");
+ return;
+ }
+ if (entity->content == NULL) {
+ xmlParserError(ctxt,
+ "internal: xmlNewEntityInputStream entity->input = NULL\n");
+ return;
+ }
+ input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
+ if (input == NULL) {
+ xmlParserError(ctxt, "malloc: couldn't allocate a new input stream\n");
+ return;
+ }
+ input->filename = entity->SystemID; /* TODO !!! char <- CHAR */
+ input->base = entity->content;
+ input->cur = entity->content;
+ input->line = 1;
+ input->col = 1;
+ xmlPushInput(ctxt, input);
+}
+
+/*
+ * A few macros needed to help building the parser.
+ */
+
+#ifdef UNICODE
+/************************************************************************
+ * *
+ * UNICODE version of the macros. *
+ * *
+ ************************************************************************/
+/*
+ * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
+ * | [#x10000-#x10FFFF]
+ * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
+ */
+#define IS_CHAR(c) \
+ (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || \
+ (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
+
+/*
+ * [3] S ::= (#x20 | #x9 | #xD | #xA)+
+ */
+#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xa) || \
+ ((c) == 0x0D))
+
+/*
+ * [85] BaseChar ::= ... long list see REC ...
+ *
+ * VI is your friend !
+ * :1,$ s/\[#x\([0-9A-Z]*\)-#x\([0-9A-Z]*\)\]/ (((c) >= 0x\1) \&\& ((c) <= 0x\2)) ||/
+ * and
+ * :1,$ s/#x\([0-9A-Z]*\)/ ((c) == 0x\1) ||/
+ */
+#define IS_BASECHAR(c) \
+ ((((c) >= 0x0041) && ((c) <= 0x005A)) || \
+ (((c) >= 0x0061) && ((c) <= 0x007A)) || \
+ (((c) >= 0x00C0) && ((c) <= 0x00D6)) || \
+ (((c) >= 0x00D8) && ((c) <= 0x00F6)) || \
+ (((c) >= 0x00F8) && ((c) <= 0x00FF)) || \
+ (((c) >= 0x0100) && ((c) <= 0x0131)) || \
+ (((c) >= 0x0134) && ((c) <= 0x013E)) || \
+ (((c) >= 0x0141) && ((c) <= 0x0148)) || \
+ (((c) >= 0x014A) && ((c) <= 0x017E)) || \
+ (((c) >= 0x0180) && ((c) <= 0x01C3)) || \
+ (((c) >= 0x01CD) && ((c) <= 0x01F0)) || \
+ (((c) >= 0x01F4) && ((c) <= 0x01F5)) || \
+ (((c) >= 0x01FA) && ((c) <= 0x0217)) || \
+ (((c) >= 0x0250) && ((c) <= 0x02A8)) || \
+ (((c) >= 0x02BB) && ((c) <= 0x02C1)) || \
+ ((c) == 0x0386) || \
+ (((c) >= 0x0388) && ((c) <= 0x038A)) || \
+ ((c) == 0x038C) || \
+ (((c) >= 0x038E) && ((c) <= 0x03A1)) || \
+ (((c) >= 0x03A3) && ((c) <= 0x03CE)) || \
+ (((c) >= 0x03D0) && ((c) <= 0x03D6)) || \
+ ((c) == 0x03DA) || \
+ ((c) == 0x03DC) || \
+ ((c) == 0x03DE) || \
+ ((c) == 0x03E0) || \
+ (((c) >= 0x03E2) && ((c) <= 0x03F3)) || \
+ (((c) >= 0x0401) && ((c) <= 0x040C)) || \
+ (((c) >= 0x040E) && ((c) <= 0x044F)) || \
+ (((c) >= 0x0451) && ((c) <= 0x045C)) || \
+ (((c) >= 0x045E) && ((c) <= 0x0481)) || \
+ (((c) >= 0x0490) && ((c) <= 0x04C4)) || \
+ (((c) >= 0x04C7) && ((c) <= 0x04C8)) || \
+ (((c) >= 0x04CB) && ((c) <= 0x04CC)) || \
+ (((c) >= 0x04D0) && ((c) <= 0x04EB)) || \
+ (((c) >= 0x04EE) && ((c) <= 0x04F5)) || \
+ (((c) >= 0x04F8) && ((c) <= 0x04F9)) || \
+ (((c) >= 0x0531) && ((c) <= 0x0556)) || \
+ ((c) == 0x0559) || \
+ (((c) >= 0x0561) && ((c) <= 0x0586)) || \
+ (((c) >= 0x05D0) && ((c) <= 0x05EA)) || \
+ (((c) >= 0x05F0) && ((c) <= 0x05F2)) || \
+ (((c) >= 0x0621) && ((c) <= 0x063A)) || \
+ (((c) >= 0x0641) && ((c) <= 0x064A)) || \
+ (((c) >= 0x0671) && ((c) <= 0x06B7)) || \
+ (((c) >= 0x06BA) && ((c) <= 0x06BE)) || \
+ (((c) >= 0x06C0) && ((c) <= 0x06CE)) || \
+ (((c) >= 0x06D0) && ((c) <= 0x06D3)) || \
+ ((c) == 0x06D5) || \
+ (((c) >= 0x06E5) && ((c) <= 0x06E6)) || \
+ (((c) >= 0x0905) && ((c) <= 0x0939)) || \
+ ((c) == 0x093D) || \
+ (((c) >= 0x0958) && ((c) <= 0x0961)) || \
+ (((c) >= 0x0985) && ((c) <= 0x098C)) || \
+ (((c) >= 0x098F) && ((c) <= 0x0990)) || \
+ (((c) >= 0x0993) && ((c) <= 0x09A8)) || \
+ (((c) >= 0x09AA) && ((c) <= 0x09B0)) || \
+ ((c) == 0x09B2) || \
+ (((c) >= 0x09B6) && ((c) <= 0x09B9)) || \
+ (((c) >= 0x09DC) && ((c) <= 0x09DD)) || \
+ (((c) >= 0x09DF) && ((c) <= 0x09E1)) || \
+ (((c) >= 0x09F0) && ((c) <= 0x09F1)) || \
+ (((c) >= 0x0A05) && ((c) <= 0x0A0A)) || \
+ (((c) >= 0x0A0F) && ((c) <= 0x0A10)) || \
+ (((c) >= 0x0A13) && ((c) <= 0x0A28)) || \
+ (((c) >= 0x0A2A) && ((c) <= 0x0A30)) || \
+ (((c) >= 0x0A32) && ((c) <= 0x0A33)) || \
+ (((c) >= 0x0A35) && ((c) <= 0x0A36)) || \
+ (((c) >= 0x0A38) && ((c) <= 0x0A39)) || \
+ (((c) >= 0x0A59) && ((c) <= 0x0A5C)) || \
+ ((c) == 0x0A5E) || \
+ (((c) >= 0x0A72) && ((c) <= 0x0A74)) || \
+ (((c) >= 0x0A85) && ((c) <= 0x0A8B)) || \
+ ((c) == 0x0A8D) || \
+ (((c) >= 0x0A8F) && ((c) <= 0x0A91)) || \
+ (((c) >= 0x0A93) && ((c) <= 0x0AA8)) || \
+ (((c) >= 0x0AAA) && ((c) <= 0x0AB0)) || \
+ (((c) >= 0x0AB2) && ((c) <= 0x0AB3)) || \
+ (((c) >= 0x0AB5) && ((c) <= 0x0AB9)) || \
+ ((c) == 0x0ABD) || \
+ ((c) == 0x0AE0) || \
+ (((c) >= 0x0B05) && ((c) <= 0x0B0C)) || \
+ (((c) >= 0x0B0F) && ((c) <= 0x0B10)) || \
+ (((c) >= 0x0B13) && ((c) <= 0x0B28)) || \
+ (((c) >= 0x0B2A) && ((c) <= 0x0B30)) || \
+ (((c) >= 0x0B32) && ((c) <= 0x0B33)) || \
+ (((c) >= 0x0B36) && ((c) <= 0x0B39)) || \
+ ((c) == 0x0B3D) || \
+ (((c) >= 0x0B5C) && ((c) <= 0x0B5D)) || \
+ (((c) >= 0x0B5F) && ((c) <= 0x0B61)) || \
+ (((c) >= 0x0B85) && ((c) <= 0x0B8A)) || \
+ (((c) >= 0x0B8E) && ((c) <= 0x0B90)) || \
+ (((c) >= 0x0B92) && ((c) <= 0x0B95)) || \
+ (((c) >= 0x0B99) && ((c) <= 0x0B9A)) || \
+ ((c) == 0x0B9C) || \
+ (((c) >= 0x0B9E) && ((c) <= 0x0B9F)) || \
+ (((c) >= 0x0BA3) && ((c) <= 0x0BA4)) || \
+ (((c) >= 0x0BA8) && ((c) <= 0x0BAA)) || \
+ (((c) >= 0x0BAE) && ((c) <= 0x0BB5)) || \
+ (((c) >= 0x0BB7) && ((c) <= 0x0BB9)) || \
+ (((c) >= 0x0C05) && ((c) <= 0x0C0C)) || \
+ (((c) >= 0x0C0E) && ((c) <= 0x0C10)) || \
+ (((c) >= 0x0C12) && ((c) <= 0x0C28)) || \
+ (((c) >= 0x0C2A) && ((c) <= 0x0C33)) || \
+ (((c) >= 0x0C35) && ((c) <= 0x0C39)) || \
+ (((c) >= 0x0C60) && ((c) <= 0x0C61)) || \
+ (((c) >= 0x0C85) && ((c) <= 0x0C8C)) || \
+ (((c) >= 0x0C8E) && ((c) <= 0x0C90)) || \
+ (((c) >= 0x0C92) && ((c) <= 0x0CA8)) || \
+ (((c) >= 0x0CAA) && ((c) <= 0x0CB3)) || \
+ (((c) >= 0x0CB5) && ((c) <= 0x0CB9)) || \
+ ((c) == 0x0CDE) || \
+ (((c) >= 0x0CE0) && ((c) <= 0x0CE1)) || \
+ (((c) >= 0x0D05) && ((c) <= 0x0D0C)) || \
+ (((c) >= 0x0D0E) && ((c) <= 0x0D10)) || \
+ (((c) >= 0x0D12) && ((c) <= 0x0D28)) || \
+ (((c) >= 0x0D2A) && ((c) <= 0x0D39)) || \
+ (((c) >= 0x0D60) && ((c) <= 0x0D61)) || \
+ (((c) >= 0x0E01) && ((c) <= 0x0E2E)) || \
+ ((c) == 0x0E30) || \
+ (((c) >= 0x0E32) && ((c) <= 0x0E33)) || \
+ (((c) >= 0x0E40) && ((c) <= 0x0E45)) || \
+ (((c) >= 0x0E81) && ((c) <= 0x0E82)) || \
+ ((c) == 0x0E84) || \
+ (((c) >= 0x0E87) && ((c) <= 0x0E88)) || \
+ ((c) == 0x0E8A) || \
+ ((c) == 0x0E8D) || \
+ (((c) >= 0x0E94) && ((c) <= 0x0E97)) || \
+ (((c) >= 0x0E99) && ((c) <= 0x0E9F)) || \
+ (((c) >= 0x0EA1) && ((c) <= 0x0EA3)) || \
+ ((c) == 0x0EA5) || \
+ ((c) == 0x0EA7) || \
+ (((c) >= 0x0EAA) && ((c) <= 0x0EAB)) || \
+ (((c) >= 0x0EAD) && ((c) <= 0x0EAE)) || \
+ ((c) == 0x0EB0) || \
+ (((c) >= 0x0EB2) && ((c) <= 0x0EB3)) || \
+ ((c) == 0x0EBD) || \
+ (((c) >= 0x0EC0) && ((c) <= 0x0EC4)) || \
+ (((c) >= 0x0F40) && ((c) <= 0x0F47)) || \
+ (((c) >= 0x0F49) && ((c) <= 0x0F69)) || \
+ (((c) >= 0x10A0) && ((c) <= 0x10C5)) || \
+ (((c) >= 0x10D0) && ((c) <= 0x10F6)) || \
+ ((c) == 0x1100) || \
+ (((c) >= 0x1102) && ((c) <= 0x1103)) || \
+ (((c) >= 0x1105) && ((c) <= 0x1107)) || \
+ ((c) == 0x1109) || \
+ (((c) >= 0x110B) && ((c) <= 0x110C)) || \
+ (((c) >= 0x110E) && ((c) <= 0x1112)) || \
+ ((c) == 0x113C) || \
+ ((c) == 0x113E) || \
+ ((c) == 0x1140) || \
+ ((c) == 0x114C) || \
+ ((c) == 0x114E) || \
+ ((c) == 0x1150) || \
+ (((c) >= 0x1154) && ((c) <= 0x1155)) || \
+ ((c) == 0x1159) || \
+ (((c) >= 0x115F) && ((c) <= 0x1161)) || \
+ ((c) == 0x1163) || \
+ ((c) == 0x1165) || \
+ ((c) == 0x1167) || \
+ ((c) == 0x1169) || \
+ (((c) >= 0x116D) && ((c) <= 0x116E)) || \
+ (((c) >= 0x1172) && ((c) <= 0x1173)) || \
+ ((c) == 0x1175) || \
+ ((c) == 0x119E) || \
+ ((c) == 0x11A8) || \
+ ((c) == 0x11AB) || \
+ (((c) >= 0x11AE) && ((c) <= 0x11AF)) || \
+ (((c) >= 0x11B7) && ((c) <= 0x11B8)) || \
+ ((c) == 0x11BA) || \
+ (((c) >= 0x11BC) && ((c) <= 0x11C2)) || \
+ ((c) == 0x11EB) || \
+ ((c) == 0x11F0) || \
+ ((c) == 0x11F9) || \
+ (((c) >= 0x1E00) && ((c) <= 0x1E9B)) || \
+ (((c) >= 0x1EA0) && ((c) <= 0x1EF9)) || \
+ (((c) >= 0x1F00) && ((c) <= 0x1F15)) || \
+ (((c) >= 0x1F18) && ((c) <= 0x1F1D)) || \
+ (((c) >= 0x1F20) && ((c) <= 0x1F45)) || \
+ (((c) >= 0x1F48) && ((c) <= 0x1F4D)) || \
+ (((c) >= 0x1F50) && ((c) <= 0x1F57)) || \
+ ((c) == 0x1F59) || \
+ ((c) == 0x1F5B) || \
+ ((c) == 0x1F5D) || \
+ (((c) >= 0x1F5F) && ((c) <= 0x1F7D)) || \
+ (((c) >= 0x1F80) && ((c) <= 0x1FB4)) || \
+ (((c) >= 0x1FB6) && ((c) <= 0x1FBC)) || \
+ ((c) == 0x1FBE) || \
+ (((c) >= 0x1FC2) && ((c) <= 0x1FC4)) || \
+ (((c) >= 0x1FC6) && ((c) <= 0x1FCC)) || \
+ (((c) >= 0x1FD0) && ((c) <= 0x1FD3)) || \
+ (((c) >= 0x1FD6) && ((c) <= 0x1FDB)) || \
+ (((c) >= 0x1FE0) && ((c) <= 0x1FEC)) || \
+ (((c) >= 0x1FF2) && ((c) <= 0x1FF4)) || \
+ (((c) >= 0x1FF6) && ((c) <= 0x1FFC)) || \
+ ((c) == 0x2126) || \
+ (((c) >= 0x212A) && ((c) <= 0x212B)) || \
+ ((c) == 0x212E) || \
+ (((c) >= 0x2180) && ((c) <= 0x2182)) || \
+ (((c) >= 0x3041) && ((c) <= 0x3094)) || \
+ (((c) >= 0x30A1) && ((c) <= 0x30FA)) || \
+ (((c) >= 0x3105) && ((c) <= 0x312C)) || \
+ (((c) >= 0xAC00) && ((c) <= 0xD7A3)))
+
+/*
+ * [88] Digit ::= ... long list see REC ...
+ */
+#define IS_DIGIT(c) \
+ ((((c) >= 0x0030) && ((c) <= 0x0039)) || \
+ (((c) >= 0x0660) && ((c) <= 0x0669)) || \
+ (((c) >= 0x06F0) && ((c) <= 0x06F9)) || \
+ (((c) >= 0x0966) && ((c) <= 0x096F)) || \
+ (((c) >= 0x09E6) && ((c) <= 0x09EF)) || \
+ (((c) >= 0x0A66) && ((c) <= 0x0A6F)) || \
+ (((c) >= 0x0AE6) && ((c) <= 0x0AEF)) || \
+ (((c) >= 0x0B66) && ((c) <= 0x0B6F)) || \
+ (((c) >= 0x0BE7) && ((c) <= 0x0BEF)) || \
+ (((c) >= 0x0C66) && ((c) <= 0x0C6F)) || \
+ (((c) >= 0x0CE6) && ((c) <= 0x0CEF)) || \
+ (((c) >= 0x0D66) && ((c) <= 0x0D6F)) || \
+ (((c) >= 0x0E50) && ((c) <= 0x0E59)) || \
+ (((c) >= 0x0ED0) && ((c) <= 0x0ED9)) || \
+ (((c) >= 0x0F20) && ((c) <= 0x0F29)))
+
+/*
+ * [87] CombiningChar ::= ... long list see REC ...
+ */
+#define IS_COMBINING(c) \
+ ((((c) >= 0x0300) && ((c) <= 0x0345)) || \
+ (((c) >= 0x0360) && ((c) <= 0x0361)) || \
+ (((c) >= 0x0483) && ((c) <= 0x0486)) || \
+ (((c) >= 0x0591) && ((c) <= 0x05A1)) || \
+ (((c) >= 0x05A3) && ((c) <= 0x05B9)) || \
+ (((c) >= 0x05BB) && ((c) <= 0x05BD)) || \
+ ((c) == 0x05BF) || \
+ (((c) >= 0x05C1) && ((c) <= 0x05C2)) || \
+ ((c) == 0x05C4) || \
+ (((c) >= 0x064B) && ((c) <= 0x0652)) || \
+ ((c) == 0x0670) || \
+ (((c) >= 0x06D6) && ((c) <= 0x06DC)) || \
+ (((c) >= 0x06DD) && ((c) <= 0x06DF)) || \
+ (((c) >= 0x06E0) && ((c) <= 0x06E4)) || \
+ (((c) >= 0x06E7) && ((c) <= 0x06E8)) || \
+ (((c) >= 0x06EA) && ((c) <= 0x06ED)) || \
+ (((c) >= 0x0901) && ((c) <= 0x0903)) || \
+ ((c) == 0x093C) || \
+ (((c) >= 0x093E) && ((c) <= 0x094C)) || \
+ ((c) == 0x094D) || \
+ (((c) >= 0x0951) && ((c) <= 0x0954)) || \
+ (((c) >= 0x0962) && ((c) <= 0x0963)) || \
+ (((c) >= 0x0981) && ((c) <= 0x0983)) || \
+ ((c) == 0x09BC) || \
+ ((c) == 0x09BE) || \
+ ((c) == 0x09BF) || \
+ (((c) >= 0x09C0) && ((c) <= 0x09C4)) || \
+ (((c) >= 0x09C7) && ((c) <= 0x09C8)) || \
+ (((c) >= 0x09CB) && ((c) <= 0x09CD)) || \
+ ((c) == 0x09D7) || \
+ (((c) >= 0x09E2) && ((c) <= 0x09E3)) || \
+ ((c) == 0x0A02) || \
+ ((c) == 0x0A3C) || \
+ ((c) == 0x0A3E) || \
+ ((c) == 0x0A3F) || \
+ (((c) >= 0x0A40) && ((c) <= 0x0A42)) || \
+ (((c) >= 0x0A47) && ((c) <= 0x0A48)) || \
+ (((c) >= 0x0A4B) && ((c) <= 0x0A4D)) || \
+ (((c) >= 0x0A70) && ((c) <= 0x0A71)) || \
+ (((c) >= 0x0A81) && ((c) <= 0x0A83)) || \
+ ((c) == 0x0ABC) || \
+ (((c) >= 0x0ABE) && ((c) <= 0x0AC5)) || \
+ (((c) >= 0x0AC7) && ((c) <= 0x0AC9)) || \
+ (((c) >= 0x0ACB) && ((c) <= 0x0ACD)) || \
+ (((c) >= 0x0B01) && ((c) <= 0x0B03)) || \
+ ((c) == 0x0B3C) || \
+ (((c) >= 0x0B3E) && ((c) <= 0x0B43)) || \
+ (((c) >= 0x0B47) && ((c) <= 0x0B48)) || \
+ (((c) >= 0x0B4B) && ((c) <= 0x0B4D)) || \
+ (((c) >= 0x0B56) && ((c) <= 0x0B57)) || \
+ (((c) >= 0x0B82) && ((c) <= 0x0B83)) || \
+ (((c) >= 0x0BBE) && ((c) <= 0x0BC2)) || \
+ (((c) >= 0x0BC6) && ((c) <= 0x0BC8)) || \
+ (((c) >= 0x0BCA) && ((c) <= 0x0BCD)) || \
+ ((c) == 0x0BD7) || \
+ (((c) >= 0x0C01) && ((c) <= 0x0C03)) || \
+ (((c) >= 0x0C3E) && ((c) <= 0x0C44)) || \
+ (((c) >= 0x0C46) && ((c) <= 0x0C48)) || \
+ (((c) >= 0x0C4A) && ((c) <= 0x0C4D)) || \
+ (((c) >= 0x0C55) && ((c) <= 0x0C56)) || \
+ (((c) >= 0x0C82) && ((c) <= 0x0C83)) || \
+ (((c) >= 0x0CBE) && ((c) <= 0x0CC4)) || \
+ (((c) >= 0x0CC6) && ((c) <= 0x0CC8)) || \
+ (((c) >= 0x0CCA) && ((c) <= 0x0CCD)) || \
+ (((c) >= 0x0CD5) && ((c) <= 0x0CD6)) || \
+ (((c) >= 0x0D02) && ((c) <= 0x0D03)) || \
+ (((c) >= 0x0D3E) && ((c) <= 0x0D43)) || \
+ (((c) >= 0x0D46) && ((c) <= 0x0D48)) || \
+ (((c) >= 0x0D4A) && ((c) <= 0x0D4D)) || \
+ ((c) == 0x0D57) || \
+ ((c) == 0x0E31) || \
+ (((c) >= 0x0E34) && ((c) <= 0x0E3A)) || \
+ (((c) >= 0x0E47) && ((c) <= 0x0E4E)) || \
+ ((c) == 0x0EB1) || \
+ (((c) >= 0x0EB4) && ((c) <= 0x0EB9)) || \
+ (((c) >= 0x0EBB) && ((c) <= 0x0EBC)) || \
+ (((c) >= 0x0EC8) && ((c) <= 0x0ECD)) || \
+ (((c) >= 0x0F18) && ((c) <= 0x0F19)) || \
+ ((c) == 0x0F35) || \
+ ((c) == 0x0F37) || \
+ ((c) == 0x0F39) || \
+ ((c) == 0x0F3E) || \
+ ((c) == 0x0F3F) || \
+ (((c) >= 0x0F71) && ((c) <= 0x0F84)) || \
+ (((c) >= 0x0F86) && ((c) <= 0x0F8B)) || \
+ (((c) >= 0x0F90) && ((c) <= 0x0F95)) || \
+ ((c) == 0x0F97) || \
+ (((c) >= 0x0F99) && ((c) <= 0x0FAD)) || \
+ (((c) >= 0x0FB1) && ((c) <= 0x0FB7)) || \
+ ((c) == 0x0FB9) || \
+ (((c) >= 0x20D0) && ((c) <= 0x20DC)) || \
+ ((c) == 0x20E1) || \
+ (((c) >= 0x302A) && ((c) <= 0x302F)) || \
+ ((c) == 0x3099) || \
+ ((c) == 0x309A))
+
+/*
+ * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
+ * #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
+ * [#x309D-#x309E] | [#x30FC-#x30FE]
+ */
+#define IS_EXTENDER(c) \
+ (((c) == 0xb7) || ((c) == 0x2d0) || ((c) == 0x2d1) || \
+ ((c) == 0x387) || ((c) == 0x640) || ((c) == 0xe46) || \
+ ((c) == 0xec6) || ((c) == 0x3005) \
+ (((c) >= 0x3031) && ((c) <= 0x3035)) || \
+ (((c) >= 0x309b) && ((c) <= 0x309e)) || \
+ (((c) >= 0x30fc) && ((c) <= 0x30fe)))
+
+/*
+ * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
+ */
+#define IS_IDEOGRAPHIC(c) \
+ ((((c) >= 0x4e00) && ((c) <= 0x9fa5)) || \
+ (((c) >= 0xf900) && ((c) <= 0xfa2d)) || \
+ (((c) >= 0x3021) && ((c) <= 0x3029)) || \
+ ((c) == 0x3007))
+
+/*
+ * [84] Letter ::= BaseChar | Ideographic
+ */
+#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))
+
+#else
+/************************************************************************
+ * *
+ * 8bits / ASCII version of the macros. *
+ * *
+ ************************************************************************/
+/*
+ * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
+ * | [#x10000-#x10FFFF]
+ * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
+ */
+#define IS_CHAR(c) \
+ (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || ((c) >= 0x20) ||\
+ ((c) == 0xa))
+
+/*
+ * [85] BaseChar ::= ... long list see REC ...
+ */
+#define IS_BASECHAR(c) \
+ ((((c) >= 0x41) && ((c) <= 0x5a)) || \
+ (((c) >= 0x61) && ((c) <= 0x7a)) || \
+ (((c) >= 0xaa) && ((c) <= 0x5b)) || \
+ (((c) >= 0xc0) && ((c) <= 0xd6)) || \
+ (((c) >= 0xd8) && ((c) <= 0xf6)) || \
+ (((c) >= 0xf8) && ((c) <= 0xff)) || \
+ ((c) == 0xba))
+
+/*
+ * [88] Digit ::= ... long list see REC ...
+ */
+#define IS_DIGIT(c) (((c) >= 0x30) && ((c) <= 0x39))
+
+/*
+ * [84] Letter ::= BaseChar | Ideographic
+ */
+#define IS_LETTER(c) IS_BASECHAR(c)
+
+
+/*
+ * [87] CombiningChar ::= ... long list see REC ...
+ */
+#define IS_COMBINING(c) 0
+
+/*
+ * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
+ * #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
+ * [#x309D-#x309E] | [#x30FC-#x30FE]
+ */
+#define IS_EXTENDER(c) ((c) == 0xb7)
+
+#endif /* !UNICODE */
+
+/*
+ * Blank chars.
+ *
+ * [3] S ::= (#x20 | #x9 | #xD | #xA)+
+ */
+#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xa) || \
+ ((c) == 0x0D))
+
+/*
+ * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
+ */
+#define IS_PUBIDCHAR(c) \
+ (((c) == 0x20) || ((c) == 0x0D) || ((c) == 0x0A) || \
+ (((c) >= 'a') && ((c) <= 'z')) || \
+ (((c) >= 'A') && ((c) <= 'Z')) || \
+ (((c) >= '0') && ((c) <= '9')) || \
+ ((c) == '-') || ((c) == '\'') || ((c) == '(') || ((c) == ')') || \
+ ((c) == '+') || ((c) == ',') || ((c) == '.') || ((c) == '/') || \
+ ((c) == ':') || ((c) == '=') || ((c) == '?') || ((c) == ';') || \
+ ((c) == '!') || ((c) == '*') || ((c) == '#') || ((c) == '@') || \
+ ((c) == '$') || ((c) == '_') || ((c) == '%'))
+
+#define SKIP_EOL(p) \
+ if (*(p) == 0x13) { p++ ; if (*(p) == 0x10) p++; } \
+ if (*(p) == 0x10) { p++ ; if (*(p) == 0x13) p++; }
+
+#define MOVETO_ENDTAG(p) \
+ while (IS_CHAR(*p) && (*(p) != '>')) (p)++
+
+#define MOVETO_STARTTAG(p) \
+ while (IS_CHAR(*p) && (*(p) != '<')) (p)++
+
+/************************************************************************
+ * *
+ * Commodity functions to handle CHARs *
+ * *
+ ************************************************************************/
+
+/*
+ * xmlStrndup : a strndup for array of CHAR's
+ */
+
+CHAR *xmlStrndup(const CHAR *cur, int len) {
+ CHAR *ret = malloc((len + 1) * sizeof(CHAR));
+
+ if (ret == NULL) {
+ fprintf(stderr, "malloc of %d byte failed\n",
+ (len + 1) * sizeof(CHAR));
+ return(NULL);
+ }
+ memcpy(ret, cur, len * sizeof(CHAR));
+ ret[len] = 0;
+ return(ret);
+}
+
+/*
+ * xmlStrdup : a strdup for CHAR's
+ */
+
+CHAR *xmlStrdup(const CHAR *cur) {
+ const CHAR *p = cur;
+
+ while (IS_CHAR(*p)) p++;
+ return(xmlStrndup(cur, p - cur));
+}
+
+/*
+ * xmlCharStrndup : a strndup for char's to CHAR's
+ */
+
+CHAR *xmlCharStrndup(const char *cur, int len) {
+ int i;
+ CHAR *ret = malloc((len + 1) * sizeof(CHAR));
+
+ if (ret == NULL) {
+ fprintf(stderr, "malloc of %d byte failed\n",
+ (len + 1) * sizeof(CHAR));
+ return(NULL);
+ }
+ for (i = 0;i < len;i++)
+ ret[i] = (CHAR) cur[i];
+ ret[len] = 0;
+ return(ret);
+}
+
+/*
+ * xmlCharStrdup : a strdup for char's to CHAR's
+ */
+
+CHAR *xmlCharStrdup(const char *cur) {
+ const char *p = cur;
+
+ while (*p != '\0') p++;
+ return(xmlCharStrndup(cur, p - cur));
+}
+
+/*
+ * xmlStrcmp : a strcmp for CHAR's
+ */
+
+int xmlStrcmp(const CHAR *str1, const CHAR *str2) {
+ register int tmp;
+
+ do {
+ tmp = *str1++ - *str2++;
+ if (tmp != 0) return(tmp);
+ } while ((*str1 != 0) && (*str2 != 0));
+ return (*str1 - *str2);
+}
+
+/*
+ * xmlStrncmp : a strncmp for CHAR's
+ */
+
+int xmlStrncmp(const CHAR *str1, const CHAR *str2, int len) {
+ register int tmp;
+
+ if (len <= 0) return(0);
+ do {
+ tmp = *str1++ - *str2++;
+ if (tmp != 0) return(tmp);
+ len--;
+ if (len <= 0) return(0);
+ } while ((*str1 != 0) && (*str2 != 0));
+ return (*str1 - *str2);
+}
+
+/*
+ * xmlStrchr : a strchr for CHAR's
+ */
+
+CHAR *xmlStrchr(const CHAR *str, CHAR val) {
+ while (*str != 0) {
+ if (*str == val) return((CHAR *) str);
+ str++;
+ }
+ return(NULL);
+}
+
+/*
+ * xmlStrlen : lenght of a CHAR's string
+ */
+
+int xmlStrlen(const CHAR *str) {
+ int len = 0;
+
+ if (str == NULL) return(0);
+ while (*str != 0) {
+ str++;
+ len++;
+ }
+ return(len);
+}
+
+/*
+ * xmlStrncat : a strncat for array of CHAR's
+ */
+
+CHAR *xmlStrncat(CHAR *cur, const CHAR *add, int len) {
+ int size;
+ CHAR *ret;
+
+ if ((add == NULL) || (len == 0))
+ return(cur);
+ if (cur == NULL)
+ return(xmlStrndup(add, len));
+
+ size = xmlStrlen(cur);
+ ret = realloc(cur, (size + len + 1) * sizeof(CHAR));
+ if (ret == NULL) {
+ fprintf(stderr, "xmlStrncat: realloc of %d byte failed\n",
+ (size + len + 1) * sizeof(CHAR));
+ return(cur);
+ }
+ memcpy(&ret[size], add, len * sizeof(CHAR));
+ ret[size + len] = 0;
+ return(ret);
+}
+
+/*
+ * xmlStrcat : a strcat for CHAR's
+ */
+
+CHAR *xmlStrcat(CHAR *cur, const CHAR *add) {
+ const CHAR *p = add;
+
+ if (add == NULL) return(cur);
+ if (cur == NULL)
+ return(xmlStrdup(add));
+
+ while (IS_CHAR(*p)) p++;
+ return(xmlStrncat(cur, add, p - add));
+}
+
+/************************************************************************
+ * *
+ * Commodity functions, cleanup needed ? *
+ * *
+ ************************************************************************/
+
+/*
+ * Is this a sequence of blank chars that one can ignore ?
+ */
+
+static int areBlanks(xmlParserCtxtPtr ctxt, const CHAR *str, int len) {
+ int i;
+ xmlNodePtr lastChild;
+
+ for (i = 0;i < len;i++)
+ if (!(IS_BLANK(str[i]))) return(0);
+
+ if (CUR != '<') return(0);
+ lastChild = xmlGetLastChild(ctxt->node);
+ if (lastChild == NULL) {
+ if (ctxt->node->content != NULL) return(0);
+ } else if (xmlNodeIsText(lastChild))
+ return(0);
+ return(1);
+}
+
+/*
+ * Handling of defined entities, when should we define a new input
+ * stream ? When do we just handle that as a set of chars ?
+ */
+
+void xmlHandleEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+ int len;
+
+ if (entity->content == NULL) {
+ xmlParserError(ctxt, "xmlHandleEntity %s: content == NULL\n",
+ entity->name);
+ return;
+ }
+ len = xmlStrlen(entity->content);
+ if (len <= 2) goto handle_as_char;
+
+ /*
+ * Redefine its content as an input stream.
+ */
+ xmlNewEntityInputStream(ctxt, entity);
+ return;
+
+handle_as_char:
+ /*
+ * Just handle the content as a set of chars.
+ */
+ if (ctxt->sax != NULL)
+ ctxt->sax->characters(ctxt, entity->content, 0, len);
+
+}
+
+/*
+ * Forward definition for recusive behaviour.
+ */
+xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt);
+CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt, int inLine);
+CHAR *xmlParseReference(xmlParserCtxtPtr ctxt, int inLine);
+
+/************************************************************************
+ * *
+ * Extra stuff for namespace support *
+ * Relates to http://www.w3.org/TR/WD-xml-names *
+ * *
+ ************************************************************************/
+
+/*
+ * xmlNamespaceParseNCName : parse an XML namespace name.
+ *
+ * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
+ *
+ * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
+ * CombiningChar | Extender
+ */
+
+CHAR *xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt) {
+ const CHAR *q;
+ CHAR *ret = NULL;
+
+ if (!IS_LETTER(CUR) && (CUR != '_')) return(NULL);
+ q = NEXT;
+
+ while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
+ (CUR == '.') || (CUR == '-') ||
+ (CUR == '_') ||
+ (IS_COMBINING(CUR)) ||
+ (IS_EXTENDER(CUR)))
+ NEXT;
+
+ ret = xmlStrndup(q, CUR_PTR - q);
+
+ return(ret);
+}
+
+/*
+ * xmlNamespaceParseQName : parse an XML qualified name
+ *
+ * [NS 5] QName ::= (Prefix ':')? LocalPart
+ *
+ * [NS 6] Prefix ::= NCName
+ *
+ * [NS 7] LocalPart ::= NCName
+ */
+
+CHAR *xmlNamespaceParseQName(xmlParserCtxtPtr ctxt, CHAR **prefix) {
+ CHAR *ret = NULL;
+
+ *prefix = NULL;
+ ret = xmlNamespaceParseNCName(ctxt);
+ if (CUR == ':') {
+ *prefix = ret;
+ NEXT;
+ ret = xmlNamespaceParseNCName(ctxt);
+ }
+
+ return(ret);
+}
+
+/*
+ * xmlNamespaceParseNSDef : parse a namespace prefix declaration
+ *
+ * [NS 1] NSDef ::= PrefixDef Eq SystemLiteral
+ *
+ * [NS 2] PrefixDef ::= 'xmlns' (':' NCName)?
+ */
+
+CHAR *xmlNamespaceParseNSDef(xmlParserCtxtPtr ctxt) {
+ CHAR *name = NULL;
+
+ if ((CUR == 'x') && (NXT(1) == 'm') &&
+ (NXT(2) == 'l') && (NXT(3) == 'n') &&
+ (NXT(4) == 's')) {
+ SKIP(5);
+ if (CUR == ':') {
+ NEXT;
+ name = xmlNamespaceParseNCName(ctxt);
+ }
+ }
+ return(name);
+}
+
+/*
+ * [OLD] Parse and return a string between quotes or doublequotes
+ */
+CHAR *xmlParseQuotedString(xmlParserCtxtPtr ctxt) {
+ CHAR *ret = NULL;
+ const CHAR *q;
+
+ if (CUR == '"') {
+ NEXT;
+ q = CUR_PTR;
+ while (IS_CHAR(CUR) && (CUR != '"')) NEXT;
+ if (CUR != '"')
+ xmlParserError(ctxt, "String not closed\"%.50s\n", q);
+ else {
+ ret = xmlStrndup(q, CUR_PTR - q);
+ NEXT;
+ }
+ } else if (CUR == '\''){
+ NEXT;
+ q = CUR_PTR;
+ while (IS_CHAR(CUR) && (CUR != '\'')) NEXT;
+ if (CUR != '\'')
+ xmlParserError(ctxt, "String not closed\"%.50s\n", q);
+ else {
+ ret = xmlStrndup(q, CUR_PTR - q);
+ NEXT;
+ }
+ }
+ return(ret);
+}
+
+/*
+ * [OLD] xmlParseNamespace: parse specific PI '<?namespace ...' constructs.
+ *
+ * This is what the older xml-name Working Draft specified, a bunch of
+ * other stuff may still rely on it, so support is still here as
+ * if ot was declared on the root of the Tree:-(
+ */
+
+void xmlParseNamespace(xmlParserCtxtPtr ctxt) {
+ CHAR *href = NULL;
+ CHAR *prefix = NULL;
+ int garbage = 0;
+
+ /*
+ * We just skipped "namespace" or "xml:namespace"
+ */
+ SKIP_BLANKS;
+
+ while (IS_CHAR(CUR) && (CUR != '>')) {
+ /*
+ * We can have "ns" or "prefix" attributes
+ * Old encoding as 'href' or 'AS' attributes is still supported
+ */
+ if ((CUR == 'n') && (NXT(1) == 's')) {
+ garbage = 0;
+ SKIP(2);
+ SKIP_BLANKS;
+
+ if (CUR != '=') continue;
+ NEXT;
+ SKIP_BLANKS;
+
+ href = xmlParseQuotedString(ctxt);
+ SKIP_BLANKS;
+ } else if ((CUR == 'h') && (NXT(1) == 'r') &&
+ (NXT(2) == 'e') && (NXT(3) == 'f')) {
+ garbage = 0;
+ SKIP(4);
+ SKIP_BLANKS;
+
+ if (CUR != '=') continue;
+ NEXT;
+ SKIP_BLANKS;
+
+ href = xmlParseQuotedString(ctxt);
+ SKIP_BLANKS;
+ } else if ((CUR == 'p') && (NXT(1) == 'r') &&
+ (NXT(2) == 'e') && (NXT(3) == 'f') &&
+ (NXT(4) == 'i') && (NXT(5) == 'x')) {
+ garbage = 0;
+ SKIP(6);
+ SKIP_BLANKS;
+
+ if (CUR != '=') continue;
+ NEXT;
+ SKIP_BLANKS;
+
+ prefix = xmlParseQuotedString(ctxt);
+ SKIP_BLANKS;
+ } else if ((CUR == 'A') && (NXT(1) == 'S')) {
+ garbage = 0;
+ SKIP(2);
+ SKIP_BLANKS;
+
+ if (CUR != '=') continue;
+ NEXT;
+ SKIP_BLANKS;
+
+ prefix = xmlParseQuotedString(ctxt);
+ SKIP_BLANKS;
+ } else if ((CUR == '?') && (NXT(1) == '>')) {
+ garbage = 0;
+ CUR_PTR ++;
+ } else {
+ /*
+ * Found garbage when parsing the namespace
+ */
+ if (!garbage)
+ xmlParserError(ctxt, "xmlParseNamespace found garbage\n");
+ NEXT;
+ }
+ }
+
+ MOVETO_ENDTAG(CUR_PTR);
+ NEXT;
+
+ /*
+ * Register the DTD.
+ */
+ if (href != NULL)
+ xmlNewGlobalNs(ctxt->doc, href, prefix);
+
+ if (prefix != NULL) free(prefix);
+ if (href != NULL) free(href);
+}
+
+/************************************************************************
+ * *
+ * The parser itself *
+ * Relates to http://www.w3.org/TR/REC-xml *
+ * *
+ ************************************************************************/
+
+/*
+ * xmlParseName : parse an XML name.
+ *
+ * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
+ * CombiningChar | Extender
+ *
+ * [5] Name ::= (Letter | '_' | ':') (NameChar)*
+ *
+ * [6] Names ::= Name (S Name)*
+ */
+
+CHAR *xmlParseName(xmlParserCtxtPtr ctxt) {
+ const CHAR *q;
+ CHAR *ret = NULL;
+
+ if (!IS_LETTER(CUR) && (CUR != '_') &&
+ (CUR != ':')) return(NULL);
+ q = NEXT;
+
+ while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
+ (CUR == '.') || (CUR == '-') ||
+ (CUR == '_') || (CUR == ':') ||
+ (IS_COMBINING(CUR)) ||
+ (IS_EXTENDER(CUR)))
+ NEXT;
+
+ ret = xmlStrndup(q, CUR_PTR - q);
+
+ return(ret);
+}
+
+/*
+ * xmlParseNmtoken : parse an XML Nmtoken.
+ *
+ * [7] Nmtoken ::= (NameChar)+
+ *
+ * [8] Nmtokens ::= Nmtoken (S Nmtoken)*
+ */
+
+CHAR *xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+ const CHAR *q;
+ CHAR *ret = NULL;
+
+ q = NEXT;
+
+ while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
+ (CUR == '.') || (CUR == '-') ||
+ (CUR == '_') || (CUR == ':') ||
+ (IS_COMBINING(CUR)) ||
+ (IS_EXTENDER(CUR)))
+ NEXT;
+
+ ret = xmlStrndup(q, CUR_PTR - q);
+
+ return(ret);
+}
+
+/*
+ * xmlParseEntityValue : parse a value for ENTITY decl.
+ *
+ * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
+ * "'" ([^%&'] | PEReference | Reference)* "'"
+ */
+
+CHAR *xmlParseEntityValue(xmlParserCtxtPtr ctxt) {
+ CHAR *ret = NULL, *cur;
+ const CHAR *q;
+
+ if (CUR == '"') {
+ NEXT;
+
+ q = CUR_PTR;
+ while ((IS_CHAR(CUR)) && (CUR != '"')) {
+ if (CUR == '%') {
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ cur = xmlParsePEReference(ctxt, 1);
+ ret = xmlStrcat(ret, cur);
+ q = CUR_PTR;
+ } else if (CUR == '&') {
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ cur = xmlParseReference(ctxt, 1);
+ ret = xmlStrcat(ret, cur);
+ q = CUR_PTR;
+ } else
+ NEXT;
+ }
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "Unfinished EntityValue\n");
+ } else {
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ NEXT;
+ }
+ } else if (CUR == '\'') {
+ NEXT;
+ q = CUR_PTR;
+ while ((IS_CHAR(CUR)) && (CUR != '\'')) {
+ if (CUR == '%') {
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ cur = xmlParsePEReference(ctxt, 1);
+ ret = xmlStrcat(ret, cur);
+ q = CUR_PTR;
+ } else if (CUR == '&') {
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ cur = xmlParseReference(ctxt, 1);
+ ret = xmlStrcat(ret, cur);
+ q = CUR_PTR;
+ } else
+ NEXT;
+ }
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "Unfinished EntityValue\n");
+ } else {
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ NEXT;
+ }
+ } else {
+ xmlParserError(ctxt, "xmlParseEntityValue \" or ' expected\n");
+ }
+
+ return(ret);
+}
+
+/*
+ * xmlParseAttValue : parse a value for an attribute
+ *
+ * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
+ * "'" ([^<&'] | Reference)* "'"
+ */
+
+CHAR *xmlParseAttValue(xmlParserCtxtPtr ctxt) {
+ CHAR *ret = NULL, *cur;
+ const CHAR *q;
+
+ if (CUR == '"') {
+ NEXT;
+
+ q = CUR_PTR;
+ while ((IS_CHAR(CUR)) && (CUR != '"')) {
+ if (CUR == '&') {
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ cur = xmlParseReference(ctxt, 1);
+ ret = xmlStrcat(ret, cur);
+ q = CUR_PTR;
+ } else
+ NEXT;
+ }
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "Unfinished AttValue\n");
+ } else {
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ NEXT;
+ }
+ } else if (CUR == '\'') {
+ NEXT;
+ q = CUR_PTR;
+ while ((IS_CHAR(CUR)) && (CUR != '\'')) {
+ if (CUR == '&') {
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ cur = xmlParseReference(ctxt, 1);
+ ret = xmlStrcat(ret, cur);
+ q = CUR_PTR;
+ } else
+ NEXT;
+ }
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "Unfinished AttValue\n");
+ } else {
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ NEXT;
+ }
+ } else {
+ xmlParserError(ctxt, "AttValue: \" or ' expected\n");
+ }
+
+ return(ret);
+}
+
+/*
+ * xmlParseSystemLiteral : parse an XML Literal
+ *
+ * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
+ */
+
+CHAR *xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
+ const CHAR *q;
+ CHAR *ret = NULL;
+
+ if (CUR == '"') {
+ NEXT;
+ q = CUR_PTR;
+ while ((IS_CHAR(CUR)) && (CUR != '"'))
+ NEXT;
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "Unfinished SystemLiteral\n");
+ } else {
+ ret = xmlStrndup(q, CUR_PTR - q);
+ NEXT;
+ }
+ } else if (CUR == '\'') {
+ NEXT;
+ q = CUR_PTR;
+ while ((IS_CHAR(CUR)) && (CUR != '\''))
+ NEXT;
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "Unfinished SystemLiteral\n");
+ } else {
+ ret = xmlStrndup(q, CUR_PTR - q);
+ NEXT;
+ }
+ } else {
+ xmlParserError(ctxt, "SystemLiteral \" or ' expected\n");
+ }
+
+ return(ret);
+}
+
+/*
+ * xmlParsePubidLiteral: parse an XML public literal
+ *
+ * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
+ */
+
+CHAR *xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
+ const CHAR *q;
+ CHAR *ret = NULL;
+ /*
+ * Name ::= (Letter | '_') (NameChar)*
+ */
+ if (CUR == '"') {
+ NEXT;
+ q = CUR_PTR;
+ while (IS_PUBIDCHAR(CUR)) NEXT;
+ if (CUR != '"') {
+ xmlParserError(ctxt, "Unfinished PubidLiteral\n");
+ } else {
+ ret = xmlStrndup(q, CUR_PTR - q);
+ NEXT;
+ }
+ } else if (CUR == '\'') {
+ NEXT;
+ q = CUR_PTR;
+ while ((IS_LETTER(CUR)) && (CUR != '\''))
+ NEXT;
+ if (!IS_LETTER(CUR)) {
+ xmlParserError(ctxt, "Unfinished PubidLiteral\n");
+ } else {
+ ret = xmlStrndup(q, CUR_PTR - q);
+ NEXT;
+ }
+ } else {
+ xmlParserError(ctxt, "SystemLiteral \" or ' expected\n");
+ }
+
+ return(ret);
+}
+
+/*
+ * xmlParseCharData: parse a CharData section.
+ * if we are within a CDATA section ']]>' marks an end of section.
+ *
+ * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
+ */
+
+void xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
+ const CHAR *q;
+
+ q = CUR_PTR;
+ while ((IS_CHAR(CUR)) && (CUR != '<') &&
+ (CUR != '&')) {
+ NEXT;
+ if ((cdata) && (CUR == ']') && (NXT(1) == ']') &&
+ (NXT(2) == '>')) break;
+ }
+ if (q == CUR_PTR) return;
+
+ /*
+ * Ok the segment [q CUR_PTR] is to be consumed as chars.
+ */
+ if (ctxt->sax != NULL) {
+ if (areBlanks(ctxt, q, CUR_PTR - q))
+ ctxt->sax->ignorableWhitespace(ctxt, q, 0, CUR_PTR - q);
+ else
+ ctxt->sax->characters(ctxt, q, 0, CUR_PTR - q);
+ }
+}
+
+/*
+ * xmlParseExternalID: Parse an External ID
+ *
+ * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
+ * | 'PUBLIC' S PubidLiteral S SystemLiteral
+ */
+
+CHAR *xmlParseExternalID(xmlParserCtxtPtr ctxt, CHAR **publicID) {
+ CHAR *URI = NULL;
+
+ if ((CUR == 'S') && (NXT(1) == 'Y') &&
+ (NXT(2) == 'S') && (NXT(3) == 'T') &&
+ (NXT(4) == 'E') && (NXT(5) == 'M')) {
+ SKIP(6);
+ SKIP_BLANKS;
+ URI = xmlParseSystemLiteral(ctxt);
+ if (URI == NULL)
+ xmlParserError(ctxt,
+ "xmlParseExternalID: SYSTEM, no URI\n");
+ } else if ((CUR == 'P') && (NXT(1) == 'U') &&
+ (NXT(2) == 'B') && (NXT(3) == 'L') &&
+ (NXT(4) == 'I') && (NXT(5) == 'C')) {
+ SKIP(6);
+ SKIP_BLANKS;
+ *publicID = xmlParsePubidLiteral(ctxt);
+ if (*publicID == NULL)
+ xmlParserError(ctxt,
+ "xmlParseExternalID: PUBLIC, no Public Identifier\n");
+ SKIP_BLANKS;
+ URI = xmlParseSystemLiteral(ctxt);
+ if (URI == NULL)
+ xmlParserError(ctxt,
+ "xmlParseExternalID: PUBLIC, no URI\n");
+ }
+ return(URI);
+}
+
+/*
+ * Skip an XML (SGML) comment <!-- .... -->
+ * This may or may not create a node (depending on the context)
+ * The spec says that "For compatibility, the string "--" (double-hyphen)
+ * must not occur within comments. "
+ *
+ * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
+ */
+xmlNodePtr xmlParseComment(xmlParserCtxtPtr ctxt, int create) {
+ xmlNodePtr ret = NULL;
+ const CHAR *q, *start;
+ const CHAR *r;
+ CHAR *val;
+
+ /*
+ * Check that there is a comment right here.
+ */
+ if ((CUR != '<') || (NXT(1) != '!') ||
+ (NXT(2) != '-') || (NXT(3) != '-')) return(NULL);
+
+ SKIP(4);
+ start = q = CUR_PTR;
+ NEXT;
+ r = CUR_PTR;
+ NEXT;
+ while (IS_CHAR(CUR) &&
+ ((CUR == ':') || (CUR != '>') ||
+ (*r != '-') || (*q != '-'))) {
+ if ((*r == '-') && (*q == '-'))
+ xmlParserError(ctxt,
+ "Comment must not contain '--' (double-hyphen)`\n");
+ NEXT;r++;q++;
+ }
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "Comment not terminated \n<!--%.50s\n", start);
+ } else {
+ NEXT;
+ if (create) {
+ val = xmlStrndup(start, q - start);
+ ret = xmlNewComment(val);
+ free(val);
+ }
+ }
+ return(ret);
+}
+
+/*
+ * xmlParsePITarget: parse the name of a PI
+ *
+ * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
+ */
+
+CHAR *xmlParsePITarget(xmlParserCtxtPtr ctxt) {
+ CHAR *name;
+
+ name = xmlParseName(ctxt);
+ if ((name != NULL) && (name[3] == 0) &&
+ ((name[0] == 'x') || (name[0] == 'X')) &&
+ ((name[1] == 'm') || (name[1] == 'M')) &&
+ ((name[2] == 'l') || (name[2] == 'L'))) {
+ xmlParserError(ctxt, "xmlParsePItarget: invalid name prefix 'xml'\n");
+ return(NULL);
+ }
+ return(name);
+}
+
+/*
+ * xmlParsePI: parse an XML Processing Instruction.
+ *
+ * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
+ */
+
+void xmlParsePI(xmlParserCtxtPtr ctxt) {
+ CHAR *target;
+
+ if ((CUR == '<') && (NXT(1) == '?')) {
+ /*
+ * this is a Processing Instruction.
+ */
+ SKIP(2);
+
+ /*
+ * Parse the target name and check for special support like
+ * namespace.
+ *
+ * TODO : PI handling should be dynamically redefinable using an
+ * API. Only namespace should be in the code IMHO ...
+ */
+ target = xmlParsePITarget(ctxt);
+ if (target != NULL) {
+ /*
+ * Support for the old Processing Instruction related to namespace.
+ */
+ if ((target[0] == 'n') && (target[1] == 'a') &&
+ (target[2] == 'm') && (target[3] == 'e') &&
+ (target[4] == 's') && (target[5] == 'p') &&
+ (target[6] == 'a') && (target[7] == 'c') &&
+ (target[8] == 'e')) {
+ xmlParseNamespace(ctxt);
+ } else if ((target[0] == 'x') && (target[1] == 'm') &&
+ (target[2] == 'l') && (target[3] == ':') &&
+ (target[4] == 'n') && (target[5] == 'a') &&
+ (target[6] == 'm') && (target[7] == 'e') &&
+ (target[8] == 's') && (target[9] == 'p') &&
+ (target[10] == 'a') && (target[11] == 'c') &&
+ (target[12] == 'e')) {
+ xmlParseNamespace(ctxt);
+ } else {
+ const CHAR *q = CUR_PTR;
+
+ while (IS_CHAR(CUR) &&
+ ((CUR != '?') || (NXT(1) != '>')))
+ NEXT;
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "xmlParsePI: PI %s never end ...\n",
+ target);
+ } else {
+ CHAR *data;
+
+ data = xmlStrndup(CUR_PTR, CUR_PTR - q);
+ SKIP(2);
+
+ /*
+ * SAX: PI detected.
+ */
+ if (ctxt->sax)
+ ctxt->sax->processingInstruction(ctxt, target, data);
+ /*
+ * Unknown PI, ignore it !
+ */
+ else
+ xmlParserWarning(ctxt,
+ "xmlParsePI : skipping unknown PI %s\n",
+ target);
+ free(data);
+ }
+ }
+ free(target);
+ } else {
+ xmlParserError(ctxt, "xmlParsePI : no target name\n");
+ /********* Should we try to complete parsing the PI ???
+ while (IS_CHAR(CUR) &&
+ (CUR != '?') && (CUR != '>'))
+ NEXT;
+ if (!IS_CHAR(CUR)) {
+ fprintf(stderr, "xmlParsePI: PI %s never end ...\n",
+ target);
+ }
+ ********************************************************/
+ }
+ }
+}
+
+/*
+ * xmlParseNotationDecl: parse a notation declaration
+ *
+ * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
+ *
+ * [83] PublicID ::= 'PUBLIC' S PubidLiteral
+ *
+ * NOTE: Actually [75] and [83] interract badly since [75] can generate
+ * 'PUBLIC' S PubidLiteral S SystemLiteral
+ *
+ * Hence there is actually 3 choices:
+ * 'PUBLIC' S PubidLiteral
+ * 'PUBLIC' S PubidLiteral S SystemLiteral
+ * and 'SYSTEM' S SystemLiteral
+ */
+
+void xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
+ CHAR *name;
+
+ if ((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == 'N') && (NXT(3) == 'O') &&
+ (NXT(4) == 'T') && (NXT(5) == 'A') &&
+ (NXT(6) == 'T') && (NXT(7) == 'I') &&
+ (NXT(8) == 'O') && (NXT(9) == 'N') &&
+ (IS_BLANK(NXT(10)))) {
+ SKIP(10);
+ SKIP_BLANKS;
+
+ name = xmlParseName(ctxt);
+ if (name == NULL) {
+ xmlParserError(ctxt,
+ "xmlParseAttributeListDecl: no name for Element\n");
+ return;
+ }
+ SKIP_BLANKS;
+ /*
+ * TODO !!!
+ */
+ while ((IS_CHAR(CUR)) && (CUR != '>'))
+ NEXT;
+ free(name);
+ }
+}
+
+/*
+ * xmlParseEntityDecl: parse <!ENTITY declarations
+ *
+ * [70] EntityDecl ::= GEDecl | PEDecl
+ *
+ * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
+ *
+ * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
+ *
+ * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
+ *
+ * [74] PEDef ::= EntityValue | ExternalID
+ *
+ * [76] NDataDecl ::= S 'NDATA' S Name
+ */
+
+void xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
+ CHAR *name = NULL;
+ CHAR *value = NULL;
+ CHAR *URI = NULL, *literal = NULL;
+ CHAR *ndata = NULL;
+ int isParameter = 0;
+
+ if ((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == 'E') && (NXT(3) == 'N') &&
+ (NXT(4) == 'T') && (NXT(5) == 'I') &&
+ (NXT(6) == 'T') && (NXT(7) == 'Y') &&
+ (IS_BLANK(NXT(8)))) {
+ SKIP(8);
+ SKIP_BLANKS;
+
+ if (CUR == '%') {
+ NEXT;
+ SKIP_BLANKS;
+ isParameter = 1;
+ }
+
+ name = xmlParseName(ctxt);
+ if (name == NULL) {
+ xmlParserError(ctxt, "xmlParseEntityDecl: no name\n");
+ return;
+ }
+ SKIP_BLANKS;
+
+ /*
+ * TODO handle the various case of definitions...
+ */
+ if (isParameter) {
+ if ((CUR == '"') || (CUR == '\''))
+ value = xmlParseEntityValue(ctxt);
+ if (value) {
+ xmlAddDocEntity(ctxt->doc, name,
+ XML_INTERNAL_PARAMETER_ENTITY,
+ NULL, NULL, value);
+ }
+ else {
+ URI = xmlParseExternalID(ctxt, &literal);
+ if (URI) {
+ xmlAddDocEntity(ctxt->doc, name,
+ XML_EXTERNAL_PARAMETER_ENTITY,
+ literal, URI, NULL);
+ }
+ }
+ } else {
+ if ((CUR == '"') || (CUR == '\'')) {
+ value = xmlParseEntityValue(ctxt);
+ xmlAddDocEntity(ctxt->doc, name,
+ XML_INTERNAL_GENERAL_ENTITY,
+ NULL, NULL, value);
+ } else {
+ URI = xmlParseExternalID(ctxt, &literal);
+ SKIP_BLANKS;
+ if ((CUR == 'N') && (NXT(1) == 'D') &&
+ (NXT(2) == 'A') && (NXT(3) == 'T') &&
+ (NXT(4) == 'A')) {
+ SKIP(5);
+ SKIP_BLANKS;
+ ndata = xmlParseName(ctxt);
+ xmlAddDocEntity(ctxt->doc, name,
+ XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
+ literal, URI, ndata);
+ } else {
+ xmlAddDocEntity(ctxt->doc, name,
+ XML_EXTERNAL_GENERAL_PARSED_ENTITY,
+ literal, URI, NULL);
+ }
+ }
+ }
+ SKIP_BLANKS;
+ if (CUR != '>') {
+ xmlParserError(ctxt,
+ "xmlParseEntityDecl: entity %s not terminated\n", name);
+ } else
+ NEXT;
+ if (name != NULL) free(name);
+ if (value != NULL) free(value);
+ if (URI != NULL) free(URI);
+ if (literal != NULL) free(literal);
+ if (ndata != NULL) free(ndata);
+ }
+}
+
+/*
+ * xmlParseEnumeratedType: parse and Enumerated attribute type.
+ *
+ * [57] EnumeratedType ::= NotationType | Enumeration
+ *
+ * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
+ *
+ * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
+ */
+
+void xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, CHAR *name) {
+ /*
+ * TODO !!!
+ */
+ while ((IS_CHAR(CUR)) && (CUR != '>'))
+ NEXT;
+}
+
+/*
+ * xmlParseAttributeType: parse the Attribute list def for an element
+ *
+ * [54] AttType ::= StringType | TokenizedType | EnumeratedType
+ *
+ * [55] StringType ::= 'CDATA'
+ *
+ * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
+ * 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
+ */
+void xmlParseAttributeType(xmlParserCtxtPtr ctxt, CHAR *name) {
+ /* TODO !!! */
+ if ((CUR == 'C') && (NXT(1) == 'D') &&
+ (NXT(2) == 'A') && (NXT(3) == 'T') &&
+ (NXT(4) == 'A')) {
+ SKIP(5);
+ } else if ((CUR == 'I') && (NXT(1) == 'D')) {
+ SKIP(2);
+ } else if ((CUR == 'I') && (NXT(1) == 'D') &&
+ (NXT(2) == 'R') && (NXT(3) == 'E') &&
+ (NXT(4) == 'F')) {
+ SKIP(5);
+ } else if ((CUR == 'I') && (NXT(1) == 'D') &&
+ (NXT(2) == 'R') && (NXT(3) == 'E') &&
+ (NXT(4) == 'F') && (NXT(5) == 'S')) {
+ SKIP(6);
+ } else if ((CUR == 'E') && (NXT(1) == 'N') &&
+ (NXT(2) == 'T') && (NXT(3) == 'I') &&
+ (NXT(4) == 'T') && (NXT(5) == 'Y')) {
+ SKIP(6);
+ } else if ((CUR == 'E') && (NXT(1) == 'N') &&
+ (NXT(2) == 'T') && (NXT(3) == 'I') &&
+ (NXT(4) == 'T') && (NXT(5) == 'I') &&
+ (NXT(6) == 'E') && (NXT(7) == 'S')) {
+ SKIP(8);
+ } else if ((CUR == 'N') && (NXT(1) == 'M') &&
+ (NXT(2) == 'T') && (NXT(3) == 'O') &&
+ (NXT(4) == 'K') && (NXT(5) == 'E') &&
+ (NXT(6) == 'N')) {
+ SKIP(7);
+ } else if ((CUR == 'N') && (NXT(1) == 'M') &&
+ (NXT(2) == 'T') && (NXT(3) == 'O') &&
+ (NXT(4) == 'K') && (NXT(5) == 'E') &&
+ (NXT(6) == 'N') && (NXT(7) == 'S')) {
+ } else {
+ xmlParseEnumeratedType(ctxt, name);
+ }
+}
+
+/*
+ * xmlParseAttributeListDecl: parse the Attribute list def for an element
+ *
+ * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
+ *
+ * [53] AttDef ::= S Name S AttType S DefaultDecl
+ */
+void xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
+ CHAR *name;
+
+ /* TODO !!! */
+ if ((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == 'A') && (NXT(3) == 'T') &&
+ (NXT(4) == 'T') && (NXT(5) == 'L') &&
+ (NXT(6) == 'I') && (NXT(7) == 'S') &&
+ (NXT(8) == 'T') && (IS_BLANK(NXT(9)))) {
+ SKIP(9);
+ SKIP_BLANKS;
+ name = xmlParseName(ctxt);
+ if (name == NULL) {
+ xmlParserError(ctxt,
+ "xmlParseAttributeListDecl: no name for Element\n");
+ return;
+ }
+ SKIP_BLANKS;
+ while (CUR != '>') {
+ const CHAR *check = CUR_PTR;
+
+ xmlParseAttributeType(ctxt, name);
+ SKIP_BLANKS;
+ if (check == CUR_PTR) {
+ xmlParserError(ctxt,
+ "xmlParseAttributeListDecl: detected error\n");
+ break;
+ }
+ }
+ if (CUR == '>')
+ NEXT;
+
+ free(name);
+ }
+}
+
+/*
+ * xmlParseElementContentDecl: parse the declaration for an Element content
+ * either Mixed or Children, the cases EMPTY and ANY being handled
+ * int xmlParseElementDecl.
+ *
+ * [47] children ::= (choice | seq) ('?' | '*' | '+')?
+ *
+ * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
+ *
+ * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
+ *
+ * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
+ *
+ * or
+ *
+ * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
+ * '(' S? '#PCDATA' S? ')'
+ */
+
+void xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, CHAR *name) {
+ /*
+ * TODO This has to be parsed correctly, currently we just skip until
+ * we reach the first '>'.
+ * !!!
+ */
+ while ((IS_CHAR(CUR)) && (CUR != '>'))
+ NEXT;
+}
+
+/*
+ * xmlParseElementDecl: parse an Element declaration.
+ *
+ * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
+ *
+ * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
+ *
+ * TODO There is a check [ VC: Unique Element Type Declaration ]
+ */
+void xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
+ CHAR *name;
+
+ if ((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == 'E') && (NXT(3) == 'L') &&
+ (NXT(4) == 'E') && (NXT(5) == 'M') &&
+ (NXT(6) == 'E') && (NXT(7) == 'N') &&
+ (NXT(8) == 'T') && (IS_BLANK(NXT(9)))) {
+ SKIP(9);
+ SKIP_BLANKS;
+ name = xmlParseName(ctxt);
+ if (name == NULL) {
+ xmlParserError(ctxt, "xmlParseElementDecl: no name for Element\n");
+ return;
+ }
+ SKIP_BLANKS;
+ if ((CUR == 'E') && (NXT(1) == 'M') &&
+ (NXT(2) == 'P') && (NXT(3) == 'T') &&
+ (NXT(4) == 'Y')) {
+ SKIP(5);
+ /*
+ * Element must always be empty.
+ */
+ } else if ((CUR == 'A') && (NXT(1) == 'N') &&
+ (NXT(2) == 'Y')) {
+ SKIP(3);
+ /*
+ * Element is a generic container.
+ */
+ } else {
+ xmlParseElementContentDecl(ctxt, name);
+ }
+ SKIP_BLANKS;
+ if (CUR != '>') {
+ xmlParserError(ctxt,
+ "xmlParseElementDecl: expected '>' at the end\n");
+ } else
+ NEXT;
+ }
+}
+
+/*
+ * xmlParseMarkupDecl: parse Markup declarations
+ *
+ * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
+ * NotationDecl | PI | Comment
+ *
+ * TODO There is a check [ VC: Proper Declaration/PE Nesting ]
+ */
+void xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
+ xmlParseElementDecl(ctxt);
+ xmlParseAttributeListDecl(ctxt);
+ xmlParseEntityDecl(ctxt);
+ xmlParseNotationDecl(ctxt);
+ xmlParsePI(ctxt);
+ xmlParseComment(ctxt, 0);
+}
+
+/*
+ * xmlParseCharRef: parse Reference declarations
+ *
+ * [66] CharRef ::= '&#' [0-9]+ ';' |
+ * '&#x' [0-9a-fA-F]+ ';'
+ */
+CHAR *xmlParseCharRef(xmlParserCtxtPtr ctxt, int inLine) {
+ int val = 0;
+ CHAR buf[2];
+
+ if ((CUR == '&') && (NXT(1) == '#') &&
+ (NXT(2) == 'x')) {
+ SKIP(3);
+ while (CUR != ';') {
+ if ((CUR >= '0') && (CUR <= '9'))
+ val = val * 16 + (CUR - '0');
+ else if ((CUR >= 'a') && (CUR <= 'f'))
+ val = val * 16 + (CUR - 'a') + 10;
+ else if ((CUR >= 'A') && (CUR <= 'F'))
+ val = val * 16 + (CUR - 'A') + 10;
+ else {
+ xmlParserError(ctxt, "xmlParseCharRef: invalid value\n");
+ val = 0;
+ break;
+ }
+ }
+ if (CUR != ';')
+ NEXT;
+ } else if ((CUR == '&') && (NXT(1) == '#')) {
+ SKIP(2);
+ while (CUR != ';') {
+ if ((CUR >= '0') && (CUR <= '9'))
+ val = val * 16 + (CUR - '0');
+ else {
+ xmlParserError(ctxt, "xmlParseCharRef: invalid value\n");
+ val = 0;
+ break;
+ }
+ }
+ if (CUR != ';')
+ NEXT;
+ } else {
+ xmlParserError(ctxt, "xmlParseCharRef: invalid value\n");
+ }
+ /*
+ * Check the value IS_CHAR ...
+ */
+ if (IS_CHAR(val)) {
+ buf[0] = (CHAR) val;
+ buf[1] = 0;
+ if (inLine)
+ return(xmlStrndup(buf, 1));
+ else if (ctxt->sax != NULL)
+ ctxt->sax->characters(ctxt, buf, 0, 1);
+ } else {
+ xmlParserError(ctxt, "xmlParseCharRef: invalid value");
+ }
+ return(NULL);
+}
+
+/*
+ * xmlParseEntityRef: parse ENTITY references declarations
+ *
+ * [68] EntityRef ::= '&' Name ';'
+ */
+CHAR *xmlParseEntityRef(xmlParserCtxtPtr ctxt, int inLine) {
+ CHAR *ret = NULL;
+ CHAR *name;
+ xmlEntityPtr entity;
+
+ if (CUR == '&') {
+ NEXT;
+ name = xmlParseName(ctxt);
+ if (name == NULL) {
+ xmlParserError(ctxt, "xmlParseEntityRef: no name\n");
+ } else {
+ if (CUR == ';') {
+ NEXT;
+ entity = xmlGetDocEntity(ctxt->doc, name);
+ if (entity == NULL) {
+ /* TODO !!! Create a reference ! */
+ xmlParserWarning(ctxt,
+ "xmlParseEntityRef: &%s; not found\n", name);
+ }
+ /*
+ * If we can get the content, push the entity content
+ * as the next input stream.
+ */
+ else {
+ switch (entity->type) {
+ case XML_INTERNAL_PARAMETER_ENTITY:
+ case XML_EXTERNAL_PARAMETER_ENTITY:
+ xmlParserError(ctxt,
+ "internal: xmlGetDtdEntity returned a general entity\n");
+ break;
+ case XML_INTERNAL_GENERAL_ENTITY:
+ if (inLine)
+ ret = entity->content;
+ else
+ xmlHandleEntity(ctxt, entity);
+ break;
+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+ xmlParserWarning(ctxt,
+ "xmlParseEntityRef: external entity &%s; not supported\n",
+ name);
+ break;
+ default:
+ xmlParserError(ctxt,
+ "internal: xmlParseEntityRef: unknown entity type %d\n",
+ entity->type);
+ }
+ }
+ } else {
+ char cst[2] = { '&', 0 };
+
+ xmlParserError(ctxt, "xmlParseEntityRef: expecting ';'\n");
+ ret = xmlStrndup(cst, 1);
+ ret = xmlStrcat(ret, name);
+ }
+ free(name);
+ }
+ }
+ return(ret);
+}
+
+/*
+ * xmlParseReference: parse Reference declarations
+ *
+ * [67] Reference ::= EntityRef | CharRef
+ */
+CHAR *xmlParseReference(xmlParserCtxtPtr ctxt, int inLine) {
+ if ((CUR == '&') && (NXT(1) == '#')) {
+ return(xmlParseCharRef(ctxt, inLine));
+ } else if (CUR == '&') {
+ return(xmlParseEntityRef(ctxt, inLine));
+ }
+ return(NULL);
+}
+
+/*
+ * xmlParsePEReference: parse PEReference declarations
+ *
+ * [69] PEReference ::= '%' Name ';'
+ */
+CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt, int inLine) {
+ CHAR *ret = NULL;
+ CHAR *name;
+ xmlEntityPtr entity;
+
+ if (CUR == '%') {
+ NEXT;
+ name = xmlParseName(ctxt);
+ if (name == NULL) {
+ xmlParserError(ctxt, "xmlParsePEReference: no name\n");
+ } else {
+ if (CUR == ';') {
+ NEXT;
+ entity = xmlGetDtdEntity(ctxt->doc, name);
+ if (entity == NULL) {
+ xmlParserWarning(ctxt,
+ "xmlParsePEReference: %%%s; not found\n");
+ }
+ /*
+ * If we can get the content, push the entity content
+ * as the next input stream.
+ */
+ else {
+ switch (entity->type) {
+ case XML_INTERNAL_PARAMETER_ENTITY:
+ if (inLine)
+ ret = entity->content;
+ else
+ xmlNewEntityInputStream(ctxt, entity);
+ break;
+ case XML_EXTERNAL_PARAMETER_ENTITY:
+ xmlParserWarning(ctxt,
+ "xmlParsePEReference: external entity %%%s; not supported\n");
+ break;
+ case XML_INTERNAL_GENERAL_ENTITY:
+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
+ xmlParserError(ctxt,
+ "internal: xmlGetDtdEntity returned a general entity\n");
+ break;
+ default:
+ xmlParserError(ctxt,
+ "internal: xmlParsePEReference: unknown entity type %d\n",
+ entity->type);
+ }
+ }
+ } else {
+ char cst[2] = { '&', 0 };
+
+ xmlParserError(ctxt, "xmlParsePEReference: expecting ';'\n");
+ ret = xmlStrndup(cst, 1);
+ ret = xmlStrcat(ret, name);
+ }
+ free(name);
+ }
+ }
+ return(ret);
+}
+
+/*
+ * xmlParseDocTypeDecl : parse a DOCTYPE declaration
+ *
+ * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
+ * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
+ */
+
+void xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
+ xmlDtdPtr dtd;
+ CHAR *name;
+ CHAR *ExternalID = NULL;
+ CHAR *URI = NULL;
+
+ /*
+ * We know that '<!DOCTYPE' has been detected.
+ */
+ SKIP(9);
+
+ SKIP_BLANKS;
+
+ /*
+ * Parse the DOCTYPE name.
+ */
+ name = xmlParseName(ctxt);
+ if (name == NULL) {
+ xmlParserError(ctxt, "xmlParseDocTypeDecl : no DOCTYPE name !\n");
+ }
+
+ SKIP_BLANKS;
+
+ /*
+ * Check for SystemID and ExternalID
+ */
+ URI = xmlParseExternalID(ctxt, &ExternalID);
+ SKIP_BLANKS;
+
+ dtd = xmlNewDtd(ctxt->doc, name, ExternalID, URI);
+
+ /*
+ * Is there any DTD definition ?
+ */
+ if (CUR == '[') {
+ NEXT;
+ /*
+ * Parse the succession of Markup declarations and
+ * PEReferences.
+ * Subsequence (markupdecl | PEReference | S)*
+ */
+ while (CUR != ']') {
+ const CHAR *check = CUR_PTR;
+
+ SKIP_BLANKS;
+ xmlParseMarkupDecl(ctxt);
+ xmlParsePEReference(ctxt, 0);
+
+ if (CUR_PTR == check) {
+ xmlParserError(ctxt,
+ "xmlParseDocTypeDecl: error detected in Markup declaration\n");
+ break;
+ }
+ }
+ if (CUR == ']') NEXT;
+ }
+
+ /*
+ * We should be at the end of the DOCTYPE declaration.
+ */
+ if (CUR != '>') {
+ xmlParserError(ctxt, "DOCTYPE unproperly terminated\n");
+ /* We shouldn't try to resynchronize ... */
+ }
+ NEXT;
+
+ /*
+ * Cleanup, since we don't use all those identifiers
+ * TODO : the DOCTYPE if available should be stored !
+ */
+ if (URI != NULL) free(URI);
+ if (ExternalID != NULL) free(ExternalID);
+ if (name != NULL) free(name);
+}
+
+/*
+ * xmlParseAttribute: parse a start of tag.
+ *
+ * [41] Attribute ::= Name Eq AttValue
+ *
+ * [25] Eq ::= S? '=' S?
+ *
+ * With namespace:
+ *
+ * [NS 11] Attribute ::= QName Eq AttValue
+ *
+ * Also the case QName == xmlns:??? is handled independently as a namespace
+ * definition.
+ */
+
+void xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
+ CHAR *name, *value = NULL;
+ CHAR *ns;
+
+ name = xmlNamespaceParseQName(ctxt, &ns);
+ if (name == NULL) {
+ xmlParserError(ctxt, "error parsing attribute name\n");
+ return;
+ }
+
+ /*
+ * read the value
+ */
+ SKIP_BLANKS;
+ if (CUR == '=') {
+ NEXT;
+ SKIP_BLANKS;
+ value = xmlParseAttValue(ctxt);
+ } else {
+ xmlParserError(ctxt, "Specification mandate value for attribute %s\n",
+ name);
+ }
+
+ /*
+ * Check whether it's a namespace definition
+ */
+ if ((ns == NULL) &&
+ (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
+ (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
+ /* a default namespace definition */
+ xmlNewNs(node, value, NULL);
+ if (name != NULL)
+ free(name);
+ if (value != NULL)
+ free(value);
+ return;
+ }
+ if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
+ (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
+ /* a standard namespace definition */
+ xmlNewNs(node, value, name);
+ if (name != NULL)
+ free(name);
+ if (value != NULL)
+ free(value);
+ return;
+ }
+
+ /*
+ * Add the attribute to the node.
+ */
+ if (name != NULL) {
+ xmlNewProp(node, name, value);
+ free(name);
+ }
+ if (value != NULL)
+ free(value);
+}
+
+/*
+ * xmlParseStartTag: parse a start of tag either for rule element or
+ * EmptyElement. In both case we don't parse the tag closing chars.
+ *
+ * [40] STag ::= '<' Name (S Attribute)* S? '>'
+ *
+ * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
+ *
+ * With namespace:
+ *
+ * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
+ *
+ * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
+ */
+
+xmlNodePtr xmlParseStartTag(xmlParserCtxtPtr ctxt) {
+ CHAR *namespace, *name;
+ xmlNsPtr ns = NULL;
+ xmlNodePtr ret = NULL;
+
+ if (CUR != '<') return(NULL);
+ NEXT;
+
+ name = xmlNamespaceParseQName(ctxt, &namespace);
+
+ /*
+ * Note : the namespace resolution is deferred until the end of the
+ * attributes parsing, since local namespace can be defined as
+ * an attribute at this level.
+ */
+ ret = xmlNewNode(ns, name, NULL);
+
+ /*
+ * Now parse the attributes, it ends up with the ending
+ *
+ * (S Attribute)* S?
+ */
+ SKIP_BLANKS;
+ while ((IS_CHAR(CUR)) &&
+ (CUR != '>') &&
+ ((CUR != '/') || (NXT(1) != '>'))) {
+ const CHAR *q = CUR_PTR;
+
+ xmlParseAttribute(ctxt, ret);
+ SKIP_BLANKS;
+
+ if (q == CUR_PTR) {
+ xmlParserError(ctxt,
+ "xmlParseStartTag: problem parsing attributes\n");
+ break;
+ }
+ }
+
+ /*
+ * Search the namespace
+ */
+ ns = xmlSearchNs(ctxt->doc, ret, namespace);
+ if (ns == NULL) /* ret still doesn't have a parent yet ! */
+ ns = xmlSearchNs(ctxt->doc, ctxt->node, namespace);
+ xmlSetNs(ret, ns);
+ if (namespace != NULL)
+ free(namespace);
+
+ /*
+ * We are parsing a new node.
+ */
+ nodePush(ctxt, ret);
+
+ /*
+ * SAX: Start of Element !
+ */
+ if (ctxt->sax != NULL)
+ ctxt->sax->startElement(ctxt, name);
+
+ return(ret);
+}
+
+/*
+ * xmlParseEndTag: parse an end of tag
+ *
+ * [42] ETag ::= '</' Name S? '>'
+ *
+ * With namespace
+ *
+ * [9] ETag ::= '</' QName S? '>'
+ */
+
+void xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlNsPtr *nsPtr, CHAR **tagPtr) {
+ CHAR *namespace, *name;
+ xmlNsPtr ns = NULL;
+
+ *nsPtr = NULL;
+ *tagPtr = NULL;
+
+ if ((CUR != '<') || (NXT(1) != '/')) {
+ xmlParserError(ctxt, "xmlParseEndTag: '</' not found\n");
+ return;
+ }
+ SKIP(2);
+
+ name = xmlNamespaceParseQName(ctxt, &namespace);
+
+ /*
+ * Search the namespace
+ */
+ ns = xmlSearchNs(ctxt->doc, ctxt->node, namespace);
+ if (namespace != NULL)
+ free(namespace);
+
+ *nsPtr = ns;
+ *tagPtr = name;
+
+ /*
+ * We should definitely be at the ending "S? '>'" part
+ */
+ SKIP_BLANKS;
+ if ((!IS_CHAR(CUR)) || (CUR != '>')) {
+ xmlParserError(ctxt, "End tag : expected '>'\n");
+ } else
+ NEXT;
+
+ return;
+}
+
+/*
+ * xmlParseCDSect: escaped pure raw content.
+ *
+ * [18] CDSect ::= CDStart CData CDEnd
+ *
+ * [19] CDStart ::= '<![CDATA['
+ *
+ * [20] Data ::= (Char* - (Char* ']]>' Char*))
+ *
+ * [21] CDEnd ::= ']]>'
+ */
+void xmlParseCDSect(xmlParserCtxtPtr ctxt) {
+ const CHAR *r, *s, *base;
+
+ if ((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == '[') && (NXT(3) == 'C') &&
+ (NXT(4) == 'D') && (NXT(5) == 'A') &&
+ (NXT(6) == 'T') && (NXT(7) == 'A') &&
+ (NXT(8) == '[')) {
+ SKIP(9);
+ } else
+ return;
+ base = CUR_PTR;
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "CData section not finished\n%.50s\n", base);
+ return;
+ }
+ r = NEXT;
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "CData section not finished\n%.50s\n", base);
+ return;
+ }
+ s = NEXT;
+ while (IS_CHAR(CUR) &&
+ ((*r != ']') || (*s != ']') || (CUR != '>'))) {
+ r++;s++;NEXT;
+ }
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "CData section not finished\n%.50s\n", base);
+ return;
+ }
+
+ /*
+ * Ok the segment [base CUR_PTR] is to be consumed as chars.
+ */
+ if (ctxt->sax != NULL) {
+ if (areBlanks(ctxt, base, CUR_PTR - base))
+ ctxt->sax->ignorableWhitespace(ctxt, base, 0, CUR_PTR - base);
+ else
+ ctxt->sax->characters(ctxt, base, 0, CUR_PTR - base);
+ }
+}
+
+/*
+ * xmlParseContent: a content is
+ * (element | PCData | Reference | CDSect | PI | Comment)
+ *
+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
+ */
+
+void xmlParseContent(xmlParserCtxtPtr ctxt) {
+ xmlNodePtr ret = NULL;
+
+ while ((CUR != '<') || (NXT(1) != '/')) {
+ const CHAR *test = CUR_PTR;
+ ret = NULL;
+
+ /*
+ * First case : a Processing Instruction.
+ */
+ if ((CUR == '<') && (NXT(1) == '?')) {
+ xmlParsePI(ctxt);
+ }
+ /*
+ * Second case : a CDSection
+ */
+ else if ((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == '[') && (NXT(3) == 'C') &&
+ (NXT(4) == 'D') && (NXT(5) == 'A') &&
+ (NXT(6) == 'T') && (NXT(7) == 'A') &&
+ (NXT(8) == '[')) {
+ xmlParseCDSect(ctxt);
+ }
+ /*
+ * Third case : a comment
+ */
+ else if ((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == '-') && (NXT(3) == '-')) {
+ ret = xmlParseComment(ctxt, 1);
+ }
+ /*
+ * Fourth case : a sub-element.
+ */
+ else if (CUR == '<') {
+ ret = xmlParseElement(ctxt);
+ }
+ /*
+ * Fifth case : a reference.
+ */
+ else if (CUR == '&') {
+ xmlParseReference(ctxt, 0);
+ }
+ /*
+ * Last case, text. Note that References are handled directly.
+ */
+ else {
+ xmlParseCharData(ctxt, 0);
+ }
+
+ /*
+ * Pop-up of finished entities.
+ */
+ while ((CUR == 0) && (ctxt->inputNr > 1)) xmlPopInput(ctxt);
+
+ if (test == CUR_PTR) {
+ xmlParserError(ctxt, "detected an error in element content\n");
+ break;
+ }
+ }
+}
+
+/*
+ * xmlParseElement: parse an XML element
+ *
+ * [39] element ::= EmptyElemTag | STag content ETag
+ *
+ * [41] Attribute ::= Name Eq AttValue
+ */
+
+
+xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt) {
+ xmlNodePtr ret;
+ const CHAR *openTag = CUR_PTR;
+ xmlParserNodeInfo node_info;
+ CHAR *endTag;
+ xmlNsPtr endNs;
+
+ /* Capture start position */
+ node_info.begin_pos = CUR_PTR - ctxt->input->base;
+ node_info.begin_line = ctxt->input->line;
+
+ ret = xmlParseStartTag(ctxt);
+ if (ret == NULL) {
+ return(NULL);
+ }
+
+ /*
+ * Check for an Empty Element.
+ */
+ if ((CUR == '/') && (NXT(1) == '>')) {
+ SKIP(2);
+ if (ctxt->sax != NULL)
+ ctxt->sax->endElement(ctxt, ret->name);
+
+ /*
+ * end of parsing of this node.
+ */
+ nodePop(ctxt);
+
+ return(ret);
+ }
+ if (CUR == '>') NEXT;
+ else {
+ xmlParserError(ctxt, "Couldn't find end of Start Tag\n%.30s\n",openTag);
+
+ /*
+ * end of parsing of this node.
+ */
+ nodePop(ctxt);
+
+ return(NULL);
+ }
+
+ /*
+ * Parse the content of the element:
+ */
+ xmlParseContent(ctxt);
+ if (!IS_CHAR(CUR)) {
+ xmlParserError(ctxt, "Premature end of data in tag %.30s\n%.30s\n",
+ openTag);
+
+ /*
+ * end of parsing of this node.
+ */
+ nodePop(ctxt);
+
+ return(NULL);
+ }
+
+ /*
+ * parse the end of tag: '</' should be here.
+ */
+ xmlParseEndTag(ctxt, &endNs, &endTag);
+
+ /*
+ * Check that the Name in the ETag is the same as in the STag.
+ */
+ if (endNs != ret->ns) {
+ xmlParserError(ctxt,
+ "Start and End tags don't use the same namespace\n%.30s\n%.30s\n",
+ openTag, endTag);
+ }
+ if (endTag == NULL ) {
+ xmlParserError(ctxt, "The End tag has no name\n%.30s\n", openTag);
+ } else if (xmlStrcmp(ret->name, endTag)) {
+ xmlParserError(ctxt,
+ "Start and End tags don't use the same name\n%.30s\n%.30s\n",
+ openTag, endTag);
+ }
+ /*
+ * SAX: End of Tag
+ */
+ else if (ctxt->sax != NULL)
+ ctxt->sax->endElement(ctxt, endTag);
+
+ if (endTag != NULL)
+ free(endTag);
+
+ /* Capture end position and add node */
+ if ( ret != NULL && ctxt->record_info ) {
+ node_info.end_pos = CUR_PTR - ctxt->input->base;
+ node_info.end_line = ctxt->input->line;
+ node_info.node = ret;
+ xmlParserAddNodeInfo(ctxt, &node_info);
+ }
+
+ /*
+ * end of parsing of this node.
+ */
+ nodePop(ctxt);
+
+ return(ret);
+}
+
+/*
+ * xmlParseVersionNum: parse the XML version value.
+ *
+ * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
+ */
+CHAR *xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
+ const CHAR *q = CUR_PTR;
+ CHAR *ret;
+
+ while (IS_CHAR(CUR) &&
+ (((CUR >= 'a') && (CUR <= 'z')) ||
+ ((CUR >= 'A') && (CUR <= 'Z')) ||
+ ((CUR >= '0') && (CUR <= '9')) ||
+ (CUR == '_') || (CUR == '.') ||
+ (CUR == ':') || (CUR == '-'))) NEXT;
+ ret = xmlStrndup(q, CUR_PTR - q);
+ return(ret);
+}
+
+/*
+ * xmlParseVersionInfo: parse the XML version.
+ *
+ * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
+ *
+ * [25] Eq ::= S? '=' S?
+ */
+
+CHAR *xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
+ CHAR *version = NULL;
+ const CHAR *q;
+
+ if ((CUR == 'v') && (NXT(1) == 'e') &&
+ (NXT(2) == 'r') && (NXT(3) == 's') &&
+ (NXT(4) == 'i') && (NXT(5) == 'o') &&
+ (NXT(6) == 'n')) {
+ SKIP(7);
+ SKIP_BLANKS;
+ if (CUR != '=') {
+ xmlParserError(ctxt, "xmlParseVersionInfo : expected '='\n");
+ return(NULL);
+ }
+ NEXT;
+ SKIP_BLANKS;
+ if (CUR == '"') {
+ NEXT;
+ q = CUR_PTR;
+ version = xmlParseVersionNum(ctxt);
+ if (CUR != '"')
+ xmlParserError(ctxt, "String not closed\n%.50s\n", q);
+ else
+ NEXT;
+ } else if (CUR == '\''){
+ NEXT;
+ q = CUR_PTR;
+ version = xmlParseVersionNum(ctxt);
+ if (CUR != '\'')
+ xmlParserError(ctxt, "String not closed\n%.50s\n", q);
+ else
+ NEXT;
+ } else {
+ xmlParserError(ctxt, "xmlParseVersionInfo : expected ' or \"\n");
+ }
+ }
+ return(version);
+}
+
+/*
+ * xmlParseEncName: parse the XML encoding name
+ *
+ * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
+ */
+CHAR *xmlParseEncName(xmlParserCtxtPtr ctxt) {
+ const CHAR *q = CUR_PTR;
+ CHAR *ret = NULL;
+
+ if (((CUR >= 'a') && (CUR <= 'z')) ||
+ ((CUR >= 'A') && (CUR <= 'Z'))) {
+ NEXT;
+ while (IS_CHAR(CUR) &&
+ (((CUR >= 'a') && (CUR <= 'z')) ||
+ ((CUR >= 'A') && (CUR <= 'Z')) ||
+ ((CUR >= '0') && (CUR <= '9')) ||
+ (CUR == '-'))) NEXT;
+ ret = xmlStrndup(q, CUR_PTR - q);
+ } else {
+ xmlParserError(ctxt, "Invalid XML encoding name\n");
+ }
+ return(ret);
+}
+
+/*
+ * xmlParseEncodingDecl: parse the XML encoding declaration
+ *
+ * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'")
+ */
+
+CHAR *xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
+ CHAR *encoding = NULL;
+ const CHAR *q;
+
+ SKIP_BLANKS;
+ if ((CUR == 'e') && (NXT(1) == 'n') &&
+ (NXT(2) == 'c') && (NXT(3) == 'o') &&
+ (NXT(4) == 'd') && (NXT(5) == 'i') &&
+ (NXT(6) == 'n') && (NXT(7) == 'g')) {
+ SKIP(8);
+ SKIP_BLANKS;
+ if (CUR != '=') {
+ xmlParserError(ctxt, "xmlParseEncodingDecl : expected '='\n");
+ return(NULL);
+ }
+ NEXT;
+ SKIP_BLANKS;
+ if (CUR == '"') {
+ NEXT;
+ q = CUR_PTR;
+ encoding = xmlParseEncName(ctxt);
+ if (CUR != '"')
+ xmlParserError(ctxt, "String not closed\n%.50s\n", q);
+ else
+ NEXT;
+ } else if (CUR == '\''){
+ NEXT;
+ q = CUR_PTR;
+ encoding = xmlParseEncName(ctxt);
+ if (CUR != '\'')
+ xmlParserError(ctxt, "String not closed\n%.50s\n", q);
+ else
+ NEXT;
+ } else if (CUR == '"'){
+ xmlParserError(ctxt, "xmlParseEncodingDecl : expected ' or \"\n");
+ }
+ }
+ return(encoding);
+}
+
+/*
+ * xmlParseSDDecl: parse the XML standalone declaration
+ *
+ * [32] SDDecl ::= S 'standalone' Eq
+ * (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
+ */
+
+int xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
+ int standalone = -1;
+
+ SKIP_BLANKS;
+ if ((CUR == 's') && (NXT(1) == 't') &&
+ (NXT(2) == 'a') && (NXT(3) == 'n') &&
+ (NXT(4) == 'd') && (NXT(5) == 'a') &&
+ (NXT(6) == 'l') && (NXT(7) == 'o') &&
+ (NXT(8) == 'n') && (NXT(9) == 'e')) {
+ SKIP(10);
+ if (CUR != '=') {
+ xmlParserError(ctxt, "XML standalone declaration : expected '='\n");
+ return(standalone);
+ }
+ NEXT;
+ SKIP_BLANKS;
+ if (CUR == '\''){
+ NEXT;
+ if ((CUR == 'n') && (NXT(1) == 'o')) {
+ standalone = 0;
+ SKIP(2);
+ } else if ((CUR == 'y') && (NXT(1) == 'e') &&
+ (NXT(2) == 's')) {
+ standalone = 1;
+ SKIP(3);
+ } else {
+ xmlParserError(ctxt, "standalone accepts only 'yes' or 'no'\n");
+ }
+ if (CUR != '\'')
+ xmlParserError(ctxt, "String not closed\n");
+ else
+ NEXT;
+ } else if (CUR == '"'){
+ NEXT;
+ if ((CUR == 'n') && (NXT(1) == 'o')) {
+ standalone = 0;
+ SKIP(2);
+ } else if ((CUR == 'y') && (NXT(1) == 'e') &&
+ (NXT(2) == 's')) {
+ standalone = 1;
+ SKIP(3);
+ } else {
+ xmlParserError(ctxt, "standalone accepts only 'yes' or 'no'\n");
+ }
+ if (CUR != '"')
+ xmlParserError(ctxt, "String not closed\n");
+ else
+ NEXT;
+ } else {
+ xmlParserError(ctxt, "Standalone value not found\n");
+ }
+ }
+ return(standalone);
+}
+
+/*
+ * xmlParseXMLDecl: parse an XML declaration header
+ *
+ * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
+ */
+
+void xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
+ CHAR *version;
+
+ /*
+ * We know that '<?xml' is here.
+ */
+ SKIP(5);
+
+ SKIP_BLANKS;
+
+ /*
+ * We should have the VersionInfo here.
+ */
+ version = xmlParseVersionInfo(ctxt);
+ if (version == NULL)
+ version = xmlCharStrdup(XML_DEFAULT_VERSION);
+ ctxt->doc = xmlNewDoc(version);
+ free(version);
+
+ /*
+ * We may have the encoding declaration
+ */
+ ctxt->doc->encoding = xmlParseEncodingDecl(ctxt);
+
+ /*
+ * We may have the standalone status.
+ */
+ ctxt->doc->standalone = xmlParseSDDecl(ctxt);
+
+ SKIP_BLANKS;
+ if ((CUR == '?') && (NXT(1) == '>')) {
+ SKIP(2);
+ } else if (CUR == '>') {
+ /* Deprecated old WD ... */
+ xmlParserError(ctxt, "XML declaration must end-up with '?>'\n");
+ NEXT;
+ } else {
+ xmlParserError(ctxt, "parsing XML declaration: '?>' expected\n");
+ MOVETO_ENDTAG(CUR_PTR);
+ NEXT;
+ }
+}
+
+/*
+ * xmlParseMisc: parse an XML Misc* optionnal field.
+ * Misc*
+ *
+ * [27] Misc ::= Comment | PI | S
+ */
+
+void xmlParseMisc(xmlParserCtxtPtr ctxt) {
+ while (((CUR == '<') && (NXT(1) == '?')) ||
+ ((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == '-') && (NXT(3) == '-')) ||
+ IS_BLANK(CUR)) {
+ if ((CUR == '<') && (NXT(1) == '?')) {
+ xmlParsePI(ctxt);
+ } else if (IS_BLANK(CUR)) {
+ NEXT;
+ } else
+ xmlParseComment(ctxt, 0);
+ }
+}
+
+/*
+ * xmlParseDocument : parse an XML document and build a tree.
+ *
+ * [1] document ::= prolog element Misc*
+ *
+ * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
+ */
+
+int xmlParseDocument(xmlParserCtxtPtr ctxt) {
+ xmlDefaultSAXHandlerInit();
+
+ /*
+ * SAX: beginning of the document processing.
+ */
+ if (ctxt->sax)
+ ctxt->sax->setDocumentLocator(ctxt, &xmlDefaultSAXLocator);
+ if (ctxt->sax)
+ ctxt->sax->startDocument(ctxt);
+
+ /*
+ * We should check for encoding here and plug-in some
+ * conversion code TODO !!!!
+ */
+
+ /*
+ * Wipe out everything which is before the first '<'
+ */
+ SKIP_BLANKS;
+
+ /*
+ * Check for the XMLDecl in the Prolog.
+ */
+ if ((CUR == '<') && (NXT(1) == '?') &&
+ (NXT(2) == 'x') && (NXT(3) == 'm') &&
+ (NXT(4) == 'l')) {
+ xmlParseXMLDecl(ctxt);
+ /* SKIP_EOL(cur); */
+ SKIP_BLANKS;
+ } else if ((CUR == '<') && (NXT(1) == '?') &&
+ (NXT(2) == 'X') && (NXT(3) == 'M') &&
+ (NXT(4) == 'L')) {
+ /*
+ * The first drafts were using <?XML and the final W3C REC
+ * now use <?xml ...
+ */
+ xmlParseXMLDecl(ctxt);
+ /* SKIP_EOL(cur); */
+ SKIP_BLANKS;
+ } else {
+ CHAR *version;
+
+ version = xmlCharStrdup(XML_DEFAULT_VERSION);
+ ctxt->doc = xmlNewDoc(version);
+ free(version);
+ }
+
+ /*
+ * The Misc part of the Prolog
+ */
+ xmlParseMisc(ctxt);
+
+ /*
+ * Then possibly doc type declaration(s) and more Misc
+ * (doctypedecl Misc*)?
+ */
+ if ((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == 'D') && (NXT(3) == 'O') &&
+ (NXT(4) == 'C') && (NXT(5) == 'T') &&
+ (NXT(6) == 'Y') && (NXT(7) == 'P') &&
+ (NXT(8) == 'E')) {
+ xmlParseDocTypeDecl(ctxt);
+ xmlParseMisc(ctxt);
+ }
+
+ /*
+ * Time to start parsing the tree itself
+ */
+ ctxt->doc->root = xmlParseElement(ctxt);
+
+ /*
+ * The Misc part at the end
+ */
+ xmlParseMisc(ctxt);
+
+ /*
+ * SAX: end of the document processing.
+ */
+ if (ctxt->sax)
+ ctxt->sax->endDocument(ctxt);
+ return(0);
+}
+
+/*
+ * xmlParseDoc : parse an XML in-memory document and build a tree.
+ */
+
+xmlDocPtr xmlParseDoc(CHAR *cur) {
+ xmlDocPtr ret;
+ xmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
+
+ if (cur == NULL) return(NULL);
+
+ ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
+ if (ctxt == NULL) {
+ perror("malloc");
+ return(NULL);
+ }
+ xmlInitParserCtxt(ctxt);
+ input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
+ if (input == NULL) {
+ perror("malloc");
+ free(ctxt);
+ return(NULL);
+ }
+
+ input->filename = NULL;
+ input->line = 1;
+ input->col = 1;
+ input->base = cur;
+ input->cur = cur;
+
+ inputPush(ctxt, input);
+
+
+ xmlParseDocument(ctxt);
+ ret = ctxt->doc;
+ free(ctxt);
+
+ return(ret);
+}
+
+/*
+ * xmlParseFile : parse an XML file and build a tree.
+ */
+
+xmlDocPtr xmlParseFile(const char *filename) {
+ xmlDocPtr ret;
+#ifdef HAVE_ZLIB_H
+ gzFile input;
+#else
+ int input;
+#endif
+ int res;
+ struct stat buf;
+ char *buffer;
+ xmlParserCtxtPtr ctxt;
+ xmlParserInputPtr inputStream;
+
+ res = stat(filename, &buf);
+ if (res < 0) return(NULL);
+
+#ifdef HAVE_ZLIB_H
+retry_bigger:
+ buffer = malloc((buf.st_size * 20) + 100);
+#else
+ buffer = malloc(buf.st_size + 100);
+#endif
+ if (buffer == NULL) {
+ perror("malloc");
+ return(NULL);
+ }
+
+ memset(buffer, 0, sizeof(buffer));
+#ifdef HAVE_ZLIB_H
+ input = gzopen (filename, "r");
+ if (input == NULL) {
+ fprintf (stderr, "Cannot read file %s :\n", filename);
+ perror ("gzopen failed");
+ return(NULL);
+ }
+#else
+ input = open (filename, O_RDONLY);
+ if (input < 0) {
+ fprintf (stderr, "Cannot read file %s :\n", filename);
+ perror ("open failed");
+ return(NULL);
+ }
+#endif
+#ifdef HAVE_ZLIB_H
+ res = gzread(input, buffer, 20 * buf.st_size);
+#else
+ res = read(input, buffer, buf.st_size);
+#endif
+ if (res < 0) {
+ fprintf (stderr, "Cannot read file %s :\n", filename);
+#ifdef HAVE_ZLIB_H
+ perror ("gzread failed");
+#else
+ perror ("read failed");
+#endif
+ return(NULL);
+ }
+#ifdef HAVE_ZLIB_H
+ gzclose(input);
+ if (res >= 20 * buf.st_size) {
+ free(buffer);
+ buf.st_size *= 2;
+ goto retry_bigger;
+ }
+ buf.st_size = res;
+#else
+ close(input);
+#endif
+
+ buffer[buf.st_size] = '\0';
+
+ ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
+ if (ctxt == NULL) {
+ perror("malloc");
+ return(NULL);
+ }
+ xmlInitParserCtxt(ctxt);
+ inputStream = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
+ if (inputStream == NULL) {
+ perror("malloc");
+ free(ctxt);
+ return(NULL);
+ }
+
+ inputStream->filename = strdup(filename);
+ inputStream->line = 1;
+ inputStream->col = 1;
+
+ /*
+ * TODO : plug some encoding conversion routines here. !!!
+ */
+ inputStream->base = buffer;
+ inputStream->cur = buffer;
+
+ inputPush(ctxt, inputStream);
+
+ xmlParseDocument(ctxt);
+
+ ret = ctxt->doc;
+ free(buffer);
+ free(ctxt);
+
+ return(ret);
+}
+
+
+/*
+ * xmlParseMemory : parse an XML memory block and build a tree.
+ */
+xmlDocPtr xmlParseMemory(char *buffer, int size) {
+ xmlDocPtr ret;
+ xmlParserCtxtPtr ctxt;
+ xmlParserInputPtr input;
+
+ buffer[size - 1] = '\0';
+
+ ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
+ if (ctxt == NULL) {
+ perror("malloc");
+ return(NULL);
+ }
+ xmlInitParserCtxt(ctxt);
+ input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
+ if (input == NULL) {
+ perror("malloc");
+ free(ctxt);
+ return(NULL);
+ }
+
+ input->filename = NULL;
+ input->line = 1;
+ input->col = 1;
+
+ /*
+ * TODO : plug some encoding conversion routines here. !!!
+ */
+ input->base = buffer;
+ input->cur = buffer;
+
+ inputPush(ctxt, input);
+
+ xmlParseDocument(ctxt);
+
+ ret = ctxt->doc;
+ free(ctxt);
+
+ return(ret);
+}
+
+
+/* Initialize parser context */
+void xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
+{
+ /* Allocate the Input stack */
+ ctxt->inputTab = (xmlParserInputPtr *) malloc(5 * sizeof(xmlParserInputPtr));
+ ctxt->inputNr = 0;
+ ctxt->inputMax = 5;
+ ctxt->input = NULL;
+
+ /* Allocate the Node stack */
+ ctxt->nodeTab = (xmlNodePtr *) malloc(10 * sizeof(xmlNodePtr));
+ ctxt->nodeNr = 0;
+ ctxt->nodeMax = 10;
+ ctxt->node = NULL;
+
+ ctxt->sax = &xmlDefaultSAXHandler;
+ ctxt->doc = NULL;
+ ctxt->record_info = 0;
+ xmlInitNodeInfoSeq(&ctxt->node_seq);
+}
+
+
+/*
+ * Clear (release owned resources) and reinitialize context
+ */
+void xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
+{
+ xmlClearNodeInfoSeq(&ctxt->node_seq);
+ xmlInitParserCtxt(ctxt);
+}
+
+
+/*
+ * Setup the parser context to parse a new buffer; Clears any prior
+ * contents from the parser context. The buffer parameter must not be
+ * NULL, but the filename parameter can be
+ */
+void xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const CHAR* buffer,
+ const char* filename)
+{
+ xmlParserInputPtr input;
+
+ input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
+ if (input == NULL) {
+ perror("malloc");
+ free(ctxt);
+ exit(1);
+ }
+
+ xmlClearParserCtxt(ctxt);
+ if (input->filename != NULL)
+ input->filename = strdup(filename);
+ else
+ input->filename = NULL;
+ input->line = 1;
+ input->col = 1;
+ input->base = buffer;
+ input->cur = buffer;
+
+ inputPush(ctxt, input);
+}
+
+
+/*
+ * xmlParserFindNodeInfo : Find the parser node info struct for a given node
+ */
+const xmlParserNodeInfo* xmlParserFindNodeInfo(const xmlParserCtxt* ctx,
+ const xmlNode* node)
+{
+ unsigned long pos;
+
+ /* Find position where node should be at */
+ pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
+ if ( ctx->node_seq.buffer[pos].node == node )
+ return &ctx->node_seq.buffer[pos];
+ else
+ return NULL;
+}
+
+
+/*
+ * xmlInitNodeInfoSeq -- Initialize (set to initial state) node info sequence
+ */
+void xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
+{
+ seq->length = 0;
+ seq->maximum = 0;
+ seq->buffer = NULL;
+}
+
+/*
+ * xmlClearNodeInfoSeq -- Clear (release memory and reinitialize) node
+ * info sequence
+ */
+void xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
+{
+ if ( seq->buffer != NULL )
+ free(seq->buffer);
+ xmlInitNodeInfoSeq(seq);
+}
+
+
+/*
+ * xmlParserFindNodeInfoIndex : Find the index that the info record for
+ * the given node is or should be at in a sorted sequence
+ */
+unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
+ const xmlNode* node)
+{
+ unsigned long upper, lower, middle;
+ int found = 0;
+
+ /* Do a binary search for the key */
+ lower = 1;
+ upper = seq->length;
+ middle = 0;
+ while ( lower <= upper && !found) {
+ middle = lower + (upper - lower) / 2;
+ if ( node == seq->buffer[middle - 1].node )
+ found = 1;
+ else if ( node < seq->buffer[middle - 1].node )
+ upper = middle - 1;
+ else
+ lower = middle + 1;
+ }
+
+ /* Return position */
+ if ( middle == 0 || seq->buffer[middle - 1].node < node )
+ return middle;
+ else
+ return middle - 1;
+}
+
+
+/*
+ * xmlParserAddNodeInfo : Insert node info record into sorted sequence
+ */
+void xmlParserAddNodeInfo(xmlParserCtxtPtr ctx,
+ const xmlParserNodeInfo* info)
+{
+ unsigned long pos;
+ static unsigned int block_size = 5;
+
+ /* Find pos and check to see if node is already in the sequence */
+ pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, info->node);
+ if ( pos < ctx->node_seq.length
+ && ctx->node_seq.buffer[pos].node == info->node ) {
+ ctx->node_seq.buffer[pos] = *info;
+ }
+
+ /* Otherwise, we need to add new node to buffer */
+ else {
+ /* Expand buffer by 5 if needed */
+ if ( ctx->node_seq.length + 1 > ctx->node_seq.maximum ) {
+ xmlParserNodeInfo* tmp_buffer;
+ unsigned int byte_size = (sizeof(*ctx->node_seq.buffer)
+ *(ctx->node_seq.maximum + block_size));
+
+ if ( ctx->node_seq.buffer == NULL )
+ tmp_buffer = (xmlParserNodeInfo*)malloc(byte_size);
+ else
+ tmp_buffer = (xmlParserNodeInfo*)realloc(ctx->node_seq.buffer, byte_size);
+
+ if ( tmp_buffer == NULL ) {
+ xmlParserError(ctx, "Out of memory");
+ return;
+ }
+ ctx->node_seq.buffer = tmp_buffer;
+ ctx->node_seq.maximum += block_size;
+ }
+
+ /* If position is not at end, move elements out of the way */
+ if ( pos != ctx->node_seq.length ) {
+ unsigned long i;
+
+ for ( i = ctx->node_seq.length; i > pos; i-- )
+ ctx->node_seq.buffer[i] = ctx->node_seq.buffer[i - 1];
+ }
+
+ /* Copy element and increase length */
+ ctx->node_seq.buffer[pos] = *info;
+ ctx->node_seq.length++;
+ }
+}
diff --git a/parser.h b/parser.h
new file mode 100644
index 0000000..a25e70a
--- /dev/null
+++ b/parser.h
@@ -0,0 +1,168 @@
+/*
+ * parser.h : constants and stuff related to the XML parser.
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_PARSER_H__
+#define __XML_PARSER_H__
+
+#include "tree.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Constants.
+ */
+#define XML_DEFAULT_VERSION "1.0"
+
+typedef struct xmlParserInput {
+ const char *filename; /* The file analyzed, if any */
+ const CHAR *base; /* Base of the array to parse */
+ const CHAR *cur; /* Current char being parsed */
+ int line; /* Current line */
+ int col; /* Current column */
+} xmlParserInput, *xmlParserInputPtr;
+
+typedef struct xmlParserNodeInfo {
+ const struct xmlNode* node;
+ /* Position & line # that text that created the node begins & ends on */
+ unsigned long begin_pos;
+ unsigned long begin_line;
+ unsigned long end_pos;
+ unsigned long end_line;
+} xmlParserNodeInfo;
+
+typedef struct xmlParserNodeInfoSeq {
+ unsigned long maximum;
+ unsigned long length;
+ xmlParserNodeInfo* buffer;
+} xmlParserNodeInfoSeq, *xmlParserNodeInfoSeqPtr;
+
+typedef struct xmlParserCtxt {
+ struct xmlSAXHandler *sax; /* The SAX handler */
+ xmlDocPtr doc; /* the document being built */
+
+ /* Input stream stack */
+ xmlParserInputPtr input; /* Current input stream */
+ int inputNr; /* Number of current input streams */
+ int inputMax; /* Max number of input streams */
+ xmlParserInputPtr *inputTab; /* stack of inputs */
+
+ /* Node analysis stack */
+ xmlNodePtr node; /* Current parsed Node */
+ int nodeNr; /* Depth of the parsing stack */
+ int nodeMax; /* Max depth of the parsing stack */
+ xmlNodePtr *nodeTab; /* array of nodes */
+
+ int record_info; /* Whether node info should be kept */
+ xmlParserNodeInfoSeq node_seq; /* info about each node parsed */
+} xmlParserCtxt, *xmlParserCtxtPtr;
+
+/*
+ * a SAX Locator.
+ */
+
+typedef struct xmlSAXLocator {
+ const CHAR *(*getPublicId)(xmlParserCtxtPtr ctxt);
+ const CHAR *(*getSystemId)(xmlParserCtxtPtr ctxt);
+ int (*getLineNumber)(xmlParserCtxtPtr ctxt);
+ int (*getColumnNumber)(xmlParserCtxtPtr ctxt);
+} xmlSAXLocator, *xmlSAXLocatorPtr;
+
+/*
+ * a SAX Exception.
+ */
+
+typedef xmlParserInputPtr (*resolveEntitySAXFunc) (xmlParserCtxtPtr ctxt,
+ const CHAR *publicId, const CHAR *systemId);
+typedef void (*notationDeclSAXFunc)(xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR *publicId, const CHAR *systemId);
+typedef void (*unparsedEntityDeclSAXFunc)(xmlParserCtxtPtr ctxt,
+ const CHAR *name, const CHAR *publicId,
+ const CHAR *systemId, const CHAR *notationName);
+typedef void (*setDocumentLocatorSAXFunc) (xmlParserCtxtPtr ctxt,
+ xmlSAXLocatorPtr loc);
+typedef void (*startDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef void (*endDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef void (*startElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
+typedef void (*endElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
+typedef void (*charactersSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *ch,
+ int start, int len);
+typedef void (*ignorableWhitespaceSAXFunc) (xmlParserCtxtPtr ctxt,
+ const CHAR *ch, int start, int len);
+typedef void (*processingInstructionSAXFunc) (xmlParserCtxtPtr ctxt,
+ const CHAR *target, const CHAR *data);
+typedef void (*warningSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+typedef void (*errorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+typedef void (*fatalErrorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+
+typedef struct xmlSAXHandler {
+ resolveEntitySAXFunc resolveEntity;
+ notationDeclSAXFunc notationDecl;
+ unparsedEntityDeclSAXFunc unparsedEntityDecl;
+ setDocumentLocatorSAXFunc setDocumentLocator;
+ startDocumentSAXFunc startDocument;
+ endDocumentSAXFunc endDocument;
+ startElementSAXFunc startElement;
+ endElementSAXFunc endElement;
+ charactersSAXFunc characters;
+ ignorableWhitespaceSAXFunc ignorableWhitespace;
+ processingInstructionSAXFunc processingInstruction;
+ warningSAXFunc warning;
+ errorSAXFunc error;
+ fatalErrorSAXFunc fatalError;
+} xmlSAXHandler, *xmlSAXHandlerPtr;
+
+/*
+ * Global variables: just the SAX interface tables we are looking for full
+ * reentrancy of the code !
+ */
+xmlSAXLocator xmlDefaultSAXLocator;
+xmlSAXHandler xmlDefaultSAXHandler;
+
+/*
+ * Interfaces
+ */
+extern int xmlParseDocument(xmlParserCtxtPtr ctxt);
+extern xmlDocPtr xmlParseDoc(CHAR *cur);
+extern xmlDocPtr xmlParseMemory(char *buffer, int size);
+extern xmlDocPtr xmlParseFile(const char *filename);
+extern CHAR *xmlStrdup(const CHAR *input);
+extern CHAR *xmlStrndup(const CHAR *input, int n);
+extern CHAR *xmlStrchr(const CHAR *str, CHAR val);
+extern int xmlStrcmp(const CHAR *str1, const CHAR *str2);
+extern int xmlStrncmp(const CHAR *str1, const CHAR *str2, int len);
+extern int xmlStrlen(const CHAR *str);
+extern CHAR *xmlStrcat(CHAR *cur, const CHAR *add);
+extern CHAR *xmlStrncat(CHAR *cur, const CHAR *add, int len);
+
+extern void xmlInitParserCtxt(xmlParserCtxtPtr ctx);
+extern void xmlClearParserCtxt(xmlParserCtxtPtr ctx);
+extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer,
+ const char* filename);
+
+extern void xmlParserError(xmlParserCtxtPtr ctxt, const char *msg, ...);
+
+extern const xmlParserNodeInfo* xmlParserFindNodeInfo(const xmlParserCtxt* c,
+ const xmlNode* node);
+extern void xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq);
+extern void xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq);
+unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeq* seq,
+ const xmlNode* node);
+extern void xmlParserAddNodeInfo(xmlParserCtxtPtr ctx,
+ const xmlParserNodeInfo* info);
+
+extern void xmlParserWarning(xmlParserCtxtPtr ctxt, const char *msg, ...);
+extern void xmlParserError(xmlParserCtxtPtr ctxt, const char *msg, ...);
+extern void xmlDefaultSAXHandlerInit(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_PARSER_H__ */
+
diff --git a/result/dav1 b/result/dav1
index 942f5ee..515463f 100644
--- a/result/dav1
+++ b/result/dav1
@@ -1,10 +1,5 @@
-
-
-------- test/dav1 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.foo.bar/boxschema" prefix="R"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/" xmlns:R="http://www.foo.bar/boxschema">
<D:response>
<D:prop>
<R:bigbox>
diff --git a/result/dav10 b/result/dav10
index eca7ad6..4b00da4 100644
--- a/result/dav10
+++ b/result/dav10
@@ -1,8 +1,4 @@
-
-
-------- test/dav10 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:owner>
+<D:owner xmlns:D="http://www.ietf.org/standards/dav/">
<D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href>
</D:owner>
diff --git a/result/dav11 b/result/dav11
index 9c7816e..a8e9c6f 100644
--- a/result/dav11
+++ b/result/dav11
@@ -1,9 +1,5 @@
-
-
-------- test/dav11 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:prop>
+<D:prop xmlns:D="http://www.ietf.org/standards/dav/">
<D:lockdiscovery>
<D:activelock>
<D:locktype>write</D:locktype>
diff --git a/result/dav12 b/result/dav12
index 9b6cbf1..d8d03fe 100644
--- a/result/dav12
+++ b/result/dav12
@@ -1,6 +1,2 @@
-
-
-------- test/dav12 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href>
+<D:href xmlns:D="http://www.ietf.org/standards/dav/">http://www.ics.uci.edu/~ejw/contact.html</D:href>
diff --git a/result/dav13 b/result/dav13
index 9ce781c..425aa43 100644
--- a/result/dav13
+++ b/result/dav13
@@ -1,9 +1,5 @@
-
-
-------- test/dav13 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/">
<D:response>
<D:href>
http://webdav.sb.aol.com/workspace/webdav/proposal.doc
diff --git a/result/dav14 b/result/dav14
deleted file mode 100644
index bf53797..0000000
--- a/result/dav14
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-------- test/dav14 -----------
-<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/patch/" prefix="D"?>
-<D:resourceupdate>
- <D:replace XML-SPACE="PRESERVE">
- <D:octet-range>14</D:octet-range>
-003CTITLE003ENew
- Title003C/TITLE003E </D:replace>
- <D:delete>
- <D:octet-range>38-50</D:octet-range>
- </D:delete>
- <D:insert XML-SPACE="PRESERVE">
- <D:octet-range>86</D:octet-range>
-003CP003ENew paragraph003C/P003E </D:insert>
-</D:resourceupdate>
diff --git a/result/dav15 b/result/dav15
index 7703289..b80802e 100644
--- a/result/dav15
+++ b/result/dav15
@@ -1,10 +1,5 @@
-
-
-------- test/dav15 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.foocorp.com/Project/" prefix="F"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:prop>
+<D:prop xmlns:D="http://www.ietf.org/standards/dav/" xmlns:F="http://www.foocorp.com/Project/">
<D:Source>
<D:link>
<F:projfiles>Source</F:projfiles>
diff --git a/result/dav16 b/result/dav16
index 3585ab1..9a7dc36 100644
--- a/result/dav16
+++ b/result/dav16
@@ -1,9 +1,5 @@
-
-
-------- test/dav16 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:propfind>
+<D:propfind xmlns:D="http://www.ietf.org/standards/dav/">
<D:prop>
<lockdiscovery/>
</D:prop>
diff --git a/result/dav17 b/result/dav17
index 30a10af..1137662 100644
--- a/result/dav17
+++ b/result/dav17
@@ -1,9 +1,5 @@
-
-
-------- test/dav17 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/">
<D:response>
<D:prop>
<D:lockdiscovery>
diff --git a/result/dav18 b/result/dav18
index 245dbdb..3de1c19 100644
--- a/result/dav18
+++ b/result/dav18
@@ -1,9 +1,5 @@
-
-
-------- test/dav18 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:propfind>
+<D:propfind xmlns:D="http://www.ietf.org/standards/dav/">
<D:prop>
<supportedlock/>
</D:prop>
diff --git a/result/dav19 b/result/dav19
index b748232..9535ffc 100644
--- a/result/dav19
+++ b/result/dav19
@@ -1,9 +1,5 @@
-
-
-------- test/dav19 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/">
<D:response>
<D:prop>
<D:supportedlock>
diff --git a/result/dav2 b/result/dav2
index f7efb03..f831b4b 100644
--- a/result/dav2
+++ b/result/dav2
@@ -1,10 +1,5 @@
-
-
-------- test/dav2 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.foo.bar/boxschema/" prefix="R"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="S"?>
-<S:multistatus>
+<S:multistatus xmlns:S="http://www.ietf.org/standards/dav/" xmlns:R="http://www.foo.bar/boxschema/">
<S:response>
<S:href>http://www.foo.bar/container/</S:href>
<S:prop>
diff --git a/result/dav3 b/result/dav3
index c4c235a..986b3fe 100644
--- a/result/dav3
+++ b/result/dav3
@@ -1,10 +1,5 @@
-
-
-------- test/dav3 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.foo.bar/boxschema/" prefix="R"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/" xmlns:R="http://www.foo.bar/boxschema/">
<D:response>
<D:href>http://www.foo.bar/container/</D:href>
<D:prop>
diff --git a/result/dav4 b/result/dav4
index 3c38b64..9ab7ceb 100644
--- a/result/dav4
+++ b/result/dav4
@@ -1,10 +1,5 @@
-
-
-------- test/dav4 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.w3.com/standards/z39.50/" prefix="Z"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:propertyupdate>
+<D:propertyupdate xmlns:D="http://www.ietf.org/standards/dav/" xmlns:Z="http://www.w3.com/standards/z39.50/">
<D:set>
<D:prop>
<Z:authors>
diff --git a/result/dav5 b/result/dav5
index cb8c1dd..4647496 100644
--- a/result/dav5
+++ b/result/dav5
@@ -1,10 +1,5 @@
-
-
-------- test/dav5 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.w3.com/standards/z39.50/" prefix="Z"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/" xmlns:Z="http://www.w3.com/standards/z39.50/">
<D:response>
<D:prop>
<Z:Authors/>
diff --git a/result/dav6 b/result/dav6
index 1fce59b..9dc1451 100644
--- a/result/dav6
+++ b/result/dav6
@@ -1,9 +1,5 @@
-
-
-------- test/dav6 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="D"?>
-<D:multistatus>
+<D:multistatus xmlns:D="http://www.ietf.org/standards/dav/">
<D:response>
<D:href>http://www.microsoft.com/user/yarong/dav_drafts/
</D:href>
diff --git a/result/dav7 b/result/dav7
index 68f43ce..ec4a952 100644
--- a/result/dav7
+++ b/result/dav7
@@ -1,9 +1,5 @@
-
-
-------- test/dav7 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="d"?>
-<d:multistatus>
+<d:multistatus xmlns:d="http://www.ietf.org/standards/dav/">
<d:response>
<d:href>http://www.foo.bar/container/resource1</d:href>
<d:href>http://www.foo.bar/container/resource2</d:href>
diff --git a/result/dav8 b/result/dav8
index e285c19..7f99baf 100644
--- a/result/dav8
+++ b/result/dav8
@@ -1,9 +1,5 @@
-
-
-------- test/dav8 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="d"?>
-<d:multistatus>
+<d:multistatus xmlns:d="http://www.ietf.org/standards/dav/">
<d:response>
<d:href>http://www.foo.bar/othercontainer/resource1</d:href>
<d:href>http://www.foo.bar/othercontainer/resource2</d:href>
diff --git a/result/dav9 b/result/dav9
index 6c505b9..8ed63b8 100644
--- a/result/dav9
+++ b/result/dav9
@@ -1,9 +1,5 @@
-
-
-------- test/dav9 -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.ietf.org/standards/dav/" prefix="d"?>
-<d:multistatus>
+<d:multistatus xmlns:d="http://www.ietf.org/standards/dav/">
<d:response>
<d:href>http://www.foo.bar/container/resource1</d:href>
<d:href>http://www.foo.bar/container/resource2</d:href>
diff --git a/result/dtd1 b/result/dtd1
new file mode 100644
index 0000000..2cb4398
--- /dev/null
+++ b/result/dtd1
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<!DOCTYPE MEMO PUBLIC "-//SGMLSOURCE//DTD MEMO//EN" "http://www.sgmlsource.com/dtds/memo.dtd">
+<MEMO/>
diff --git a/result/ent1 b/result/ent1
new file mode 100644
index 0000000..14bf428
--- /dev/null
+++ b/result/ent1
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE>
+ Extensible Markup Language
+</EXAMPLE>
diff --git a/result/ent2 b/result/ent2
new file mode 100644
index 0000000..754f257
--- /dev/null
+++ b/result/ent2
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+<!ENTITY title PUBLIC "-//MY-TITLE//FR" "title.xml">
+<!ENTITY image SYSTEM "img.gif" NDATA GIF>
+]>
+<EXAMPLE>
+
+ This text is about XML, the Extensible Markup Language and this is an embedded
+</EXAMPLE>
diff --git a/result/ent3 b/result/ent3
new file mode 100644
index 0000000..b1c0b14
--- /dev/null
+++ b/result/ent3
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE prop1="a&b" prop2="Extensible Markup Language">
+ Test of entities in attributes.
+</EXAMPLE>
diff --git a/result/p3p b/result/p3p
index 41f5a35..75eec90 100644
--- a/result/p3p
+++ b/result/p3p
@@ -1,26 +1,22 @@
-
-
-------- test/p3p -----------
<?xml version="1.0"?>
-<?xml:namespace ns="http://www.w3.org/TR/WD-rdf-syntax#" prefix="RDF"?>
-<RDF:RDF>
- <PROP assurance="http://www.TrustUs.org" agreeID="94df1293a3e519bb" entity="CoolCatalog" realm="http://www.CoolCatalog.com/catalogue/">
+<RDF:RDF xmlns:p3p="http//www.w3.org/TR/1998/WD-P3P10-syntax#proposal.DTD" xmlns:RDF="http://www.w3.org/TR/WD-rdf-syntax#">
+ <PROP realm="http://www.CoolCatalog.com/catalogue/" entity="CoolCatalog" agreeID="94df1293a3e519bb" assurance="http://www.TrustUs.org">
<USES>
- <STATEMENT consq="a site with clothes you'd appreciate." id="0" recpnt="0" purp="2,3">
+ <STATEMENT purp="2,3" recpnt="0" id="0" consq="a site with clothes you'd appreciate.">
<WITH>
<PREFIX name="User.">
<REF name="Name.First"/>
- <REF optional="1" name="Bdate.Year"/>
+ <REF name="Bdate.Year" optional="1"/>
<REF name="Gender"/>
</PREFIX>
</WITH>
</STATEMENT>
</USES>
<USES>
- <STATEMENT id="1" recpnt="0" purp="0" action="read&write">
+ <STATEMENT action="read&write" purp="0" recpnt="0" id="1">
<REF name="User.Shipping."/>
</STATEMENT>
</USES>
- <DISCLOSURE other="0,1" access="3" discURI="http://www.CoolCatalog.com/PrivacyPractice.html"/>
+ <DISCLOSURE discURI="http://www.CoolCatalog.com/PrivacyPractice.html" access="3" other="0,1"/>
</PROP>
</RDF:RDF>
diff --git a/result/rdf1 b/result/rdf1
new file mode 100644
index 0000000..d44c3c6
--- /dev/null
+++ b/result/rdf1
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RPM="http://www.rpm.org/" xmlns:RDF="http://www.w3.org/TR/WD-rdf-syntax#">
+ <RDF:Description HREF="ftp://rufus.w3.org/linux/redhat/redhat-5.1/i386/RedHat/RPMS/rpm-2.5-2.i386.rpm">
+ <RPM:Name>rpm</RPM:Name>
+ <RPM:Version>2.5</RPM:Version>
+ <RPM:Release>2</RPM:Release>
+ <RPM:Arch>i386</RPM:Arch>
+ <RPM:Os>Linux</RPM:Os>
+ <RPM:Distribution>Manhattan </RPM:Distribution>
+ <RPM:Vendor>Red Hat Software</RPM:Vendor>
+ <RPM:Packager>Red Hat Software <bugs@redhat.com></RPM:Packager>
+ <RPM:Group>Utilities/System</RPM:Group>
+ <RPM:Summary>Red Hat Package Manager</RPM:Summary>
+ <RPM:Description>RPM is a powerful package manager, which can be used to build, install,
+query, verify, update, and uninstall individual software packages. A
+package consists of an archive of files, and package information, including
+name, version, and description.</RPM:Description>
+ <RPM:Copyright>GPL</RPM:Copyright>
+ <RPM:Changelog>* Sun May 10 1998 Prospector System <bugs@redhat.com>
+ - translations modified for de, fr, tr
+</RPM:Changelog>
+ <RPM:Sources>rpm-2.5-2.src.rpm</RPM:Sources>
+ <RPM:SourcesFtp>ftp://ftp.redhat.com/pub/redhat/redhat-5.1/SRPMS</RPM:SourcesFtp>
+ <RPM:BuildDate>Sun May 10 14:52:32 1998</RPM:BuildDate>
+ <RPM:Date>894826352</RPM:Date>
+ <RPM:Size>850599</RPM:Size>
+ <RPM:BuildHost>porky.redhat.com</RPM:BuildHost>
+ <RPM:Provides>
+ <RDF:Bag>
+ <RPM:Resource>rpm</RPM:Resource>
+ </RDF:Bag>
+ </RPM:Provides>
+ <RPM:Requires>
+ <RDF:Bag>
+ <RPM:Resource>/bin/sh</RPM:Resource>
+ <RPM:Resource>ld-linux.so.2</RPM:Resource>
+ <RPM:Resource>libc.so.6</RPM:Resource>
+ <RPM:Resource>libdb.so.2</RPM:Resource>
+ <RPM:Resource>libz.so.1</RPM:Resource>
+ <RPM:Resource>/bin/bash</RPM:Resource>
+ <RPM:Resource>/bin/sh</RPM:Resource>
+ </RDF:Bag>
+ </RPM:Requires>
+ <RPM:Files>/bin/rpm
+/usr/bin/find-provides
+/usr/bin/find-requires
+/usr/bin/gendiff
+/usr/bin/rpm2cpio
+/usr/doc/rpm-2.5
+/usr/doc/rpm-2.5/CHANGES
+/usr/doc/rpm-2.5/RPM-PGP-KEY
+/usr/doc/rpm-2.5/buildroot
+/usr/doc/rpm-2.5/dependencies
+/usr/doc/rpm-2.5/format
+/usr/doc/rpm-2.5/groups
+/usr/doc/rpm-2.5/macros
+/usr/doc/rpm-2.5/queryformat
+/usr/doc/rpm-2.5/relocatable
+/usr/doc/rpm-2.5/signatures
+/usr/doc/rpm-2.5/spec
+/usr/doc/rpm-2.5/triggers
+/usr/lib/rpmpopt
+/usr/lib/rpmrc
+/usr/man/man8/rpm.8
+/usr/man/man8/rpm2cpio.8
+/usr/share/locale/de/LC_MESSAGES/rpm.mo
+/usr/share/locale/fr/LC_MESSAGES/rpm.mo
+/usr/share/locale/pt-br/LC_MESSAGES/rpm.mo
+/usr/share/locale/sv/LC_MESSAGES/rpm.mo
+/usr/share/locale/tr/LC_MESSAGES/rpm.mo
+/usr/src/redhat
+/usr/src/redhat/BUILD
+/usr/src/redhat/RPMS
+/usr/src/redhat/RPMS/i386
+/usr/src/redhat/RPMS/noarch
+/usr/src/redhat/SOURCES
+/usr/src/redhat/SPECS
+/usr/src/redhat/SRPMS
+</RPM:Files>
+ </RDF:Description>
+</RDF:RDF>
diff --git a/test/dav1 b/test/dav1
index e7ad9e6..47b66bf 100644
--- a/test/dav1
+++ b/test/dav1
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href ="http://www.ietf.org/standards/dav/" AS = "D"?>
<?namespace href = "http://www.foo.bar/boxschema" AS = "R"?>
<D:multistatus>
diff --git a/test/dav10 b/test/dav10
index 4a444b9..aa7f94f 100644
--- a/test/dav10
+++ b/test/dav10
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href="http://www.ietf.org/standards/dav/" AS = "D"?>
<D:owner>
<D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href>
diff --git a/test/dav11 b/test/dav11
index ece73dc..99e777b 100644
--- a/test/dav11
+++ b/test/dav11
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href ="http://www.ietf.org/standards/dav/" AS = "D"?>
<D:prop>
<D:lockdiscovery>
diff --git a/test/dav12 b/test/dav12
index 47a1a9d..eff2139 100644
--- a/test/dav12
+++ b/test/dav12
@@ -1,3 +1,3 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href="http://www.ietf.org/standards/dav/" AS = "D"?>
<D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href>
diff --git a/test/dav13 b/test/dav13
index df92ae5..bb83088 100644
--- a/test/dav13
+++ b/test/dav13
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
<D:multistatus>
<D:response>
diff --git a/test/dav14 b/test/dav14
deleted file mode 100644
index 7fe8bf4..0000000
--- a/test/dav14
+++ /dev/null
@@ -1,10 +0,0 @@
- <?XML version="1.0">
- <?namespace href = "http://www.ietf.org/standards/dav/patch/" AS =
- "D"?>
- <D:resourceupdate>
- <D:replace XML-SPACE = "PRESERVE">
- <D:octet-range>14</D:octet-range>&003CTITLE&003ENew
- Title&003C/TITLE&003E</D:replace>
- <D:delete><D:octet-range>38-50</D:octet-range></D:delete>
- <D:insert XML-SPACE = "PRESERVE"><D:octet-range>86</D:octet-range>&003CP&003ENew paragraph&003C/P&003E</D:insert>
- </D:resourceupdate>
diff --git a/test/dav15 b/test/dav15
index 1d35430..201e90a 100644
--- a/test/dav15
+++ b/test/dav15
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
<?namespace href = "http://www.foocorp.com/Project/" AS = "F"?>
<D:prop>
diff --git a/test/dav16 b/test/dav16
index 29fe256..ea4d7b8 100644
--- a/test/dav16
+++ b/test/dav16
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
<D:propfind>
<D:prop><lockdiscovery/></D:prop>
diff --git a/test/dav17 b/test/dav17
index f1dabda..4aa20c8 100644
--- a/test/dav17
+++ b/test/dav17
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href ="http://www.ietf.org/standards/dav/" AS = "D"?>
<D:multistatus>
<D:response>
diff --git a/test/dav18 b/test/dav18
index 545c7e5..cdf5daa 100644
--- a/test/dav18
+++ b/test/dav18
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
<D:propfind>
<D:prop><supportedlock/></D:prop>
diff --git a/test/dav19 b/test/dav19
index e75fedb..d6d2e96 100644
--- a/test/dav19
+++ b/test/dav19
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href ="http://www.ietf.org/standards/dav/" AS = "D"?>
<D:multistatus>
<D:response>
diff --git a/test/dav2 b/test/dav2
index 2b73d5f..af100a8 100644
--- a/test/dav2
+++ b/test/dav2
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "S"?>
<?namespace href = "http://www.foo.bar/boxschema/" AS = "R"?>
<S:multistatus>
diff --git a/test/dav3 b/test/dav3
index 964f344..7618a41 100644
--- a/test/dav3
+++ b/test/dav3
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
<?namespace href = "http://www.foo.bar/boxschema/" AS = "R"?>
<D:multistatus>
diff --git a/test/dav4 b/test/dav4
index 26f6153..4ba4ad9 100644
--- a/test/dav4
+++ b/test/dav4
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
<?namespace href = "http://www.w3.com/standards/z39.50/" AS = "Z"?>
<D:propertyupdate>
diff --git a/test/dav5 b/test/dav5
index b51b0f8..ee9fa37 100644
--- a/test/dav5
+++ b/test/dav5
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href="http://www.ietf.org/standards/dav/" AS = "D"?>
<?namespace href="http://www.w3.com/standards/z39.50/" AS = "Z"?>
<D:multistatus>
diff --git a/test/dav6 b/test/dav6
index b970c8a..929848a 100644
--- a/test/dav6
+++ b/test/dav6
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "D"?>
<D:multistatus>
<D:response>
diff --git a/test/dav7 b/test/dav7
index 7ed12fa..feafe39 100644
--- a/test/dav7
+++ b/test/dav7
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "d"?>
<d:multistatus>
<d:response>
diff --git a/test/dav8 b/test/dav8
index b5c0c6b..220ebe3 100644
--- a/test/dav8
+++ b/test/dav8
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "d"?>
<d:multistatus>
<d:response>
diff --git a/test/dav9 b/test/dav9
index a1dfa43..4201300 100644
--- a/test/dav9
+++ b/test/dav9
@@ -1,4 +1,4 @@
- <?XML version="1.0">
+ <?XML version="1.0"?>
<?namespace href = "http://www.ietf.org/standards/dav/" AS = "d"?>
<d:multistatus>
<d:response>
diff --git a/test/dtd1 b/test/dtd1
new file mode 100644
index 0000000..35c9dc7
--- /dev/null
+++ b/test/dtd1
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<!DOCTYPE MEMO PUBLIC "-//SGMLSOURCE//DTD MEMO//EN"
+ "http://www.sgmlsource.com/dtds/memo.dtd">
+<MEMO>
+</MEMO>
diff --git a/test/ent1 b/test/ent1
new file mode 100644
index 0000000..3e24756
--- /dev/null
+++ b/test/ent1
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE>
+ &xml;
+</EXAMPLE>
diff --git a/test/ent2 b/test/ent2
new file mode 100644
index 0000000..533f5a3
--- /dev/null
+++ b/test/ent2
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+<!ENTITY title PUBLIC "-//MY-TITLE//FR" "title.xml">
+<!ENTITY image SYSTEM "img.gif" NDATA GIF>
+]>
+<EXAMPLE>
+ &title;
+ This text is about XML, the &xml; and this is an embedded ℑ
+</EXAMPLE>
+
diff --git a/test/ent3 b/test/ent3
new file mode 100644
index 0000000..f9803b8
--- /dev/null
+++ b/test/ent3
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE prop1="a&b" prop2="&xml;">
+ Test of entities in attributes.
+</EXAMPLE>
+
diff --git a/test/p3p b/test/p3p
index 1a83af2..d21325e 100644
--- a/test/p3p
+++ b/test/p3p
@@ -1,3 +1,4 @@
+<?xml version="1.0"?>
<?xml:namespace ns="http//www.w3.org/TR/1998/WD-P3P10-syntax#proposal.DTD" prefix="p3p"?>
<?xml:namespace ns="http://www.w3.org/TR/WD-rdf-syntax#" prefix="RDF"?>
<RDF:RDF><PROP realm="http://www.CoolCatalog.com/catalogue/"
diff --git a/test/rdf1 b/test/rdf1
new file mode 100644
index 0000000..ea6763e
--- /dev/null
+++ b/test/rdf1
@@ -0,0 +1,83 @@
+<?XML version="1.0"?>
+<?namespace href="http://www.rpm.org/" AS="RPM"?>
+<?namespace href="http://www.w3.org/TR/WD-rdf-syntax#" AS="RDF"?>
+<RDF:RDF>
+ <RDF:Description RDF:HREF="ftp://rufus.w3.org/linux/redhat/redhat-5.1/i386/RedHat/RPMS/rpm-2.5-2.i386.rpm">
+ <RPM:Name>rpm</RPM:Name>
+ <RPM:Version>2.5</RPM:Version>
+ <RPM:Release>2</RPM:Release>
+ <RPM:Arch>i386</RPM:Arch>
+ <RPM:Os>Linux</RPM:Os>
+ <RPM:Distribution>Manhattan </RPM:Distribution>
+ <RPM:Vendor>Red Hat Software</RPM:Vendor>
+ <RPM:Packager>Red Hat Software <bugs@redhat.com></RPM:Packager>
+ <RPM:Group>Utilities/System</RPM:Group>
+ <RPM:Summary>Red Hat Package Manager</RPM:Summary>
+ <RPM:Description>RPM is a powerful package manager, which can be used to build, install,
+query, verify, update, and uninstall individual software packages. A
+package consists of an archive of files, and package information, including
+name, version, and description.</RPM:Description>
+ <RPM:Copyright>GPL</RPM:Copyright>
+ <RPM:Changelog>* Sun May 10 1998 Prospector System <bugs@redhat.com>
+ - translations modified for de, fr, tr
+</RPM:Changelog>
+ <RPM:Sources>rpm-2.5-2.src.rpm</RPM:Sources>
+ <RPM:SourcesFtp>ftp://ftp.redhat.com/pub/redhat/redhat-5.1/SRPMS</RPM:SourcesFtp>
+ <RPM:BuildDate>Sun May 10 14:52:32 1998</RPM:BuildDate>
+ <RPM:Date>894826352</RPM:Date>
+ <RPM:Size>850599</RPM:Size>
+ <RPM:BuildHost>porky.redhat.com</RPM:BuildHost>
+ <RPM:Provides>
+ <RDF:Bag>
+ <RPM:Resource>rpm</RPM:Resource>
+ </RDF:Bag>
+ </RPM:Provides>
+ <RPM:Requires>
+ <RDF:Bag>
+ <RPM:Resource>/bin/sh</RPM:Resource>
+ <RPM:Resource>ld-linux.so.2</RPM:Resource>
+ <RPM:Resource>libc.so.6</RPM:Resource>
+ <RPM:Resource>libdb.so.2</RPM:Resource>
+ <RPM:Resource>libz.so.1</RPM:Resource>
+ <RPM:Resource>/bin/bash</RPM:Resource>
+ <RPM:Resource>/bin/sh</RPM:Resource>
+ </RDF:Bag>
+ </RPM:Requires>
+ <RPM:Files>/bin/rpm
+/usr/bin/find-provides
+/usr/bin/find-requires
+/usr/bin/gendiff
+/usr/bin/rpm2cpio
+/usr/doc/rpm-2.5
+/usr/doc/rpm-2.5/CHANGES
+/usr/doc/rpm-2.5/RPM-PGP-KEY
+/usr/doc/rpm-2.5/buildroot
+/usr/doc/rpm-2.5/dependencies
+/usr/doc/rpm-2.5/format
+/usr/doc/rpm-2.5/groups
+/usr/doc/rpm-2.5/macros
+/usr/doc/rpm-2.5/queryformat
+/usr/doc/rpm-2.5/relocatable
+/usr/doc/rpm-2.5/signatures
+/usr/doc/rpm-2.5/spec
+/usr/doc/rpm-2.5/triggers
+/usr/lib/rpmpopt
+/usr/lib/rpmrc
+/usr/man/man8/rpm.8
+/usr/man/man8/rpm2cpio.8
+/usr/share/locale/de/LC_MESSAGES/rpm.mo
+/usr/share/locale/fr/LC_MESSAGES/rpm.mo
+/usr/share/locale/pt-br/LC_MESSAGES/rpm.mo
+/usr/share/locale/sv/LC_MESSAGES/rpm.mo
+/usr/share/locale/tr/LC_MESSAGES/rpm.mo
+/usr/src/redhat
+/usr/src/redhat/BUILD
+/usr/src/redhat/RPMS
+/usr/src/redhat/RPMS/i386
+/usr/src/redhat/RPMS/noarch
+/usr/src/redhat/SOURCES
+/usr/src/redhat/SPECS
+/usr/src/redhat/SRPMS
+</RPM:Files>
+ </RDF:Description>
+</RDF:RDF>
diff --git a/tester.c b/tester.c
index 030ee1c..0075ad7 100644
--- a/tester.c
+++ b/tester.c
@@ -6,20 +6,33 @@
* $Id$
*/
+#ifdef WIN32
+#define HAVE_FCNTL_H
+#include <io.h>
+#else
+#include <config.h>
+#endif
#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <stdio.h>
#include <string.h>
#include <malloc.h>
-#include "xml_parser.h"
-#include "xml_tree.h"
+#include "parser.h"
+#include "tree.h"
-#define MAX_BUF 500000
-
-static CHAR buffer[MAX_BUF] =
+/*
+ * Note: there is a couple of errors introduced on purpose.
+ */
+static CHAR buffer[] =
"\n\
<?xml version=\"1.0\">\n\
<?xml:namespace ns = \"http://www.ietf.org/standards/dav/\" prefix = \"D\"?>\n\
@@ -40,37 +53,31 @@
\n\
";
-int readFile(char *filename) {
- int input;
- int res;
- memset(buffer, 0, sizeof(buffer));
- input = open (filename, O_RDONLY);
- if (input < 0) {
- fprintf (stderr, "Cannot read file %s :\n", filename);
- perror ("open failed");
- return(-1);
- }
- res = read(input, buffer, sizeof(buffer));
- if (res < 0) {
- fprintf (stderr, "Cannot read file %s :\n", filename);
- perror ("read failed");
- return(-1);
- }
- if (res >= MAX_BUF) {
- fprintf (stderr, "Read only %d byte of %s, increase MAX_BUF\n",
- res, filename);
- return(-1);
- }
- close(input);
- return(res);
-}
-
-void parseAndPrint(CHAR *buf) {
+void parseAndPrintFile(char *filename) {
xmlDocPtr doc;
/*
- * build a fake XML document from a string;
+ * build an XML tree from a string;
+ */
+ doc = xmlParseFile(filename);
+
+ /*
+ * print it.
+ */
+ xmlDocDump(stdout, doc);
+
+ /*
+ * free it.
+ */
+ xmlFreeDoc(doc);
+}
+
+void parseAndPrintBuffer(CHAR *buf) {
+ xmlDocPtr doc;
+
+ /*
+ * build an XML tree from a string;
*/
doc = xmlParseDoc(buf);
@@ -90,13 +97,10 @@
if (argc > 1) {
for (i = 1; i < argc ; i++) {
- if (readFile(argv[i]) >= 0) {
- printf("\n\n------- %s -----------\n", argv[i]);
- parseAndPrint(buffer);
- }
+ parseAndPrintFile(argv[i]);
}
} else
- parseAndPrint(buffer);
+ parseAndPrintBuffer(buffer);
return(0);
}
diff --git a/tree.c b/tree.c
new file mode 100644
index 0000000..59d8454
--- /dev/null
+++ b/tree.c
@@ -0,0 +1,1209 @@
+/*
+ * tree.c : implemetation of access function for an XML tree.
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ *
+ * TODO Cleanup the Dump mechanism.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <string.h> /* for memset() only ! */
+
+#include "tree.h"
+#include "entities.h"
+
+static CHAR xmlStringText[] = { 't', 'e', 'x', 't', 0 };
+int oldXMLWDcompatibility = 0;
+int xmlIndentTreeOutput = 1;
+
+/************************************************************************
+ * *
+ * Allocation and deallocation of basic structures *
+ * *
+ ************************************************************************/
+
+/*
+ * Upgrade old Namespace and move them to the root of the document.
+ */
+
+void xmlUpgradeOldNs(xmlDocPtr doc) {
+ xmlNsPtr cur;
+
+ if ((doc == NULL) || (doc->oldNs == NULL)) return;
+ if (doc->root == NULL) {
+ fprintf(stderr, "xmlUpgradeOldNs: failed no root !\n");
+ return;
+ }
+
+ cur = doc->oldNs;
+ while (cur->next != NULL) {
+ cur->type = XML_LOCAL_NAMESPACE;
+ cur = cur->next;
+ }
+ cur->type = XML_LOCAL_NAMESPACE;
+ cur->next = doc->root->nsDef;
+ doc->root->nsDef = doc->oldNs;
+ doc->oldNs = NULL;
+}
+
+/*
+ * Creation of a new Namespace.
+ */
+xmlNsPtr xmlNewNs(xmlNodePtr node, const CHAR *href, const CHAR *prefix) {
+ xmlNsPtr cur;
+
+ if (href == NULL) {
+ fprintf(stderr, "xmlNewNs: href == NULL !\n");
+ return(NULL);
+ }
+
+ /*
+ * Allocate a new DTD and fill the fields.
+ */
+ cur = (xmlNsPtr) malloc(sizeof(xmlNs));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewNs : malloc failed\n");
+ return(NULL);
+ }
+
+ cur->type = XML_LOCAL_NAMESPACE;
+ if (href != NULL)
+ cur->href = xmlStrdup(href);
+ else
+ cur->href = NULL;
+ if (prefix != NULL)
+ cur->prefix = xmlStrdup(prefix);
+ else
+ cur->prefix = NULL;
+
+ /*
+ * Add it at the end to preserve parsing order ...
+ */
+ cur->next = NULL;
+ if (node != NULL) {
+ if (node->nsDef == NULL) {
+ node->nsDef = cur;
+ } else {
+ xmlNsPtr prev = node->nsDef;
+
+ while (prev->next != NULL) prev = prev->next;
+ prev->next = cur;
+ }
+ }
+
+ return(cur);
+}
+
+/*
+ * Creation of a new global namespace (the old way ...).
+ */
+xmlNsPtr xmlNewGlobalNs(xmlDocPtr doc, const CHAR *href, const CHAR *prefix) {
+ xmlNsPtr cur;
+
+ /*
+ * Allocate a new DTD and fill the fields.
+ */
+ cur = (xmlNsPtr) malloc(sizeof(xmlNs));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewNs : malloc failed\n");
+ return(NULL);
+ }
+
+ cur->type = XML_GLOBAL_NAMESPACE;
+ if (href != NULL)
+ cur->href = xmlStrdup(href);
+ else
+ cur->href = NULL;
+ if (prefix != NULL)
+ cur->prefix = xmlStrdup(prefix);
+ else
+ cur->prefix = NULL;
+
+ /*
+ * Add it at the end to preserve parsing order ...
+ */
+ cur->next = NULL;
+ if (doc != NULL) {
+ if (doc->oldNs == NULL) {
+ doc->oldNs = cur;
+ } else {
+ xmlNsPtr prev = doc->oldNs;
+
+ while (prev->next != NULL) prev = prev->next;
+ prev->next = cur;
+ }
+ }
+
+ return(cur);
+}
+
+/*
+ * Set the node namespace a posteriori
+ */
+void xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
+ if (node == NULL) {
+ fprintf(stderr, "xmlSetNs: node == NULL\n");
+ return;
+ }
+ node->ns = ns;
+}
+
+/*
+ * Freeing a Namespace
+ */
+void xmlFreeNs(xmlNsPtr cur) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlFreeNs : ns == NULL\n");
+ return;
+ }
+ if (cur->href != NULL) free((char *) cur->href);
+ if (cur->prefix != NULL) free((char *) cur->prefix);
+ memset(cur, -1, sizeof(xmlNs));
+ free(cur);
+}
+
+/*
+ * Freeing a Namespace list
+ */
+void xmlFreeNsList(xmlNsPtr cur) {
+ xmlNsPtr next;
+ if (cur == NULL) {
+ fprintf(stderr, "xmlFreeNsList : ns == NULL\n");
+ return;
+ }
+ while (cur != NULL) {
+ next = cur->next;
+ xmlFreeNs(cur);
+ cur = next;
+ }
+}
+
+/*
+ * Creation of a new DTD.
+ */
+xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *name,
+ const CHAR *ExternalID, const CHAR *SystemID) {
+ xmlDtdPtr cur;
+
+ if (doc->dtd != NULL) {
+ fprintf(stderr, "xmlNewDtd(%s): document %s already have a DTD %s\n",
+ /* !!! */ (char *) name, doc->name, /* !!! */ (char *)doc->dtd->name);
+ }
+
+ /*
+ * Allocate a new DTD and fill the fields.
+ */
+ cur = (xmlDtdPtr) malloc(sizeof(xmlDtd));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewNs : malloc failed\n");
+ return(NULL);
+ }
+
+ if (name != NULL)
+ cur->name = xmlStrdup(name);
+ else
+ cur->name = NULL;
+ if (ExternalID != NULL)
+ cur->ExternalID = xmlStrdup(ExternalID);
+ else
+ cur->ExternalID = NULL;
+ if (SystemID != NULL)
+ cur->SystemID = xmlStrdup(SystemID);
+ else
+ cur->SystemID = NULL;
+ cur->elements = NULL;
+ cur->entities = NULL;
+ doc->dtd = cur;
+
+ return(cur);
+}
+
+/*
+ * Freeing a DTD
+ */
+void xmlFreeDtd(xmlDtdPtr cur) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlFreeDtd : DTD == NULL\n");
+ return;
+ }
+ if (cur->name != NULL) free((char *) cur->name);
+ if (cur->SystemID != NULL) free((char *) cur->SystemID);
+ if (cur->ExternalID != NULL) free((char *) cur->ExternalID);
+ if (cur->elements != NULL)
+ fprintf(stderr, "xmlFreeDtd: cur->elements != NULL !!! \n");
+ if (cur->entities != NULL)
+ xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
+ memset(cur, -1, sizeof(xmlDtd));
+ free(cur);
+}
+
+/*
+ * Creation of a new document
+ */
+xmlDocPtr xmlNewDoc(const CHAR *version) {
+ xmlDocPtr cur;
+
+ if (version == NULL) {
+ fprintf(stderr, "xmlNewDoc : version == NULL\n");
+ return(NULL);
+ }
+
+ /*
+ * Allocate a new document and fill the fields.
+ */
+ cur = (xmlDocPtr) malloc(sizeof(xmlDoc));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewDoc : malloc failed\n");
+ return(NULL);
+ }
+
+ cur->version = xmlStrdup(version);
+ cur->name = NULL;
+ cur->root = NULL;
+ cur->dtd = NULL;
+ cur->oldNs = NULL;
+ cur->encoding = NULL;
+ cur->entities = NULL;
+ cur->standalone = -1;
+ return(cur);
+}
+
+/*
+ * Freeing a document : all the tree is freed too.
+ */
+void xmlFreeDoc(xmlDocPtr cur) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlFreeDoc : document == NULL\n");
+ return;
+ }
+ free((char *) cur->version);
+ if (cur->name != NULL) free((char *) cur->name);
+ if (cur->encoding != NULL) free((char *) cur->encoding);
+ if (cur->root != NULL) xmlFreeNode(cur->root);
+ if (cur->dtd != NULL) xmlFreeDtd(cur->dtd);
+ if (cur->entities != NULL)
+ xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
+ memset(cur, -1, sizeof(xmlDoc));
+ free(cur);
+}
+
+/*
+ * Creation of a new property of a node.
+ */
+xmlAttrPtr xmlNewProp(xmlNodePtr node, const CHAR *name, const CHAR *value) {
+ xmlAttrPtr cur;
+
+ if (name == NULL) {
+ fprintf(stderr, "xmlNewProp : name == NULL\n");
+ return(NULL);
+ }
+
+ /*
+ * Allocate a new property and fill the fields.
+ */
+ cur = (xmlAttrPtr) malloc(sizeof(xmlAttr));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewProp : malloc failed\n");
+ return(NULL);
+ }
+
+ cur->node = node;
+ cur->name = xmlStrdup(name);
+ if (value != NULL)
+ cur->value = xmlStrdup(value);
+ else
+ cur->value = NULL;
+
+ /*
+ * Add it at the end to preserve parsing order ...
+ */
+ cur->next = NULL;
+ if (node != NULL) {
+ if (node->properties == NULL) {
+ node->properties = cur;
+ } else {
+ xmlAttrPtr prev = node->properties;
+
+ while (prev->next != NULL) prev = prev->next;
+ prev->next = cur;
+ }
+ }
+ return(cur);
+}
+
+/*
+ * Freeing a property list : Free a property and all its siblings,
+ * this is a recursive behaviour, all the childs
+ * are freed too.
+ */
+void xmlFreePropList(xmlAttrPtr cur) {
+ xmlAttrPtr next;
+ if (cur == NULL) {
+ fprintf(stderr, "xmlFreePropList : property == NULL\n");
+ return;
+ }
+ while (cur != NULL) {
+ next = cur->next;
+ xmlFreeProp(cur);
+ cur = next;
+ }
+}
+
+/*
+ * Freeing a property.
+ */
+void xmlFreeProp(xmlAttrPtr cur) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlFreeProp : property == NULL\n");
+ return;
+ }
+ if (cur->name != NULL) free((char *) cur->name);
+ if (cur->value != NULL) free((char *) cur->value);
+ memset(cur, -1, sizeof(xmlAttr));
+ free(cur);
+}
+
+/*
+ * Creation of a new node element in a given DTD.
+ * We assume that the "name" has already being strdup'd !
+ */
+xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content) {
+ xmlNodePtr cur;
+
+ if (name == NULL) {
+ fprintf(stderr, "xmlNewNode : name == NULL\n");
+ return(NULL);
+ }
+
+ /*
+ * Allocate a new node and fill the fields.
+ */
+ cur = (xmlNodePtr) malloc(sizeof(xmlNode));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewNode : malloc failed\n");
+ return(NULL);
+ }
+
+ cur->parent = NULL;
+ cur->next = NULL;
+ cur->childs = NULL;
+ cur->properties = NULL;
+ cur->type = 0;
+ cur->name = xmlStrdup(name);
+ cur->ns = ns;
+ cur->nsDef = NULL;
+ if (content != NULL)
+ cur->content = xmlStrdup(content);
+ else
+ cur->content = NULL;
+ return(cur);
+}
+
+/*
+ * Creation of a new node contening text.
+ */
+xmlNodePtr xmlNewText(const CHAR *content) {
+ xmlNodePtr cur;
+
+ /*
+ * Allocate a new node and fill the fields.
+ */
+ cur = (xmlNodePtr) malloc(sizeof(xmlNode));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewText : malloc failed\n");
+ return(NULL);
+ }
+
+ cur->parent = NULL;
+ cur->next = NULL;
+ cur->childs = NULL;
+ cur->properties = NULL;
+ cur->type = XML_TYPE_TEXT;
+ cur->name = xmlStrdup(xmlStringText);
+ cur->ns = NULL;
+ cur->nsDef = NULL;
+ if (content != NULL)
+ cur->content = xmlStrdup(content);
+ else
+ cur->content = NULL;
+ return(cur);
+}
+
+/*
+ * Creation of a new node contening text.
+ */
+xmlNodePtr xmlNewTextLen(const CHAR *content, int len) {
+ xmlNodePtr cur;
+
+ /*
+ * Allocate a new node and fill the fields.
+ */
+ cur = (xmlNodePtr) malloc(sizeof(xmlNode));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewText : malloc failed\n");
+ return(NULL);
+ }
+
+ cur->parent = NULL;
+ cur->next = NULL;
+ cur->childs = NULL;
+ cur->properties = NULL;
+ cur->type = XML_TYPE_TEXT;
+ cur->name = xmlStrdup(xmlStringText);
+ cur->ns = NULL;
+ cur->nsDef = NULL;
+ if (content != NULL)
+ cur->content = xmlStrndup(content, len);
+ else
+ cur->content = NULL;
+ return(cur);
+}
+
+/*
+ * Creation of a new node contening a comment.
+ */
+xmlNodePtr xmlNewComment(CHAR *content) {
+ xmlNodePtr cur;
+
+ /*
+ * Allocate a new node and fill the fields.
+ */
+ cur = (xmlNodePtr) malloc(sizeof(xmlNode));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewComment : malloc failed\n");
+ return(NULL);
+ }
+
+ cur->parent = NULL;
+ cur->next = NULL;
+ cur->childs = NULL;
+ cur->properties = NULL;
+ cur->type = XML_TYPE_COMMENT;
+ cur->name = xmlStrdup(xmlStringText);
+ cur->ns = NULL;
+ cur->nsDef = NULL;
+ if (content != NULL)
+ cur->content = xmlStrdup(content);
+ else
+ cur->content = NULL;
+ return(cur);
+}
+
+/*
+ * Creation of a new child element, added at the end.
+ */
+xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
+ const CHAR *name, CHAR *content) {
+ xmlNodePtr cur, prev;
+
+ if (parent == NULL) {
+ fprintf(stderr, "xmlNewChild : parent == NULL\n");
+ return(NULL);
+ }
+
+ if (name == NULL) {
+ fprintf(stderr, "xmlNewChild : name == NULL\n");
+ return(NULL);
+ }
+
+ /*
+ * Allocate a new node
+ */
+ if (ns == NULL)
+ cur = xmlNewNode(parent->ns, name, content);
+ else
+ cur = xmlNewNode(ns, name, content);
+ if (cur == NULL) return(NULL);
+
+ /*
+ * add the new element at the end of the childs list.
+ */
+ cur->parent = parent;
+ if (parent->childs == NULL) {
+ parent->childs = cur;
+ } else {
+ prev = parent->childs;
+ while (prev->next != NULL) prev = prev->next;
+ prev->next = cur;
+ }
+
+ return(cur);
+}
+
+/*
+ * Add a new child element, added at the end.
+ */
+xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
+ xmlNodePtr prev;
+
+ if (parent == NULL) {
+ fprintf(stderr, "xmladdChild : parent == NULL\n");
+ return(NULL);
+ }
+
+ if (cur == NULL) {
+ fprintf(stderr, "xmladdChild : child == NULL\n");
+ return(NULL);
+ }
+
+ /*
+ * add the new element at the end of the childs list.
+ */
+ cur->parent = parent;
+ if (parent->childs == NULL) {
+ parent->childs = cur;
+ } else {
+ prev = parent->childs;
+ while (prev->next != NULL) prev = prev->next;
+ prev->next = cur;
+ }
+
+ return(cur);
+}
+
+/*
+ * Search the last child, if any.
+ */
+xmlNodePtr xmlGetLastChild(xmlNodePtr parent) {
+ xmlNodePtr last;
+
+ if (parent == NULL) {
+ fprintf(stderr, "xmlGetLastChild : parent == NULL\n");
+ return(NULL);
+ }
+
+ /*
+ * add the new element at the end of the childs list.
+ */
+ if (parent->childs == NULL) {
+ return(NULL);
+ } else {
+ last = parent->childs;
+ while (last->next != NULL) last = last->next;
+ }
+ return(last);
+}
+
+/*
+ * Freeing a node list : Free a node and all its siblings,
+ * this is a recursive behaviour, all the childs
+ * are freed too.
+ */
+void xmlFreeNodeList(xmlNodePtr cur) {
+ xmlNodePtr next;
+ if (cur == NULL) {
+ fprintf(stderr, "xmlFreeNodeList : node == NULL\n");
+ return;
+ }
+ while (cur != NULL) {
+ next = cur->next;
+ xmlFreeNode(cur);
+ cur = next;
+ }
+}
+
+/*
+ * Freeing a node : this is a recursive behaviour, all the childs
+ * are freed too.
+ */
+void xmlFreeNode(xmlNodePtr cur) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlFreeNode : node == NULL\n");
+ return;
+ }
+ if (cur->properties != NULL) xmlFreePropList(cur->properties);
+ if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
+ if (cur->content != NULL) free(cur->content);
+ if (cur->name != NULL) free((char *) cur->name);
+ if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef);
+ memset(cur, -1, sizeof(xmlNode));
+ free(cur);
+}
+
+/************************************************************************
+ * *
+ * Content access functions *
+ * *
+ ************************************************************************/
+
+/*
+ * Changing the content of a node.
+ */
+void xmlNodeSetContent(xmlNodePtr cur, const CHAR *content) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNodeSetContent : node == NULL\n");
+ return;
+ }
+ if (cur->content != NULL) free(cur->content);
+ if (content != NULL)
+ cur->content = xmlStrdup(content);
+ else
+ cur->content = NULL;
+}
+
+/*
+ * Changing the content of a node.
+ */
+void xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNodeSetContent : node == NULL\n");
+ return;
+ }
+ if (cur->content != NULL) free(cur->content);
+ if (content != NULL)
+ cur->content = xmlStrndup(content, len);
+ else
+ cur->content = NULL;
+}
+
+/*
+ * Adding content to a node.
+ */
+void xmlNodeAddContent(xmlNodePtr cur, const CHAR *content) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNodeAddContent : node == NULL\n");
+ return;
+ }
+ cur->content = xmlStrcat(cur->content, content);
+}
+
+/*
+ * Adding content to a node.
+ */
+void xmlNodeAddContentLen(xmlNodePtr cur, const CHAR *content, int len) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNodeAddContent : node == NULL\n");
+ return;
+ }
+ cur->content = xmlStrncat(cur->content, content, len);
+}
+
+/*
+ * Search a Ns registered under a given name space for a document.
+ * recurse on the parents until it finds the defined namespace
+ * or return NULL otherwise.
+ *
+ * Note : nameSpace == NULL is valid, this is a search for the default
+ * namespace.
+ */
+xmlNsPtr xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const CHAR *nameSpace) {
+ xmlNsPtr cur;
+
+ while (node != NULL) {
+ cur = node->nsDef;
+ while (cur != NULL) {
+ if ((cur->prefix == NULL) && (nameSpace == NULL))
+ return(cur);
+ if ((cur->prefix != NULL) && (nameSpace != NULL) &&
+ (!xmlStrcmp(cur->prefix, nameSpace)))
+ return(cur);
+ cur = cur->next;
+ }
+ node = node->parent;
+ }
+ if (doc != NULL) {
+ cur = doc->oldNs;
+ while (cur != NULL) {
+ if ((cur->prefix != NULL) && (nameSpace != NULL) &&
+ (!xmlStrcmp(cur->prefix, nameSpace)))
+ return(cur);
+ cur = cur->next;
+ }
+ }
+ return(NULL);
+}
+
+/*
+ * Search a Ns aliasing a given URI
+ * recurse on the parents until it finds the defined namespace
+ * or return NULL otherwise.
+ */
+xmlNsPtr xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const CHAR *href) {
+ xmlNsPtr cur;
+
+ while (node != NULL) {
+ cur = node->nsDef;
+ while (cur != NULL) {
+ if ((cur->href != NULL) && (href != NULL) &&
+ (!xmlStrcmp(cur->href, href)))
+ return(cur);
+ cur = cur->next;
+ }
+ node = node->parent;
+ }
+ if (doc != NULL) {
+ cur = doc->oldNs;
+ while (cur != NULL) {
+ if ((cur->href != NULL) && (href != NULL) &&
+ (!xmlStrcmp(cur->href, href)))
+ return(cur);
+ cur = cur->next;
+ }
+ }
+ return(NULL);
+}
+
+/*
+ * Reading the content of a given property.
+ */
+const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name) {
+ xmlAttrPtr prop = node->properties;
+
+ while (prop != NULL) {
+ if (!xmlStrcmp(prop->name, name)) return(prop->value);
+ prop = prop->next;
+ }
+ return(NULL);
+}
+
+/*
+ * Setting the content of a given property.
+ */
+xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name, const CHAR *value) {
+ xmlAttrPtr prop = node->properties;
+
+ while (prop != NULL) {
+ if (!xmlStrcmp(prop->name, name)) {
+ if (prop->value != NULL)
+ free((char *) prop->value);
+ prop->value = NULL;
+ if (value != NULL)
+ prop->value = xmlStrdup(value);
+ return(prop);
+ }
+ prop = prop->next;
+ }
+ prop = xmlNewProp(node, name, value);
+ return(prop);
+}
+
+/*
+ * Is this node a piece of text
+ */
+int xmlNodeIsText(xmlNodePtr node) {
+ if (node == NULL) return(0);
+
+ if (node->type == XML_TYPE_TEXT) return(1);
+ return(0);
+}
+
+/*
+ * Concat a piece of text to an existing text node
+ *
+ * TODO !!! Should be optimized with a bit of preallocation.
+ */
+void xmlTextConcat(xmlNodePtr node, const CHAR *content, int len) {
+ if (node == NULL) return;
+
+ if (node->type != XML_TYPE_TEXT) {
+ fprintf(stderr, "xmlTextConcat: node is not text\n");
+ return;
+ }
+ node->content = xmlStrncat(node->content, content, len);
+}
+
+/************************************************************************
+ * *
+ * Output : to a FILE or in memory *
+ * *
+ ************************************************************************/
+
+/*
+ * routine which manage and grows an output buffer. One can write
+ * standard char array's (8 bits char) or CHAR's arrays.
+ */
+static CHAR *buffer = NULL;
+static int buffer_index = 0;
+static int buffer_size = 0;
+
+void xmlBufferWriteCHAR(const CHAR *string) {
+ const CHAR *cur;
+
+ if (buffer == NULL) {
+ buffer_size = 50000;
+ buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
+ if (buffer == NULL) {
+ fprintf(stderr, "xmlBufferWrite : out of memory!\n");
+ exit(1);
+ }
+ }
+
+ if (string == NULL) return;
+ for (cur = string;*cur != 0;cur++) {
+ if (buffer_index + 10 >= buffer_size) {
+ buffer_size *= 2;
+ buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
+ if (buffer == NULL) {
+ fprintf(stderr, "xmlBufferWrite : out of memory!\n");
+ exit(1);
+ }
+ }
+ buffer[buffer_index++] = *cur;
+ }
+ buffer[buffer_index] = 0;
+}
+
+void xmlBufferWriteChar(const char *string) {
+ const char *cur;
+
+ if (buffer == NULL) {
+ buffer_size = 50000;
+ buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
+ if (buffer == NULL) {
+ fprintf(stderr, "xmlBufferWrite : out of memory!\n");
+ exit(1);
+ }
+ }
+
+ if (string == NULL) return;
+ for (cur = string;*cur != 0;cur++) {
+ if (buffer_index + 10 >= buffer_size) {
+ buffer_size *= 2;
+ buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
+ if (buffer == NULL) {
+ fprintf(stderr, "xmlBufferWrite : out of memory!\n");
+ exit(1);
+ }
+ }
+ buffer[buffer_index++] = *cur;
+ }
+ buffer[buffer_index] = 0;
+}
+
+/*
+ * Dump the global Namespace inherited from the old WD.
+ * Within the context of the document header.
+ */
+static void xmlGlobalNsDump(xmlNsPtr cur) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlGlobalNsDump : Ns == NULL\n");
+ return;
+ }
+ if (cur->type == XML_GLOBAL_NAMESPACE) {
+ xmlBufferWriteChar("<?namespace");
+ if (cur->href != NULL) {
+ xmlBufferWriteChar(" href=\"");
+ xmlBufferWriteCHAR(cur->href);
+ xmlBufferWriteChar("\"");
+ }
+ if (cur->prefix != NULL) {
+ xmlBufferWriteChar(" AS=\"");
+ xmlBufferWriteCHAR(cur->prefix);
+ xmlBufferWriteChar("\"");
+ }
+ xmlBufferWriteChar("?>\n");
+ }
+}
+
+/*
+ * Dump an old global XML Namespace list
+ */
+
+static void xmlGlobalNsListDump(xmlNsPtr cur) {
+ while (cur != NULL) {
+ xmlGlobalNsDump(cur);
+ cur = cur->next;
+ }
+}
+
+/*
+ * Dump a local Namespace definition.
+ * Within the context of an element attributes.
+ */
+static void xmlNsDump(xmlNsPtr cur) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNsDump : Ns == NULL\n");
+ return;
+ }
+ if (cur->type == XML_LOCAL_NAMESPACE) {
+ /* Within the context of an element attributes */
+ if (cur->prefix != NULL) {
+ xmlBufferWriteChar(" xmlns:");
+ xmlBufferWriteCHAR(cur->prefix);
+ } else
+ xmlBufferWriteChar(" xmlns");
+ xmlBufferWriteChar("=\"");
+ xmlBufferWriteCHAR(cur->href);
+ xmlBufferWriteChar("\"");
+ }
+}
+
+/*
+ * Dump an XML Namespace list
+ */
+
+static void xmlNsListDump(xmlNsPtr cur) {
+ while (cur != NULL) {
+ xmlNsDump(cur);
+ cur = cur->next;
+ }
+}
+
+/*
+ * Dump an XML DTD
+ */
+
+static void xmlDtdDump(xmlDocPtr doc) {
+ xmlDtdPtr cur = doc->dtd;
+
+ if (cur == NULL) {
+ fprintf(stderr, "xmlDtdDump : DTD == NULL\n");
+ return;
+ }
+ xmlBufferWriteChar("<!DOCTYPE ");
+ xmlBufferWriteCHAR(cur->name);
+ if (cur->ExternalID != NULL) {
+ xmlBufferWriteChar(" PUBLIC \"");
+ xmlBufferWriteCHAR(cur->ExternalID);
+ xmlBufferWriteChar("\" \"");
+ xmlBufferWriteCHAR(cur->SystemID);
+ xmlBufferWriteChar("\"");
+ } else if (cur->SystemID != NULL) {
+ xmlBufferWriteChar(" SYSTEM \"");
+ xmlBufferWriteCHAR(cur->SystemID);
+ xmlBufferWriteChar("\"");
+ }
+ if ((cur->entities == NULL) && (doc->entities == NULL)) {
+ xmlBufferWriteChar(">\n");
+ return;
+ }
+ xmlBufferWriteChar(" [\n");
+ if (cur->entities != NULL)
+ xmlDumpEntitiesTable((xmlEntitiesTablePtr) cur->entities);
+ if (doc->entities != NULL)
+ xmlDumpEntitiesTable((xmlEntitiesTablePtr) doc->entities);
+ xmlBufferWriteChar("]");
+
+ /* TODO !!! a lot more things to dump ... */
+ xmlBufferWriteChar(">\n");
+}
+
+/*
+ * Dump an XML property
+ */
+
+static void xmlAttrDump(xmlDocPtr doc, xmlAttrPtr cur) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlAttrDump : property == NULL\n");
+ return;
+ }
+ xmlBufferWriteChar(" ");
+ xmlBufferWriteCHAR(cur->name);
+ if (cur->value) {
+ xmlBufferWriteChar("=\"");
+ xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->value));
+ xmlBufferWriteChar("\"");
+ }
+}
+
+/*
+ * Dump an XML property list
+ */
+
+static void xmlAttrListDump(xmlDocPtr doc, xmlAttrPtr cur) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlAttrListDump : property == NULL\n");
+ return;
+ }
+ while (cur != NULL) {
+ xmlAttrDump(doc, cur);
+ cur = cur->next;
+ }
+}
+
+/*
+ * Dump an XML node list
+ */
+
+static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level);
+static void xmlNodeListDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNodeListDump : node == NULL\n");
+ return;
+ }
+ while (cur != NULL) {
+ xmlNodeDump(doc, cur, level);
+ cur = cur->next;
+ }
+}
+
+/*
+ * Dump an XML node
+ */
+
+static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
+ int i;
+
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNodeDump : node == NULL\n");
+ return;
+ }
+ if (cur->type == XML_TYPE_TEXT) {
+ if (cur->content != NULL)
+ xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
+ return;
+ }
+ if (cur->type == XML_TYPE_COMMENT) {
+ if (cur->content != NULL) {
+ xmlBufferWriteChar("<!--");
+ xmlBufferWriteCHAR(cur->content);
+ xmlBufferWriteChar("-->");
+ }
+ return;
+ }
+ if (xmlIndentTreeOutput)
+ for (i = 0;i < level;i++)
+ xmlBufferWriteChar(" ");
+
+ xmlBufferWriteChar("<");
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+ xmlBufferWriteCHAR(cur->ns->prefix);
+ xmlBufferWriteChar(":");
+ }
+
+ xmlBufferWriteCHAR(cur->name);
+ if (cur->nsDef)
+ xmlNsListDump(cur->nsDef);
+ if (cur->properties != NULL)
+ xmlAttrListDump(doc, cur->properties);
+
+ if ((cur->content == NULL) && (cur->childs == NULL)) {
+ xmlBufferWriteChar("/>\n");
+ return;
+ }
+ xmlBufferWriteChar(">");
+ if (cur->content != NULL)
+ xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
+ if (cur->childs != NULL) {
+ xmlBufferWriteChar("\n");
+ xmlNodeListDump(doc, cur->childs, level + 1);
+ if (xmlIndentTreeOutput)
+ for (i = 0;i < level;i++)
+ xmlBufferWriteChar(" ");
+ }
+ xmlBufferWriteChar("</");
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+ xmlBufferWriteCHAR(cur->ns->prefix);
+ xmlBufferWriteChar(":");
+ }
+
+ xmlBufferWriteCHAR(cur->name);
+ xmlBufferWriteChar(">\n");
+}
+
+/*
+ * Dump an XML document
+ */
+static void xmlDocContentDump(xmlDocPtr cur) {
+ if (oldXMLWDcompatibility)
+ xmlBufferWriteChar("<?XML version=\"");
+ else
+ xmlBufferWriteChar("<?xml version=\"");
+ xmlBufferWriteCHAR(cur->version);
+ xmlBufferWriteChar("\"");
+ if (cur->encoding != NULL) {
+ xmlBufferWriteChar(" encoding=\"");
+ xmlBufferWriteCHAR(cur->encoding);
+ xmlBufferWriteChar("\"");
+ }
+ switch (cur->standalone) {
+ case 0:
+ xmlBufferWriteChar(" standalone=\"no\"");
+ break;
+ case 1:
+ xmlBufferWriteChar(" standalone=\"yes\"");
+ break;
+ }
+ xmlBufferWriteChar("?>\n");
+ if ((cur->dtd != NULL) || (cur->entities != NULL))
+ xmlDtdDump(cur);
+ if (cur->root != NULL) {
+ /* global namespace definitions, the old way */
+ if (oldXMLWDcompatibility)
+ xmlGlobalNsListDump(cur->oldNs);
+ else
+ xmlUpgradeOldNs(cur);
+ xmlNodeDump(cur, cur->root, 0);
+ }
+}
+
+/*
+ * Dump an XML document to memory.
+ */
+
+void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlDocDump : document == NULL\n");
+ *mem = NULL;
+ *size = 0;
+ return;
+ }
+ buffer_index = 0;
+ xmlDocContentDump(cur);
+
+ *mem = buffer;
+ *size = buffer_index;
+}
+
+/*
+ * Dump an XML document to the given FD
+ */
+
+void xmlDocDump(FILE *f, xmlDocPtr cur) {
+ if (cur == NULL) {
+ fprintf(stderr, "xmlDocDump : document == NULL\n");
+ return;
+ }
+ buffer_index = 0;
+ xmlDocContentDump(cur);
+
+ fwrite(buffer, sizeof(CHAR), buffer_index, f);
+}
+
+/************************************************************************
+ * *
+ * Debug *
+ * *
+ ************************************************************************/
+
+#ifdef STANDALONE
+int main(void) {
+ xmlDocPtr doc;
+ xmlNodePtr tree, subtree;
+ xmlNsPtr ns1;
+ xmlNsPtr ns2;
+
+ /*
+ * build a fake XML document
+ */
+ doc = xmlNewDoc("1.0");
+ ns1 = xmlNewNs(doc, "http://www.ietf.org/standards/dav/", "D");
+ ns2 = xmlNewNs(doc, "http://www.w3.com/standards/z39.50/", "Z");
+ doc->root = xmlNewNode(ns1, "multistatus", NULL);
+ tree = xmlNewChild(doc->root, NULL, "response", NULL);
+ subtree = xmlNewChild(tree, NULL, "prop", NULL);
+ xmlNewChild(subtree, ns2, "Authors", NULL);
+ subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 420 Method Failure");
+ tree = xmlNewChild(doc->root, NULL, "response", NULL);
+ subtree = xmlNewChild(tree, NULL, "prop", NULL);
+ xmlNewChild(subtree, ns2, "Copyright-Owner", NULL);
+ subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 409 Conflict");
+ tree = xmlNewChild(doc->root, NULL, "responsedescription",
+ "Copyright Owner can not be deleted or altered");
+
+ /*
+ * print it.
+ */
+ xmlDocDump(stdout, doc);
+
+ /*
+ * free it.
+ */
+ xmlFreeDoc(doc);
+ return(0);
+}
+#endif
diff --git a/tree.h b/tree.h
new file mode 100644
index 0000000..7a48a9b
--- /dev/null
+++ b/tree.h
@@ -0,0 +1,180 @@
+/*
+ * tree.h : describes the structures found in an tree resulting
+ * from an XML parsing.
+ *
+ * See Copyright for the status of this software.
+ *
+ * $Id$
+ */
+
+#ifndef __XML_TREE_H__
+#define __XML_TREE_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Type definitions
+ */
+#ifdef UNICODE
+typedef unsigned short CHAR;
+#else
+typedef unsigned char CHAR;
+#endif
+
+/*
+ * a DTD Notation definition
+ * TODO !!!!
+ */
+
+/*
+ * a DTD Attribute definition
+ * TODO !!!!
+ */
+
+/*
+ * a DTD Element definition.
+ */
+#define XML_ELEMENT_TYPE_EMPTY 1
+#define XML_ELEMENT_TYPE_ANY 2
+#define XML_ELEMENT_TYPE_MIXED 3
+#define XML_ELEMENT_TYPE_ELEMENT 4
+
+typedef struct xmlElement {
+ const CHAR *name; /* Element name */
+ int type; /* type (too simple, to extend ...) */
+ /* TODO !!! more needed */
+} xmlElement, *xmlElementPtr;
+
+/*
+ * An XML namespace.
+ * Note that prefix == NULL is valid, it defines the default namespace
+ * within the subtree (until overriden).
+ */
+
+#define XML_GLOBAL_NAMESPACE 1 /* old style global namespace */
+#define XML_LOCAL_NAMESPACE 2 /* new style local scoping */
+
+typedef struct xmlNs {
+ struct xmlNs *next; /* next Ns link for this node */
+ int type; /* global or local */
+ const CHAR *href; /* URL for the namespace */
+ const CHAR *prefix; /* prefix for the namespace */
+} xmlNs, *xmlNsPtr;
+
+/*
+ * An XML DtD, as defined by <!DOCTYPE.
+ */
+typedef struct xmlDtd {
+ const CHAR *name; /* Name of the DTD */
+ const CHAR *ExternalID; /* External identifier for PUBLIC DTD */
+ const CHAR *SystemID; /* URI for a SYSTEM or PUBLIC DTD */
+ void *elements; /* Hash table for elements if any */
+ void *entities; /* Hash table for entities if any */
+ /* struct xmlDtd *next; * next link for this document */
+} xmlDtd, *xmlDtdPtr;
+
+/*
+ * A attribute of an XML node.
+ */
+typedef struct xmlAttr {
+ struct xmlNode *node; /* attr->node link */
+ struct xmlAttr *next; /* parent->childs link */
+ const CHAR *name; /* the name of the property */
+ const CHAR *value; /* the value of the property */
+} xmlAttr, *xmlAttrPtr;
+
+/*
+ * A node in an XML tree.
+ */
+#define XML_TYPE_TEXT 1
+#define XML_TYPE_COMMENT 2
+#define XML_TYPE_ENTITY 3
+
+typedef struct xmlNode {
+ struct xmlNode *parent; /* child->parent link */
+ struct xmlNode *next; /* next sibling link */
+ struct xmlNode *childs; /* parent->childs link */
+ struct xmlAttr *properties; /* properties list */
+ int type; /* type number in the DTD */
+ const CHAR *name; /* the name of the node, or the entity */
+ xmlNs *ns; /* pointer to the associated namespace */
+ xmlNs *nsDef; /* namespace definitions on this node */
+ CHAR *content; /* the content */
+} xmlNode, *xmlNodePtr;
+
+/*
+ * An XML document.
+ */
+typedef struct xmlDoc {
+ char *name; /* name/filename/URI of the document */
+ const CHAR *version; /* the XML version string */
+ const CHAR *encoding; /* encoding, if any */
+ int standalone; /* standalone document (no external refs) */
+ struct xmlDtd *dtd; /* the document DTD if available */
+ struct xmlNs *oldNs; /* Global namespace, the old way */
+ void *entities; /* Hash table for general entities if any */
+ struct xmlNode *root; /* the document tree */
+} xmlDoc, *xmlDocPtr;
+
+/*
+ * Variables.
+ */
+extern xmlNsPtr baseDTD;
+extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
+extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
+
+/*
+ * Functions.
+ */
+extern xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *name,
+ const CHAR *ExternalID, const CHAR *SystemID);
+extern void xmlFreeDtd(xmlDtdPtr cur);
+extern xmlNsPtr xmlNewGlobalNs(xmlDocPtr doc, const CHAR *href, const CHAR *AS);
+extern xmlNsPtr xmlNewNs(xmlNodePtr node, const CHAR *href, const CHAR *AS);
+extern void xmlFreeNs(xmlNsPtr cur);
+extern xmlDocPtr xmlNewDoc(const CHAR *version);
+extern void xmlFreeDoc(xmlDocPtr cur);
+extern xmlAttrPtr xmlNewProp(xmlNodePtr node, const CHAR *name,
+ const CHAR *value);
+extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
+ const CHAR *value);
+extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
+extern void xmlFreePropList(xmlAttrPtr cur);
+extern void xmlFreeProp(xmlAttrPtr cur);
+extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content);
+extern xmlNodePtr xmlNewText(const CHAR *content);
+extern xmlNodePtr xmlNewTextLen(const CHAR *content, int len);
+extern xmlNodePtr xmlNewComment(CHAR *content);
+extern xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
+extern xmlNodePtr xmlGetLastChild(xmlNodePtr node);
+extern int xmlNodeIsText(xmlNodePtr node);
+extern void xmlTextConcat(xmlNodePtr node, const CHAR *content, int len);
+extern void xmlFreeNodeList(xmlNodePtr cur);
+extern void xmlFreeNode(xmlNodePtr cur);
+extern void xmlNodeSetContent(xmlNodePtr cur, const CHAR *content);
+extern void xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len);
+extern void xmlNodeAddContent(xmlNodePtr cur, const CHAR *content);
+extern void xmlNodeAddContentLen(xmlNodePtr cur, const CHAR *content, int len);
+extern xmlNsPtr xmlSearchNs(xmlDocPtr doc, xmlNodePtr node,
+ const CHAR *nameSpace);
+extern xmlNsPtr xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node,
+ const CHAR *href);
+extern void xmlSetNs(xmlNodePtr node, xmlNsPtr ns);
+extern xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
+ const CHAR *name, CHAR *content);
+
+extern void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size);
+extern void xmlDocDump(FILE *f, xmlDocPtr doc);
+extern void xmlBufferWriteCHAR(const CHAR *string);
+extern void xmlBufferWriteChar(const char *string);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_TREE_H__ */
+
diff --git a/xml_entities.c b/xml_entities.c
deleted file mode 100644
index 3c9d55c..0000000
--- a/xml_entities.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * entities.c : implementation for the XML entities handking
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#include <stdio.h>
-#include <malloc.h>
-#include <strings.h>
-#include "xml_entities.h"
-
-/*
- * A buffer used for converting entities to their equivalent and back.
- */
-static CHAR *buffer = NULL;
-static int buffer_size = 0;
-
-void growBuffer(void) {
- buffer_size *= 2;
- buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
- if (buffer == NULL) {
- perror("realloc failed");
- exit(1);
- }
-}
-
-/*
- * xmlFreeEntity : clean-up an entity record.
- */
-
-void xmlFreeEntity(xmlEntityPtr entity) {
- if (entity == NULL) return;
-
- if (entity->value != NULL) free(entity->value);
- entity->value = NULL;
- if (entity->id != NULL)
- free((char *) entity->id);
-}
-
-/*
- * xmlAddDocEntity : register a new entity for an entities table.
- */
-static void xmlAddEntity(xmlEntitiesTablePtr table, CHAR *value,
- const CHAR *id) {
- int i;
- xmlEntityPtr cur;
-
- for (i = 0;i < table->nb_entities;i++) {
- cur = &table->table[i];
- if (!xmlStrcmp(cur->id, id)) {
- free(cur->value);
- cur->value = xmlStrdup(value);
- }
- }
- if (table->nb_entities >= table->max_entities) {
- /*
- * need more elements.
- */
- table->max_entities *= 2;
- table->table = (xmlEntityPtr)
- realloc(table->table, table->max_entities * sizeof(xmlEntity));
- if (table->table) {
- perror("realloc failed");
- exit(1);
- }
- }
- cur = &table->table[table->nb_entities];
- cur->value = xmlStrdup(value);
- cur->id = xmlStrdup(id);
- table->nb_entities++;
-}
-
-
-/*
- * xmlAddDtdEntity : register a new entity for this document.
- */
-void xmlAddDtdEntity(xmlDtdPtr dtd, CHAR *value, const CHAR *id) {
- xmlEntitiesTablePtr table;
-
- table = (xmlEntitiesTablePtr) dtd->entities;
- if (table == NULL) {
- table = xmlCreateEntitiesTable();
- dtd->entities = table;
- }
- xmlAddEntity(table, value, id);
-}
-
-/*
- * xmlAddDocEntity : register a new entity for this document.
- */
-void xmlAddDocEntity(xmlDocPtr doc, CHAR *value, const CHAR *id) {
- xmlEntitiesTablePtr table;
-
- table = (xmlEntitiesTablePtr) doc->entities;
- if (table == NULL) {
- table = xmlCreateEntitiesTable();
- doc->entities = table;
- }
- xmlAddEntity(table, value, id);
-}
-
-/*
- * xmlGetEntity : do an entity lookup in the hash table and
- * returns the corrsponding CHAR *, if found, zero otherwise.
- */
-CHAR *xmlGetEntity(xmlDocPtr doc, const CHAR *id) {
- int i;
- xmlEntityPtr cur;
- xmlEntitiesTablePtr table;
-
- if (doc->entities == NULL) return(0);
- table = (xmlEntitiesTablePtr) doc->entities;
- for (i = 0;i < table->nb_entities;i++) {
- cur = &table->table[i];
- if (!xmlStrcmp(cur->id, id)) return(cur->value);
- }
- return(NULL);
-}
-
-/*
- * xmlReadEntities : read an entity.
- */
-const CHAR *xmlReadEntity(xmlDocPtr doc, const CHAR **input) {
- static CHAR *entity = NULL;
- static int entity_size = 100;
- const CHAR *cur = *input;
-
- if (entity == NULL) {
- entity = (CHAR *) malloc(entity_size * sizeof(CHAR));
- if (entity == NULL) {
- fprintf(stderr, "xmlReadEntity : cannot allocate %d bytes\n",
- entity_size * sizeof(CHAR));
- return(NULL);
- }
- }
- if (*cur == '&') {
- cur++;
- if (*cur == '#') {
- /* TODO !!!!
- fprintf(stderr, "Character reference not yet implemented\n"); */
- } else {
- /* TODO !!!!
- fprintf(stderr, "Entity search not yet implemented\n"); */
- }
- }
-
- /*
- * The few predefined entities.
- */
- if ((cur[0] == 'a') && (cur[1] == 'm') && (cur[2] == 'p') &&
- (cur[3] == ';')) {
- entity[0] = '%';
- entity[1] = 0;
- cur += 3;
- *input = cur;
- return(entity);
- } else if ((cur[0] == 'q') && (cur[1] == 'u') && (cur[2] == 'o') &&
- (cur[3] == 't') && (cur[4] == ';')) {
- entity[0] = '"';
- entity[1] = 0;
- cur += 4;
- *input = cur;
- return(entity);
- } else if ((cur[0] == 'a') && (cur[1] == 'p') && (cur[2] == 'o') &&
- (cur[3] == 's') && (cur[4] == ';')) {
- entity[0] = '\'';
- entity[1] = 0;
- cur += 4;
- *input = cur;
- return(entity);
- } else if ((cur[0] == 'l') && (cur[1] == 't') && (cur[2] == ';')) {
- entity[0] = '<';
- entity[1] = 0;
- cur += 2;
- *input = cur;
- return(entity);
- } else if ((cur[0] == 'g') && (cur[1] == 't') && (cur[2] == ';')) {
- entity[0] = '>';
- entity[1] = 0;
- cur += 2;
- *input = cur;
- return(entity);
- }
-
- return(NULL);
-}
-
-/*
- * xmlDecodeEntities : do a global entities lookup on a input string
- * and returns a duplicate after the entities substitution.
- */
-CHAR *xmlDecodeEntities(xmlDocPtr doc, const CHAR *input, int len) {
- const CHAR *cur = input;
- CHAR *out = buffer;
- int i;
-
- if (buffer == NULL) {
- buffer_size = 1000;
- buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
- if (buffer == NULL) {
- perror("malloc failed");
- exit(1);
- }
- out = buffer;
- }
- for (i = 0;(*cur != 0) && (cur - input < len);cur++) {
- if (*cur == '&') {
- const CHAR *entity = xmlReadEntity(doc, &cur);
- if (entity != NULL)
- while (*entity != 0) {
- *out++ = *entity++;
- i++;
- if (i + 10 > buffer_size) {
- int index = out - buffer;
-
- growBuffer();
- out = &buffer[index];
- }
- }
- } else if (*cur == '%') {
- /* TODO !!!!!
- fprintf(stderr, " \n"); */
- } else {
- *out++ = *cur;
- i++;
- }
-
- if (i + 10 > buffer_size) {
- int index = out - buffer;
-
- growBuffer();
- out = &buffer[index];
- }
- }
- *out++ = 0;
- return(buffer);
-}
-
-/*
- * xmlEncodeEntities : do a global encoding of a string, replacing the
- * basic values with their entities form.
- */
-CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
- const CHAR *cur = input;
- CHAR *out = buffer;
-
- if (buffer == NULL) {
- buffer_size = 1000;
- buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
- if (buffer == NULL) {
- perror("malloc failed");
- exit(1);
- }
- out = buffer;
- }
- while (*cur != '\0') {
- if (out - buffer > buffer_size - 100) {
- int index = out - buffer;
-
- growBuffer();
- out = &buffer[index];
- }
-
- /*
- * By default one have to encode at least '<', '>', '"' and '&' !
- * One could try a better encoding using the entities defined and
- * used as a compression code !!!.
- */
- if (*cur == '<') {
- *out++ = '&';
- *out++ = 'l';
- *out++ = 't';
- *out++ = ';';
- } else if (*cur == '>') {
- *out++ = '&';
- *out++ = 'g';
- *out++ = 't';
- *out++ = ';';
- } else if (*cur == '&') {
- *out++ = '&';
- *out++ = 'a';
- *out++ = 'm';
- *out++ = 'p';
- *out++ = ';';
- } else if (*cur == '"') {
- *out++ = '&';
- *out++ = 'q';
- *out++ = 'u';
- *out++ = 'o';
- *out++ = 't';
- *out++ = ';';
- } else if (*cur == '\'') {
- *out++ = '&';
- *out++ = 'a';
- *out++ = 'p';
- *out++ = 'o';
- *out++ = 's';
- *out++ = ';';
- } else {
- /*
- * default case, just copy !
- */
- *out++ = *cur;
- }
- cur++;
- }
- *out++ = 0;
- return(buffer);
-}
-
-/*
- * xmlCreateEntitiesTable : create and initialize an enmpty hash table
- */
-xmlEntitiesTablePtr xmlCreateEntitiesTable(void) {
- xmlEntitiesTablePtr ret;
-
- ret = (xmlEntitiesTablePtr)
- malloc(sizeof(xmlEntitiesTable));
- if (ret == NULL) {
- fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
- sizeof(xmlEntitiesTable));
- return(NULL);
- }
- ret->max_entities = XML_MIN_ENTITIES_TABLE;
- ret->nb_entities = 0;
- ret->table = (xmlEntityPtr )
- malloc(ret->max_entities * sizeof(xmlEntity));
- if (ret == NULL) {
- fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
- ret->max_entities * sizeof(xmlEntity));
- free(ret);
- return(NULL);
- }
- return(ret);
-}
-
-/*
- * xmlFreeEntitiesTable : clean up and free an entities hash table.
- */
-void xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
- int i;
-
- if (table == NULL) return;
-
- for (i = 0;i < table->nb_entities;i++) {
- xmlFreeEntity(&table->table[i]);
- }
- free(table->table);
- free(table);
-}
-
diff --git a/xml_entities.h b/xml_entities.h
deleted file mode 100644
index a0b24ac..0000000
--- a/xml_entities.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * entities.h : interface for the XML entities handking
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#ifndef __XML_ENTITIES_H__
-#define __XML_ENTITIES_H__
-#include "xml_parser.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * An unit of storage for an entity, contains the string, the value
- * and the linkind data needed for the linking in the hash table.
- */
-
-typedef struct xmlEntity {
- const CHAR *id; /* The entity name */
- CHAR *value; /* The entity CHAR equivalent */
-} xmlEntity, *xmlEntityPtr;
-
-/*
- * ALl entities are stored in a table there is one table per DTD
- * and one extra per document.
- */
-
-#define XML_MIN_ENTITIES_TABLE 32
-
-typedef struct xmlEntitiesTable {
- int nb_entities; /* number of elements stored */
- int max_entities; /* maximum number of elements */
- xmlEntityPtr table; /* the table of entities */
-} xmlEntitiesTable, *xmlEntitiesTablePtr;
-
-/*
- * External functions :
- */
-
-extern void xmlAddDocEntity(xmlDocPtr doc, CHAR *value, const CHAR *id);
-extern void xmlAddDtdEntity(xmlDtdPtr dtd, CHAR *value, const CHAR *id);
-extern CHAR *xmlGetEntity(xmlDocPtr doc, const CHAR *id);
-extern CHAR *xmlSubstituteEntities(xmlDocPtr doc, const CHAR *input);
-extern CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input);
-extern CHAR *xmlDecodeEntities(xmlDocPtr doc, const CHAR *input, int len);
-extern xmlEntitiesTablePtr xmlCreateEntitiesTable(void);
-extern void xmlFreeEntitiesTable(xmlEntitiesTablePtr table);
-
-#ifdef __cplusplus
-}
-#endif
-
-# endif /* __XML_ENTITIES_H__ */
diff --git a/xml_parser.c b/xml_parser.c
deleted file mode 100644
index dfec5a7..0000000
--- a/xml_parser.c
+++ /dev/null
@@ -1,1183 +0,0 @@
-/*
- * parser.c : an XML 1.0 non-verifying parser
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h> /* for memset() only */
-#include <malloc.h>
-#include <sys/stat.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include "xml_tree.h"
-#include "xml_parser.h"
-#include "xml_entities.h"
-
-/*
- * A few macros needed to help building the parser.
- */
-
-#ifdef UNICODE
-/*
- * UNICODE version of the macros. Incomplete now TODO !!!!
- */
-#define IS_CHAR(c) \
- (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || \
- (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
-
-#define SKIP_BLANKS(p) \
- while ((*(p) == 0x20) || (*(p) == 0x09) || (*(p) == 0xa) || \
- (*(p) == 0x3000)) (p)++;
-
-/* I'm too lazy to complete this one TODO !!!! */
-#define IS_BASECHAR(c) \
- ((((c) >= 0x41) && ((c) <= 0x5a)) || \
- (((c) >= 0x61) && ((c) <= 0x7a)) || \
- (((c) >= 0xaa) && ((c) <= 0x5b)) || \
- (((c) >= 0xc0) && ((c) <= 0xd6)) || \
- (((c) >= 0xd8) && ((c) <= 0xf6)) || \
- (((c) >= 0xf8) && ((c) <= 0xff)) || \
- ((c) == 0xba))
-
-/* I'm too lazy to complete this one TODO !!!! */
-#define IS_DIGIT(c) (((c) >= 0x30) && ((c) <= 0x39))
-
-/* I'm too lazy to complete this one TODO !!!! */
-#define IS_COMBINING(c) 0
-
-#define IS_IGNORABLE(c) \
- ((((c) >= 0x200c) && ((c) <= 0x200f)) || \
- (((c) >= 0x202a) && ((c) <= 0x202e)) || \
- (((c) >= 0x206a) && ((c) <= 0x206f)) || \
- ((c) == 0xfeff))
-
-#define IS_EXTENDER(c) \
- (((c) == 0xb7) || ((c) == 0x2d0) || ((c) == 0x2d1) || \
- ((c) == 0x387) || ((c) == 0x640) || ((c) == 0xe46) || \
- ((c) == 0xec6) || ((c) == 0x3005) \
- (((c) >= 0x3031) && ((c) <= 0x3035)) || \
- (((c) >= 0x309b) && ((c) <= 0x309e)) || \
- (((c) >= 0x30fc) && ((c) <= 0x30fe)) || \
- (((c) >= 0xff70) && ((c) <= 0xff9e)) || \
- ((c) == 0xff9f))
-
-#define IS_IDEOGRAPHIC(c) \
- ((((c) >= 0x4e00) && ((c) <= 0x9fa5)) || \
- (((c) >= 0xf900) && ((c) <= 0xfa2d)) || \
- (((c) >= 0x3021) && ((c) <= 0x3029)) || \
- ((c) == 0x3007))
-
-#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))
-
-/* I'm too lazy to complete this one ! */
-#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xa))
-#else
-/*
- * 8bits / ASCII version of the macros.
- */
-#define IS_CHAR(c) \
- (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || ((c) >= 0x20))
-
-#define IS_BASECHAR(c) \
- ((((c) >= 0x41) && ((c) <= 0x5a)) || \
- (((c) >= 0x61) && ((c) <= 0x7a)) || \
- (((c) >= 0xaa) && ((c) <= 0x5b)) || \
- (((c) >= 0xc0) && ((c) <= 0xd6)) || \
- (((c) >= 0xd8) && ((c) <= 0xf6)) || \
- (((c) >= 0xf8) && ((c) <= 0xff)) || \
- ((c) == 0xba))
-
-#define IS_DIGIT(c) (((c) >= 0x30) && ((c) <= 0x39))
-
-#define IS_LETTER(c) IS_BASECHAR(c)
-
-#define IS_COMBINING(c) 0
-
-#define IS_IGNORABLE(c) 0
-
-#define IS_EXTENDER(c) ((c) == 0xb7)
-
-#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xa))
-#endif
-
-
-#define SKIP_EOL(p) \
- if (*(p) == 0x13) { p++ ; if (*(p) == 0x10) p++; } \
- if (*(p) == 0x10) { p++ ; if (*(p) == 0x13) p++; }
-
-#define SKIP_BLANKS(p) \
- while (IS_BLANK(*(p))) (p)++;
-
-#define MOVETO_ENDTAG(p) \
- while (IS_CHAR(*p) && (*(p) != '>')) (p)++;
-
-#define MOVETO_STARTTAG(p) \
- while (IS_CHAR(*p) && (*(p) != '<')) (p)++;
-
-/*
- * Forward definition for recusive behaviour.
- */
-xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt);
-
-/*
- * xmlHandleData : this routine represent's the specific application
- * behaviour when reading a piece of text.
- *
- * For example in WebDav, any piece made only of blanks is eliminated
- */
-
-CHAR *xmlHandleData(CHAR *in) {
- CHAR *cur;
-
- if (in == NULL) return(NULL);
- cur = in;
- while (IS_CHAR(*cur)) {
- if (!IS_BLANK(*cur)) goto not_blank;
- cur++;
- }
- free(in);
- return(NULL);
-
-not_blank:
- return(in);
-}
-
-/*
- * xmlStrndup : a strdup for array of CHAR's
- */
-
-CHAR *xmlStrndup(const CHAR *cur, int len) {
- CHAR *ret = malloc((len + 1) * sizeof(CHAR));
-
- if (ret == NULL) {
- fprintf(stderr, "malloc of %d byte failed\n",
- (len + 1) * sizeof(CHAR));
- return(NULL);
- }
- memcpy(ret, cur, len * sizeof(CHAR));
- ret[len] = 0;
- return(ret);
-}
-
-/*
- * xmlStrdup : a strdup for CHAR's
- */
-
-CHAR *xmlStrdup(const CHAR *cur) {
- const CHAR *p = cur;
-
- while (IS_CHAR(*p)) p++;
- return(xmlStrndup(cur, p - cur));
-}
-
-/*
- * xmlStrcmp : a strcmp for CHAR's
- */
-
-int xmlStrcmp(const CHAR *str1, const CHAR *str2) {
- register int tmp;
-
- do {
- tmp = *str1++ - *str2++;
- if (tmp != 0) return(tmp);
- } while ((*str1 != 0) && (*str2 != 0));
- return (*str1 - *str2);
-}
-
-/*
- * xmlStrncmp : a strncmp for CHAR's
- */
-
-int xmlStrncmp(const CHAR *str1, const CHAR *str2, int len) {
- register int tmp;
-
- if (len <= 0) return(0);
- do {
- tmp = *str1++ - *str2++;
- if (tmp != 0) return(tmp);
- len--;
- if (len <= 0) return(0);
- } while ((*str1 != 0) && (*str2 != 0));
- return (*str1 - *str2);
-}
-
-/*
- * xmlStrchr : a strchr for CHAR's
- */
-
-CHAR *xmlStrchr(const CHAR *str, CHAR val) {
- while (*str != 0) {
- if (*str == val) return((CHAR *) str);
- str++;
- }
- return(NULL);
-}
-
-/*
- * xmlParseName : parse an XML name.
- */
-
-CHAR *xmlParseName(xmlParserCtxtPtr ctxt) {
- const CHAR *q;
- CHAR *ret = NULL;
-
- /*
- * Name ::= (Letter | '_') (NameChar)*
- */
- if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) return(NULL);
- q = ctxt->cur++;
- while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
- (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') || (ctxt->cur[0] == '_') ||
- (ctxt->cur[0] == ':') ||
- (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
- (IS_EXTENDER(ctxt->cur[0])))
- ctxt->cur++;
-
- ret = xmlStrndup(q, ctxt->cur - q);
-
- return(ret);
-}
-
-/*
- * Parse and return a string between quotes or doublequotes
- */
-CHAR *xmlParseQuotedString(xmlParserCtxtPtr ctxt) {
- CHAR *ret = NULL;
- const CHAR *q;
-
- if (ctxt->cur[0] == '"') {
- ctxt->cur++;
- q = ctxt->cur;
- while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '"')) ctxt->cur++;
- if (ctxt->cur[0] != '"')
- fprintf(stderr, "String not closed \"%.50s\n", q);
- else {
- ret = xmlStrndup(q, ctxt->cur - q);
- ctxt->cur++;
- }
- } else if (ctxt->cur[0] == '\''){
- ctxt->cur++;
- q = ctxt->cur;
- while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '\'')) ctxt->cur++;
- if (ctxt->cur[0] != '\'')
- fprintf(stderr, "String not closed '%.50s\n", q);
- else {
- ret = xmlStrndup(q, ctxt->cur - q);
- ctxt->cur++;
- }
- }
- return(ret);
-}
-
-/*
- * Skip an XML (SGML) comment <!-- .... -->
- *
- * TODO !!!! Save the comment in the tree !!!
- */
-void xmlParserSkipComment(xmlParserCtxtPtr ctxt) {
- const CHAR *q, *start;
- const CHAR *r;
-
- /*
- * An extra check may avoid errors and isn't that costly !
- */
- if ((ctxt->cur[0] != '<') || (ctxt->cur[1] != '!') ||
- (ctxt->cur[2] != '-') || (ctxt->cur[3] != '-')) return;
-
- ctxt->cur += 4;
- start = q = ctxt->cur;
- ctxt->cur++;
- r = ctxt->cur;
- ctxt->cur++;
- while (IS_CHAR(ctxt->cur[0]) &&
- ((ctxt->cur[0] == ':') || (ctxt->cur[0] != '>') ||
- (*r != '-') || (*q != '-'))) {
- ctxt->cur++;r++;q++;
- }
- if (!IS_CHAR(ctxt->cur[0])) {
- fprintf(stderr, "Comment not terminated <!--%.50s\n", start);
- ctxt->cur = start; /* !!! We shouldn't really try to recover !!! */
- } else {
- ctxt->cur++;
- }
-}
-
-/*
- * xmlParseNamespace: parse specific '<?namespace ...' constructs.
- */
-
-void xmlParseNamespace(xmlParserCtxtPtr ctxt) {
- CHAR *href = NULL;
- CHAR *AS = NULL;
- int garbage = 0;
-
- /*
- * We just skipped "namespace" or "xml:namespace"
- */
- SKIP_BLANKS(ctxt->cur);
-
- while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '>')) {
- /*
- * We can have "ns" or "prefix" attributes
- * Old encoding as 'href' or 'AS' attributes is still supported
- */
- if ((ctxt->cur[0] == 'n') && (ctxt->cur[1] == 's')) {
- garbage = 0;
- ctxt->cur += 2;
- SKIP_BLANKS(ctxt->cur);
-
- if (ctxt->cur[0] != '=') continue;
- ctxt->cur++;
- SKIP_BLANKS(ctxt->cur);
-
- href = xmlParseQuotedString(ctxt);
- SKIP_BLANKS(ctxt->cur);
- } else if ((ctxt->cur[0] == 'h') && (ctxt->cur[1] == 'r') &&
- (ctxt->cur[2] == 'e') && (ctxt->cur[3] == 'f')) {
- garbage = 0;
- ctxt->cur += 4;
- SKIP_BLANKS(ctxt->cur);
-
- if (ctxt->cur[0] != '=') continue;
- ctxt->cur++;
- SKIP_BLANKS(ctxt->cur);
-
- href = xmlParseQuotedString(ctxt);
- SKIP_BLANKS(ctxt->cur);
- } else if ((ctxt->cur[0] == 'p') && (ctxt->cur[1] == 'r') &&
- (ctxt->cur[2] == 'e') && (ctxt->cur[3] == 'f') &&
- (ctxt->cur[4] == 'i') && (ctxt->cur[5] == 'x')) {
- garbage = 0;
- ctxt->cur += 6;
- SKIP_BLANKS(ctxt->cur);
-
- if (ctxt->cur[0] != '=') continue;
- ctxt->cur++;
- SKIP_BLANKS(ctxt->cur);
-
- AS = xmlParseQuotedString(ctxt);
- SKIP_BLANKS(ctxt->cur);
- } else if ((ctxt->cur[0] == 'A') && (ctxt->cur[1] == 'S')) {
- garbage = 0;
- ctxt->cur += 2;
- SKIP_BLANKS(ctxt->cur);
-
- if (ctxt->cur[0] != '=') continue;
- ctxt->cur++;
- SKIP_BLANKS(ctxt->cur);
-
- AS = xmlParseQuotedString(ctxt);
- SKIP_BLANKS(ctxt->cur);
- } else if ((ctxt->cur[0] == '?') && (ctxt->cur[1] == '>')) {
- garbage = 0;
- ctxt->cur ++;
- } else {
- /*
- * Found garbage when parsing the namespace
- */
- if (!garbage) fprintf(stderr,
- "\nxmlParseNamespace found garbage: ");
- fprintf(stderr, "%c", ctxt->cur[0]);
- ctxt->cur++;
- }
- }
-
- MOVETO_ENDTAG(ctxt->cur);
- ctxt->cur++;
-
- /*
- * Register the DTD.
- */
- if (href != NULL)
- xmlNewDtd(ctxt->doc, href, AS);
-
- if (AS != NULL) free(AS);
- if (href != NULL) free(href);
-}
-
-/*
- * xmlParsePI: parse an XML Processing Instruction.
- */
-
-void xmlParsePI(xmlParserCtxtPtr ctxt) {
- if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) {
- /*
- * this is a Processing Instruction.
- */
- ctxt->cur += 2;
-
- /*
- * Special for WebDav, support for the Processing Instruction
- * '<?namespace ...' contruct in the header of the XML document.
- */
- if ((ctxt->cur[0] == 'n') && (ctxt->cur[1] == 'a') &&
- (ctxt->cur[2] == 'm') && (ctxt->cur[3] == 'e') &&
- (ctxt->cur[4] == 's') && (ctxt->cur[5] == 'p') &&
- (ctxt->cur[6] == 'a') && (ctxt->cur[7] == 'c') &&
- (ctxt->cur[8] == 'e')) {
- ctxt->cur += 9;
- xmlParseNamespace(ctxt);
- } else if ((ctxt->cur[0] == 'x') && (ctxt->cur[1] == 'm') &&
- (ctxt->cur[2] == 'l') && (ctxt->cur[3] == ':') &&
- (ctxt->cur[4] == 'n') && (ctxt->cur[5] == 'a') &&
- (ctxt->cur[6] == 'm') && (ctxt->cur[7] == 'e') &&
- (ctxt->cur[8] == 's') && (ctxt->cur[9] == 'p') &&
- (ctxt->cur[10] == 'a') && (ctxt->cur[11] == 'c') &&
- (ctxt->cur[12] == 'e')) {
- ctxt->cur += 13;
- xmlParseNamespace(ctxt);
- } else {
- /* Unknown PI, ignore it ! */
- fprintf(stderr, "xmlParsePI : skipping unknown PI %30s\n",
- ctxt->cur);
- MOVETO_ENDTAG(ctxt->cur);
- ctxt->cur++;
- }
- }
-}
-
-/*
- * xmlParseAttribute: parse a start of tag.
- *
- * Attribute ::= Name Eq AttValue
- */
-
-void xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
- const CHAR *q;
- CHAR *name, *value = NULL;
-
- if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) {
- return;
- }
- q = ctxt->cur++;
- while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
- (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
- (ctxt->cur[0] == '_') || (ctxt->cur[0] == ':') ||
- (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
- (IS_EXTENDER(ctxt->cur[0])))
- ctxt->cur++;
- name = xmlStrndup(q, ctxt->cur - q);
-
- /*
- * We should have the equal, we are laxist here and allow attributes
- * without values and extra spaces.
- */
- SKIP_BLANKS(ctxt->cur);
- if (ctxt->cur[0] == '=') {
- ctxt->cur++;
- SKIP_BLANKS(ctxt->cur);
- if ((ctxt->cur[0] != '\'') && (ctxt->cur[0] != '"')) {
- fprintf(stderr, "Quotes were expected for attribute value %.20s\n",
- q);
- } else
- value = xmlParseQuotedString(ctxt);
- }
-
- /*
- * Add the attribute to the node.
- */
- if (name != NULL) {
- xmlNewProp(node, name, value);
- free(name);
- }
- if ( value != NULL )
- free(value);
-}
-
-/*
- * xmlParseStartTag: parse a start of tag.
- */
-
-xmlNodePtr xmlParseStartTag(xmlParserCtxtPtr ctxt) {
- const CHAR *q;
- CHAR *ns, *name;
- xmlDtdPtr dtd = NULL;
- xmlNodePtr ret = NULL;
-
- /*
- * Theorically one should just parse a Name, but with the addition
- * of the namespace needed for WebDav, it's a bit more complicated
- * since the element name may be prefixed by a namespace prefix.
- *
- * QName ::= (NSPart ':')? LocalPart
- * NSPart ::= Name
- * LocalPart ::= Name
- * STag ::= '<' QName (S Attribute)* S? '>'
- *
- * instead of :
- *
- * STag ::= '<' QName (S Attribute)* S? '>'
- */
- if (ctxt->cur[0] != '<') return(NULL);
- ctxt->cur++;
-
- if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) return(NULL);
- q = ctxt->cur++;
- while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
- (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
- (ctxt->cur[0] == '_') ||
- (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
- (IS_EXTENDER(ctxt->cur[0])))
- ctxt->cur++;
-
- if (ctxt->cur[0] == ':') {
- ns = xmlStrndup(q, ctxt->cur - q);
-
- ctxt->cur++; /* skip the column */
- if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) {
- fprintf(stderr,
- "Start tag : no element name after namespace identifier %.20s\n",
- q);
- free(ns);
- return(NULL);
- }
- q = ctxt->cur++;
- while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
- (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
- (ctxt->cur[0] == '_') || (ctxt->cur[0] == ':') ||
- (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
- (IS_EXTENDER(ctxt->cur[0])))
- ctxt->cur++;
- name = xmlStrndup(q, ctxt->cur - q);
-
- /*
- * Search the DTD associated to ns.
- */
- dtd = xmlSearchDtd(ctxt->doc, ns);
- if (dtd == NULL)
- fprintf(stderr, "Start tag : Couldn't find namespace %s\n", ns);
- free(ns);
- } else
- name = xmlStrndup(q, ctxt->cur - q);
-
- ret = xmlNewNode(dtd, name, NULL);
-
- /*
- * Now parse the attributes, it ends up with the ending
- *
- * (S Attribute)* S?
- */
- SKIP_BLANKS(ctxt->cur);
- while ((IS_CHAR(ctxt->cur[0])) &&
- (ctxt->cur[0] != '>') &&
- ((ctxt->cur[0] != '/') || (ctxt->cur[1] != '>'))) {
- if (IS_LETTER(ctxt->cur[0]) || (ctxt->cur[0] == '_'))
- xmlParseAttribute(ctxt, ret);
- else {
- /* We should warn TODO !!! */
- ctxt->cur++;
- }
- SKIP_BLANKS(ctxt->cur);
- }
-
- return(ret);
-}
-
-/*
- * xmlParseEndTag: parse an end of tag, note that the '</' part has
- * already been read.
- */
-
-void xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlDtdPtr *dtdPtr, CHAR **tagPtr) {
- const CHAR *q;
- CHAR *ns, *name;
- xmlDtdPtr dtd = NULL;
-
- *dtdPtr = NULL;
- *tagPtr = NULL;
-
- /*
- * Theorically one should just parse a Name, but with the addition
- * of the namespace needed for WebDav, it's a bit more complicated
- * since the element name may be prefixed by a namespace prefix.
- *
- * QName ::= (NSPart ':')? LocalPart
- * NSPart ::= Name
- * LocalPart ::= Name
- * ETag ::= '</' QName S? '>'
- *
- * instead of :
- *
- * ETag ::= '</' Name S? '>'
- */
- if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) return;
- q = ctxt->cur++;
- while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
- (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
- (ctxt->cur[0] == '_') ||
- (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
- (IS_EXTENDER(ctxt->cur[0])))
- ctxt->cur++;
-
- if (ctxt->cur[0] == ':') {
- ns = xmlStrndup(q, ctxt->cur - q);
-
- ctxt->cur++; /* skip the column */
- if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) {
- fprintf(stderr,
- "End tag : no element name after namespace identifier %.20s\n",
- q);
- free(ns);
- return;
- }
- q = ctxt->cur++;
- while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
- (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
- (ctxt->cur[0] == '_') || (ctxt->cur[0] == ':') ||
- (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
- (IS_EXTENDER(ctxt->cur[0])))
- ctxt->cur++;
- name = xmlStrndup(q, ctxt->cur - q);
-
- /*
- * Search the DTD associated to ns.
- */
- dtd = xmlSearchDtd(ctxt->doc, ns);
- if (dtd == NULL)
- fprintf(stderr, "End tag : Couldn't find namespace %s\n", ns);
- free(ns);
- } else
- name = xmlStrndup(q, ctxt->cur - q);
-
- *dtdPtr = dtd;
- *tagPtr = name;
-
- /*
- * We should definitely be at the ending "S? '>'" part
- */
- SKIP_BLANKS(ctxt->cur);
- if ((!IS_CHAR(ctxt->cur[0])) || (ctxt->cur[0] != '>')) {
- fprintf(stderr, "End tag : expected '>', got %.20s\n", ctxt->cur);
- /*
- * Note : skipping to the next '>' is probably otherkill,
- * especially in case the '>' is hust missing.
- *
- * Otherwise add:
- * MOVETO_ENDTAG(ctxt->cur);
- */
- } else
- ctxt->cur++;
-
- return;
-}
-
-/*
- * xmlParseCDSect: escaped pure raw content.
- */
-CHAR *xmlParseCDSect(xmlParserCtxtPtr ctxt) {
- const CHAR *r, *s, *base;
- CHAR *ret;
-
- base = ctxt->cur;
- if (!IS_CHAR(ctxt->cur[0])) {
- fprintf(stderr, "CData section not finished : %.20s\n", base);
- return(NULL);
- }
- r = ctxt->cur++;
- if (!IS_CHAR(ctxt->cur[0])) {
- fprintf(stderr, "CData section not finished : %.20s\n", base);
- return(NULL);
- }
- s = ctxt->cur++;
- while (IS_CHAR(ctxt->cur[0]) &&
- ((*r != ']') || (*s != ']') || (ctxt->cur[0] != '>'))) {
- r++;s++;ctxt->cur++;
- }
- if (!IS_CHAR(ctxt->cur[0])) {
- fprintf(stderr, "CData section not finished : %.20s\n", base);
- return(NULL);
- }
- ret = xmlStrndup(base, ctxt->cur-base);
-
- return(ret);
-}
-
-/*
- * xmlParseContent: a content is
- * (element | PCData | Reference | CDSect | PI | Comment)
- *
- * element : starts by '<'
- * PCData : any CHAR but '&' or '<'
- * Reference : starts by '&'
- * CDSect : starts by '<![CDATA['
- * PI : starts by '<?'
- */
-
-xmlNodePtr xmlParseContent(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
- const CHAR *q;
- CHAR *data = NULL;
- xmlNodePtr ret = NULL;
-
- /*
- * First case : a Processing Instruction.
- */
- if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) {
- xmlParsePI(ctxt);
- }
- /*
- * Second case : a CDSection
- */
- if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '!') &&
- (ctxt->cur[2] == '[') && (ctxt->cur[3] == 'C') &&
- (ctxt->cur[4] == 'D') && (ctxt->cur[5] == 'A') &&
- (ctxt->cur[6] == 'T') && (ctxt->cur[7] == 'A') &&
- (ctxt->cur[8] == '[')) {
- ctxt->cur += 9;
- data = xmlParseCDSect(ctxt);
- }
- /*
- * Third case : a sub-element.
- */
- else if (ctxt->cur[0] == '<') {
- ret = xmlParseElement(ctxt);
- }
- /*
- * Last case, text. Note that References are handled directly.
- */
- else {
- q = ctxt->cur;
- while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '<')) ctxt->cur++;
-
- if (!IS_CHAR(ctxt->cur[0])) {
- fprintf(stderr, "Truncated content : %.50s\n", q);
- return(NULL);
- }
-
- /*
- * Do the Entities decoding...
- */
- data = xmlStrdup(xmlDecodeEntities(ctxt->doc, q, ctxt->cur - q));
- }
-
- /*
- * Handle the data if any. If there is no child
- * add it as content, otherwise create a new node of type text.
- */
- if (data != NULL)
- data = xmlHandleData(data);
- if (data != NULL) {
- if (node->childs == NULL)
- xmlNodeSetContent(node, data);
- else
- ret = xmlNewText(data);
- free(data);
- }
-
- return(ret);
-}
-
-/*
- * xmlParseElement: parse an XML element
- */
-
-xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt) {
- xmlNodePtr ret, child;
- const CHAR *openTag = ctxt->cur;
- const CHAR *closeTag = ctxt->cur;
-
- ret = xmlParseStartTag(ctxt);
- if (ret == NULL) {
- return(NULL);
- }
-
- /*
- * Check for an Empty Element.
- */
- if ((ctxt->cur[0] == '/') && (ctxt->cur[1] == '>')) {
- ctxt->cur += 2;
- return(ret);
- }
- if (ctxt->cur[0] == '>') ctxt->cur++;
- else {
- fprintf(stderr, "Couldn't find end of Start Tag %.30s\n", openTag);
- return(NULL);
- }
-
- /*
- * Parse the content of the element:
- * (element | PCData | Reference | CDSect | PI | Comment) *
- *
- * element : starts by '<'
- * PCData : any CHAR but '&' or '<'
- * Reference : starts by '&'
- * CDSect : starts by '<![CDATA['
- * PI : starts by '<?'
- *
- * The loop stops upon detection of an end of tag '</'
- */
- while ((IS_CHAR(ctxt->cur[0])) &&
- ((ctxt->cur[0] != '<') || (ctxt->cur[1] != '/'))) {
- child = xmlParseContent(ctxt, ret);
- if (child != NULL)
- xmlAddChild(ret, child);
- }
- if (!IS_CHAR(ctxt->cur[0])) {
- fprintf(stderr, "Premature end of data in tag %.30s\n", openTag);
- return(NULL);
- }
-
- /*
- * parse the end of tag : '</' has been detected.
- */
- ctxt->cur += 2;
- if (ctxt->cur[0] == '>') ctxt->cur++; /* simplified closing </> */
- else {
- CHAR *endTag;
- xmlDtdPtr endDtd;
-
- xmlParseEndTag(ctxt, &endDtd, &endTag);
-
- /*
- * Check that the Name in the ETag is the same as in the STag.
- */
- if (endDtd != ret->dtd) {
- fprintf(stderr, "Start and End tags don't use the same DTD:\n");
- fprintf(stderr, "\t%.30s\n\t%.30s\n", openTag, closeTag);
- }
- if (strcmp(ret->name, endTag)) {
- fprintf(stderr, "Start and End tags don't use the same name:\n");
- fprintf(stderr, "\t%.30s\n\t%.30s\n", openTag, closeTag);
- }
-
- if ( endTag != NULL )
- free(endTag);
- }
-
- return(ret);
-}
-
-/*
- * xmlParseXMLDecl: parse an XML declaration header
- */
-
-void xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
- CHAR *version;
-
- /*
- * We know that '<?xml' is here.
- */
- ctxt->cur += 5;
-
- /*
- * Parse the version info
- */
- SKIP_BLANKS(ctxt->cur);
-
- /*
- * We should have 'version=' here !
- */
- if ((ctxt->cur[0] == 'v') && (ctxt->cur[1] == 'e') &&
- (ctxt->cur[2] == 'r') && (ctxt->cur[3] == 's') &&
- (ctxt->cur[4] == 'i') && (ctxt->cur[5] == 'o') &&
- (ctxt->cur[6] == 'n') && (ctxt->cur[7] == '=')) {
- ctxt->cur += 8;
- version = xmlParseQuotedString(ctxt);
- if (version == NULL)
- ctxt->doc = xmlNewDoc(XML_DEFAULT_VERSION);
- else {
- ctxt->doc = xmlNewDoc(version);
- free(version);
- }
- } else {
- ctxt->doc = xmlNewDoc(XML_DEFAULT_VERSION);
- }
-
- /*
- * We should check for Required Markup Declaration TODO !!!!
- */
- MOVETO_ENDTAG(ctxt->cur);
- ctxt->cur++;
-
-}
-
-/*
- * xmlParseMisc: parse an XML Misc optionnal field.
- * (Comment | PI | S)*
- */
-
-void xmlParseMisc(xmlParserCtxtPtr ctxt) {
- while (((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) ||
- ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '!') &&
- (ctxt->cur[2] == '-') && (ctxt->cur[2] == '-')) ||
- IS_BLANK(ctxt->cur[0])) {
- if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) {
- xmlParsePI(ctxt);
- } else if (IS_BLANK(ctxt->cur[0])) {
- ctxt->cur++;
- } else
- xmlParserSkipComment(ctxt);
- }
-}
-
-/*
- * xmlParseDocument : parse an XML document and build a tree.
- */
-
-int xmlParseDocument(xmlParserCtxtPtr ctxt) {
- /*
- * We should check for encoding here and plug-in some
- * conversion code TODO !!!!
- */
-
- /*
- * Wipe out everything which is before the first '<'
- */
- SKIP_BLANKS(ctxt->cur);
-
- /*
- * Check for the XMLDecl in the Prolog.
- */
- if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?') &&
- (ctxt->cur[2] == 'x') && (ctxt->cur[3] == 'm') &&
- (ctxt->cur[4] == 'l')) {
- xmlParseXMLDecl(ctxt);
- /* SKIP_EOL(cur); */
- SKIP_BLANKS(ctxt->cur);
- } else if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?') &&
- (ctxt->cur[2] == 'X') && (ctxt->cur[3] == 'M') &&
- (ctxt->cur[4] == 'L')) {
- /*
- * The first drafts were using <?XML and the final W3C REC
- * now use <?xml ...
- */
- xmlParseXMLDecl(ctxt);
- /* SKIP_EOL(cur); */
- SKIP_BLANKS(ctxt->cur);
- } else {
- ctxt->doc = xmlNewDoc(XML_DEFAULT_VERSION);
- }
-
- /*
- * The Misc part of the Prolog
- * (Comment | PI | S) *
- */
- xmlParseMisc(ctxt);
-
- /*
- * Time to start parsing
- */
- ctxt->doc->root = xmlParseElement(ctxt);
-
- return(0);
-}
-
-/*
- * xmlParseDoc : parse an XML in-memory document and build a tree.
- */
-
-xmlDocPtr xmlParseDoc(CHAR *cur) {
- xmlDocPtr ret;
- xmlParserCtxtPtr ctxt;
-
- if (cur == NULL) return(NULL);
-
- ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
- if (ctxt == NULL) {
- perror("malloc");
- return(NULL);
- }
-
- xmlInitParserCtxt(ctxt);
- ctxt->base = cur;
- ctxt->cur = cur;
-
- xmlParseDocument(ctxt);
- ret = ctxt->doc;
- free(ctxt->nodes);
- free(ctxt);
-
- return(ret);
-}
-
-/*
- * xmlParseFile : parse an XML file and build a tree.
- */
-
-xmlDocPtr xmlParseFile(const char *filename) {
- xmlDocPtr ret;
-#ifdef HAVE_ZLIB_H
- gzFile input;
-#else
- int input;
-#endif
- int res;
- struct stat buf;
- char *buffer;
- xmlParserCtxtPtr ctxt;
-
- res = stat(filename, &buf);
- if (res < 0) return(NULL);
-
-#ifdef HAVE_ZLIB_H
-retry_bigger:
- buffer = malloc((buf.st_size * 20) + 100);
-#else
- buffer = malloc(buf.st_size + 100);
-#endif
- if (buffer == NULL) {
- perror("malloc");
- return(NULL);
- }
-
- memset(buffer, 0, sizeof(buffer));
-#ifdef HAVE_ZLIB_H
- input = gzopen (filename, "r");
- if (input == NULL) {
- fprintf (stderr, "Cannot read file %s :\n", filename);
- perror ("gzopen failed");
- return(NULL);
- }
-#else
- input = open (filename, O_RDONLY);
- if (input < 0) {
- fprintf (stderr, "Cannot read file %s :\n", filename);
- perror ("open failed");
- return(NULL);
- }
-#endif
-#ifdef HAVE_ZLIB_H
- res = gzread(input, buffer, 20 * buf.st_size);
-#else
- res = read(input, buffer, buf.st_size);
-#endif
- if (res < 0) {
- fprintf (stderr, "Cannot read file %s :\n", filename);
-#ifdef HAVE_ZLIB_H
- perror ("gzread failed");
-#else
- perror ("read failed");
-#endif
- return(NULL);
- }
-#ifdef HAVE_ZLIB_H
- gzclose(input);
- if (res >= 20 * buf.st_size) {
- free(buffer);
- buf.st_size *= 2;
- goto retry_bigger;
- }
- buf.st_size = res;
-#else
- close(input);
-#endif
-
-
- ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
- if (ctxt == NULL) {
- perror("malloc");
- return(NULL);
- }
- buffer[buf.st_size] = '\0';
-
- xmlInitParserCtxt(ctxt);
- ctxt->filename = filename;
- ctxt->base = buffer;
- ctxt->cur = buffer;
-
- xmlParseDocument(ctxt);
- ret = ctxt->doc;
- free(buffer);
- free(ctxt->nodes);
- free(ctxt);
-
- return(ret);
-}
-
-/*
- * xmlParseFile : parse an XML memory block and build a tree.
- */
-
-xmlDocPtr xmlParseMemory(char *buffer, int size) {
- xmlDocPtr ret;
- xmlParserCtxtPtr ctxt;
-
- ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
- if (ctxt == NULL) {
- perror("malloc");
- return(NULL);
- }
-
- buffer[size - 1] = '\0';
-
- xmlInitParserCtxt(ctxt);
- ctxt->base = buffer;
- ctxt->cur = buffer;
-
- xmlParseDocument(ctxt);
- ret = ctxt->doc;
- free(ctxt->nodes);
- free(ctxt);
-
- return(ret);
-}
-
-
-
-
-/* Initialize parser context */
-void xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
-{
- int i;
-
- ctxt->filename = NULL;
- ctxt->base = NULL;
- ctxt->cur = NULL;
- ctxt->line = 1;
- ctxt->col = 1;
- ctxt->doc = NULL;
- ctxt->depth = 0;
- ctxt->max_depth = 10;
- ctxt->nodes = (xmlNodePtr *) malloc(ctxt->max_depth * sizeof(xmlNodePtr));
- if (ctxt->nodes == NULL) {
- fprintf(stderr, "malloc of %d byte failed\n",
- ctxt->max_depth * sizeof(xmlNodePtr));
- ctxt->max_depth = 0;
- } else {
- for (i = 0;i < ctxt->max_depth;i++)
- ctxt->nodes[i] = NULL;
- }
-}
-
-
-/*
- * Clear (release owned resources) and reinitialize context
- */
-void xmlClearParserCtxt(xmlParserCtxtPtr ctx)
-{
- xmlInitParserCtxt(ctx);
-}
-
-
-/*
- * Setup the parser context to parse a new buffer; Clears any prior
- * contents from the parser context. The buffer parameter must not be
- * NULL, but the filename parameter can be
- */
-void xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const CHAR* buffer,
- const char* filename)
-{
- xmlClearParserCtxt(ctxt);
- ctxt->base = buffer;
- ctxt->cur = buffer;
- ctxt->filename = filename;
-}
-
-
-
-void xmlReportError(xmlParserCtxtPtr ctx, const CHAR* msg)
-{
- fputs(msg, stderr);
-}
diff --git a/xml_parser.h b/xml_parser.h
deleted file mode 100644
index a20c95a..0000000
--- a/xml_parser.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * parser.h : constants and stuff related to the XML parser.
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#ifndef __XML_PARSER_H__
-#define __XML_PARSER_H__
-
-#include "xml_tree.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Constants.
- */
-#define XML_DEFAULT_VERSION "1.0"
-
-
-typedef struct xmlParserCtxt {
- const char *filename; /* The file analyzed, if any */
- const CHAR *base; /* Base of the array to parse */
- const CHAR *cur; /* Current char being parsed */
- int line; /* Current line */
- int col; /* Current column */
- xmlDocPtr doc; /* the document being built */
- int depth; /* Depth of current element */
- int max_depth; /* Max depth allocated */
- xmlNodePtr *nodes; /* The node hierarchy being built */
-} xmlParserCtxt, *xmlParserCtxtPtr;
-
-/*
- * Interfaces
- */
-extern int xmlParseDocument(xmlParserCtxtPtr ctxt);
-extern xmlDocPtr xmlParseDoc(CHAR *cur);
-extern xmlDocPtr xmlParseMemory(char *buffer, int size);
-extern xmlDocPtr xmlParseFile(const char *filename);
-extern CHAR *xmlStrdup(const CHAR *input);
-extern CHAR *xmlStrndup(const CHAR *input, int n);
-extern CHAR *xmlStrchr(const CHAR *str, CHAR val);
-extern int xmlStrcmp(const CHAR *str1, const CHAR *str2);
-extern int xmlStrncmp(const CHAR *str1, const CHAR *str2, int len);
-
-extern void xmlInitParserCtxt(xmlParserCtxtPtr ctx);
-extern void xmlClearParserCtxt(xmlParserCtxtPtr ctx);
-extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer,
- const char* filename);
-
-extern void xmlReportError(xmlParserCtxtPtr ctx, const CHAR* msg);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XML_PARSER_H__ */
-
diff --git a/xml_tree.c b/xml_tree.c
deleted file mode 100644
index e939a47..0000000
--- a/xml_tree.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * tree.c : implemetation of access function for an XML tree.
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <malloc.h>
-#include <string.h> /* for memset() only ! */
-
-#include "xml_tree.h"
-#include "xml_entities.h"
-
-static CHAR xmlStringText[] = { 't', 'e', 'x', 't', 0 };
-int oldXMLWDcompatibility = 0;
-
-/************************************************************************
- * *
- * Allocation and deallocation of basic structures *
- * *
- ************************************************************************/
-
-/*
- * Creation of a new DTD.
- */
-xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *href, const CHAR *AS) {
- xmlDtdPtr cur;
-
- /*
- * Allocate a new DTD and fill the fields.
- */
- cur = (xmlDtdPtr) malloc(sizeof(xmlDtd));
- if (cur == NULL) {
- fprintf(stderr, "xmlNewDtd : malloc failed\n");
- return(NULL);
- }
-
- cur->next = NULL;
- if (href != NULL)
- cur->href = xmlStrdup(href);
- else
- cur->href = NULL;
- if (AS != NULL)
- cur->AS = xmlStrdup(AS);
- else
- cur->AS = NULL;
- if (doc != NULL) {
- cur->next = doc->dtds;
- doc->dtds = cur;
- }
-
- return(cur);
-}
-
-/*
- * Freeing a DTD
- */
-void xmlFreeDtd(xmlDtdPtr cur) {
- if (cur == NULL) {
- fprintf(stderr, "xmlFreeDtd : DTD == NULL\n");
- return;
- }
- if (cur->href != NULL) free((char *) cur->href);
- if (cur->AS != NULL) free((char *) cur->AS);
- memset(cur, -1, sizeof(xmlDtd));
- free(cur);
-}
-
-/*
- * Freeing a DTD list
- */
-void xmlFreeDtdList(xmlDtdPtr cur) {
- xmlDtdPtr next;
- if (cur == NULL) {
- fprintf(stderr, "xmlFreeDtdList : dtd == NULL\n");
- return;
- }
- while (cur != NULL) {
- next = cur->next;
- xmlFreeDtd(cur);
- cur = next;
- }
-}
-
-/*
- * Creation of a new document
- */
-xmlDocPtr xmlNewDoc(const CHAR *version) {
- xmlDocPtr cur;
-
- if (version == NULL) {
- fprintf(stderr, "xmlNewDoc : version == NULL\n");
- return(NULL);
- }
-
- /*
- * Allocate a new document and fill the fields.
- */
- cur = (xmlDocPtr) malloc(sizeof(xmlDoc));
- if (cur == NULL) {
- fprintf(stderr, "xmlNewDoc : malloc failed\n");
- return(NULL);
- }
-
- cur->version = xmlStrdup(version);
- cur->root = NULL;
- cur->dtds = NULL;
- return(cur);
-}
-
-/*
- * Freeing a document : all the tree is freed too.
- */
-void xmlFreeDoc(xmlDocPtr cur) {
- if (cur == NULL) {
- fprintf(stderr, "xmlFreeDoc : document == NULL\n");
- return;
- }
- free((char *) cur->version);
- if (cur->root != NULL) xmlFreeNode(cur->root);
- if (cur->dtds != NULL) xmlFreeDtdList(cur->dtds);
- memset(cur, -1, sizeof(xmlDoc));
- free(cur);
-}
-
-/*
- * Creation of a new property element in a given DTD.
- */
-xmlPropPtr xmlNewProp(xmlNodePtr node, const CHAR *name, const CHAR *value) {
- xmlPropPtr cur;
-
- if (name == NULL) {
- fprintf(stderr, "xmlNewProp : name == NULL\n");
- return(NULL);
- }
-
- /*
- * Allocate a new property and fill the fields.
- */
- cur = (xmlPropPtr) malloc(sizeof(xmlProp));
- if (cur == NULL) {
- fprintf(stderr, "xmlNewProp : malloc failed\n");
- return(NULL);
- }
-
- cur->node = node;
- cur->name = xmlStrdup(name);
- if (value != NULL)
- cur->value = xmlStrdup(value);
- else
- cur->value = NULL;
- if (node != NULL) {
- cur->next = node->properties;
- node->properties = cur;
- } else
- cur->next = NULL;
- return(cur);
-}
-
-/*
- * Freeing a property list : Free a property and all its siblings,
- * this is a recursive behaviour, all the childs
- * are freed too.
- */
-void xmlFreePropList(xmlPropPtr cur) {
- xmlPropPtr next;
- if (cur == NULL) {
- fprintf(stderr, "xmlFreePropList : property == NULL\n");
- return;
- }
- while (cur != NULL) {
- next = cur->next;
- xmlFreeProp(cur);
- cur = next;
- }
-}
-
-/*
- * Freeing a property.
- */
-void xmlFreeProp(xmlPropPtr cur) {
- if (cur == NULL) {
- fprintf(stderr, "xmlFreeProp : property == NULL\n");
- return;
- }
- if (cur->name != NULL) free((char *) cur->name);
- if (cur->value != NULL) free((char *) cur->value);
- memset(cur, -1, sizeof(xmlProp));
- free(cur);
-}
-
-/*
- * Creation of a new node element in a given DTD.
- * We don't assume that the "name" has already being strdup'd anymore !
- */
-xmlNodePtr xmlNewNode(xmlDtdPtr dtd, const CHAR *name, CHAR *content) {
- xmlNodePtr cur;
-
- if (name == NULL) {
- fprintf(stderr, "xmlNewNode : name == NULL\n");
- return(NULL);
- }
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) malloc(sizeof(xmlNode));
- if (cur == NULL) {
- fprintf(stderr, "xmlNewNode : malloc failed\n");
- return(NULL);
- }
-
- cur->parent = NULL;
- cur->next = NULL;
- cur->childs = NULL;
- cur->properties = NULL;
- cur->type = 0;
- cur->name = xmlStrdup(name);
- cur->dtd = dtd;
- if (content != NULL)
- cur->content = xmlStrdup(content);
- else
- cur->content = NULL;
- return(cur);
-}
-
-/*
- * Creation of a new node contening text.
- */
-xmlNodePtr xmlNewText(CHAR *content) {
- xmlNodePtr cur;
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) malloc(sizeof(xmlNode));
- if (cur == NULL) {
- fprintf(stderr, "xmlNewNode : malloc failed\n");
- return(NULL);
- }
-
- cur->parent = NULL;
- cur->next = NULL;
- cur->childs = NULL;
- cur->properties = NULL;
- cur->type = XML_TYPE_TEXT;
- cur->name = xmlStrdup(xmlStringText);;
- cur->dtd = NULL;
- if (content != NULL)
- cur->content = xmlStrdup(content);
- else
- cur->content = NULL;
- return(cur);
-}
-
-/*
- * Creation of a new child element, added at the end.
- */
-xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlDtdPtr dtd,
- const CHAR *name, CHAR *content) {
- xmlNodePtr cur, prev;
-
- if (parent == NULL) {
- fprintf(stderr, "xmlNewChild : parent == NULL\n");
- return(NULL);
- }
-
- if (name == NULL) {
- fprintf(stderr, "xmlNewChild : name == NULL\n");
- return(NULL);
- }
-
- /*
- * Allocate a new node
- */
- if (dtd == NULL)
- cur = xmlNewNode(parent->dtd, name, content);
- else
- cur = xmlNewNode(dtd, name, content);
- if (cur == NULL) return(NULL);
-
- /*
- * add the new element at the end of the childs list.
- */
- cur->parent = parent;
- if (parent->childs == NULL) {
- parent->childs = cur;
- } else {
- prev = parent->childs;
- while (prev->next != NULL) prev = prev->next;
- prev->next = cur;
- }
-
- return(cur);
-}
-
-/*
- * Add a new child element, added at the end.
- */
-xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
- xmlNodePtr prev;
-
- if (parent == NULL) {
- fprintf(stderr, "xmladdChild : parent == NULL\n");
- return(NULL);
- }
-
- if (cur == NULL) {
- fprintf(stderr, "xmladdChild : child == NULL\n");
- return(NULL);
- }
-
- /*
- * add the new element at the end of the childs list.
- */
- cur->parent = parent;
- if (parent->childs == NULL) {
- parent->childs = cur;
- } else {
- prev = parent->childs;
- while (prev->next != NULL) prev = prev->next;
- prev->next = cur;
- }
-
- return(cur);
-}
-
-/*
- * Freeing a node list : Free a node and all its siblings,
- * this is a recursive behaviour, all the childs
- * are freed too.
- */
-void xmlFreeNodeList(xmlNodePtr cur) {
- xmlNodePtr next;
- if (cur == NULL) {
- fprintf(stderr, "xmlFreeNodeList : node == NULL\n");
- return;
- }
- while (cur != NULL) {
- next = cur->next;
- xmlFreeNode(cur);
- cur = next;
- }
-}
-
-/*
- * Freeing a node : this is a recursive behaviour, all the childs
- * are freed too.
- */
-void xmlFreeNode(xmlNodePtr cur) {
- if (cur == NULL) {
- fprintf(stderr, "xmlFreeNode : node == NULL\n");
- return;
- }
- if (cur->properties != NULL) xmlFreePropList(cur->properties);
- if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
- if (cur->content != NULL) free(cur->content);
- if (cur->name != NULL) free((char *) cur->name);
- memset(cur, -1, sizeof(xmlNode));
- free(cur);
-}
-
-/************************************************************************
- * *
- * Content access functions *
- * *
- ************************************************************************/
-
-/*
- * Changing the content of a node.
- */
-void xmlNodeSetContent(xmlNodePtr cur, CHAR *content) {
- if (cur == NULL) {
- fprintf(stderr, "xmlNodeSetContent : node == NULL\n");
- return;
- }
- if (cur->content != NULL) free(cur->content);
- if (content != NULL)
- cur->content = xmlStrdup(content);
- else
- cur->content = NULL;
-}
-
-/*
- * Search a Dtd registered under a given name space for a document.
- */
-xmlDtdPtr xmlSearchDtd(xmlDocPtr doc, CHAR *nameSpace) {
- xmlDtdPtr cur;
-
- if ((doc == NULL) || (nameSpace == NULL)) return(NULL);
-
- cur = doc->dtds;
- while (cur != NULL) {
- if ((cur->AS != NULL) && (!xmlStrcmp(cur->AS, nameSpace)))
- return(cur);
- cur = cur->next;
- }
- return(NULL);
-}
-
-/*
- * Reading the content of a given property.
- */
-const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name) {
- xmlPropPtr prop = node->properties;
-
- while (prop != NULL) {
- if (!xmlStrcmp(prop->name, name)) return(prop->value);
- prop = prop->next;
- }
- return(NULL);
-}
-
-/************************************************************************
- * *
- * Output : to a FILE or in memory *
- * *
- ************************************************************************/
-
-/*
- * routine which manage and grows an output buffer. One can write
- * standard char array's (8 bits char) or CHAR's arrays.
- */
-static CHAR *buffer = NULL;
-static int buffer_index = 0;
-static int buffer_size = 0;
-
-static void xmlBufferWriteCHAR(const CHAR *string) {
- const CHAR *cur;
-
- if (buffer == NULL) {
- buffer_size = 50000;
- buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
- if (buffer == NULL) {
- fprintf(stderr, "xmlBufferWrite : out of memory!\n");
- exit(1);
- }
- }
-
- if (string == NULL) return;
- for (cur = string;*cur != 0;cur++) {
- if (buffer_index + 10 >= buffer_size) {
- buffer_size *= 2;
- buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
- if (buffer == NULL) {
- fprintf(stderr, "xmlBufferWrite : out of memory!\n");
- exit(1);
- }
- }
- buffer[buffer_index++] = *cur;
- }
- buffer[buffer_index] = 0;
-}
-
-static void xmlBufferWriteChar(const char *string) {
- const CHAR *cur;
-
- if (buffer == NULL) {
- buffer_size = 50000;
- buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
- if (buffer == NULL) {
- fprintf(stderr, "xmlBufferWrite : out of memory!\n");
- exit(1);
- }
- }
-
- if (string == NULL) return;
- for (cur = string;*cur != 0;cur++) {
- if (buffer_index + 10 >= buffer_size) {
- buffer_size *= 2;
- buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
- if (buffer == NULL) {
- fprintf(stderr, "xmlBufferWrite : out of memory!\n");
- exit(1);
- }
- }
- buffer[buffer_index++] = *cur;
- }
- buffer[buffer_index] = 0;
-}
-
-/*
- * Dump a DTD to the given FD
- */
-static void xmlDtdDump(xmlDtdPtr cur) {
- if (cur == NULL) {
- fprintf(stderr, "xmlDtdDump : DTD == NULL\n");
- return;
- }
- if (oldXMLWDcompatibility) {
- xmlBufferWriteChar("<?namespace");
- if (cur->href != NULL) {
- xmlBufferWriteChar(" href=\"");
- xmlBufferWriteCHAR(cur->href);
- xmlBufferWriteChar("\"");
- }
- if (cur->AS != NULL) {
- xmlBufferWriteChar(" AS=\"");
- xmlBufferWriteCHAR(cur->AS);
- xmlBufferWriteChar("\"");
- }
- xmlBufferWriteChar("?>\n");
- } else {
- xmlBufferWriteChar("<?xml:namespace");
- if (cur->href != NULL) {
- xmlBufferWriteChar(" ns=\"");
- xmlBufferWriteCHAR(cur->href);
- xmlBufferWriteChar("\"");
- }
- if (cur->AS != NULL) {
- xmlBufferWriteChar(" prefix=\"");
- xmlBufferWriteCHAR(cur->AS);
- xmlBufferWriteChar("\"");
- }
- xmlBufferWriteChar("?>\n");
- }
-}
-
-/*
- * Dump an XML property to the given FD
- */
-
-static void xmlPropDump(xmlDocPtr doc, xmlPropPtr cur) {
- if (cur == NULL) {
- fprintf(stderr, "xmlPropDump : property == NULL\n");
- return;
- }
- xmlBufferWriteChar(" ");
- xmlBufferWriteCHAR(cur->name);
- if (cur->value) {
- xmlBufferWriteChar("=\"");
- xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->value));
- xmlBufferWriteChar("\"");
- }
-}
-
-/*
- * Dump an XML property list to the given FD
- */
-
-static void xmlPropListDump(xmlDocPtr doc, xmlPropPtr cur) {
- if (cur == NULL) {
- fprintf(stderr, "xmlPropListDump : property == NULL\n");
- return;
- }
- while (cur != NULL) {
- xmlPropDump(doc, cur);
- cur = cur->next;
- }
-}
-
-/*
- * Dump an XML node list to the given FD
- */
-
-static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level);
-static void xmlNodeListDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
- if (cur == NULL) {
- fprintf(stderr, "xmlNodeListDump : node == NULL\n");
- return;
- }
- while (cur != NULL) {
- xmlNodeDump(doc, cur, level);
- cur = cur->next;
- }
-}
-
-/*
- * Dump an XML node to the given FD
- */
-
-static void xmlNodeDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
- int i;
-
- if (cur == NULL) {
- fprintf(stderr, "xmlNodeDump : node == NULL\n");
- return;
- }
- if (cur->type == XML_TYPE_TEXT) {
- if (cur->content != NULL)
- xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
- return;
- }
- for (i = 0;i < level;i++)
- xmlBufferWriteChar(" ");
-
- xmlBufferWriteChar("<");
- if ((cur->dtd != NULL) && (cur->dtd->AS != NULL)) {
- xmlBufferWriteCHAR(cur->dtd->AS);
- xmlBufferWriteChar(":");
- }
-
- xmlBufferWriteCHAR(cur->name);
- if (cur->properties != NULL)
- xmlPropListDump(doc, cur->properties);
-
- if ((cur->content == NULL) && (cur->childs == NULL)) {
- xmlBufferWriteChar("/>\n");
- return;
- }
- xmlBufferWriteChar(">");
- if (cur->content != NULL)
- xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
- if (cur->childs != NULL) {
- xmlBufferWriteChar("\n");
- xmlNodeListDump(doc, cur->childs, level + 1);
- for (i = 0;i < level;i++)
- xmlBufferWriteChar(" ");
- }
- xmlBufferWriteChar("</");
- if ((cur->dtd != NULL) && (cur->dtd->AS != NULL)) {
- xmlBufferWriteCHAR(cur->dtd->AS);
- xmlBufferWriteChar(":");
- }
-
- xmlBufferWriteCHAR(cur->name);
- xmlBufferWriteChar(">\n");
-}
-
-/*
- * Dump an XML DTD list to the given FD
- */
-
-static void xmlDtdListDump(xmlDtdPtr cur) {
- if (cur == NULL) {
- fprintf(stderr, "xmlDtdListDump : DTD == NULL\n");
- return;
- }
- while (cur != NULL) {
- xmlDtdDump(cur);
- cur = cur->next;
- }
-}
-
-/*
- * Dump an XML document to memory.
- */
-
-void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size) {
- if (cur == NULL) {
- fprintf(stderr, "xmlDocDump : document == NULL\n");
- *mem = NULL;
- *size = 0;
- return;
- }
- buffer_index = 0;
- if (oldXMLWDcompatibility)
- xmlBufferWriteChar("<?XML version=\"");
- else
- xmlBufferWriteChar("<?xml version=\"");
- xmlBufferWriteCHAR(cur->version);
- xmlBufferWriteChar("\"?>\n");
- if (cur->dtds != NULL)
- xmlDtdListDump(cur->dtds);
- if (cur->root != NULL)
- xmlNodeDump(cur, cur->root, 0);
-
- *mem = buffer;
- *size = buffer_index;
-}
-
-/*
- * Dump an XML document to the given FD
- */
-
-void xmlDocDump(FILE *f, xmlDocPtr cur) {
- if (cur == NULL) {
- fprintf(stderr, "xmlDocDump : document == NULL\n");
- return;
- }
- buffer_index = 0;
- if (oldXMLWDcompatibility)
- xmlBufferWriteChar("<?XML version=\"");
- else
- xmlBufferWriteChar("<?xml version=\"");
- xmlBufferWriteCHAR(cur->version);
- xmlBufferWriteChar("\"?>\n");
- if (cur->dtds != NULL)
- xmlDtdListDump(cur->dtds);
- if (cur->root != NULL)
- xmlNodeDump(cur, cur->root, 0);
-
- fwrite(buffer, sizeof(CHAR), buffer_index, f);
-}
-
-/************************************************************************
- * *
- * Debug *
- * *
- ************************************************************************/
-
-#ifdef DEBUG_TREE
-int main(void) {
- xmlDocPtr doc;
- xmlNodePtr tree, subtree;
- xmlDtdPtr dtd1;
- xmlDtdPtr dtd2;
-
- /*
- * build a fake XML document
- */
- doc = xmlNewDoc("1.0");
- dtd1 = xmlNewDtd(doc, "http://www.ietf.org/standards/dav/", "D");
- dtd2 = xmlNewDtd(doc, "http://www.w3.com/standards/z39.50/", "Z");
- doc->root = xmlNewNode(dtd1, "multistatus", NULL);
- tree = xmlNewChild(doc->root, NULL, "response", NULL);
- subtree = xmlNewChild(tree, NULL, "prop", NULL);
- xmlNewChild(subtree, dtd2, "Authors", NULL);
- subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 420 Method Failure");
- tree = xmlNewChild(doc->root, NULL, "response", NULL);
- subtree = xmlNewChild(tree, NULL, "prop", NULL);
- xmlNewChild(subtree, dtd2, "Copyright-Owner", NULL);
- subtree = xmlNewChild(tree, NULL, "status", "HTTP/1.1 409 Conflict");
- tree = xmlNewChild(doc->root, NULL, "responsedescription",
- "Copyright Owner can not be deleted or altered");
-
- /*
- * print it.
- */
- xmlDocDump(stdout, doc);
-
- /*
- * free it.
- */
- xmlFreeDoc(doc);
- return(0);
-}
-#endif
diff --git a/xml_tree.h b/xml_tree.h
deleted file mode 100644
index 00322c1..0000000
--- a/xml_tree.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * tree.h : describes the structures found in an tree resulting
- * from an XML parsing.
- *
- * See Copyright for the status of this software.
- *
- * $Id$
- */
-
-#ifndef __XML_TREE_H__
-#define __XML_TREE_H__
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Type definitions
- */
-#ifdef UNICODE
-typedef unsigned short CHAR;
-#else
-typedef unsigned char CHAR;
-#endif
-
-/*
- * Constants.
- */
-#define XML_TYPE_TEXT 1
-
-/*
- * An XML DTD defining a given name space.
- */
-typedef struct xmlDtd {
- struct xmlDtd *next; /* next Dtd link for this document */
- const CHAR *href; /* URL for the DTD */
- const CHAR *AS; /* URL for the DTD */
- void *entities; /* Hash table for entities if any */
-} xmlDtd, *xmlDtdPtr;
-
-/*
- * A property of an XML node.
- */
-typedef struct xmlProp {
- struct xmlNode *node; /* prop->node link */
- struct xmlProp *next; /* parent->childs link */
- const CHAR *name; /* the name of the property */
- const CHAR *value; /* the value of the property */
-} xmlProp, *xmlPropPtr;
-
-/*
- * A node in an XML tree.
- */
-typedef struct xmlNode {
- struct xmlNode *parent; /* child->parent link */
- struct xmlNode *next; /* next sibling link */
- struct xmlNode *childs; /* parent->childs link */
- struct xmlProp *properties; /* properties list */
- int type; /* type number in the DTD */
- const CHAR *name; /* the name of the node */
- xmlDtd *dtd; /* pointer to the DTD */
- CHAR *content; /* the content */
-} xmlNode, *xmlNodePtr;
-
-/*
- * An XML document.
- */
-typedef struct xmlDoc {
- const CHAR *version; /* the XML version string */
- struct xmlDtd *dtds; /* referenced DTDs */
- struct xmlNode *root; /* parent->childs link */
- void *entities; /* Hash table for entities if any */
-} xmlDoc, *xmlDocPtr;
-
-/*
- * Variables.
- */
-extern xmlDtdPtr baseDTD;
-extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
-
-/*
- * Functions.
- */
-extern xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *href, const CHAR *AS);
-extern void xmlFreeDtd(xmlDtdPtr cur);
-extern xmlDocPtr xmlNewDoc(const CHAR *version);
-extern void xmlFreeDoc(xmlDocPtr cur);
-extern xmlPropPtr xmlNewProp(xmlNodePtr node, const CHAR *name,
- const CHAR *value);
-extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
-extern void xmlFreePropList(xmlPropPtr cur);
-extern void xmlFreeProp(xmlPropPtr cur);
-extern xmlNodePtr xmlNewNode(xmlDtdPtr dtd, const CHAR *name, CHAR *content);
-extern xmlNodePtr xmlNewText(CHAR *content);
-extern xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
-extern void xmlFreeNodeList(xmlNodePtr cur);
-extern void xmlFreeNode(xmlNodePtr cur);
-extern void xmlNodeSetContent(xmlNodePtr cur, CHAR *content);
-extern xmlDtdPtr xmlSearchDtd(xmlDocPtr doc, CHAR *nameSpace);
-extern xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlDtdPtr dtd,
- const CHAR *name, CHAR *content);
-
-extern void xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size);
-extern void xmlDocDump(FILE *f, xmlDocPtr doc);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XML_TREE_H__ */
-