apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jor...@apache.org
Subject svn commit: r1002549 [9/14] - in /apr/apr-util/vendor/expat/current: ./ bcb5/ conftools/ doc/ examples/ lib/ tests/ vms/ win32/ xmlwf/
Date Wed, 29 Sep 2010 09:59:07 GMT
Modified: apr/apr-util/vendor/expat/current/lib/xmlparse.c
URL: http://svn.apache.org/viewvc/apr/apr-util/vendor/expat/current/lib/xmlparse.c?rev=1002549&r1=1002548&r2=1002549&view=diff
==============================================================================
--- apr/apr-util/vendor/expat/current/lib/xmlparse.c (original)
+++ apr/apr-util/vendor/expat/current/lib/xmlparse.c Wed Sep 29 09:59:04 2010
@@ -1,29 +1,23 @@
-/*
-Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
-#ifdef COMPILED_FROM_DSP
-#  include "winconfig.h"
-#  define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
-#  include "expat.h"
-#  undef XMLPARSEAPI
-#else
-#include <config.h>
-
-#ifdef __declspec
-#  define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
-#endif
+#include <stddef.h>
+#include <string.h>                     /* memset(), memcpy() */
 
-#include "expat.h"
+#define XML_BUILDING_EXPAT 1
 
-#ifdef __declspec
-#  undef XMLPARSEAPI
+#ifdef COMPILED_FROM_DSP
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
+#else
+#ifdef HAVE_EXPAT_CONFIG_H
+#include <expat_config.h>
 #endif
 #endif /* ndef COMPILED_FROM_DSP */
 
-#include <stddef.h>
-#include <string.h>
+#include "expat.h"
 
 #ifdef XML_UNICODE
 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
@@ -54,15 +48,36 @@ typedef char ICHAR;
 
 #endif
 
+#ifdef XML_UNICODE
+
 #ifdef XML_UNICODE_WCHAR_T
-#define XML_T(x) L ## x
+#define XML_T(x) (const wchar_t)x
+#define XML_L(x) L ## x
 #else
+#define XML_T(x) (const unsigned short)x
+#define XML_L(x) x
+#endif
+
+#else
+
 #define XML_T(x) x
+#define XML_L(x) x
+
 #endif
 
 /* Round up n to be a multiple of sz, where sz is a power of 2. */
 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
 
+/* Handle the case where memmove() doesn't exist. */
+#ifndef HAVE_MEMMOVE
+#ifdef HAVE_BCOPY
+#define memmove(d,s,l) bcopy((s),(d),(l))
+#else
+#error memmove does not exist on this platform, nor is a substitute available
+#endif /* HAVE_BCOPY */
+#endif /* HAVE_MEMMOVE */
+
+#include "internal.h"
 #include "xmltok.h"
 #include "xmlrole.h"
 
@@ -74,12 +89,37 @@ typedef struct {
 
 typedef struct {
   NAMED **v;
+  unsigned char power;
   size_t size;
   size_t used;
-  size_t usedLim;
-  XML_Memory_Handling_Suite *mem;
+  const XML_Memory_Handling_Suite *mem;
 } HASH_TABLE;
 
+/* Basic character hash algorithm, taken from Python's string hash:
+   h = h * 1000003 ^ character, the constant being a prime number.
+
+*/
+#ifdef XML_UNICODE
+#define CHAR_HASH(h, c) \
+  (((h) * 0xF4243) ^ (unsigned short)(c))
+#else
+#define CHAR_HASH(h, c) \
+  (((h) * 0xF4243) ^ (unsigned char)(c))
+#endif
+
+/* For probing (after a collision) we need a step size relative prime
+   to the hash table size, which is a power of 2. We use double-hashing,
+   since we can calculate a second hash value cheaply by taking those bits
+   of the first hash value that were discarded (masked out) when the table
+   index was calculated: index = hash & mask, where mask = table->size - 1.
+   We limit the maximum step size to table->size / 4 (mask >> 2) and make
+   it odd, since odd numbers are always relative prime to a power of 2.
+*/
+#define SECOND_HASH(hash, mask, power) \
+  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
+#define PROBE_STEP(hash, mask, power) \
+  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
+
 typedef struct {
   NAMED **p;
   NAMED **end;
@@ -88,6 +128,7 @@ typedef struct {
 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
 #define INIT_DATA_BUF_SIZE 1024
 #define INIT_ATTS_SIZE 16
+#define INIT_ATTS_VERSION 0xFFFFFFFF
 #define INIT_BLOCK_SIZE 1024
 #define INIT_BUFFER_SIZE 1024
 
@@ -111,16 +152,32 @@ typedef struct prefix {
 typedef struct {
   const XML_Char *str;
   const XML_Char *localPart;
+  const XML_Char *prefix;
+  int strLen;
   int uriLen;
+  int prefixLen;
 } TAG_NAME;
 
+/* TAG represents an open element.
+   The name of the element is stored in both the document and API
+   encodings.  The memory buffer 'buf' is a separately-allocated
+   memory area which stores the name.  During the XML_Parse()/
+   XMLParseBuffer() when the element is open, the memory for the 'raw'
+   version of the name (in the document encoding) is shared with the
+   document buffer.  If the element is open across calls to
+   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
+   contain the 'raw' name as well.
+
+   A parser re-uses these structures, maintaining a list of allocated
+   TAG objects in a free list.
+*/
 typedef struct tag {
-  struct tag *parent;
-  const char *rawName;
+  struct tag *parent;           /* parent of this element */
+  const char *rawName;          /* tagName in the original encoding */
   int rawNameLength;
-  TAG_NAME name;
-  char *buf;
-  char *bufEnd;
+  TAG_NAME name;                /* tagName in the API encoding */
+  char *buf;                    /* buffer for name components */
+  char *bufEnd;                 /* end of the buffer */
   BINDING *bindings;
 } TAG;
 
@@ -132,20 +189,23 @@ typedef struct {
   const XML_Char *base;
   const XML_Char *publicId;
   const XML_Char *notation;
-  char open;
-  char is_param;
+  XML_Bool open;
+  XML_Bool is_param;
+  XML_Bool is_internal; /* true if declared in internal subset outside PE */
 } ENTITY;
 
 typedef struct {
-  enum XML_Content_Type		type;
-  enum XML_Content_Quant	quant;
-  const XML_Char *		name;
-  int				firstchild;
-  int				lastchild;
-  int				childcnt;
-  int				nextsib;
+  enum XML_Content_Type         type;
+  enum XML_Content_Quant        quant;
+  const XML_Char *              name;
+  int                           firstchild;
+  int                           lastchild;
+  int                           childcnt;
+  int                           nextsib;
 } CONTENT_SCAFFOLD;
 
+#define INIT_SCAFFOLD_ELEMENTS 32
+
 typedef struct block {
   struct block *next;
   int size;
@@ -158,25 +218,31 @@ typedef struct {
   const XML_Char *end;
   XML_Char *ptr;
   XML_Char *start;
-  XML_Memory_Handling_Suite *mem;
+  const XML_Memory_Handling_Suite *mem;
 } STRING_POOL;
 
 /* The XML_Char before the name is used to determine whether
-an attribute has been specified. */
+   an attribute has been specified. */
 typedef struct attribute_id {
   XML_Char *name;
   PREFIX *prefix;
-  char maybeTokenized;
-  char xmlns;
+  XML_Bool maybeTokenized;
+  XML_Bool xmlns;
 } ATTRIBUTE_ID;
 
 typedef struct {
   const ATTRIBUTE_ID *id;
-  char isCdata;
+  XML_Bool isCdata;
   const XML_Char *value;
 } DEFAULT_ATTRIBUTE;
 
 typedef struct {
+  unsigned long version;
+  unsigned long hash;
+  const XML_Char *uriName;
+} NS_ATT;
+
+typedef struct {
   const XML_Char *name;
   PREFIX *prefix;
   const ATTRIBUTE_ID *idAtt;
@@ -191,14 +257,21 @@ typedef struct {
   HASH_TABLE attributeIds;
   HASH_TABLE prefixes;
   STRING_POOL pool;
-  int complete;
-  int standalone;
+  STRING_POOL entityValuePool;
+  /* false once a parameter entity reference has been skipped */
+  XML_Bool keepProcessing;
+  /* true once an internal or external PE reference has been encountered;
+     this includes the reference to an external subset */
+  XML_Bool hasParamEntityRefs;
+  XML_Bool standalone;
 #ifdef XML_DTD
+  /* indicates if external PE has been read */
+  XML_Bool paramEntityRead;
   HASH_TABLE paramEntities;
 #endif /* XML_DTD */
   PREFIX defaultPrefix;
   /* === scaffolding for building content model === */
-  int in_eldecl;
+  XML_Bool in_eldecl;
   CONTENT_SCAFFOLD *scaffold;
   unsigned contentStringLen;
   unsigned scaffSize;
@@ -214,10 +287,10 @@ typedef struct open_internal_entity {
   ENTITY *entity;
 } OPEN_INTERNAL_ENTITY;
 
-typedef enum XML_Error Processor(XML_Parser parser,
-				 const char *start,
-				 const char *end,
-				 const char **endPtr);
+typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
+                                         const char *start,
+                                         const char *end,
+                                         const char **endPtr);
 
 static Processor prologProcessor;
 static Processor prologInitProcessor;
@@ -225,6 +298,10 @@ static Processor contentProcessor;
 static Processor cdataSectionProcessor;
 #ifdef XML_DTD
 static Processor ignoreSectionProcessor;
+static Processor externalParEntProcessor;
+static Processor externalParEntInitProcessor;
+static Processor entityValueProcessor;
+static Processor entityValueInitProcessor;
 #endif /* XML_DTD */
 static Processor epilogProcessor;
 static Processor errorProcessor;
@@ -236,94 +313,118 @@ static Processor externalEntityContentPr
 static enum XML_Error
 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
 static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+               const char *, const char *);
 static enum XML_Error
 initializeEncoding(XML_Parser parser);
 static enum XML_Error
 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
-	 const char *end, int tok, const char *next, const char **nextPtr);
+         const char *end, int tok, const char *next, const char **nextPtr);
 static enum XML_Error
 processInternalParamEntity(XML_Parser parser, ENTITY *entity);
 static enum XML_Error
 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
-	  const char *start, const char *end, const char **endPtr);
+          const char *start, const char *end, const char **endPtr);
 static enum XML_Error
-doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+               const char *end, const char **nextPtr);
 #ifdef XML_DTD
 static enum XML_Error
-doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+                const char *end, const char **nextPtr);
 #endif /* XML_DTD */
-static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
-				TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
-static
-int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
 
+static enum XML_Error
+storeAtts(XML_Parser parser, const ENCODING *, const char *s,
+          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
+static enum XML_Error
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+           const XML_Char *uri, BINDING **bindingsPtr);
 static int
 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
-		int isCdata, int isId, const XML_Char *dfltValue,
-		XML_Parser parser);
-
+                XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue,
+                XML_Parser parser);
 static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
-		    STRING_POOL *);
+storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
+                    const char *, const char *, STRING_POOL *);
 static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
-		    STRING_POOL *);
+appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
+                     const char *, const char *, STRING_POOL *);
 static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
+               const char *end);
+static int
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
 static enum XML_Error
-storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
+                 const char *end);
 static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+                            const char *start, const char *end);
 static int
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
+              const char *end);
 static void
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-
-static const XML_Char *getContext(XML_Parser parser);
-static int setContext(XML_Parser parser, const XML_Char *context);
-static void normalizePublicId(XML_Char *s);
-static int dtdInit(DTD *, XML_Parser parser);
-
-static void dtdDestroy(DTD *, XML_Parser parser);
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
+              const char *end);
 
-static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
-
-static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *,
-			   XML_Parser parser);
-
-#ifdef XML_DTD
-static void dtdSwap(DTD *, DTD *);
-#endif /* XML_DTD */
+static const XML_Char * getContext(XML_Parser parser);
+static XML_Bool
+setContext(XML_Parser parser, const XML_Char *context);
+
+static void FASTCALL normalizePublicId(XML_Char *s);
+
+static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
+/* do not call if parentParser != NULL */
+static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
+static void
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
+static int
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
+static int
+copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
 
-static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
+static NAMED *
+lookup(HASH_TABLE *table, KEY name, size_t createSize);
+static void FASTCALL
+hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL hashTableClear(HASH_TABLE *);
+static void FASTCALL hashTableDestroy(HASH_TABLE *);
+static void FASTCALL
+hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
+
+static void FASTCALL
+poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL poolClear(STRING_POOL *);
+static void FASTCALL poolDestroy(STRING_POOL *);
+static XML_Char *
+poolAppend(STRING_POOL *pool, const ENCODING *enc,
+           const char *ptr, const char *end);
+static XML_Char *
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+                const char *ptr, const char *end);
+static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
+static const XML_Char * FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
+static const XML_Char * FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s);
 
-static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
+static int FASTCALL nextScaffoldPart(XML_Parser parser);
+static XML_Content * build_model(XML_Parser parser);
+static ELEMENT_TYPE *
+getElementType(XML_Parser parser, const ENCODING *enc,
+               const char *ptr, const char *end);
 
-static void hashTableDestroy(HASH_TABLE *);
-static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
-static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
-static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
-static void poolClear(STRING_POOL *);
-static void poolDestroy(STRING_POOL *);
-static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
-			    const char *ptr, const char *end);
-static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
-				  const char *ptr, const char *end);
-
-static int poolGrow(STRING_POOL *pool);
-
-static int nextScaffoldPart(XML_Parser parser);
-static XML_Content *build_model(XML_Parser parser);
-
-static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
-static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
-static const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s);
-static ELEMENT_TYPE * getElementType(XML_Parser Paraser,
-				     const ENCODING *enc,
-				     const char *ptr,
-				     const char *end);
+static XML_Parser
+parserCreate(const XML_Char *encodingName,
+             const XML_Memory_Handling_Suite *memsuite,
+             const XML_Char *nameSep,
+             DTD *dtd);
+static void
+parserInit(XML_Parser parser, const XML_Char *encodingName);
 
 #define poolStart(pool) ((pool)->start)
 #define poolEnd(pool) ((pool)->ptr)
@@ -337,12 +438,13 @@ static ELEMENT_TYPE * getElementType(XML
    ? 0 \
    : ((*((pool)->ptr)++ = c), 1))
 
-typedef struct {
-  /* The first member must be userData so that the XML_GetUserData macro works. */
+struct XML_ParserStruct {
+  /* The first member must be userData so that the XML_GetUserData
+     macro works. */
   void *m_userData;
   void *m_handlerArg;
   char *m_buffer;
-  XML_Memory_Handling_Suite m_mem;
+  const XML_Memory_Handling_Suite m_mem;
   /* first character to be parsed */
   const char *m_bufferPtr;
   /* past last character to be parsed */
@@ -369,7 +471,8 @@ typedef struct {
   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
   XML_NotStandaloneHandler m_notStandaloneHandler;
   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
-  void *m_externalEntityRefHandlerArg;
+  XML_Parser m_externalEntityRefHandlerArg;
+  XML_SkippedEntityHandler m_skippedEntityHandler;
   XML_UnknownEncodingHandler m_unknownEncodingHandler;
   XML_ElementDeclHandler m_elementDeclHandler;
   XML_AttlistDeclHandler m_attlistDeclHandler;
@@ -379,8 +482,8 @@ typedef struct {
   INIT_ENCODING m_initEncoding;
   const ENCODING *m_internalEncoding;
   const XML_Char *m_protocolEncodingName;
-  int m_ns;
-  int m_ns_triplets;
+  XML_Bool m_ns;
+  XML_Bool m_ns_triplets;
   void *m_unknownEncodingMem;
   void *m_unknownEncodingData;
   void *m_unknownEncodingHandlerData;
@@ -392,7 +495,7 @@ typedef struct {
   const char *m_eventEndPtr;
   const char *m_positionPtr;
   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
-  int m_defaultExpandInternalEntities;
+  XML_Bool m_defaultExpandInternalEntities;
   int m_tagLevel;
   ENTITY *m_declEntity;
   const XML_Char *m_doctypeName;
@@ -403,9 +506,9 @@ typedef struct {
   const XML_Char *m_declNotationPublicId;
   ELEMENT_TYPE *m_declElementType;
   ATTRIBUTE_ID *m_declAttributeId;
-  char m_declAttributeIsCdata;
-  char m_declAttributeIsId;
-  DTD m_dtd;
+  XML_Bool m_declAttributeIsCdata;
+  XML_Bool m_declAttributeIsId;
+  DTD *m_dtd;
   const XML_Char *m_curBase;
   TAG *m_tagStack;
   TAG *m_freeTagList;
@@ -415,309 +518,446 @@ typedef struct {
   int m_nSpecifiedAtts;
   int m_idAttIndex;
   ATTRIBUTE *m_atts;
+  NS_ATT *m_nsAtts;
+  unsigned long m_nsAttsVersion;
+  unsigned char m_nsAttsPower;
   POSITION m_position;
   STRING_POOL m_tempPool;
   STRING_POOL m_temp2Pool;
   char *m_groupConnector;
-  unsigned m_groupSize;
-  int m_hadExternalDoctype;
+  unsigned int m_groupSize;
   XML_Char m_namespaceSeparator;
+  XML_Parser m_parentParser;
 #ifdef XML_DTD
+  XML_Bool m_isParamEntity;
+  XML_Bool m_useForeignDTD;
   enum XML_ParamEntityParsing m_paramEntityParsing;
-  XML_Parser m_parentParser;
 #endif
-} Parser;
+};
 
-#define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
-#define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
-#define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
-
-#define userData (((Parser *)parser)->m_userData)
-#define handlerArg (((Parser *)parser)->m_handlerArg)
-#define startElementHandler (((Parser *)parser)->m_startElementHandler)
-#define endElementHandler (((Parser *)parser)->m_endElementHandler)
-#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
-#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
-#define commentHandler (((Parser *)parser)->m_commentHandler)
-#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
-#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
-#define defaultHandler (((Parser *)parser)->m_defaultHandler)
-#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
-#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
-#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
-#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
-#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
-#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
-#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
-#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
-#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
-#define internalEntityRefHandler (((Parser *)parser)->m_internalEntityRefHandler)
-#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
-#define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
-#define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
-#define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
-#define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
-#define encoding (((Parser *)parser)->m_encoding)
-#define initEncoding (((Parser *)parser)->m_initEncoding)
-#define internalEncoding (((Parser *)parser)->m_internalEncoding)
-#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
-#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
+#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
+#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
+#define FREE(p) (parser->m_mem.free_fcn((p)))
+
+#define userData (parser->m_userData)
+#define handlerArg (parser->m_handlerArg)
+#define startElementHandler (parser->m_startElementHandler)
+#define endElementHandler (parser->m_endElementHandler)
+#define characterDataHandler (parser->m_characterDataHandler)
+#define processingInstructionHandler \
+        (parser->m_processingInstructionHandler)
+#define commentHandler (parser->m_commentHandler)
+#define startCdataSectionHandler \
+        (parser->m_startCdataSectionHandler)
+#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
+#define defaultHandler (parser->m_defaultHandler)
+#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
+#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
+#define unparsedEntityDeclHandler \
+        (parser->m_unparsedEntityDeclHandler)
+#define notationDeclHandler (parser->m_notationDeclHandler)
+#define startNamespaceDeclHandler \
+        (parser->m_startNamespaceDeclHandler)
+#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
+#define notStandaloneHandler (parser->m_notStandaloneHandler)
+#define externalEntityRefHandler \
+        (parser->m_externalEntityRefHandler)
+#define externalEntityRefHandlerArg \
+        (parser->m_externalEntityRefHandlerArg)
+#define internalEntityRefHandler \
+        (parser->m_internalEntityRefHandler)
+#define skippedEntityHandler (parser->m_skippedEntityHandler)
+#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
+#define elementDeclHandler (parser->m_elementDeclHandler)
+#define attlistDeclHandler (parser->m_attlistDeclHandler)
+#define entityDeclHandler (parser->m_entityDeclHandler)
+#define xmlDeclHandler (parser->m_xmlDeclHandler)
+#define encoding (parser->m_encoding)
+#define initEncoding (parser->m_initEncoding)
+#define internalEncoding (parser->m_internalEncoding)
+#define unknownEncodingMem (parser->m_unknownEncodingMem)
+#define unknownEncodingData (parser->m_unknownEncodingData)
 #define unknownEncodingHandlerData \
-  (((Parser *)parser)->m_unknownEncodingHandlerData)
-#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
-#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
-#define ns (((Parser *)parser)->m_ns)
-#define ns_triplets (((Parser *)parser)->m_ns_triplets)
-#define prologState (((Parser *)parser)->m_prologState)
-#define processor (((Parser *)parser)->m_processor)
-#define errorCode (((Parser *)parser)->m_errorCode)
-#define eventPtr (((Parser *)parser)->m_eventPtr)
-#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
-#define positionPtr (((Parser *)parser)->m_positionPtr)
-#define position (((Parser *)parser)->m_position)
-#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
-#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
-#define tagLevel (((Parser *)parser)->m_tagLevel)
-#define buffer (((Parser *)parser)->m_buffer)
-#define bufferPtr (((Parser *)parser)->m_bufferPtr)
-#define bufferEnd (((Parser *)parser)->m_bufferEnd)
-#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
-#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
-#define bufferLim (((Parser *)parser)->m_bufferLim)
-#define dataBuf (((Parser *)parser)->m_dataBuf)
-#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
-#define dtd (((Parser *)parser)->m_dtd)
-#define curBase (((Parser *)parser)->m_curBase)
-#define declEntity (((Parser *)parser)->m_declEntity)
-#define doctypeName (((Parser *)parser)->m_doctypeName)
-#define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
-#define doctypePubid (((Parser *)parser)->m_doctypePubid)
-#define declAttributeType (((Parser *)parser)->m_declAttributeType)
-#define declNotationName (((Parser *)parser)->m_declNotationName)
-#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
-#define declElementType (((Parser *)parser)->m_declElementType)
-#define declAttributeId (((Parser *)parser)->m_declAttributeId)
-#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
-#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
-#define freeTagList (((Parser *)parser)->m_freeTagList)
-#define freeBindingList (((Parser *)parser)->m_freeBindingList)
-#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
-#define tagStack (((Parser *)parser)->m_tagStack)
-#define atts (((Parser *)parser)->m_atts)
-#define attsSize (((Parser *)parser)->m_attsSize)
-#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
-#define idAttIndex (((Parser *)parser)->m_idAttIndex)
-#define tempPool (((Parser *)parser)->m_tempPool)
-#define temp2Pool (((Parser *)parser)->m_temp2Pool)
-#define groupConnector (((Parser *)parser)->m_groupConnector)
-#define groupSize (((Parser *)parser)->m_groupSize)
-#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
-#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
+  (parser->m_unknownEncodingHandlerData)
+#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
+#define protocolEncodingName (parser->m_protocolEncodingName)
+#define ns (parser->m_ns)
+#define ns_triplets (parser->m_ns_triplets)
+#define prologState (parser->m_prologState)
+#define processor (parser->m_processor)
+#define errorCode (parser->m_errorCode)
+#define eventPtr (parser->m_eventPtr)
+#define eventEndPtr (parser->m_eventEndPtr)
+#define positionPtr (parser->m_positionPtr)
+#define position (parser->m_position)
+#define openInternalEntities (parser->m_openInternalEntities)
+#define defaultExpandInternalEntities \
+        (parser->m_defaultExpandInternalEntities)
+#define tagLevel (parser->m_tagLevel)
+#define buffer (parser->m_buffer)
+#define bufferPtr (parser->m_bufferPtr)
+#define bufferEnd (parser->m_bufferEnd)
+#define parseEndByteIndex (parser->m_parseEndByteIndex)
+#define parseEndPtr (parser->m_parseEndPtr)
+#define bufferLim (parser->m_bufferLim)
+#define dataBuf (parser->m_dataBuf)
+#define dataBufEnd (parser->m_dataBufEnd)
+#define _dtd (parser->m_dtd)
+#define curBase (parser->m_curBase)
+#define declEntity (parser->m_declEntity)
+#define doctypeName (parser->m_doctypeName)
+#define doctypeSysid (parser->m_doctypeSysid)
+#define doctypePubid (parser->m_doctypePubid)
+#define declAttributeType (parser->m_declAttributeType)
+#define declNotationName (parser->m_declNotationName)
+#define declNotationPublicId (parser->m_declNotationPublicId)
+#define declElementType (parser->m_declElementType)
+#define declAttributeId (parser->m_declAttributeId)
+#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
+#define declAttributeIsId (parser->m_declAttributeIsId)
+#define freeTagList (parser->m_freeTagList)
+#define freeBindingList (parser->m_freeBindingList)
+#define inheritedBindings (parser->m_inheritedBindings)
+#define tagStack (parser->m_tagStack)
+#define atts (parser->m_atts)
+#define attsSize (parser->m_attsSize)
+#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
+#define idAttIndex (parser->m_idAttIndex)
+#define nsAtts (parser->m_nsAtts)
+#define nsAttsVersion (parser->m_nsAttsVersion)
+#define nsAttsPower (parser->m_nsAttsPower)
+#define tempPool (parser->m_tempPool)
+#define temp2Pool (parser->m_temp2Pool)
+#define groupConnector (parser->m_groupConnector)
+#define groupSize (parser->m_groupSize)
+#define namespaceSeparator (parser->m_namespaceSeparator)
+#define parentParser (parser->m_parentParser)
 #ifdef XML_DTD
-#define parentParser (((Parser *)parser)->m_parentParser)
-#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
+#define isParamEntity (parser->m_isParamEntity)
+#define useForeignDTD (parser->m_useForeignDTD)
+#define paramEntityParsing (parser->m_paramEntityParsing)
 #endif /* XML_DTD */
 
-#ifdef COMPILED_FROM_DSP
-BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p) {
-  return TRUE;
-}
-#endif /* def COMPILED_FROM_DSP */
-
-#ifdef _MSC_VER
-#ifdef _DEBUG
-Parser *asParser(XML_Parser parser)
-{
-  return parser;
-}
-#endif
-#endif
+#ifdef XML_DTD
+#define parsing \
+  (parentParser \
+    ? \
+    (isParamEntity \
+      ? \
+      (processor != externalParEntInitProcessor) \
+      : \
+      (processor != externalEntityInitProcessor)) \
+    : \
+    (processor != prologInitProcessor))
+#else
+#define parsing \
+  (parentParser \
+    ? \
+    (processor != externalEntityInitProcessor) \
+    : \
+    (processor != prologInitProcessor))
+#endif /* XML_DTD */
 
-XML_Parser XML_ParserCreate(const XML_Char *encodingName)
+XML_Parser XMLCALL
+XML_ParserCreate(const XML_Char *encodingName)
 {
   return XML_ParserCreate_MM(encodingName, NULL, NULL);
 }
 
-XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
+XML_Parser XMLCALL
+XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
 {
   XML_Char tmp[2];
   *tmp = nsSep;
   return XML_ParserCreate_MM(encodingName, NULL, tmp);
 }
 
-XML_Parser
+static const XML_Char implicitContext[] = {
+  'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
+  'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+  'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
+  'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+};
+
+XML_Parser XMLCALL
 XML_ParserCreate_MM(const XML_Char *encodingName,
-		    const XML_Memory_Handling_Suite *memsuite,
-		    const XML_Char *nameSep) {
-  
-  XML_Parser parser;
-  static
-  const XML_Char implicitContext[] = {
-    XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
-    XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
-    XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
-    XML_T('.'), XML_T('w'), XML_T('3'),
-    XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
-    XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
-    XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
-    XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
-    XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
-    XML_T('\0')
-  };
+                    const XML_Memory_Handling_Suite *memsuite,
+                    const XML_Char *nameSep)
+{
+  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
+  if (parser != NULL && ns) {
+    /* implicit context only set for root parser, since child
+       parsers (i.e. external entity parsers) will inherit it
+    */
+    if (!setContext(parser, implicitContext)) {
+      XML_ParserFree(parser);
+      return NULL;
+    }
+  }
+  return parser;
+}
 
+static XML_Parser
+parserCreate(const XML_Char *encodingName,
+             const XML_Memory_Handling_Suite *memsuite,
+             const XML_Char *nameSep,
+             DTD *dtd)
+{
+  XML_Parser parser;
 
   if (memsuite) {
     XML_Memory_Handling_Suite *mtemp;
-    parser = memsuite->malloc_fcn(sizeof(Parser));
-    mtemp = &(((Parser *) parser)->m_mem);
-    mtemp->malloc_fcn = memsuite->malloc_fcn;
-    mtemp->realloc_fcn = memsuite->realloc_fcn;
-    mtemp->free_fcn = memsuite->free_fcn;
+    parser = (XML_Parser)
+      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
+    if (parser != NULL) {
+      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
+      mtemp->malloc_fcn = memsuite->malloc_fcn;
+      mtemp->realloc_fcn = memsuite->realloc_fcn;
+      mtemp->free_fcn = memsuite->free_fcn;
+    }
   }
   else {
     XML_Memory_Handling_Suite *mtemp;
-    parser = malloc(sizeof(Parser));
-    mtemp = &(((Parser *) parser)->m_mem);
-    mtemp->malloc_fcn = malloc;
-    mtemp->realloc_fcn = realloc;
-    mtemp->free_fcn = free;
+    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
+    if (parser != NULL) {
+      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
+      mtemp->malloc_fcn = malloc;
+      mtemp->realloc_fcn = realloc;
+      mtemp->free_fcn = free;
+    }
   }
 
   if (!parser)
     return parser;
-  processor = prologInitProcessor;
-  XmlPrologStateInit(&prologState);
-  userData = 0;
-  handlerArg = 0;
-  startElementHandler = 0;
-  endElementHandler = 0;
-  characterDataHandler = 0;
-  processingInstructionHandler = 0;
-  commentHandler = 0;
-  startCdataSectionHandler = 0;
-  endCdataSectionHandler = 0;
-  defaultHandler = 0;
-  startDoctypeDeclHandler = 0;
-  endDoctypeDeclHandler = 0;
-  unparsedEntityDeclHandler = 0;
-  notationDeclHandler = 0;
-  startNamespaceDeclHandler = 0;
-  endNamespaceDeclHandler = 0;
-  notStandaloneHandler = 0;
-  externalEntityRefHandler = 0;
-  externalEntityRefHandlerArg = parser;
-  unknownEncodingHandler = 0;
-  elementDeclHandler = 0;
-  attlistDeclHandler = 0;
-  entityDeclHandler = 0;
-  xmlDeclHandler = 0;
-  buffer = 0;
-  bufferPtr = 0;
-  bufferEnd = 0;
-  parseEndByteIndex = 0;
-  parseEndPtr = 0;
-  bufferLim = 0;
-  declElementType = 0;
-  declAttributeId = 0;
-  declEntity = 0;
-  doctypeName = 0;
-  doctypeSysid = 0;
-  doctypePubid = 0;
-  declAttributeType = 0;
-  declNotationName = 0;
-  declNotationPublicId = 0;
-  memset(&position, 0, sizeof(POSITION));
-  errorCode = XML_ERROR_NONE;
-  eventPtr = 0;
-  eventEndPtr = 0;
-  positionPtr = 0;
-  openInternalEntities = 0;
-  tagLevel = 0;
-  tagStack = 0;
-  freeTagList = 0;
-  freeBindingList = 0;
-  inheritedBindings = 0;
+
+  buffer = NULL;
+  bufferLim = NULL;
+
   attsSize = INIT_ATTS_SIZE;
-  atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
-  nSpecifiedAtts = 0;
-  dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
+  if (atts == NULL) {
+    FREE(parser);
+    return NULL;
+  }
+  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+  if (dataBuf == NULL) {
+    FREE(atts);
+    FREE(parser);
+    return NULL;
+  }
+  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+
+  if (dtd)
+    _dtd = dtd;
+  else {
+    _dtd = dtdCreate(&parser->m_mem);
+    if (_dtd == NULL) {
+      FREE(dataBuf);
+      FREE(atts);
+      FREE(parser);
+      return NULL;
+    }
+  }
+
+  freeBindingList = NULL;
+  freeTagList = NULL;
+
   groupSize = 0;
-  groupConnector = 0;
-  hadExternalDoctype = 0;
-  unknownEncodingMem = 0;
-  unknownEncodingRelease = 0;
-  unknownEncodingData = 0;
-  unknownEncodingHandlerData = 0;
+  groupConnector = NULL;
+
+  unknownEncodingHandler = NULL;
+  unknownEncodingHandlerData = NULL;
+
   namespaceSeparator = '!';
-#ifdef XML_DTD
-  parentParser = 0;
-  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
-#endif
-  ns = 0;
-  ns_triplets = 0;
-  poolInit(&tempPool, &(((Parser *) parser)->m_mem));
-  poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
-  protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
-  curBase = 0;
-  if (!dtdInit(&dtd, parser) || !atts || !dataBuf
-      || (encodingName && !protocolEncodingName)) {
+  ns = XML_FALSE;
+  ns_triplets = XML_FALSE;
+
+  nsAtts = NULL;
+  nsAttsVersion = 0;
+  nsAttsPower = 0;
+
+  poolInit(&tempPool, &(parser->m_mem));
+  poolInit(&temp2Pool, &(parser->m_mem));
+  parserInit(parser, encodingName);
+
+  if (encodingName && !protocolEncodingName) {
     XML_ParserFree(parser);
-    return 0;
+    return NULL;
   }
-  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
 
   if (nameSep) {
-    XmlInitEncodingNS(&initEncoding, &encoding, 0);
-    ns = 1;
+    ns = XML_TRUE;
     internalEncoding = XmlGetInternalEncodingNS();
     namespaceSeparator = *nameSep;
-
-    if (! setContext(parser, implicitContext)) {
-      XML_ParserFree(parser);
-      return 0;
-    }
   }
   else {
-    XmlInitEncoding(&initEncoding, &encoding, 0);
     internalEncoding = XmlGetInternalEncoding();
   }
 
   return parser;
-}  /* End XML_ParserCreate_MM */
+}
+
+static void
+parserInit(XML_Parser parser, const XML_Char *encodingName)
+{
+  processor = prologInitProcessor;
+  XmlPrologStateInit(&prologState);
+  protocolEncodingName = (encodingName != NULL
+                          ? poolCopyString(&tempPool, encodingName)
+                          : NULL);
+  curBase = NULL;
+  XmlInitEncoding(&initEncoding, &encoding, 0);
+  userData = NULL;
+  handlerArg = NULL;
+  startElementHandler = NULL;
+  endElementHandler = NULL;
+  characterDataHandler = NULL;
+  processingInstructionHandler = NULL;
+  commentHandler = NULL;
+  startCdataSectionHandler = NULL;
+  endCdataSectionHandler = NULL;
+  defaultHandler = NULL;
+  startDoctypeDeclHandler = NULL;
+  endDoctypeDeclHandler = NULL;
+  unparsedEntityDeclHandler = NULL;
+  notationDeclHandler = NULL;
+  startNamespaceDeclHandler = NULL;
+  endNamespaceDeclHandler = NULL;
+  notStandaloneHandler = NULL;
+  externalEntityRefHandler = NULL;
+  externalEntityRefHandlerArg = parser;
+  skippedEntityHandler = NULL;
+  elementDeclHandler = NULL;
+  attlistDeclHandler = NULL;
+  entityDeclHandler = NULL;
+  xmlDeclHandler = NULL;
+  bufferPtr = buffer;
+  bufferEnd = buffer;
+  parseEndByteIndex = 0;
+  parseEndPtr = NULL;
+  declElementType = NULL;
+  declAttributeId = NULL;
+  declEntity = NULL;
+  doctypeName = NULL;
+  doctypeSysid = NULL;
+  doctypePubid = NULL;
+  declAttributeType = NULL;
+  declNotationName = NULL;
+  declNotationPublicId = NULL;
+  declAttributeIsCdata = XML_FALSE;
+  declAttributeIsId = XML_FALSE;
+  memset(&position, 0, sizeof(POSITION));
+  errorCode = XML_ERROR_NONE;
+  eventPtr = NULL;
+  eventEndPtr = NULL;
+  positionPtr = NULL;
+  openInternalEntities = 0;
+  defaultExpandInternalEntities = XML_TRUE;
+  tagLevel = 0;
+  tagStack = NULL;
+  inheritedBindings = NULL;
+  nSpecifiedAtts = 0;
+  unknownEncodingMem = NULL;
+  unknownEncodingRelease = NULL;
+  unknownEncodingData = NULL;
+  parentParser = NULL;
+#ifdef XML_DTD
+  isParamEntity = XML_FALSE;
+  useForeignDTD = XML_FALSE;
+  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
 
-int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+/* moves list of bindings to freeBindingList */
+static void FASTCALL
+moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
 {
-  if (!encodingName)
-    protocolEncodingName = 0;
+  while (bindings) {
+    BINDING *b = bindings;
+    bindings = bindings->nextTagBinding;
+    b->nextTagBinding = freeBindingList;
+    freeBindingList = b;
+  }
+}
+
+XML_Bool XMLCALL
+XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
+{
+  TAG *tStk;
+  if (parentParser)
+    return XML_FALSE;
+  /* move tagStack to freeTagList */
+  tStk = tagStack;
+  while (tStk) {
+    TAG *tag = tStk;
+    tStk = tStk->parent;
+    tag->parent = freeTagList;
+    moveToFreeBindingList(parser, tag->bindings);
+    tag->bindings = NULL;
+    freeTagList = tag;
+  }
+  moveToFreeBindingList(parser, inheritedBindings);
+  FREE(unknownEncodingMem);
+  if (unknownEncodingRelease)
+    unknownEncodingRelease(unknownEncodingData);
+  poolClear(&tempPool);
+  poolClear(&temp2Pool);
+  parserInit(parser, encodingName);
+  dtdReset(_dtd, &parser->m_mem);
+  return setContext(parser, implicitContext);
+}
+
+enum XML_Status XMLCALL
+XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  /* Block after XML_Parse()/XML_ParseBuffer() has been called.
+     XXX There's no way for the caller to determine which of the
+     XXX possible error cases caused the XML_STATUS_ERROR return.
+  */
+  if (parsing)
+    return XML_STATUS_ERROR;
+  if (encodingName == NULL)
+    protocolEncodingName = NULL;
   else {
     protocolEncodingName = poolCopyString(&tempPool, encodingName);
     if (!protocolEncodingName)
-      return 0;
+      return XML_STATUS_ERROR;
   }
-  return 1;
+  return XML_STATUS_OK;
 }
 
-XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
-					  const XML_Char *context,
-					  const XML_Char *encodingName)
+XML_Parser XMLCALL
+XML_ExternalEntityParserCreate(XML_Parser oldParser,
+                               const XML_Char *context,
+                               const XML_Char *encodingName)
 {
   XML_Parser parser = oldParser;
-  DTD *oldDtd = &dtd;
+  DTD *newDtd = NULL;
+  DTD *oldDtd = _dtd;
   XML_StartElementHandler oldStartElementHandler = startElementHandler;
   XML_EndElementHandler oldEndElementHandler = endElementHandler;
   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
-  XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
+  XML_ProcessingInstructionHandler oldProcessingInstructionHandler
+      = processingInstructionHandler;
   XML_CommentHandler oldCommentHandler = commentHandler;
-  XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
-  XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
+  XML_StartCdataSectionHandler oldStartCdataSectionHandler
+      = startCdataSectionHandler;
+  XML_EndCdataSectionHandler oldEndCdataSectionHandler
+      = endCdataSectionHandler;
   XML_DefaultHandler oldDefaultHandler = defaultHandler;
-  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
+      = unparsedEntityDeclHandler;
   XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
-  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
-  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
+      = startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
+      = endNamespaceDeclHandler;
   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
-  XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
-  XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
+  XML_ExternalEntityRefHandler oldExternalEntityRefHandler
+      = externalEntityRefHandler;
+  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
+  XML_UnknownEncodingHandler oldUnknownEncodingHandler
+      = unknownEncodingHandler;
   XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
   XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
   XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
@@ -726,27 +966,35 @@ XML_Parser XML_ExternalEntityParserCreat
 
   void *oldUserData = userData;
   void *oldHandlerArg = handlerArg;
-  int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
-  void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
 #ifdef XML_DTD
-  int oldParamEntityParsing = paramEntityParsing;
+  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
+  int oldInEntityValue = prologState.inEntityValue;
 #endif
-  int oldns_triplets = ns_triplets;
+  XML_Bool oldns_triplets = ns_triplets;
+
+#ifdef XML_DTD
+  if (!context)
+    newDtd = oldDtd;
+#endif /* XML_DTD */
 
+  /* Note that the magical uses of the pre-processor to make field
+     access look more like C++ require that `parser' be overwritten
+     here.  This makes this function more painful to follow than it
+     would be otherwise.
+  */
   if (ns) {
     XML_Char tmp[2];
-
     *tmp = namespaceSeparator;
-    parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
-				 tmp);
+    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
   }
   else {
-    parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
-				 NULL);
+    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
   }
 
   if (!parser)
-    return 0;
+    return NULL;
 
   startElementHandler = oldStartElementHandler;
   endElementHandler = oldEndElementHandler;
@@ -762,6 +1010,7 @@ XML_Parser XML_ExternalEntityParserCreat
   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
   notStandaloneHandler = oldNotStandaloneHandler;
   externalEntityRefHandler = oldExternalEntityRefHandler;
+  skippedEntityHandler = oldSkippedEntityHandler;
   unknownEncodingHandler = oldUnknownEncodingHandler;
   elementDeclHandler = oldElementDeclHandler;
   attlistDeclHandler = oldAttlistDeclHandler;
@@ -777,30 +1026,38 @@ XML_Parser XML_ExternalEntityParserCreat
     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
   ns_triplets = oldns_triplets;
+  parentParser = oldParser;
 #ifdef XML_DTD
   paramEntityParsing = oldParamEntityParsing;
+  prologState.inEntityValue = oldInEntityValue;
   if (context) {
 #endif /* XML_DTD */
-    if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
+    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
+      || !setContext(parser, context)) {
       XML_ParserFree(parser);
-      return 0;
+      return NULL;
     }
     processor = externalEntityInitProcessor;
 #ifdef XML_DTD
   }
   else {
-    dtdSwap(&dtd, oldDtd);
-    parentParser = oldParser;
+    /* The DTD instance referenced by _dtd is shared between the document's
+       root parser and external PE parsers, therefore one does not need to
+       call setContext. In addition, one also *must* not call setContext,
+       because this would overwrite existing prefix->binding pointers in
+       _dtd with ones that get destroyed with the external PE parser.
+       This would leave those prefixes with dangling pointers.
+    */
+    isParamEntity = XML_TRUE;
     XmlPrologStateInitExternalEntity(&prologState);
-    dtd.complete = 1;
-    hadExternalDoctype = 1;
+    processor = externalParEntInitProcessor;
   }
 #endif /* XML_DTD */
   return parser;
 }
 
-static
-void destroyBindings(BINDING *bindings, XML_Parser parser)
+static void FASTCALL
+destroyBindings(BINDING *bindings, XML_Parser parser)
 {
   for (;;) {
     BINDING *b = bindings;
@@ -812,15 +1069,16 @@ void destroyBindings(BINDING *bindings, 
   }
 }
 
-void XML_ParserFree(XML_Parser parser)
+void XMLCALL
+XML_ParserFree(XML_Parser parser)
 {
   for (;;) {
     TAG *p;
-    if (tagStack == 0) {
-      if (freeTagList == 0)
-	break;
+    if (tagStack == NULL) {
+      if (freeTagList == NULL)
+        break;
       tagStack = freeTagList;
-      freeTagList = 0;
+      freeTagList = NULL;
     }
     p = tagStack;
     tagStack = tagStack->parent;
@@ -833,37 +1091,56 @@ void XML_ParserFree(XML_Parser parser)
   poolDestroy(&tempPool);
   poolDestroy(&temp2Pool);
 #ifdef XML_DTD
-  if (parentParser) {
-    if (hadExternalDoctype)
-      dtd.complete = 0;
-    dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
-  }
+  /* external parameter entity parsers share the DTD structure
+     parser->m_dtd with the root parser, so we must not destroy it
+  */
+  if (!isParamEntity && _dtd)
+#else
+  if (_dtd)
 #endif /* XML_DTD */
-  dtdDestroy(&dtd, parser);
+    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
   FREE((void *)atts);
-  if (groupConnector)
-    FREE(groupConnector);
-  if (buffer)
-    FREE(buffer);
+  FREE(groupConnector);
+  FREE(buffer);
   FREE(dataBuf);
-  if (unknownEncodingMem)
-    FREE(unknownEncodingMem);
+  FREE(nsAtts);
+  FREE(unknownEncodingMem);
   if (unknownEncodingRelease)
     unknownEncodingRelease(unknownEncodingData);
   FREE(parser);
 }
 
-void XML_UseParserAsHandlerArg(XML_Parser parser)
+void XMLCALL
+XML_UseParserAsHandlerArg(XML_Parser parser)
 {
   handlerArg = parser;
 }
 
-void
-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
-  ns_triplets = do_nst;
+enum XML_Error XMLCALL
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
+{
+#ifdef XML_DTD
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */
+  if (parsing)
+    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
+  useForeignDTD = useDTD;
+  return XML_ERROR_NONE;
+#else
+  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
+#endif
+}
+
+void XMLCALL
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
+{
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */
+  if (parsing)
+    return;
+  ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
 }
 
-void XML_SetUserData(XML_Parser parser, void *p)
+void XMLCALL
+XML_SetUserData(XML_Parser parser, void *p)
 {
   if (handlerArg == userData)
     handlerArg = userData = p;
@@ -871,225 +1148,267 @@ void XML_SetUserData(XML_Parser parser, 
     userData = p;
 }
 
-int XML_SetBase(XML_Parser parser, const XML_Char *p)
+enum XML_Status XMLCALL
+XML_SetBase(XML_Parser parser, const XML_Char *p)
 {
   if (p) {
-    p = poolCopyString(&dtd.pool, p);
+    p = poolCopyString(&_dtd->pool, p);
     if (!p)
-      return 0;
+      return XML_STATUS_ERROR;
     curBase = p;
   }
   else
-    curBase = 0;
-  return 1;
+    curBase = NULL;
+  return XML_STATUS_OK;
 }
 
-const XML_Char *XML_GetBase(XML_Parser parser)
+const XML_Char * XMLCALL
+XML_GetBase(XML_Parser parser)
 {
   return curBase;
 }
 
-int XML_GetSpecifiedAttributeCount(XML_Parser parser)
+int XMLCALL
+XML_GetSpecifiedAttributeCount(XML_Parser parser)
 {
   return nSpecifiedAtts;
 }
 
-int XML_GetIdAttributeIndex(XML_Parser parser)
+int XMLCALL
+XML_GetIdAttributeIndex(XML_Parser parser)
 {
   return idAttIndex;
 }
 
-void XML_SetElementHandler(XML_Parser parser,
-			   XML_StartElementHandler start,
-			   XML_EndElementHandler end)
+void XMLCALL
+XML_SetElementHandler(XML_Parser parser,
+                      XML_StartElementHandler start,
+                      XML_EndElementHandler end)
 {
   startElementHandler = start;
   endElementHandler = end;
 }
 
-void XML_SetStartElementHandler(XML_Parser parser,
-				XML_StartElementHandler start) {
+void XMLCALL
+XML_SetStartElementHandler(XML_Parser parser,
+                           XML_StartElementHandler start) {
   startElementHandler = start;
 }
 
-void XML_SetEndElementHandler(XML_Parser parser,
-			      XML_EndElementHandler end) {
+void XMLCALL
+XML_SetEndElementHandler(XML_Parser parser,
+                         XML_EndElementHandler end) {
   endElementHandler = end;
 }
 
-void XML_SetCharacterDataHandler(XML_Parser parser,
-				 XML_CharacterDataHandler handler)
+void XMLCALL
+XML_SetCharacterDataHandler(XML_Parser parser,
+                            XML_CharacterDataHandler handler)
 {
   characterDataHandler = handler;
 }
 
-void XML_SetProcessingInstructionHandler(XML_Parser parser,
-					 XML_ProcessingInstructionHandler handler)
+void XMLCALL
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+                                    XML_ProcessingInstructionHandler handler)
 {
   processingInstructionHandler = handler;
 }
 
-void XML_SetCommentHandler(XML_Parser parser,
-			   XML_CommentHandler handler)
+void XMLCALL
+XML_SetCommentHandler(XML_Parser parser,
+                      XML_CommentHandler handler)
 {
   commentHandler = handler;
 }
 
-void XML_SetCdataSectionHandler(XML_Parser parser,
-				XML_StartCdataSectionHandler start,
-			        XML_EndCdataSectionHandler end)
+void XMLCALL
+XML_SetCdataSectionHandler(XML_Parser parser,
+                           XML_StartCdataSectionHandler start,
+                           XML_EndCdataSectionHandler end)
 {
   startCdataSectionHandler = start;
   endCdataSectionHandler = end;
 }
 
-void XML_SetStartCdataSectionHandler(XML_Parser parser,
-                                     XML_StartCdataSectionHandler start) {
+void XMLCALL
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+                                XML_StartCdataSectionHandler start) {
   startCdataSectionHandler = start;
 }
 
-void XML_SetEndCdataSectionHandler(XML_Parser parser,
-                                   XML_EndCdataSectionHandler end) {
+void XMLCALL
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+                              XML_EndCdataSectionHandler end) {
   endCdataSectionHandler = end;
 }
 
-void XML_SetDefaultHandler(XML_Parser parser,
-			   XML_DefaultHandler handler)
+void XMLCALL
+XML_SetDefaultHandler(XML_Parser parser,
+                      XML_DefaultHandler handler)
 {
   defaultHandler = handler;
-  defaultExpandInternalEntities = 0;
+  defaultExpandInternalEntities = XML_FALSE;
 }
 
-void XML_SetDefaultHandlerExpand(XML_Parser parser,
-				 XML_DefaultHandler handler)
+void XMLCALL
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+                            XML_DefaultHandler handler)
 {
   defaultHandler = handler;
-  defaultExpandInternalEntities = 1;
+  defaultExpandInternalEntities = XML_TRUE;
 }
 
-void XML_SetDoctypeDeclHandler(XML_Parser parser,
-			       XML_StartDoctypeDeclHandler start,
-			       XML_EndDoctypeDeclHandler end)
+void XMLCALL
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+                          XML_StartDoctypeDeclHandler start,
+                          XML_EndDoctypeDeclHandler end)
 {
   startDoctypeDeclHandler = start;
   endDoctypeDeclHandler = end;
 }
 
-void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
-				    XML_StartDoctypeDeclHandler start) {
+void XMLCALL
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+                               XML_StartDoctypeDeclHandler start) {
   startDoctypeDeclHandler = start;
 }
 
-void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
-				  XML_EndDoctypeDeclHandler end) {
+void XMLCALL
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+                             XML_EndDoctypeDeclHandler end) {
   endDoctypeDeclHandler = end;
 }
 
-void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
-				      XML_UnparsedEntityDeclHandler handler)
+void XMLCALL
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+                                 XML_UnparsedEntityDeclHandler handler)
 {
   unparsedEntityDeclHandler = handler;
 }
 
-void XML_SetNotationDeclHandler(XML_Parser parser,
-				XML_NotationDeclHandler handler)
+void XMLCALL
+XML_SetNotationDeclHandler(XML_Parser parser,
+                           XML_NotationDeclHandler handler)
 {
   notationDeclHandler = handler;
 }
 
-void XML_SetNamespaceDeclHandler(XML_Parser parser,
-				 XML_StartNamespaceDeclHandler start,
-				 XML_EndNamespaceDeclHandler end)
+void XMLCALL
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+                            XML_StartNamespaceDeclHandler start,
+                            XML_EndNamespaceDeclHandler end)
 {
   startNamespaceDeclHandler = start;
   endNamespaceDeclHandler = end;
 }
 
-void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
-				      XML_StartNamespaceDeclHandler start) {
+void XMLCALL
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+                                 XML_StartNamespaceDeclHandler start) {
   startNamespaceDeclHandler = start;
 }
 
-void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
-				    XML_EndNamespaceDeclHandler end) {
+void XMLCALL
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+                               XML_EndNamespaceDeclHandler end) {
   endNamespaceDeclHandler = end;
 }
 
-
-void XML_SetNotStandaloneHandler(XML_Parser parser,
-				 XML_NotStandaloneHandler handler)
+void XMLCALL
+XML_SetNotStandaloneHandler(XML_Parser parser,
+                            XML_NotStandaloneHandler handler)
 {
   notStandaloneHandler = handler;
 }
 
-void XML_SetExternalEntityRefHandler(XML_Parser parser,
-				     XML_ExternalEntityRefHandler handler)
+void XMLCALL
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+                                XML_ExternalEntityRefHandler handler)
 {
   externalEntityRefHandler = handler;
 }
 
-void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
+void XMLCALL
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
 {
   if (arg)
-    externalEntityRefHandlerArg = arg;
+    externalEntityRefHandlerArg = (XML_Parser)arg;
   else
     externalEntityRefHandlerArg = parser;
 }
 
-void XML_SetUnknownEncodingHandler(XML_Parser parser,
-				   XML_UnknownEncodingHandler handler,
-				   void *data)
+void XMLCALL
+XML_SetSkippedEntityHandler(XML_Parser parser,
+                            XML_SkippedEntityHandler handler)
+{
+  skippedEntityHandler = handler;
+}
+
+void XMLCALL
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+                              XML_UnknownEncodingHandler handler,
+                              void *data)
 {
   unknownEncodingHandler = handler;
   unknownEncodingHandlerData = data;
 }
 
-void XML_SetElementDeclHandler(XML_Parser parser,
-			       XML_ElementDeclHandler eldecl)
+void XMLCALL
+XML_SetElementDeclHandler(XML_Parser parser,
+                          XML_ElementDeclHandler eldecl)
 {
   elementDeclHandler = eldecl;
 }
 
-void XML_SetAttlistDeclHandler(XML_Parser parser,
-			       XML_AttlistDeclHandler attdecl)
+void XMLCALL
+XML_SetAttlistDeclHandler(XML_Parser parser,
+                          XML_AttlistDeclHandler attdecl)
 {
   attlistDeclHandler = attdecl;
 }
 
-void XML_SetEntityDeclHandler(XML_Parser parser,
-			      XML_EntityDeclHandler handler)
+void XMLCALL
+XML_SetEntityDeclHandler(XML_Parser parser,
+                         XML_EntityDeclHandler handler)
 {
   entityDeclHandler = handler;
 }
 
-void XML_SetXmlDeclHandler(XML_Parser parser,
-			   XML_XmlDeclHandler handler) {
+void XMLCALL
+XML_SetXmlDeclHandler(XML_Parser parser,
+                      XML_XmlDeclHandler handler) {
   xmlDeclHandler = handler;
 }
 
-int XML_SetParamEntityParsing(XML_Parser parser,
-			      enum XML_ParamEntityParsing parsing)
+int XMLCALL
+XML_SetParamEntityParsing(XML_Parser parser,
+                          enum XML_ParamEntityParsing peParsing)
 {
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */
+  if (parsing)
+    return 0;
 #ifdef XML_DTD
-  paramEntityParsing = parsing;
+  paramEntityParsing = peParsing;
   return 1;
 #else
-  return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
+  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
 #endif
 }
 
-int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+enum XML_Status XMLCALL
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
 {
   if (len == 0) {
     if (!isFinal)
-      return 1;
+      return XML_STATUS_OK;
     positionPtr = bufferPtr;
     errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
     if (errorCode == XML_ERROR_NONE)
-      return 1;
+      return XML_STATUS_OK;
     eventEndPtr = eventPtr;
     processor = errorProcessor;
-    return 0;
+    return XML_STATUS_ERROR;
   }
 #ifndef XML_CONTEXT_BYTES
   else if (bufferPtr == bufferEnd) {
@@ -1100,66 +1419,83 @@ int XML_Parse(XML_Parser parser, const c
     if (isFinal) {
       errorCode = processor(parser, s, parseEndPtr = s + len, 0);
       if (errorCode == XML_ERROR_NONE)
-	return 1;
+        return XML_STATUS_OK;
       eventEndPtr = eventPtr;
       processor = errorProcessor;
-      return 0;
+      return XML_STATUS_ERROR;
     }
     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
     if (errorCode != XML_ERROR_NONE) {
       eventEndPtr = eventPtr;
       processor = errorProcessor;
-      return 0;
+      return XML_STATUS_ERROR;
     }
     XmlUpdatePosition(encoding, positionPtr, end, &position);
+    positionPtr = end;
     nLeftOver = s + len - end;
     if (nLeftOver) {
-      if (buffer == 0 || nLeftOver > bufferLim - buffer) {
-	/* FIXME avoid integer overflow */
-	buffer = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
-	/* FIXME storage leak if realloc fails */
-	if (!buffer) {
-	  errorCode = XML_ERROR_NO_MEMORY;
-	  eventPtr = eventEndPtr = 0;
-	  processor = errorProcessor;
-	  return 0;
-	}
-	bufferLim = buffer + len * 2;
+      if (buffer == NULL || nLeftOver > bufferLim - buffer) {
+        /* FIXME avoid integer overflow */
+        char *temp;
+        temp = (buffer == NULL
+                ? (char *)MALLOC(len * 2)
+                : (char *)REALLOC(buffer, len * 2));
+        if (temp == NULL) {
+          errorCode = XML_ERROR_NO_MEMORY;
+          return XML_STATUS_ERROR;
+        }
+        buffer = temp;
+        if (!buffer) {
+          errorCode = XML_ERROR_NO_MEMORY;
+          eventPtr = eventEndPtr = NULL;
+          processor = errorProcessor;
+          return XML_STATUS_ERROR;
+        }
+        bufferLim = buffer + len * 2;
       }
       memcpy(buffer, end, nLeftOver);
       bufferPtr = buffer;
       bufferEnd = buffer + nLeftOver;
     }
-    return 1;
+    return XML_STATUS_OK;
   }
 #endif  /* not defined XML_CONTEXT_BYTES */
   else {
-    memcpy(XML_GetBuffer(parser, len), s, len);
-    return XML_ParseBuffer(parser, len, isFinal);
+    void *buff = XML_GetBuffer(parser, len);
+    if (buff == NULL)
+      return XML_STATUS_ERROR;
+    else {
+      memcpy(buff, s, len);
+      return XML_ParseBuffer(parser, len, isFinal);
+    }
   }
 }
 
-int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+enum XML_Status XMLCALL
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
 {
   const char *start = bufferPtr;
   positionPtr = start;
   bufferEnd += len;
   parseEndByteIndex += len;
   errorCode = processor(parser, start, parseEndPtr = bufferEnd,
-			isFinal ? (const char **)0 : &bufferPtr);
+                        isFinal ? (const char **)NULL : &bufferPtr);
   if (errorCode == XML_ERROR_NONE) {
-    if (!isFinal)
+    if (!isFinal) {
       XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
-    return 1;
+      positionPtr = bufferPtr;
+    }
+    return XML_STATUS_OK;
   }
   else {
     eventEndPtr = eventPtr;
     processor = errorProcessor;
-    return 0;
+    return XML_STATUS_ERROR;
   }
 }
 
-void *XML_GetBuffer(XML_Parser parser, int len)
+void * XMLCALL
+XML_GetBuffer(XML_Parser parser, int len)
 {
   if (len > bufferLim - bufferEnd) {
     /* FIXME avoid integer overflow */
@@ -1174,10 +1510,10 @@ void *XML_GetBuffer(XML_Parser parser, i
     if (neededSize  <= bufferLim - buffer) {
 #ifdef XML_CONTEXT_BYTES
       if (keep < bufferPtr - buffer) {
-	int offset = (bufferPtr - buffer) - keep;
-	memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
-	bufferEnd -= offset;
-	bufferPtr -= offset;
+        int offset = (bufferPtr - buffer) - keep;
+        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
+        bufferEnd -= offset;
+        bufferPtr -= offset;
       }
 #else
       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
@@ -1189,35 +1525,35 @@ void *XML_GetBuffer(XML_Parser parser, i
       char *newBuf;
       int bufferSize = bufferLim - bufferPtr;
       if (bufferSize == 0)
-	bufferSize = INIT_BUFFER_SIZE;
+        bufferSize = INIT_BUFFER_SIZE;
       do {
-	bufferSize *= 2;
+        bufferSize *= 2;
       } while (bufferSize < neededSize);
-      newBuf = MALLOC(bufferSize);
+      newBuf = (char *)MALLOC(bufferSize);
       if (newBuf == 0) {
-	errorCode = XML_ERROR_NO_MEMORY;
-	return 0;
+        errorCode = XML_ERROR_NO_MEMORY;
+        return NULL;
       }
       bufferLim = newBuf + bufferSize;
 #ifdef XML_CONTEXT_BYTES
       if (bufferPtr) {
-	int keep = bufferPtr - buffer;
-	if (keep > XML_CONTEXT_BYTES)
-	  keep = XML_CONTEXT_BYTES;
-	memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
-	FREE(buffer);
-	buffer = newBuf;
-	bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
-	bufferPtr = buffer + keep;
+        int keep = bufferPtr - buffer;
+        if (keep > XML_CONTEXT_BYTES)
+          keep = XML_CONTEXT_BYTES;
+        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
+        FREE(buffer);
+        buffer = newBuf;
+        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
+        bufferPtr = buffer + keep;
       }
       else {
-	bufferEnd = newBuf + (bufferEnd - bufferPtr);
-	bufferPtr = buffer = newBuf;
+        bufferEnd = newBuf + (bufferEnd - bufferPtr);
+        bufferPtr = buffer = newBuf;
       }
 #else
       if (bufferPtr) {
-	memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
-	FREE(buffer);
+        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+        FREE(buffer);
       }
       bufferEnd = newBuf + (bufferEnd - bufferPtr);
       bufferPtr = buffer = newBuf;
@@ -1227,26 +1563,30 @@ void *XML_GetBuffer(XML_Parser parser, i
   return bufferEnd;
 }
 
-enum XML_Error XML_GetErrorCode(XML_Parser parser)
+enum XML_Error XMLCALL
+XML_GetErrorCode(XML_Parser parser)
 {
   return errorCode;
 }
 
-long XML_GetCurrentByteIndex(XML_Parser parser)
+long XMLCALL
+XML_GetCurrentByteIndex(XML_Parser parser)
 {
   if (eventPtr)
     return parseEndByteIndex - (parseEndPtr - eventPtr);
   return -1;
 }
 
-int XML_GetCurrentByteCount(XML_Parser parser)
+int XMLCALL
+XML_GetCurrentByteCount(XML_Parser parser)
 {
   if (eventEndPtr && eventPtr)
     return eventEndPtr - eventPtr;
   return 0;
 }
 
-const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
+const char * XMLCALL
+XML_GetInputContext(XML_Parser parser, int *offset, int *size)
 {
 #ifdef XML_CONTEXT_BYTES
   if (eventPtr && buffer) {
@@ -1258,7 +1598,8 @@ const char * XML_GetInputContext(XML_Par
   return (char *) 0;
 }
 
-int XML_GetCurrentLineNumber(XML_Parser parser)
+int XMLCALL
+XML_GetCurrentLineNumber(XML_Parser parser)
 {
   if (eventPtr) {
     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
@@ -1267,7 +1608,8 @@ int XML_GetCurrentLineNumber(XML_Parser 
   return position.lineNumber + 1;
 }
 
-int XML_GetCurrentColumnNumber(XML_Parser parser)
+int XMLCALL
+XML_GetCurrentColumnNumber(XML_Parser parser)
 {
   if (eventPtr) {
     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
@@ -1276,59 +1618,105 @@ int XML_GetCurrentColumnNumber(XML_Parse
   return position.columnNumber;
 }
 
-void XML_DefaultCurrent(XML_Parser parser)
+void XMLCALL
+XML_FreeContentModel(XML_Parser parser, XML_Content *model)
+{
+  FREE(model);
+}
+
+void * XMLCALL
+XML_MemMalloc(XML_Parser parser, size_t size)
+{
+  return MALLOC(size);
+}
+
+void * XMLCALL
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
+{
+  return REALLOC(ptr, size);
+}
+
+void XMLCALL
+XML_MemFree(XML_Parser parser, void *ptr)
+{
+  FREE(ptr);
+}
+
+void XMLCALL
+XML_DefaultCurrent(XML_Parser parser)
 {
   if (defaultHandler) {
     if (openInternalEntities)
       reportDefault(parser,
-	            internalEncoding,
-		    openInternalEntities->internalEventPtr,
-		    openInternalEntities->internalEventEndPtr);
+                    internalEncoding,
+                    openInternalEntities->internalEventPtr,
+                    openInternalEntities->internalEventEndPtr);
     else
       reportDefault(parser, encoding, eventPtr, eventEndPtr);
   }
 }
 
-const XML_LChar *XML_ErrorString(int code)
+const XML_LChar * XMLCALL
+XML_ErrorString(enum XML_Error code)
 {
   static const XML_LChar *message[] = {
     0,
-    XML_T("out of memory"),
-    XML_T("syntax error"),
-    XML_T("no element found"),
-    XML_T("not well-formed (invalid token)"),
-    XML_T("unclosed token"),
-    XML_T("unclosed token"),
-    XML_T("mismatched tag"),
-    XML_T("duplicate attribute"),
-    XML_T("junk after document element"),
-    XML_T("illegal parameter entity reference"),
-    XML_T("undefined entity"),
-    XML_T("recursive entity reference"),
-    XML_T("asynchronous entity"),
-    XML_T("reference to invalid character number"),
-    XML_T("reference to binary entity"),
-    XML_T("reference to external entity in attribute"),
-    XML_T("xml processing instruction not at start of external entity"),
-    XML_T("unknown encoding"),
-    XML_T("encoding specified in XML declaration is incorrect"),
-    XML_T("unclosed CDATA section"),
-    XML_T("error in processing external entity reference"),
-    XML_T("document is not standalone"),
-    XML_T("unexpected parser state - please send a bug report")
+    XML_L("out of memory"),
+    XML_L("syntax error"),
+    XML_L("no element found"),
+    XML_L("not well-formed (invalid token)"),
+    XML_L("unclosed token"),
+    XML_L("partial character"),
+    XML_L("mismatched tag"),
+    XML_L("duplicate attribute"),
+    XML_L("junk after document element"),
+    XML_L("illegal parameter entity reference"),
+    XML_L("undefined entity"),
+    XML_L("recursive entity reference"),
+    XML_L("asynchronous entity"),
+    XML_L("reference to invalid character number"),
+    XML_L("reference to binary entity"),
+    XML_L("reference to external entity in attribute"),
+    XML_L("xml declaration not at start of external entity"),
+    XML_L("unknown encoding"),
+    XML_L("encoding specified in XML declaration is incorrect"),
+    XML_L("unclosed CDATA section"),
+    XML_L("error in processing external entity reference"),
+    XML_L("document is not standalone"),
+    XML_L("unexpected parser state - please send a bug report"),
+    XML_L("entity declared in parameter entity"),
+    XML_L("requested feature requires XML_DTD support in Expat"),
+    XML_L("cannot change setting once parsing has begun"),
+    XML_L("unbound prefix")
   };
   if (code > 0 && code < sizeof(message)/sizeof(message[0]))
     return message[code];
-  return 0;
+  return NULL;
 }
 
-const XML_LChar *
+const XML_LChar * XMLCALL
 XML_ExpatVersion(void) {
-  return VERSION;
+
+  /* V1 is used to string-ize the version number. However, it would
+     string-ize the actual version macro *names* unless we get them
+     substituted before being passed to V1. CPP is defined to expand
+     a macro, then rescan for more expansions. Thus, we use V2 to expand
+     the version macros, then CPP will expand the resulting V1() macro
+     with the correct numerals. */
+  /* ### I'm assuming cpp is portable in this respect... */
+
+#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
+#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
+
+  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
+
+#undef V1
+#undef V2
 }
 
-XML_Expat_Version
-XML_ExpatVersionInfo(void) {
+XML_Expat_Version XMLCALL
+XML_ExpatVersionInfo(void)
+{
   XML_Expat_Version version;
 
   version.major = XML_MAJOR_VERSION;
@@ -1338,20 +1726,106 @@ XML_ExpatVersionInfo(void) {
   return version;
 }
 
-static
-enum XML_Error contentProcessor(XML_Parser parser,
-				const char *start,
-				const char *end,
-				const char **endPtr)
-{
-  return doContent(parser, 0, encoding, start, end, endPtr);
+const XML_Feature * XMLCALL
+XML_GetFeatureList(void)
+{
+  static XML_Feature features[] = {
+    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"), 0},
+    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 0},
+#ifdef XML_UNICODE
+    {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
+#endif
+#ifdef XML_UNICODE_WCHAR_T
+    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
+#endif
+#ifdef XML_DTD
+    {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
+#endif
+#ifdef XML_CONTEXT_BYTES
+    {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
+     XML_CONTEXT_BYTES},
+#endif
+#ifdef XML_MIN_SIZE
+    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
+#endif
+    {XML_FEATURE_END,              NULL, 0}
+  };
+
+  features[0].value = sizeof(XML_Char);
+  features[1].value = sizeof(XML_LChar);
+  return features;
+}
+
+/* Initially tag->rawName always points into the parse buffer;
+   for those TAG instances opened while the current parse buffer was
+   processed, and not yet closed, we need to store tag->rawName in a more
+   permanent location, since the parse buffer is about to be discarded.
+*/
+static XML_Bool
+storeRawNames(XML_Parser parser)
+{
+  TAG *tag = tagStack;
+  while (tag) {
+    int bufSize;
+    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
+    char *rawNameBuf = tag->buf + nameLen;
+    /* Stop if already stored.  Since tagStack is a stack, we can stop
+       at the first entry that has already been copied; everything
+       below it in the stack is already been accounted for in a
+       previous call to this function.
+    */
+    if (tag->rawName == rawNameBuf)
+      break;
+    /* For re-use purposes we need to ensure that the
+       size of tag->buf is a multiple of sizeof(XML_Char).
+    */
+    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
+    if (bufSize > tag->bufEnd - tag->buf) {
+      char *temp = (char *)REALLOC(tag->buf, bufSize);
+      if (temp == NULL)
+        return XML_FALSE;
+      /* if tag->name.str points to tag->buf (only when namespace
+         processing is off) then we have to update it
+      */
+      if (tag->name.str == (XML_Char *)tag->buf)
+        tag->name.str = (XML_Char *)temp;
+      /* if tag->name.localPart is set (when namespace processing is on)
+         then update it as well, since it will always point into tag->buf
+      */
+      if (tag->name.localPart)
+        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
+                                                  (XML_Char *)tag->buf);
+      tag->buf = temp;
+      tag->bufEnd = temp + bufSize;
+      rawNameBuf = temp + nameLen;
+    }
+    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
+    tag->rawName = rawNameBuf;
+    tag = tag->parent;
+  }
+  return XML_TRUE;
+}
+
+static enum XML_Error PTRCALL
+contentProcessor(XML_Parser parser,
+                 const char *start,
+                 const char *end,
+                 const char **endPtr)
+{
+  enum XML_Error result =
+    doContent(parser, 0, encoding, start, end, endPtr);
+  if (result != XML_ERROR_NONE)
+    return result;
+  if (!storeRawNames(parser))
+    return XML_ERROR_NO_MEMORY;
+  return result;
 }
 
-static
-enum XML_Error externalEntityInitProcessor(XML_Parser parser,
-					   const char *start,
-					   const char *end,
-					   const char **endPtr)
+static enum XML_Error PTRCALL
+externalEntityInitProcessor(XML_Parser parser,
+                            const char *start,
+                            const char *end,
+                            const char **endPtr)
 {
   enum XML_Error result = initializeEncoding(parser);
   if (result != XML_ERROR_NONE)
@@ -1360,16 +1834,25 @@ enum XML_Error externalEntityInitProcess
   return externalEntityInitProcessor2(parser, start, end, endPtr);
 }
 
-static
-enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
-					    const char *start,
-					    const char *end,
-					    const char **endPtr)
+static enum XML_Error PTRCALL
+externalEntityInitProcessor2(XML_Parser parser,
+                             const char *start,
+                             const char *end,
+                             const char **endPtr)
 {
-  const char *next;
+  const char *next = start; /* XmlContentTok doesn't always set the last arg */
   int tok = XmlContentTok(encoding, start, end, &next);
   switch (tok) {
   case XML_TOK_BOM:
+    /* If we are at the end of the buffer, this would cause the next stage,
+       i.e. externalEntityInitProcessor3, to pass control directly to
+       doContent (by detecting XML_TOK_NONE) without processing any xml text
+       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
+    */
+    if (next == end && endPtr) {
+      *endPtr = next;
+      return XML_ERROR_NONE;
+    }
     start = next;
     break;
   case XML_TOK_PARTIAL:
@@ -1391,20 +1874,20 @@ enum XML_Error externalEntityInitProcess
   return externalEntityInitProcessor3(parser, start, end, endPtr);
 }
 
-static
-enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
-					    const char *start,
-					    const char *end,
-					    const char **endPtr)
+static enum XML_Error PTRCALL
+externalEntityInitProcessor3(XML_Parser parser,
+                             const char *start,
+                             const char *end,
+                             const char **endPtr)
 {
-  const char *next;
+  const char *next = start; /* XmlContentTok doesn't always set the last arg */
   int tok = XmlContentTok(encoding, start, end, &next);
   switch (tok) {
   case XML_TOK_XML_DECL:
     {
       enum XML_Error result = processXmlDecl(parser, 1, start, next);
       if (result != XML_ERROR_NONE)
-	return result;
+        return result;
       start = next;
     }
     break;
@@ -1425,26 +1908,33 @@ enum XML_Error externalEntityInitProcess
   }
   processor = externalEntityContentProcessor;
   tagLevel = 1;
-  return doContent(parser, 1, encoding, start, end, endPtr);
+  return externalEntityContentProcessor(parser, start, end, endPtr);
 }
 
-static
-enum XML_Error externalEntityContentProcessor(XML_Parser parser,
-					      const char *start,
-					      const char *end,
-					      const char **endPtr)
+static enum XML_Error PTRCALL
+externalEntityContentProcessor(XML_Parser parser,
+                               const char *start,
+                               const char *end,
+                               const char **endPtr)
 {
-  return doContent(parser, 1, encoding, start, end, endPtr);
+  enum XML_Error result =
+    doContent(parser, 1, encoding, start, end, endPtr);
+  if (result != XML_ERROR_NONE)
+    return result;
+  if (!storeRawNames(parser))
+    return XML_ERROR_NO_MEMORY;
+  return result;
 }
 
 static enum XML_Error
 doContent(XML_Parser parser,
-	  int startTagLevel,
-	  const ENCODING *enc,
-	  const char *s,
-	  const char *end,
-	  const char **nextPtr)
+          int startTagLevel,
+          const ENCODING *enc,
+          const char *s,
+          const char *end,
+          const char **nextPtr)
 {
+  DTD * const dtd = _dtd;  /* save one level of indirection */
   const char **eventPP;
   const char **eventEndPP;
   if (enc == encoding) {
@@ -1463,30 +1953,30 @@ doContent(XML_Parser parser,
     switch (tok) {
     case XML_TOK_TRAILING_CR:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       *eventEndPP = end;
       if (characterDataHandler) {
-	XML_Char c = 0xA;
-	characterDataHandler(handlerArg, &c, 1);
+        XML_Char c = 0xA;
+        characterDataHandler(handlerArg, &c, 1);
       }
       else if (defaultHandler)
-	reportDefault(parser, enc, s, end);
+        reportDefault(parser, enc, s, end);
       if (startTagLevel == 0)
-	return XML_ERROR_NO_ELEMENTS;
+        return XML_ERROR_NO_ELEMENTS;
       if (tagLevel != startTagLevel)
-	return XML_ERROR_ASYNC_ENTITY;
+        return XML_ERROR_ASYNC_ENTITY;
       return XML_ERROR_NONE;
     case XML_TOK_NONE:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       if (startTagLevel > 0) {
-	if (tagLevel != startTagLevel)
-	  return XML_ERROR_ASYNC_ENTITY;
-	return XML_ERROR_NONE;
+        if (tagLevel != startTagLevel)
+          return XML_ERROR_ASYNC_ENTITY;
+        return XML_ERROR_NONE;
       }
       return XML_ERROR_NO_ELEMENTS;
     case XML_TOK_INVALID:
@@ -1494,374 +1984,386 @@ doContent(XML_Parser parser,
       return XML_ERROR_INVALID_TOKEN;
     case XML_TOK_PARTIAL:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       return XML_ERROR_UNCLOSED_TOKEN;
     case XML_TOK_PARTIAL_CHAR:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       return XML_ERROR_PARTIAL_CHAR;
     case XML_TOK_ENTITY_REF:
       {
-	const XML_Char *name;
-	ENTITY *entity;
-	XML_Char ch = XmlPredefinedEntityName(enc,
-					      s + enc->minBytesPerChar,
-					      next - enc->minBytesPerChar);
-	if (ch) {
-	  if (characterDataHandler)
-	    characterDataHandler(handlerArg, &ch, 1);
-	  else if (defaultHandler)
-	    reportDefault(parser, enc, s, next);
-	  break;
-	}
-	name = poolStoreString(&dtd.pool, enc,
-				s + enc->minBytesPerChar,
-				next - enc->minBytesPerChar);
-	if (!name)
-	  return XML_ERROR_NO_MEMORY;
-	entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
-	poolDiscard(&dtd.pool);
-	if (!entity) {
-	  if (dtd.complete || dtd.standalone)
-	    return XML_ERROR_UNDEFINED_ENTITY;
-	  if (defaultHandler)
-	    reportDefault(parser, enc, s, next);
-	  break;
-	}
-	if (entity->open)
-	  return XML_ERROR_RECURSIVE_ENTITY_REF;
-	if (entity->notation)
-	  return XML_ERROR_BINARY_ENTITY_REF;
-	if (entity) {
-	  if (entity->textPtr) {
-	    enum XML_Error result;
-	    OPEN_INTERNAL_ENTITY openEntity;
-	    if (defaultHandler && !defaultExpandInternalEntities) {
-	      reportDefault(parser, enc, s, next);
-	      break;
-	    }
-	    entity->open = 1;
-	    openEntity.next = openInternalEntities;
-	    openInternalEntities = &openEntity;
-	    openEntity.entity = entity;
-	    openEntity.internalEventPtr = 0;
-	    openEntity.internalEventEndPtr = 0;
-	    result = doContent(parser,
-			       tagLevel,
-			       internalEncoding,
-			       (char *)entity->textPtr,
-			       (char *)(entity->textPtr + entity->textLen),
-			       0);
-	    entity->open = 0;
-	    openInternalEntities = openEntity.next;
-	    if (result)
-	      return result;
-	  }
-	  else if (externalEntityRefHandler) {
-	    const XML_Char *context;
-	    entity->open = 1;
-	    context = getContext(parser);
-	    entity->open = 0;
-	    if (!context)
-	      return XML_ERROR_NO_MEMORY;
-	    if (!externalEntityRefHandler(externalEntityRefHandlerArg,
-				          context,
-					  entity->base,
-					  entity->systemId,
-					  entity->publicId))
-	      return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
-	    poolDiscard(&tempPool);
-	  }
-	  else if (defaultHandler)
-	    reportDefault(parser, enc, s, next);
-	}
-	break;
-      }
-    case XML_TOK_START_TAG_WITH_ATTS:
-      if (!startElementHandler) {
-	enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
-	if (result)
-	  return result;
+        const XML_Char *name;
+        ENTITY *entity;
+        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
+                                              s + enc->minBytesPerChar,
+                                              next - enc->minBytesPerChar);
+        if (ch) {
+          if (characterDataHandler)
+            characterDataHandler(handlerArg, &ch, 1);
+          else if (defaultHandler)
+            reportDefault(parser, enc, s, next);
+          break;
+        }
+        name = poolStoreString(&dtd->pool, enc,
+                                s + enc->minBytesPerChar,
+                                next - enc->minBytesPerChar);
+        if (!name)
+          return XML_ERROR_NO_MEMORY;
+        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
+        poolDiscard(&dtd->pool);
+        /* First, determine if a check for an existing declaration is needed;
+           if yes, check that the entity exists, and that it is internal,
+           otherwise call the skipped entity or default handler.
+        */
+        if (!dtd->hasParamEntityRefs || dtd->standalone) {
+          if (!entity)
+            return XML_ERROR_UNDEFINED_ENTITY;
+          else if (!entity->is_internal)
+            return XML_ERROR_ENTITY_DECLARED_IN_PE;
+        }
+        else if (!entity) {
+          if (skippedEntityHandler)
+            skippedEntityHandler(handlerArg, name, 0);
+          else if (defaultHandler)
+            reportDefault(parser, enc, s, next);
+          break;
+        }
+        if (entity->open)
+          return XML_ERROR_RECURSIVE_ENTITY_REF;
+        if (entity->notation)
+          return XML_ERROR_BINARY_ENTITY_REF;
+        if (entity->textPtr) {
+          enum XML_Error result;
+          OPEN_INTERNAL_ENTITY openEntity;
+          if (!defaultExpandInternalEntities) {
+            if (skippedEntityHandler)
+              skippedEntityHandler(handlerArg, entity->name, 0);
+            else if (defaultHandler)
+              reportDefault(parser, enc, s, next);
+            break;
+          }
+          entity->open = XML_TRUE;
+          openEntity.next = openInternalEntities;
+          openInternalEntities = &openEntity;
+          openEntity.entity = entity;
+          openEntity.internalEventPtr = NULL;
+          openEntity.internalEventEndPtr = NULL;
+          result = doContent(parser,
+                             tagLevel,
+                             internalEncoding,
+                             (char *)entity->textPtr,
+                             (char *)(entity->textPtr + entity->textLen),
+                             0);
+          entity->open = XML_FALSE;
+          openInternalEntities = openEntity.next;
+          if (result)
+            return result;
+        }
+        else if (externalEntityRefHandler) {
+          const XML_Char *context;
+          entity->open = XML_TRUE;
+          context = getContext(parser);
+          entity->open = XML_FALSE;
+          if (!context)
+            return XML_ERROR_NO_MEMORY;
+          if (!externalEntityRefHandler((XML_Parser)externalEntityRefHandlerArg,
+                                        context,
+                                        entity->base,
+                                        entity->systemId,
+                                        entity->publicId))
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+          poolDiscard(&tempPool);
+        }
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        break;
       }
-      /* fall through */
     case XML_TOK_START_TAG_NO_ATTS:
+      /* fall through */
+    case XML_TOK_START_TAG_WITH_ATTS:
       {
-	TAG *tag;
-	if (freeTagList) {
-	  tag = freeTagList;
-	  freeTagList = freeTagList->parent;
-	}
-	else {
-	  tag = MALLOC(sizeof(TAG));
-	  if (!tag)
-	    return XML_ERROR_NO_MEMORY;
-	  tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
-	  if (!tag->buf)
-	    return XML_ERROR_NO_MEMORY;
-	  tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
-	}
-	tag->bindings = 0;
-	tag->parent = tagStack;
-	tagStack = tag;
-	tag->name.localPart = 0;
-	tag->rawName = s + enc->minBytesPerChar;
-	tag->rawNameLength = XmlNameLength(enc, tag->rawName);
-	if (nextPtr) {
-	  /* Need to guarantee that:
-	     tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
-	  if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
-	    int bufSize = tag->rawNameLength * 4;
-	    bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
-	    tag->buf = REALLOC(tag->buf, bufSize);
-	    if (!tag->buf)
-	      return XML_ERROR_NO_MEMORY;
-	    tag->bufEnd = tag->buf + bufSize;
-	  }
-	  memcpy(tag->buf, tag->rawName, tag->rawNameLength);
-	  tag->rawName = tag->buf;
-	}
-	++tagLevel;
-	if (startElementHandler) {
-	  enum XML_Error result;
-	  XML_Char *toPtr;
-	  for (;;) {
-	    const char *rawNameEnd = tag->rawName + tag->rawNameLength;
-	    const char *fromPtr = tag->rawName;
-	    int bufSize;
-	    if (nextPtr)
-	      toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
-	    else
-	      toPtr = (XML_Char *)tag->buf;
-	    tag->name.str = toPtr;
-	    XmlConvert(enc,
-		       &fromPtr, rawNameEnd,
-		       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
-	    if (fromPtr == rawNameEnd)
-	      break;
-	    bufSize = (tag->bufEnd - tag->buf) << 1;
-	    tag->buf = REALLOC(tag->buf, bufSize);
-	    if (!tag->buf)
-	      return XML_ERROR_NO_MEMORY;
-	    tag->bufEnd = tag->buf + bufSize;
-	    if (nextPtr)
-	      tag->rawName = tag->buf;
-	  }
-	  *toPtr = XML_T('\0');
-	  result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
-	  if (result)
-	    return result;
-	  startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
-	  poolClear(&tempPool);
-	}
-	else {
-	  tag->name.str = 0;

[... 4964 lines stripped ...]


Mime
View raw message