apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jor...@apache.org
Subject svn commit: r1002512 [9/12] - in /apr/apr-util/vendor/expat/current: ./ conftools/ doc/ examples/ lib/ xmlwf/
Date Wed, 29 Sep 2010 08:17:00 GMT
Added: 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=1002512&view=auto
==============================================================================
--- apr/apr-util/vendor/expat/current/lib/xmlparse.c (added)
+++ apr/apr-util/vendor/expat/current/lib/xmlparse.c Wed Sep 29 08:16:58 2010
@@ -0,0 +1,4635 @@
+/*
+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 "expat.h"
+
+#ifdef __declspec
+#  undef XMLPARSEAPI
+#endif
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include <stddef.h>
+#include <string.h>
+
+#ifdef XML_UNICODE
+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
+#define XmlConvert XmlUtf16Convert
+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
+#define XmlEncode XmlUtf16Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
+typedef unsigned short ICHAR;
+#else
+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
+#define XmlConvert XmlUtf8Convert
+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
+#define XmlEncode XmlUtf8Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
+typedef char ICHAR;
+#endif
+
+
+#ifndef XML_NS
+
+#define XmlInitEncodingNS XmlInitEncoding
+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
+#undef XmlGetInternalEncodingNS
+#define XmlGetInternalEncodingNS XmlGetInternalEncoding
+#define XmlParseXmlDeclNS XmlParseXmlDecl
+
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_T(x) L ## x
+#else
+#define XML_T(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))
+
+#include "xmltok.h"
+#include "xmlrole.h"
+
+typedef const XML_Char *KEY;
+
+typedef struct {
+  KEY name;
+} NAMED;
+
+typedef struct {
+  NAMED **v;
+  size_t size;
+  size_t used;
+  size_t usedLim;
+  XML_Memory_Handling_Suite *mem;
+} HASH_TABLE;
+
+typedef struct {
+  NAMED **p;
+  NAMED **end;
+} HASH_TABLE_ITER;
+
+#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_BLOCK_SIZE 1024
+#define INIT_BUFFER_SIZE 1024
+
+#define EXPAND_SPARE 24
+
+typedef struct binding {
+  struct prefix *prefix;
+  struct binding *nextTagBinding;
+  struct binding *prevPrefixBinding;
+  const struct attribute_id *attId;
+  XML_Char *uri;
+  int uriLen;
+  int uriAlloc;
+} BINDING;
+
+typedef struct prefix {
+  const XML_Char *name;
+  BINDING *binding;
+} PREFIX;
+
+typedef struct {
+  const XML_Char *str;
+  const XML_Char *localPart;
+  int uriLen;
+} TAG_NAME;
+
+typedef struct tag {
+  struct tag *parent;
+  const char *rawName;
+  int rawNameLength;
+  TAG_NAME name;
+  char *buf;
+  char *bufEnd;
+  BINDING *bindings;
+} TAG;
+
+typedef struct {
+  const XML_Char *name;
+  const XML_Char *textPtr;
+  int textLen;
+  const XML_Char *systemId;
+  const XML_Char *base;
+  const XML_Char *publicId;
+  const XML_Char *notation;
+  char open;
+  char is_param;
+} 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;
+} CONTENT_SCAFFOLD;
+
+typedef struct block {
+  struct block *next;
+  int size;
+  XML_Char s[1];
+} BLOCK;
+
+typedef struct {
+  BLOCK *blocks;
+  BLOCK *freeBlocks;
+  const XML_Char *end;
+  XML_Char *ptr;
+  XML_Char *start;
+  XML_Memory_Handling_Suite *mem;
+} STRING_POOL;
+
+/* The XML_Char before the name is used to determine whether
+an attribute has been specified. */
+typedef struct attribute_id {
+  XML_Char *name;
+  PREFIX *prefix;
+  char maybeTokenized;
+  char xmlns;
+} ATTRIBUTE_ID;
+
+typedef struct {
+  const ATTRIBUTE_ID *id;
+  char isCdata;
+  const XML_Char *value;
+} DEFAULT_ATTRIBUTE;
+
+typedef struct {
+  const XML_Char *name;
+  PREFIX *prefix;
+  const ATTRIBUTE_ID *idAtt;
+  int nDefaultAtts;
+  int allocDefaultAtts;
+  DEFAULT_ATTRIBUTE *defaultAtts;
+} ELEMENT_TYPE;
+
+typedef struct {
+  HASH_TABLE generalEntities;
+  HASH_TABLE elementTypes;
+  HASH_TABLE attributeIds;
+  HASH_TABLE prefixes;
+  STRING_POOL pool;
+  int complete;
+  int standalone;
+#ifdef XML_DTD
+  HASH_TABLE paramEntities;
+#endif /* XML_DTD */
+  PREFIX defaultPrefix;
+  /* === scaffolding for building content model === */
+  int in_eldecl;
+  CONTENT_SCAFFOLD *scaffold;
+  unsigned contentStringLen;
+  unsigned scaffSize;
+  unsigned scaffCount;
+  int scaffLevel;
+  int *scaffIndex;
+} DTD;
+
+typedef struct open_internal_entity {
+  const char *internalEventPtr;
+  const char *internalEventEndPtr;
+  struct open_internal_entity *next;
+  ENTITY *entity;
+} OPEN_INTERNAL_ENTITY;
+
+typedef enum XML_Error Processor(XML_Parser parser,
+				 const char *start,
+				 const char *end,
+				 const char **endPtr);
+
+static Processor prologProcessor;
+static Processor prologInitProcessor;
+static Processor contentProcessor;
+static Processor cdataSectionProcessor;
+#ifdef XML_DTD
+static Processor ignoreSectionProcessor;
+#endif /* XML_DTD */
+static Processor epilogProcessor;
+static Processor errorProcessor;
+static Processor externalEntityInitProcessor;
+static Processor externalEntityInitProcessor2;
+static Processor externalEntityInitProcessor3;
+static Processor externalEntityContentProcessor;
+
+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 *);
+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);
+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);
+static enum XML_Error
+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);
+#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 int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
+		int isCdata, int 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 *);
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *, int 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 *);
+static enum XML_Error
+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);
+static int
+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);
+
+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 NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
+
+static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
+
+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);
+
+#define poolStart(pool) ((pool)->start)
+#define poolEnd(pool) ((pool)->ptr)
+#define poolLength(pool) ((pool)->ptr - (pool)->start)
+#define poolChop(pool) ((void)--(pool->ptr))
+#define poolLastChar(pool) (((pool)->ptr)[-1])
+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
+#define poolFinish(pool) ((pool)->start = (pool)->ptr)
+#define poolAppendChar(pool, c) \
+  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
+   ? 0 \
+   : ((*((pool)->ptr)++ = c), 1))
+
+typedef struct {
+  /* 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;
+  /* first character to be parsed */
+  const char *m_bufferPtr;
+  /* past last character to be parsed */
+  char *m_bufferEnd;
+  /* allocated end of buffer */
+  const char *m_bufferLim;
+  long m_parseEndByteIndex;
+  const char *m_parseEndPtr;
+  XML_Char *m_dataBuf;
+  XML_Char *m_dataBufEnd;
+  XML_StartElementHandler m_startElementHandler;
+  XML_EndElementHandler m_endElementHandler;
+  XML_CharacterDataHandler m_characterDataHandler;
+  XML_ProcessingInstructionHandler m_processingInstructionHandler;
+  XML_CommentHandler m_commentHandler;
+  XML_StartCdataSectionHandler m_startCdataSectionHandler;
+  XML_EndCdataSectionHandler m_endCdataSectionHandler;
+  XML_DefaultHandler m_defaultHandler;
+  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
+  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
+  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
+  XML_NotationDeclHandler m_notationDeclHandler;
+  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
+  XML_NotStandaloneHandler m_notStandaloneHandler;
+  XML_ExternalEntityRefHandler m_externalEntityRefHandler;
+  void *m_externalEntityRefHandlerArg;
+  XML_UnknownEncodingHandler m_unknownEncodingHandler;
+  XML_ElementDeclHandler m_elementDeclHandler;
+  XML_AttlistDeclHandler m_attlistDeclHandler;
+  XML_EntityDeclHandler m_entityDeclHandler;
+  XML_XmlDeclHandler m_xmlDeclHandler;
+  const ENCODING *m_encoding;
+  INIT_ENCODING m_initEncoding;
+  const ENCODING *m_internalEncoding;
+  const XML_Char *m_protocolEncodingName;
+  int m_ns;
+  int m_ns_triplets;
+  void *m_unknownEncodingMem;
+  void *m_unknownEncodingData;
+  void *m_unknownEncodingHandlerData;
+  void (*m_unknownEncodingRelease)(void *);
+  PROLOG_STATE m_prologState;
+  Processor *m_processor;
+  enum XML_Error m_errorCode;
+  const char *m_eventPtr;
+  const char *m_eventEndPtr;
+  const char *m_positionPtr;
+  OPEN_INTERNAL_ENTITY *m_openInternalEntities;
+  int m_defaultExpandInternalEntities;
+  int m_tagLevel;
+  ENTITY *m_declEntity;
+  const XML_Char *m_doctypeName;
+  const XML_Char *m_doctypeSysid;
+  const XML_Char *m_doctypePubid;
+  const XML_Char *m_declAttributeType;
+  const XML_Char *m_declNotationName;
+  const XML_Char *m_declNotationPublicId;
+  ELEMENT_TYPE *m_declElementType;
+  ATTRIBUTE_ID *m_declAttributeId;
+  char m_declAttributeIsCdata;
+  char m_declAttributeIsId;
+  DTD m_dtd;
+  const XML_Char *m_curBase;
+  TAG *m_tagStack;
+  TAG *m_freeTagList;
+  BINDING *m_inheritedBindings;
+  BINDING *m_freeBindingList;
+  int m_attsSize;
+  int m_nSpecifiedAtts;
+  int m_idAttIndex;
+  ATTRIBUTE *m_atts;
+  POSITION m_position;
+  STRING_POOL m_tempPool;
+  STRING_POOL m_temp2Pool;
+  char *m_groupConnector;
+  unsigned m_groupSize;
+  int m_hadExternalDoctype;
+  XML_Char m_namespaceSeparator;
+#ifdef XML_DTD
+  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 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)
+#ifdef XML_DTD
+#define parentParser (((Parser *)parser)->m_parentParser)
+#define paramEntityParsing (((Parser *)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
+
+XML_Parser 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_Char tmp[2];
+  *tmp = nsSep;
+  return XML_ParserCreate_MM(encodingName, NULL, tmp);
+}
+
+XML_Parser
+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')
+  };
+
+
+  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;
+  }
+  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;
+  }
+
+  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;
+  attsSize = INIT_ATTS_SIZE;
+  atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
+  nSpecifiedAtts = 0;
+  dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+  groupSize = 0;
+  groupConnector = 0;
+  hadExternalDoctype = 0;
+  unknownEncodingMem = 0;
+  unknownEncodingRelease = 0;
+  unknownEncodingData = 0;
+  unknownEncodingHandlerData = 0;
+  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)) {
+    XML_ParserFree(parser);
+    return 0;
+  }
+  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+
+  if (nameSep) {
+    XmlInitEncodingNS(&initEncoding, &encoding, 0);
+    ns = 1;
+    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 */
+
+int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  if (!encodingName)
+    protocolEncodingName = 0;
+  else {
+    protocolEncodingName = poolCopyString(&tempPool, encodingName);
+    if (!protocolEncodingName)
+      return 0;
+  }
+  return 1;
+}
+
+XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
+					  const XML_Char *context,
+					  const XML_Char *encodingName)
+{
+  XML_Parser parser = oldParser;
+  DTD *oldDtd = &dtd;
+  XML_StartElementHandler oldStartElementHandler = startElementHandler;
+  XML_EndElementHandler oldEndElementHandler = endElementHandler;
+  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
+  XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
+  XML_CommentHandler oldCommentHandler = commentHandler;
+  XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
+  XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
+  XML_DefaultHandler oldDefaultHandler = defaultHandler;
+  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
+  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
+  XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
+  XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
+  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
+  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
+  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
+  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
+  ELEMENT_TYPE * oldDeclElementType = declElementType;
+
+  void *oldUserData = userData;
+  void *oldHandlerArg = handlerArg;
+  int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+  void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+  int oldParamEntityParsing = paramEntityParsing;
+#endif
+  int oldns_triplets = ns_triplets;
+
+  if (ns) {
+    XML_Char tmp[2];
+
+    *tmp = namespaceSeparator;
+    parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
+				 tmp);
+  }
+  else {
+    parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
+				 NULL);
+  }
+
+  if (!parser)
+    return 0;
+
+  startElementHandler = oldStartElementHandler;
+  endElementHandler = oldEndElementHandler;
+  characterDataHandler = oldCharacterDataHandler;
+  processingInstructionHandler = oldProcessingInstructionHandler;
+  commentHandler = oldCommentHandler;
+  startCdataSectionHandler = oldStartCdataSectionHandler;
+  endCdataSectionHandler = oldEndCdataSectionHandler;
+  defaultHandler = oldDefaultHandler;
+  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
+  notationDeclHandler = oldNotationDeclHandler;
+  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
+  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
+  notStandaloneHandler = oldNotStandaloneHandler;
+  externalEntityRefHandler = oldExternalEntityRefHandler;
+  unknownEncodingHandler = oldUnknownEncodingHandler;
+  elementDeclHandler = oldElementDeclHandler;
+  attlistDeclHandler = oldAttlistDeclHandler;
+  entityDeclHandler = oldEntityDeclHandler;
+  xmlDeclHandler = oldXmlDeclHandler;
+  declElementType = oldDeclElementType;
+  userData = oldUserData;
+  if (oldUserData == oldHandlerArg)
+    handlerArg = userData;
+  else
+    handlerArg = parser;
+  if (oldExternalEntityRefHandlerArg != oldParser)
+    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
+  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
+  ns_triplets = oldns_triplets;
+#ifdef XML_DTD
+  paramEntityParsing = oldParamEntityParsing;
+  if (context) {
+#endif /* XML_DTD */
+    if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
+      XML_ParserFree(parser);
+      return 0;
+    }
+    processor = externalEntityInitProcessor;
+#ifdef XML_DTD
+  }
+  else {
+    dtdSwap(&dtd, oldDtd);
+    parentParser = oldParser;
+    XmlPrologStateInitExternalEntity(&prologState);
+    dtd.complete = 1;
+    hadExternalDoctype = 1;
+  }
+#endif /* XML_DTD */
+  return parser;
+}
+
+static
+void destroyBindings(BINDING *bindings, XML_Parser parser)
+{
+  for (;;) {
+    BINDING *b = bindings;
+    if (!b)
+      break;
+    bindings = b->nextTagBinding;
+    FREE(b->uri);
+    FREE(b);
+  }
+}
+
+void XML_ParserFree(XML_Parser parser)
+{
+  for (;;) {
+    TAG *p;
+    if (tagStack == 0) {
+      if (freeTagList == 0)
+	break;
+      tagStack = freeTagList;
+      freeTagList = 0;
+    }
+    p = tagStack;
+    tagStack = tagStack->parent;
+    FREE(p->buf);
+    destroyBindings(p->bindings, parser);
+    FREE(p);
+  }
+  destroyBindings(freeBindingList, parser);
+  destroyBindings(inheritedBindings, parser);
+  poolDestroy(&tempPool);
+  poolDestroy(&temp2Pool);
+#ifdef XML_DTD
+  if (parentParser) {
+    if (hadExternalDoctype)
+      dtd.complete = 0;
+    dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
+  }
+#endif /* XML_DTD */
+  dtdDestroy(&dtd, parser);
+  FREE((void *)atts);
+  if (groupConnector)
+    FREE(groupConnector);
+  if (buffer)
+    FREE(buffer);
+  FREE(dataBuf);
+  if (unknownEncodingMem)
+    FREE(unknownEncodingMem);
+  if (unknownEncodingRelease)
+    unknownEncodingRelease(unknownEncodingData);
+  FREE(parser);
+}
+
+void XML_UseParserAsHandlerArg(XML_Parser parser)
+{
+  handlerArg = parser;
+}
+
+void
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
+  ns_triplets = do_nst;
+}
+
+void XML_SetUserData(XML_Parser parser, void *p)
+{
+  if (handlerArg == userData)
+    handlerArg = userData = p;
+  else
+    userData = p;
+}
+
+int XML_SetBase(XML_Parser parser, const XML_Char *p)
+{
+  if (p) {
+    p = poolCopyString(&dtd.pool, p);
+    if (!p)
+      return 0;
+    curBase = p;
+  }
+  else
+    curBase = 0;
+  return 1;
+}
+
+const XML_Char *XML_GetBase(XML_Parser parser)
+{
+  return curBase;
+}
+
+int XML_GetSpecifiedAttributeCount(XML_Parser parser)
+{
+  return nSpecifiedAtts;
+}
+
+int XML_GetIdAttributeIndex(XML_Parser parser)
+{
+  return idAttIndex;
+}
+
+void XML_SetElementHandler(XML_Parser parser,
+			   XML_StartElementHandler start,
+			   XML_EndElementHandler end)
+{
+  startElementHandler = start;
+  endElementHandler = end;
+}
+
+void XML_SetStartElementHandler(XML_Parser parser,
+				XML_StartElementHandler start) {
+  startElementHandler = start;
+}
+
+void XML_SetEndElementHandler(XML_Parser parser,
+			      XML_EndElementHandler end) {
+  endElementHandler = end;
+}
+
+void XML_SetCharacterDataHandler(XML_Parser parser,
+				 XML_CharacterDataHandler handler)
+{
+  characterDataHandler = handler;
+}
+
+void XML_SetProcessingInstructionHandler(XML_Parser parser,
+					 XML_ProcessingInstructionHandler handler)
+{
+  processingInstructionHandler = handler;
+}
+
+void XML_SetCommentHandler(XML_Parser parser,
+			   XML_CommentHandler handler)
+{
+  commentHandler = handler;
+}
+
+void XML_SetCdataSectionHandler(XML_Parser parser,
+				XML_StartCdataSectionHandler start,
+			        XML_EndCdataSectionHandler end)
+{
+  startCdataSectionHandler = start;
+  endCdataSectionHandler = end;
+}
+
+void XML_SetStartCdataSectionHandler(XML_Parser parser,
+                                     XML_StartCdataSectionHandler start) {
+  startCdataSectionHandler = start;
+}
+
+void XML_SetEndCdataSectionHandler(XML_Parser parser,
+                                   XML_EndCdataSectionHandler end) {
+  endCdataSectionHandler = end;
+}
+
+void XML_SetDefaultHandler(XML_Parser parser,
+			   XML_DefaultHandler handler)
+{
+  defaultHandler = handler;
+  defaultExpandInternalEntities = 0;
+}
+
+void XML_SetDefaultHandlerExpand(XML_Parser parser,
+				 XML_DefaultHandler handler)
+{
+  defaultHandler = handler;
+  defaultExpandInternalEntities = 1;
+}
+
+void XML_SetDoctypeDeclHandler(XML_Parser parser,
+			       XML_StartDoctypeDeclHandler start,
+			       XML_EndDoctypeDeclHandler end)
+{
+  startDoctypeDeclHandler = start;
+  endDoctypeDeclHandler = end;
+}
+
+void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+				    XML_StartDoctypeDeclHandler start) {
+  startDoctypeDeclHandler = start;
+}
+
+void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+				  XML_EndDoctypeDeclHandler end) {
+  endDoctypeDeclHandler = end;
+}
+
+void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+				      XML_UnparsedEntityDeclHandler handler)
+{
+  unparsedEntityDeclHandler = handler;
+}
+
+void XML_SetNotationDeclHandler(XML_Parser parser,
+				XML_NotationDeclHandler handler)
+{
+  notationDeclHandler = handler;
+}
+
+void XML_SetNamespaceDeclHandler(XML_Parser parser,
+				 XML_StartNamespaceDeclHandler start,
+				 XML_EndNamespaceDeclHandler end)
+{
+  startNamespaceDeclHandler = start;
+  endNamespaceDeclHandler = end;
+}
+
+void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+				      XML_StartNamespaceDeclHandler start) {
+  startNamespaceDeclHandler = start;
+}
+
+void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+				    XML_EndNamespaceDeclHandler end) {
+  endNamespaceDeclHandler = end;
+}
+
+
+void XML_SetNotStandaloneHandler(XML_Parser parser,
+				 XML_NotStandaloneHandler handler)
+{
+  notStandaloneHandler = handler;
+}
+
+void XML_SetExternalEntityRefHandler(XML_Parser parser,
+				     XML_ExternalEntityRefHandler handler)
+{
+  externalEntityRefHandler = handler;
+}
+
+void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
+{
+  if (arg)
+    externalEntityRefHandlerArg = arg;
+  else
+    externalEntityRefHandlerArg = parser;
+}
+
+void XML_SetUnknownEncodingHandler(XML_Parser parser,
+				   XML_UnknownEncodingHandler handler,
+				   void *data)
+{
+  unknownEncodingHandler = handler;
+  unknownEncodingHandlerData = data;
+}
+
+void XML_SetElementDeclHandler(XML_Parser parser,
+			       XML_ElementDeclHandler eldecl)
+{
+  elementDeclHandler = eldecl;
+}
+
+void XML_SetAttlistDeclHandler(XML_Parser parser,
+			       XML_AttlistDeclHandler attdecl)
+{
+  attlistDeclHandler = attdecl;
+}
+
+void XML_SetEntityDeclHandler(XML_Parser parser,
+			      XML_EntityDeclHandler handler)
+{
+  entityDeclHandler = handler;
+}
+
+void XML_SetXmlDeclHandler(XML_Parser parser,
+			   XML_XmlDeclHandler handler) {
+  xmlDeclHandler = handler;
+}
+
+int XML_SetParamEntityParsing(XML_Parser parser,
+			      enum XML_ParamEntityParsing parsing)
+{
+#ifdef XML_DTD
+  paramEntityParsing = parsing;
+  return 1;
+#else
+  return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+{
+  if (len == 0) {
+    if (!isFinal)
+      return 1;
+    positionPtr = bufferPtr;
+    errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
+    if (errorCode == XML_ERROR_NONE)
+      return 1;
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return 0;
+  }
+#ifndef XML_CONTEXT_BYTES
+  else if (bufferPtr == bufferEnd) {
+    const char *end;
+    int nLeftOver;
+    parseEndByteIndex += len;
+    positionPtr = s;
+    if (isFinal) {
+      errorCode = processor(parser, s, parseEndPtr = s + len, 0);
+      if (errorCode == XML_ERROR_NONE)
+	return 1;
+      eventEndPtr = eventPtr;
+      processor = errorProcessor;
+      return 0;
+    }
+    errorCode = processor(parser, s, parseEndPtr = s + len, &end);
+    if (errorCode != XML_ERROR_NONE) {
+      eventEndPtr = eventPtr;
+      processor = errorProcessor;
+      return 0;
+    }
+    XmlUpdatePosition(encoding, positionPtr, end, &position);
+    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;
+      }
+      memcpy(buffer, end, nLeftOver);
+      bufferPtr = buffer;
+      bufferEnd = buffer + nLeftOver;
+    }
+    return 1;
+  }
+#endif  /* not defined XML_CONTEXT_BYTES */
+  else {
+    memcpy(XML_GetBuffer(parser, len), s, len);
+    return XML_ParseBuffer(parser, len, isFinal);
+  }
+}
+
+int 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);
+  if (errorCode == XML_ERROR_NONE) {
+    if (!isFinal)
+      XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+    return 1;
+  }
+  else {
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return 0;
+  }
+}
+
+void *XML_GetBuffer(XML_Parser parser, int len)
+{
+  if (len > bufferLim - bufferEnd) {
+    /* FIXME avoid integer overflow */
+    int neededSize = len + (bufferEnd - bufferPtr);
+#ifdef XML_CONTEXT_BYTES
+    int keep = bufferPtr - buffer;
+
+    if (keep > XML_CONTEXT_BYTES)
+      keep = XML_CONTEXT_BYTES;
+    neededSize += keep;
+#endif  /* defined XML_CONTEXT_BYTES */
+    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;
+      }
+#else
+      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
+      bufferEnd = buffer + (bufferEnd - bufferPtr);
+      bufferPtr = buffer;
+#endif  /* not defined XML_CONTEXT_BYTES */
+    }
+    else {
+      char *newBuf;
+      int bufferSize = bufferLim - bufferPtr;
+      if (bufferSize == 0)
+	bufferSize = INIT_BUFFER_SIZE;
+      do {
+	bufferSize *= 2;
+      } while (bufferSize < neededSize);
+      newBuf = MALLOC(bufferSize);
+      if (newBuf == 0) {
+	errorCode = XML_ERROR_NO_MEMORY;
+	return 0;
+      }
+      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;
+      }
+      else {
+	bufferEnd = newBuf + (bufferEnd - bufferPtr);
+	bufferPtr = buffer = newBuf;
+      }
+#else
+      if (bufferPtr) {
+	memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+	FREE(buffer);
+      }
+      bufferEnd = newBuf + (bufferEnd - bufferPtr);
+      bufferPtr = buffer = newBuf;
+#endif  /* not defined XML_CONTEXT_BYTES */
+    }
+  }
+  return bufferEnd;
+}
+
+enum XML_Error XML_GetErrorCode(XML_Parser parser)
+{
+  return errorCode;
+}
+
+long XML_GetCurrentByteIndex(XML_Parser parser)
+{
+  if (eventPtr)
+    return parseEndByteIndex - (parseEndPtr - eventPtr);
+  return -1;
+}
+
+int XML_GetCurrentByteCount(XML_Parser parser)
+{
+  if (eventEndPtr && eventPtr)
+    return eventEndPtr - eventPtr;
+  return 0;
+}
+
+const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
+{
+#ifdef XML_CONTEXT_BYTES
+  if (eventPtr && buffer) {
+    *offset = eventPtr - buffer;
+    *size   = bufferEnd - buffer;
+    return buffer;
+  }
+#endif /* defined XML_CONTEXT_BYTES */
+  return (char *) 0;
+}
+
+int XML_GetCurrentLineNumber(XML_Parser parser)
+{
+  if (eventPtr) {
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+    positionPtr = eventPtr;
+  }
+  return position.lineNumber + 1;
+}
+
+int XML_GetCurrentColumnNumber(XML_Parser parser)
+{
+  if (eventPtr) {
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+    positionPtr = eventPtr;
+  }
+  return position.columnNumber;
+}
+
+void XML_DefaultCurrent(XML_Parser parser)
+{
+  if (defaultHandler) {
+    if (openInternalEntities)
+      reportDefault(parser,
+	            internalEncoding,
+		    openInternalEntities->internalEventPtr,
+		    openInternalEntities->internalEventEndPtr);
+    else
+      reportDefault(parser, encoding, eventPtr, eventEndPtr);
+  }
+}
+
+const XML_LChar *XML_ErrorString(int 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")
+  };
+  if (code > 0 && code < sizeof(message)/sizeof(message[0]))
+    return message[code];
+  return 0;
+}
+
+const XML_LChar *
+XML_ExpatVersion(void) {
+  return VERSION;
+}
+
+XML_Expat_Version
+XML_ExpatVersionInfo(void) {
+  XML_Expat_Version version;
+
+  version.major = XML_MAJOR_VERSION;
+  version.minor = XML_MINOR_VERSION;
+  version.micro = XML_MICRO_VERSION;
+
+  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);
+}
+
+static
+enum XML_Error externalEntityInitProcessor(XML_Parser parser,
+					   const char *start,
+					   const char *end,
+					   const char **endPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+  processor = externalEntityInitProcessor2;
+  return externalEntityInitProcessor2(parser, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
+					    const char *start,
+					    const char *end,
+					    const char **endPtr)
+{
+  const char *next;
+  int tok = XmlContentTok(encoding, start, end, &next);
+  switch (tok) {
+  case XML_TOK_BOM:
+    start = next;
+    break;
+  case XML_TOK_PARTIAL:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_UNCLOSED_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_PARTIAL_CHAR;
+  }
+  processor = externalEntityInitProcessor3;
+  return externalEntityInitProcessor3(parser, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
+					    const char *start,
+					    const char *end,
+					    const char **endPtr)
+{
+  const char *next;
+  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;
+      start = next;
+    }
+    break;
+  case XML_TOK_PARTIAL:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_UNCLOSED_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_PARTIAL_CHAR;
+  }
+  processor = externalEntityContentProcessor;
+  tagLevel = 1;
+  return doContent(parser, 1, encoding, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityContentProcessor(XML_Parser parser,
+					      const char *start,
+					      const char *end,
+					      const char **endPtr)
+{
+  return doContent(parser, 1, encoding, start, end, endPtr);
+}
+
+static enum XML_Error
+doContent(XML_Parser parser,
+	  int startTagLevel,
+	  const ENCODING *enc,
+	  const char *s,
+	  const char *end,
+	  const char **nextPtr)
+{
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  for (;;) {
+    const char *next = s; /* XmlContentTok doesn't always set the last arg */
+    int tok = XmlContentTok(enc, s, end, &next);
+    *eventEndPP = next;
+    switch (tok) {
+    case XML_TOK_TRAILING_CR:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      *eventEndPP = end;
+      if (characterDataHandler) {
+	XML_Char c = 0xA;
+	characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, end);
+      if (startTagLevel == 0)
+	return XML_ERROR_NO_ELEMENTS;
+      if (tagLevel != startTagLevel)
+	return XML_ERROR_ASYNC_ENTITY;
+      return XML_ERROR_NONE;
+    case XML_TOK_NONE:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      if (startTagLevel > 0) {
+	if (tagLevel != startTagLevel)
+	  return XML_ERROR_ASYNC_ENTITY;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_NO_ELEMENTS;
+    case XML_TOK_INVALID:
+      *eventPP = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+	*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;
+      }
+      /* fall through */
+    case XML_TOK_START_TAG_NO_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;
+	  if (defaultHandler)
+	    reportDefault(parser, enc, s, next);
+	}
+	break;
+      }
+    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
+      if (!startElementHandler) {
+	enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
+	if (result)
+	  return result;
+      }
+      /* fall through */
+    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
+      if (startElementHandler || endElementHandler) {
+	const char *rawName = s + enc->minBytesPerChar;
+	enum XML_Error result;
+	BINDING *bindings = 0;
+	TAG_NAME name;
+	name.str = poolStoreString(&tempPool, enc, rawName,
+				   rawName + XmlNameLength(enc, rawName));
+	if (!name.str)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&tempPool);
+	result = storeAtts(parser, enc, s, &name, &bindings);
+	if (result)
+	  return result;
+	poolFinish(&tempPool);
+	if (startElementHandler)
+	  startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
+	if (endElementHandler) {
+	  if (startElementHandler)
+	    *eventPP = *eventEndPP;
+	  endElementHandler(handlerArg, name.str);
+	}
+	poolClear(&tempPool);
+	while (bindings) {
+	  BINDING *b = bindings;
+	  if (endNamespaceDeclHandler)
+	    endNamespaceDeclHandler(handlerArg, b->prefix->name);
+	  bindings = bindings->nextTagBinding;
+	  b->nextTagBinding = freeBindingList;
+	  freeBindingList = b;
+	  b->prefix->binding = b->prevPrefixBinding;
+	}
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      if (tagLevel == 0)
+	return epilogProcessor(parser, next, end, nextPtr);
+      break;
+    case XML_TOK_END_TAG:
+      if (tagLevel == startTagLevel)
+        return XML_ERROR_ASYNC_ENTITY;
+      else {
+	int len;
+	const char *rawName;
+	TAG *tag = tagStack;
+	tagStack = tag->parent;
+	tag->parent = freeTagList;
+	freeTagList = tag;
+	rawName = s + enc->minBytesPerChar*2;
+	len = XmlNameLength(enc, rawName);
+	if (len != tag->rawNameLength
+	    || memcmp(tag->rawName, rawName, len) != 0) {
+	  *eventPP = rawName;
+	  return XML_ERROR_TAG_MISMATCH;
+	}
+	--tagLevel;
+	if (endElementHandler && tag->name.str) {
+	  if (tag->name.localPart) {
+	    XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
+	    const XML_Char *from = tag->name.localPart;
+	    while ((*to++ = *from++) != 0)
+	      ;
+	  }
+	  endElementHandler(handlerArg, tag->name.str);
+	}
+	else if (defaultHandler)
+	  reportDefault(parser, enc, s, next);
+	while (tag->bindings) {
+	  BINDING *b = tag->bindings;
+	  if (endNamespaceDeclHandler)
+	    endNamespaceDeclHandler(handlerArg, b->prefix->name);
+	  tag->bindings = tag->bindings->nextTagBinding;
+	  b->nextTagBinding = freeBindingList;
+	  freeBindingList = b;
+	  b->prefix->binding = b->prevPrefixBinding;
+	}
+	if (tagLevel == 0)
+	  return epilogProcessor(parser, next, end, nextPtr);
+      }
+      break;
+    case XML_TOK_CHAR_REF:
+      {
+	int n = XmlCharRefNumber(enc, s);
+	if (n < 0)
+	  return XML_ERROR_BAD_CHAR_REF;
+	if (characterDataHandler) {
+	  XML_Char buf[XML_ENCODE_MAX];
+	  characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+	}
+	else if (defaultHandler)
+	  reportDefault(parser, enc, s, next);
+      }
+      break;
+    case XML_TOK_XML_DECL:
+      return XML_ERROR_MISPLACED_XML_PI;
+    case XML_TOK_DATA_NEWLINE:
+      if (characterDataHandler) {
+	XML_Char c = 0xA;
+	characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_CDATA_SECT_OPEN:
+      {
+	enum XML_Error result;
+	if (startCdataSectionHandler)
+  	  startCdataSectionHandler(handlerArg);
+#if 0
+	/* Suppose you doing a transformation on a document that involves
+	   changing only the character data.  You set up a defaultHandler
+	   and a characterDataHandler.  The defaultHandler simply copies
+	   characters through.  The characterDataHandler does the transformation
+	   and writes the characters out escaping them as necessary.  This case
+	   will fail to work if we leave out the following two lines (because &
+	   and < inside CDATA sections will be incorrectly escaped).
+
+	   However, now we have a start/endCdataSectionHandler, so it seems
+	   easier to let the user deal with this. */
+
+	else if (characterDataHandler)
+  	  characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+	else if (defaultHandler)
+	  reportDefault(parser, enc, s, next);
+	result = doCdataSection(parser, enc, &next, end, nextPtr);
+	if (!next) {
+	  processor = cdataSectionProcessor;
+	  return result;
+	}
+      }
+      break;
+    case XML_TOK_TRAILING_RSQB:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      if (characterDataHandler) {
+	if (MUST_CONVERT(enc, s)) {
+	  ICHAR *dataPtr = (ICHAR *)dataBuf;
+	  XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+	  characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+	}
+	else
+	  characterDataHandler(handlerArg,
+		  	       (XML_Char *)s,
+			       (XML_Char *)end - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, end);
+      if (startTagLevel == 0) {
+        *eventPP = end;
+	return XML_ERROR_NO_ELEMENTS;
+      }
+      if (tagLevel != startTagLevel) {
+	*eventPP = end;
+	return XML_ERROR_ASYNC_ENTITY;
+      }
+      return XML_ERROR_NONE;
+    case XML_TOK_DATA_CHARS:
+      if (characterDataHandler) {
+	if (MUST_CONVERT(enc, s)) {
+	  for (;;) {
+	    ICHAR *dataPtr = (ICHAR *)dataBuf;
+	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+	    *eventEndPP = s;
+	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+	    if (s == next)
+	      break;
+	    *eventPP = s;
+	  }
+	}
+	else
+	  characterDataHandler(handlerArg,
+			       (XML_Char *)s,
+			       (XML_Char *)next - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_PI:
+      if (!reportProcessingInstruction(parser, enc, s, next))
+	return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_COMMENT:
+      if (!reportComment(parser, enc, s, next))
+	return XML_ERROR_NO_MEMORY;
+      break;
+    default:
+      if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+    }
+    *eventPP = s = next;
+  }
+  /* not reached */
+}
+
+/* If tagNamePtr is non-null, build a real list of attributes,
+otherwise just check the attributes for well-formedness. */
+
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
+				const char *attStr, TAG_NAME *tagNamePtr,
+				BINDING **bindingsPtr)
+{
+  ELEMENT_TYPE *elementType = 0;
+  int nDefaultAtts = 0;
+  const XML_Char **appAtts;   /* the attribute list to pass to the application */
+  int attIndex = 0;
+  int i;
+  int n;
+  int nPrefixes = 0;
+  BINDING *binding;
+  const XML_Char *localPart;
+
+  /* lookup the element type name */
+  if (tagNamePtr) {
+    elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
+    if (!elementType) {
+      tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
+      if (!tagNamePtr->str)
+	return XML_ERROR_NO_MEMORY;
+      elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
+      if (!elementType)
+        return XML_ERROR_NO_MEMORY;
+      if (ns && !setElementTypePrefix(parser, elementType))
+        return XML_ERROR_NO_MEMORY;
+    }
+    nDefaultAtts = elementType->nDefaultAtts;
+  }
+  /* get the attributes from the tokenizer */
+  n = XmlGetAttributes(enc, attStr, attsSize, atts);
+  if (n + nDefaultAtts > attsSize) {
+    int oldAttsSize = attsSize;
+    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+    atts = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
+    if (!atts)
+      return XML_ERROR_NO_MEMORY;
+    if (n > oldAttsSize)
+      XmlGetAttributes(enc, attStr, n, atts);
+  }
+  appAtts = (const XML_Char **)atts;
+  for (i = 0; i < n; i++) {
+    /* add the name and value to the attribute list */
+    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
+					 atts[i].name
+					 + XmlNameLength(enc, atts[i].name));
+    if (!attId)
+      return XML_ERROR_NO_MEMORY;
+    /* detect duplicate attributes */
+    if ((attId->name)[-1]) {
+      if (enc == encoding)
+	eventPtr = atts[i].name;
+      return XML_ERROR_DUPLICATE_ATTRIBUTE;
+    }
+    (attId->name)[-1] = 1;
+    appAtts[attIndex++] = attId->name;
+    if (!atts[i].normalized) {
+      enum XML_Error result;
+      int isCdata = 1;
+
+      /* figure out whether declared as other than CDATA */
+      if (attId->maybeTokenized) {
+	int j;
+	for (j = 0; j < nDefaultAtts; j++) {
+	  if (attId == elementType->defaultAtts[j].id) {
+	    isCdata = elementType->defaultAtts[j].isCdata;
+	    break;
+	  }
+	}
+      }
+
+      /* normalize the attribute value */
+      result = storeAttributeValue(parser, enc, isCdata,
+				   atts[i].valuePtr, atts[i].valueEnd,
+			           &tempPool);
+      if (result)
+	return result;
+      if (tagNamePtr) {
+	appAtts[attIndex] = poolStart(&tempPool);
+	poolFinish(&tempPool);
+      }
+      else
+	poolDiscard(&tempPool);
+    }
+    else if (tagNamePtr) {
+      /* the value did not need normalizing */
+      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
+      if (appAtts[attIndex] == 0)
+	return XML_ERROR_NO_MEMORY;
+      poolFinish(&tempPool);
+    }
+    /* handle prefixed attribute names */
+    if (attId->prefix && tagNamePtr) {
+      if (attId->xmlns) {
+	/* deal with namespace declarations here */
+        if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
+          return XML_ERROR_NO_MEMORY;
+        --attIndex;
+      }
+      else {
+	/* deal with other prefixed names later */
+        attIndex++;
+        nPrefixes++;
+        (attId->name)[-1] = 2;
+      }
+    }
+    else
+      attIndex++;
+  }
+  if (tagNamePtr) {
+    int j;
+    nSpecifiedAtts = attIndex;
+    if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
+      for (i = 0; i < attIndex; i += 2)
+	if (appAtts[i] == elementType->idAtt->name) {
+	  idAttIndex = i;
+	  break;
+	}
+    }
+    else
+      idAttIndex = -1;
+    /* do attribute defaulting */
+    for (j = 0; j < nDefaultAtts; j++) {
+      const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
+      if (!(da->id->name)[-1] && da->value) {
+        if (da->id->prefix) {
+          if (da->id->xmlns) {
+	    if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
+	      return XML_ERROR_NO_MEMORY;
+	  }
+          else {
+	    (da->id->name)[-1] = 2;
+	    nPrefixes++;
+  	    appAtts[attIndex++] = da->id->name;
+	    appAtts[attIndex++] = da->value;
+	  }
+	}
+	else {
+	  (da->id->name)[-1] = 1;
+	  appAtts[attIndex++] = da->id->name;
+	  appAtts[attIndex++] = da->value;
+	}
+      }
+    }
+    appAtts[attIndex] = 0;
+  }
+  i = 0;
+  if (nPrefixes) {
+    /* expand prefixed attribute names */
+    for (; i < attIndex; i += 2) {
+      if (appAtts[i][-1] == 2) {
+        ATTRIBUTE_ID *id;
+        ((XML_Char *)(appAtts[i]))[-1] = 0;
+	id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
+	if (id->prefix->binding) {
+	  int j;
+	  const BINDING *b = id->prefix->binding;
+	  const XML_Char *s = appAtts[i];
+	  for (j = 0; j < b->uriLen; j++) {
+	    if (!poolAppendChar(&tempPool, b->uri[j]))
+	      return XML_ERROR_NO_MEMORY;
+	  }
+	  while (*s++ != ':')
+	    ;
+	  do {
+	    if (!poolAppendChar(&tempPool, *s))
+	      return XML_ERROR_NO_MEMORY;
+	  } while (*s++);
+	  if (ns_triplets) {
+	    tempPool.ptr[-1] = namespaceSeparator;
+	    s = b->prefix->name;
+	    do {
+	      if (!poolAppendChar(&tempPool, *s))
+		return XML_ERROR_NO_MEMORY;
+	    } while (*s++);
+	  }
+
+	  appAtts[i] = poolStart(&tempPool);
+	  poolFinish(&tempPool);
+	}
+	if (!--nPrefixes)
+	  break;
+      }
+      else
+	((XML_Char *)(appAtts[i]))[-1] = 0;
+    }
+  }
+  /* clear the flags that say whether attributes were specified */
+  for (; i < attIndex; i += 2)
+    ((XML_Char *)(appAtts[i]))[-1] = 0;
+  if (!tagNamePtr)
+    return XML_ERROR_NONE;
+  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
+    binding->attId->name[-1] = 0;
+  /* expand the element type name */
+  if (elementType->prefix) {
+    binding = elementType->prefix->binding;
+    if (!binding)
+      return XML_ERROR_NONE;
+    localPart = tagNamePtr->str;
+    while (*localPart++ != XML_T(':'))
+      ;
+  }
+  else if (dtd.defaultPrefix.binding) {
+    binding = dtd.defaultPrefix.binding;
+    localPart = tagNamePtr->str;
+  }
+  else
+    return XML_ERROR_NONE;
+  tagNamePtr->localPart = localPart;
+  tagNamePtr->uriLen = binding->uriLen;
+  for (i = 0; localPart[i++];)
+    ;
+  n = i + binding->uriLen;
+  if (n > binding->uriAlloc) {
+    TAG *p;
+    XML_Char *uri = MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
+    if (!uri)
+      return XML_ERROR_NO_MEMORY;
+    binding->uriAlloc = n + EXPAND_SPARE;
+    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
+    for (p = tagStack; p; p = p->parent)
+      if (p->name.str == binding->uri)
+	p->name.str = uri;
+    FREE(binding->uri);
+    binding->uri = uri;
+  }
+  memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
+  tagNamePtr->str = binding->uri;
+  return XML_ERROR_NONE;
+}
+
+static
+int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
+{
+  BINDING *b;
+  int len;
+  for (len = 0; uri[len]; len++)
+    ;
+  if (namespaceSeparator)
+    len++;
+  if (freeBindingList) {
+    b = freeBindingList;
+    if (len > b->uriAlloc) {
+      b->uri = REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
+      if (!b->uri)
+	return 0;
+      b->uriAlloc = len + EXPAND_SPARE;
+    }
+    freeBindingList = b->nextTagBinding;
+  }
+  else {
+    b = MALLOC(sizeof(BINDING));
+    if (!b)
+      return 0;
+    b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
+    if (!b->uri) {
+      FREE(b);
+      return 0;
+    }
+    b->uriAlloc = len + EXPAND_SPARE;
+  }
+  b->uriLen = len;
+  memcpy(b->uri, uri, len * sizeof(XML_Char));
+  if (namespaceSeparator)
+    b->uri[len - 1] = namespaceSeparator;
+  b->prefix = prefix;
+  b->attId = attId;
+  b->prevPrefixBinding = prefix->binding;
+  if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
+    prefix->binding = 0;
+  else
+    prefix->binding = b;
+  b->nextTagBinding = *bindingsPtr;
+  *bindingsPtr = b;
+  if (startNamespaceDeclHandler)
+    startNamespaceDeclHandler(handlerArg, prefix->name,
+			      prefix->binding ? uri : 0);
+  return 1;
+}
+
+/* The idea here is to avoid using stack for each CDATA section when
+the whole file is parsed with one call. */
+
+static
+enum XML_Error cdataSectionProcessor(XML_Parser parser,
+				     const char *start,
+			    	     const char *end,
+				     const char **endPtr)
+{
+  enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
+  if (start) {
+    processor = contentProcessor;
+    return contentProcessor(parser, start, end, endPtr);
+  }
+  return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null if
+the section is not yet closed. */
+
+static
+enum XML_Error doCdataSection(XML_Parser parser,
+			      const ENCODING *enc,
+			      const char **startPtr,
+			      const char *end,
+			      const char **nextPtr)
+{
+  const char *s = *startPtr;
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    *eventPP = s;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  *startPtr = 0;
+  for (;;) {
+    const char *next;
+    int tok = XmlCdataSectionTok(enc, s, end, &next);
+    *eventEndPP = next;
+    switch (tok) {
+    case XML_TOK_CDATA_SECT_CLOSE:
+      if (endCdataSectionHandler)
+	endCdataSectionHandler(handlerArg);
+#if 0
+      /* see comment under XML_TOK_CDATA_SECT_OPEN */
+      else if (characterDataHandler)
+	characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      *startPtr = next;
+      return XML_ERROR_NONE;
+    case XML_TOK_DATA_NEWLINE:
+      if (characterDataHandler) {
+	XML_Char c = 0xA;
+	characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_DATA_CHARS:
+      if (characterDataHandler) {
+	if (MUST_CONVERT(enc, s)) {
+	  for (;;) {
+  	    ICHAR *dataPtr = (ICHAR *)dataBuf;
+	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+	    *eventEndPP = next;
+	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+	    if (s == next)
+	      break;
+	    *eventPP = s;
+	  }
+	}
+	else
+	  characterDataHandler(handlerArg,
+		  	       (XML_Char *)s,
+			       (XML_Char *)next - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_INVALID:
+      *eventPP = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_PARTIAL:
+    case XML_TOK_NONE:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_CDATA_SECTION;
+    default:
+      *eventPP = next;
+      return XML_ERROR_UNEXPECTED_STATE;
+    }
+    *eventPP = s = next;
+  }
+  /* not reached */
+}
+
+#ifdef XML_DTD
+
+/* The idea here is to avoid using stack for each IGNORE section when
+the whole file is parsed with one call. */
+
+static
+enum XML_Error ignoreSectionProcessor(XML_Parser parser,
+				      const char *start,
+				      const char *end,
+				      const char **endPtr)
+{
+  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
+  if (start) {
+    processor = prologProcessor;
+    return prologProcessor(parser, start, end, endPtr);
+  }
+  return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null if
+the section is not yet closed. */
+
+static
+enum XML_Error doIgnoreSection(XML_Parser parser,
+			       const ENCODING *enc,
+			       const char **startPtr,
+			       const char *end,
+			       const char **nextPtr)
+{
+  const char *next;
+  int tok;
+  const char *s = *startPtr;
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    *eventPP = s;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  *startPtr = 0;
+  tok = XmlIgnoreSectionTok(enc, s, end, &next);
+  *eventEndPP = next;
+  switch (tok) {
+  case XML_TOK_IGNORE_SECT:
+    if (defaultHandler)
+      reportDefault(parser, enc, s, next);
+    *startPtr = next;
+    return XML_ERROR_NONE;
+  case XML_TOK_INVALID:
+    *eventPP = next;
+    return XML_ERROR_INVALID_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (nextPtr) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_PARTIAL_CHAR;
+  case XML_TOK_PARTIAL:
+  case XML_TOK_NONE:
+    if (nextPtr) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
+  default:
+    *eventPP = next;
+    return XML_ERROR_UNEXPECTED_STATE;
+  }
+  /* not reached */
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error
+initializeEncoding(XML_Parser parser)
+{
+  const char *s;
+#ifdef XML_UNICODE
+  char encodingBuf[128];
+  if (!protocolEncodingName)
+    s = 0;
+  else {
+    int i;
+    for (i = 0; protocolEncodingName[i]; i++) {
+      if (i == sizeof(encodingBuf) - 1
+	  || (protocolEncodingName[i] & ~0x7f) != 0) {
+	encodingBuf[0] = '\0';
+	break;
+      }
+      encodingBuf[i] = (char)protocolEncodingName[i];
+    }
+    encodingBuf[i] = '\0';
+    s = encodingBuf;
+  }
+#else
+  s = protocolEncodingName;
+#endif
+  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
+    return XML_ERROR_NONE;
+  return handleUnknownEncoding(parser, protocolEncodingName);
+}
+
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+	       const char *s, const char *next)
+{
+  const char *encodingName = 0;
+  const char *storedEncName = 0;
+  const ENCODING *newEncoding = 0;
+  const char *version = 0;
+  const char *versionend;
+  const char *storedversion = 0;
+  int standalone = -1;
+  if (!(ns
+        ? XmlParseXmlDeclNS
+	: XmlParseXmlDecl)(isGeneralTextEntity,
+		           encoding,
+		           s,
+		           next,
+		           &eventPtr,
+		           &version,
+			   &versionend,
+		           &encodingName,
+		           &newEncoding,
+		           &standalone))
+    return XML_ERROR_SYNTAX;
+  if (!isGeneralTextEntity && standalone == 1) {
+    dtd.standalone = 1;
+#ifdef XML_DTD
+    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif /* XML_DTD */
+  }
+  if (xmlDeclHandler) {
+    if (encodingName) {
+      storedEncName = poolStoreString(&temp2Pool,
+				      encoding,
+				      encodingName,
+				      encodingName
+				      + XmlNameLength(encoding, encodingName));
+      if (! storedEncName)
+	return XML_ERROR_NO_MEMORY;
+      poolFinish(&temp2Pool);
+    }
+    if (version) {
+      storedversion = poolStoreString(&temp2Pool,
+				      encoding,
+				      version,
+				      versionend - encoding->minBytesPerChar);
+      if (! storedversion)
+	return XML_ERROR_NO_MEMORY;
+    }
+    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
+  }
+  else if (defaultHandler)
+    reportDefault(parser, encoding, s, next);
+  if (!protocolEncodingName) {
+    if (newEncoding) {
+      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
+	eventPtr = encodingName;
+	return XML_ERROR_INCORRECT_ENCODING;
+      }
+      encoding = newEncoding;
+    }
+    else if (encodingName) {
+      enum XML_Error result;
+      if (! storedEncName) {
+	storedEncName = poolStoreString(&temp2Pool,
+					encoding,
+					encodingName,
+					encodingName
+					+ XmlNameLength(encoding, encodingName));
+	if (! storedEncName)
+	  return XML_ERROR_NO_MEMORY;
+      }
+      result = handleUnknownEncoding(parser, storedEncName);
+      poolClear(&tempPool);
+      if (result == XML_ERROR_UNKNOWN_ENCODING)
+	eventPtr = encodingName;
+      return result;
+    }
+  }
+
+  if (storedEncName || storedversion)
+    poolClear(&temp2Pool);
+
+  return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  if (unknownEncodingHandler) {
+    XML_Encoding info;
+    int i;
+    for (i = 0; i < 256; i++)
+      info.map[i] = -1;
+    info.convert = 0;
+    info.data = 0;
+    info.release = 0;
+    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
+      ENCODING *enc;
+      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
+      if (!unknownEncodingMem) {
+	if (info.release)
+	  info.release(info.data);
+	return XML_ERROR_NO_MEMORY;
+      }
+      enc = (ns
+	     ? XmlInitUnknownEncodingNS
+	     : XmlInitUnknownEncoding)(unknownEncodingMem,
+				       info.map,
+				       info.convert,
+				       info.data);
+      if (enc) {
+	unknownEncodingData = info.data;
+	unknownEncodingRelease = info.release;
+	encoding = enc;
+	return XML_ERROR_NONE;
+      }
+    }
+    if (info.release)
+      info.release(info.data);
+  }
+  return XML_ERROR_UNKNOWN_ENCODING;
+}
+
+static enum XML_Error
+prologInitProcessor(XML_Parser parser,
+		    const char *s,
+		    const char *end,
+		    const char **nextPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+  processor = prologProcessor;
+  return prologProcessor(parser, s, end, nextPtr);
+}
+
+static enum XML_Error
+prologProcessor(XML_Parser parser,
+		const char *s,
+		const char *end,
+		const char **nextPtr)
+{
+  const char *next;
+  int tok = XmlPrologTok(encoding, s, end, &next);
+  return doProlog(parser, encoding, s, end, tok, next, nextPtr);
+}
+
+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)
+{
+#ifdef XML_DTD
+  static const XML_Char externalSubsetName[] = { '#' , '\0' };
+#endif /* XML_DTD */
+
+  const char **eventPP;
+  const char **eventEndPP;
+  enum XML_Content_Quant quant;
+
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  for (;;) {
+    int role;
+    *eventPP = s;
+    *eventEndPP = next;
+    if (tok <= 0) {
+      if (nextPtr != 0 && tok != XML_TOK_INVALID) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      switch (tok) {
+      case XML_TOK_INVALID:
+	*eventPP = next;
+	return XML_ERROR_INVALID_TOKEN;
+      case XML_TOK_PARTIAL:
+	return XML_ERROR_UNCLOSED_TOKEN;
+      case XML_TOK_PARTIAL_CHAR:
+	return XML_ERROR_PARTIAL_CHAR;
+      case XML_TOK_NONE:
+#ifdef XML_DTD
+	if (enc != encoding)
+	  return XML_ERROR_NONE;
+	if (parentParser) {
+	  if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
+	      == XML_ROLE_ERROR)
+	    return XML_ERROR_SYNTAX;
+	  hadExternalDoctype = 0;
+	  return XML_ERROR_NONE;
+	}
+#endif /* XML_DTD */
+	return XML_ERROR_NO_ELEMENTS;
+      default:
+	tok = -tok;
+	next = end;
+	break;
+      }
+    }
+    role = XmlTokenRole(&prologState, tok, s, next, enc);
+    switch (role) {
+    case XML_ROLE_XML_DECL:
+      {
+	enum XML_Error result = processXmlDecl(parser, 0, s, next);
+	if (result != XML_ERROR_NONE)
+	  return result;
+	enc = encoding;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_NAME:
+      if (startDoctypeDeclHandler) {
+	doctypeName = poolStoreString(&tempPool, enc, s, next);
+	if (! doctypeName)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&tempPool);
+	doctypeSysid = 0;
+	doctypePubid = 0;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
+      if (startDoctypeDeclHandler) {
+	startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
+				doctypePubid, 1);
+	doctypeName = 0;
+	poolClear(&tempPool);
+      }
+      break;
+#ifdef XML_DTD
+    case XML_ROLE_TEXT_DECL:
+      {
+	enum XML_Error result = processXmlDecl(parser, 1, s, next);
+	if (result != XML_ERROR_NONE)
+	  return result;
+	enc = encoding;
+      }
+      break;
+#endif /* XML_DTD */
+    case XML_ROLE_DOCTYPE_PUBLIC_ID:
+      if (startDoctypeDeclHandler) {
+	doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1);
+	if (! doctypePubid)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&tempPool);
+      }
+#ifdef XML_DTD
+      declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+				    externalSubsetName,
+				    sizeof(ENTITY));
+      if (!declEntity)
+	return XML_ERROR_NO_MEMORY;
+#endif /* XML_DTD */
+      /* fall through */
+    case XML_ROLE_ENTITY_PUBLIC_ID:
+      if (!XmlIsPublicId(enc, s, next, eventPP))
+	return XML_ERROR_SYNTAX;
+      if (declEntity) {
+	XML_Char *tem = poolStoreString(&dtd.pool,
+	                                enc,
+					s + enc->minBytesPerChar,
+	  				next - enc->minBytesPerChar);
+	if (!tem)
+	  return XML_ERROR_NO_MEMORY;
+	normalizePublicId(tem);
+	declEntity->publicId = tem;
+	poolFinish(&dtd.pool);
+      }
+      break;
+    case XML_ROLE_DOCTYPE_CLOSE:
+      if (doctypeName) {
+	startDoctypeDeclHandler(handlerArg, doctypeName,
+				doctypeSysid, doctypePubid, 0);
+	poolClear(&tempPool);
+      }
+      if (dtd.complete && hadExternalDoctype) {
+	dtd.complete = 0;
+#ifdef XML_DTD
+	if (paramEntityParsing && externalEntityRefHandler) {
+	  ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
+					    externalSubsetName,
+					    0);
+	  if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+					0,
+					entity->base,
+					entity->systemId,
+					entity->publicId))
+	   return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+	}
+#endif /* XML_DTD */
+	if (!dtd.complete
+	    && !dtd.standalone
+	    && notStandaloneHandler
+	    && !notStandaloneHandler(handlerArg))
+	  return XML_ERROR_NOT_STANDALONE;
+      }
+      if (endDoctypeDeclHandler)
+	endDoctypeDeclHandler(handlerArg);
+      break;
+    case XML_ROLE_INSTANCE_START:
+      processor = contentProcessor;
+      return contentProcessor(parser, s, end, nextPtr);
+    case XML_ROLE_ATTLIST_ELEMENT_NAME:
+      declElementType = getElementType(parser, enc, s, next);
+      if (!declElementType)
+	return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_ROLE_ATTRIBUTE_NAME:
+      declAttributeId = getAttributeId(parser, enc, s, next);
+      if (!declAttributeId)
+	return XML_ERROR_NO_MEMORY;
+      declAttributeIsCdata = 0;
+      declAttributeType = 0;
+      declAttributeIsId = 0;
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
+      declAttributeIsCdata = 1;
+      declAttributeType = "CDATA";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_ID:
+      declAttributeIsId = 1;
+      declAttributeType = "ID";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
+      declAttributeType = "IDREF";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
+      declAttributeType = "IDREFS";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
+      declAttributeType = "ENTITY";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
+      declAttributeType = "ENTITIES";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
+      declAttributeType = "NMTOKEN";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
+      declAttributeType = "NMTOKENS";
+      break;
+
+    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
+    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
+      if (attlistDeclHandler)
+      {
+	char *prefix;
+	if (declAttributeType) {
+	  prefix = "|";
+	}
+	else {
+	  prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
+		    ? "NOTATION("
+		    : "(");
+	}
+	if (! poolAppendString(&tempPool, prefix))
+	  return XML_ERROR_NO_MEMORY;
+	if (! poolAppend(&tempPool, enc, s, next))
+	  return XML_ERROR_NO_MEMORY;
+	declAttributeType = tempPool.start;
+      }
+      break;
+    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
+    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
+      if (dtd.complete
+	  && !defineAttribute(declElementType, declAttributeId,
+			      declAttributeIsCdata, declAttributeIsId, 0,
+			      parser))
+	return XML_ERROR_NO_MEMORY;
+      if (attlistDeclHandler && declAttributeType) {
+	if (*declAttributeType == '('
+	    || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
+	  /* Enumerated or Notation type */
+	  if (! poolAppendChar(&tempPool, ')')
+	      || ! poolAppendChar(&tempPool, '\0'))
+	    return XML_ERROR_NO_MEMORY;
+	  declAttributeType = tempPool.start;
+	  poolFinish(&tempPool);
+	}
+	*eventEndPP = s;
+	attlistDeclHandler(handlerArg, declElementType->name,
+			   declAttributeId->name, declAttributeType,
+			   0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
+	poolClear(&tempPool);
+      }
+      break;
+    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
+    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
+      {
+	const XML_Char *attVal;
+	enum XML_Error result
+	  = storeAttributeValue(parser, enc, declAttributeIsCdata,
+				s + enc->minBytesPerChar,
+			        next - enc->minBytesPerChar,
+			        &dtd.pool);
+	if (result)
+	  return result;
+	attVal = poolStart(&dtd.pool);
+	poolFinish(&dtd.pool);
+	if (dtd.complete
+	    /* ID attributes aren't allowed to have a default */
+	    && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
+	  return XML_ERROR_NO_MEMORY;
+	if (attlistDeclHandler && declAttributeType) {
+	  if (*declAttributeType == '('
+	      || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
+	    /* Enumerated or Notation type */
+	    if (! poolAppendChar(&tempPool, ')')
+		|| ! poolAppendChar(&tempPool, '\0'))
+	      return XML_ERROR_NO_MEMORY;
+	    declAttributeType = tempPool.start;
+	    poolFinish(&tempPool);
+	  }
+	  *eventEndPP = s;
+	  attlistDeclHandler(handlerArg, declElementType->name,
+			     declAttributeId->name, declAttributeType,
+			     attVal,
+			     role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
+	  poolClear(&tempPool);
+	}
+	break;
+      }
+    case XML_ROLE_ENTITY_VALUE:
+      {
+	enum XML_Error result = storeEntityValue(parser, enc,
+						 s + enc->minBytesPerChar,
+						 next - enc->minBytesPerChar);
+	if (declEntity) {
+	  declEntity->textPtr = poolStart(&dtd.pool);
+	  declEntity->textLen = poolLength(&dtd.pool);
+	  poolFinish(&dtd.pool);
+	  if (entityDeclHandler) {
+	    *eventEndPP = s;
+	    entityDeclHandler(handlerArg,
+			      declEntity->name,
+			      declEntity->is_param,
+			      declEntity->textPtr,
+			      declEntity->textLen,
+			      curBase, 0, 0, 0);
+	  }
+	}
+	else
+	  poolDiscard(&dtd.pool);
+	if (result != XML_ERROR_NONE)
+	  return result;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_SYSTEM_ID:
+      if (startDoctypeDeclHandler) {
+	doctypeSysid = poolStoreString(&tempPool, enc, s + 1, next - 1);
+	if (! doctypeSysid)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&tempPool);
+      }
+      if (!dtd.standalone
+#ifdef XML_DTD
+	  && !paramEntityParsing
+#endif /* XML_DTD */
+	  && notStandaloneHandler
+	  && !notStandaloneHandler(handlerArg))
+	return XML_ERROR_NOT_STANDALONE;
+      hadExternalDoctype = 1;
+#ifndef XML_DTD
+      break;
+#else /* XML_DTD */
+      if (!declEntity) {
+	declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+				      externalSubsetName,
+				      sizeof(ENTITY));
+	declEntity->publicId = 0;
+	if (!declEntity)
+	  return XML_ERROR_NO_MEMORY;
+      }
+      /* fall through */
+#endif /* XML_DTD */
+    case XML_ROLE_ENTITY_SYSTEM_ID:
+      if (declEntity) {
+	declEntity->systemId = poolStoreString(&dtd.pool, enc,
+	                                       s + enc->minBytesPerChar,
+	  				       next - enc->minBytesPerChar);
+	if (!declEntity->systemId)
+	  return XML_ERROR_NO_MEMORY;
+	declEntity->base = curBase;
+	poolFinish(&dtd.pool);
+      }
+      break;
+    case XML_ROLE_ENTITY_COMPLETE:
+      if (declEntity && entityDeclHandler) {
+	*eventEndPP = s;
+	entityDeclHandler(handlerArg,
+			  declEntity->name,
+			  0,0,0,
+			  declEntity->base,
+			  declEntity->systemId,
+			  declEntity->publicId,
+			  0);
+      }
+      break;
+    case XML_ROLE_ENTITY_NOTATION_NAME:
+      if (declEntity) {
+	declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
+	if (!declEntity->notation)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&dtd.pool);
+	if (unparsedEntityDeclHandler) {
+	  *eventEndPP = s;
+	  unparsedEntityDeclHandler(handlerArg,
+				    declEntity->name,
+				    declEntity->base,
+				    declEntity->systemId,
+				    declEntity->publicId,
+				    declEntity->notation);
+	}
+	else if (entityDeclHandler) {
+	  *eventEndPP = s;
+	  entityDeclHandler(handlerArg,
+			    declEntity->name,
+			    0,0,0,
+			    declEntity->base,
+			    declEntity->systemId,
+			    declEntity->publicId,
+			    declEntity->notation);
+	}
+      }
+      break;
+    case XML_ROLE_GENERAL_ENTITY_NAME:
+      {
+	const XML_Char *name;
+	if (XmlPredefinedEntityName(enc, s, next)) {
+	  declEntity = 0;
+	  break;
+	}
+	name = poolStoreString(&dtd.pool, enc, s, next);
+	if (!name)
+	  return XML_ERROR_NO_MEMORY;
+	if (dtd.complete) {
+	  declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
+	  if (!declEntity)
+	    return XML_ERROR_NO_MEMORY;
+	  if (declEntity->name != name) {
+	    poolDiscard(&dtd.pool);
+	    declEntity = 0;
+	  }
+	  else {
+	    poolFinish(&dtd.pool);
+	    declEntity->publicId = 0;
+	    declEntity->is_param = 0;
+	  }
+	}
+	else {
+	  poolDiscard(&dtd.pool);
+	  declEntity = 0;
+	}
+      }
+      break;
+    case XML_ROLE_PARAM_ENTITY_NAME:
+#ifdef XML_DTD
+      if (dtd.complete) {
+	const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
+	if (!name)
+	  return XML_ERROR_NO_MEMORY;
+	declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+				      name, sizeof(ENTITY));
+	if (!declEntity)
+	  return XML_ERROR_NO_MEMORY;
+	if (declEntity->name != name) {
+	  poolDiscard(&dtd.pool);
+	  declEntity = 0;
+	}
+	else {
+	  poolFinish(&dtd.pool);
+	  declEntity->publicId = 0;
+	  declEntity->is_param = 1;
+	}
+      }
+#else /* not XML_DTD */
+      declEntity = 0;
+#endif /* not XML_DTD */
+      break;
+    case XML_ROLE_NOTATION_NAME:
+      declNotationPublicId = 0;
+      declNotationName = 0;
+      if (notationDeclHandler) {
+	declNotationName = poolStoreString(&tempPool, enc, s, next);
+	if (!declNotationName)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&tempPool);
+      }
+      break;
+    case XML_ROLE_NOTATION_PUBLIC_ID:
+      if (!XmlIsPublicId(enc, s, next, eventPP))
+	return XML_ERROR_SYNTAX;
+      if (declNotationName) {
+	XML_Char *tem = poolStoreString(&tempPool,
+	                                enc,
+					s + enc->minBytesPerChar,
+	  				next - enc->minBytesPerChar);
+	if (!tem)
+	  return XML_ERROR_NO_MEMORY;
+	normalizePublicId(tem);
+	declNotationPublicId = tem;
+	poolFinish(&tempPool);
+      }
+      break;
+    case XML_ROLE_NOTATION_SYSTEM_ID:
+      if (declNotationName && notationDeclHandler) {
+	const XML_Char *systemId
+	  = poolStoreString(&tempPool, enc,
+			    s + enc->minBytesPerChar,
+	  		    next - enc->minBytesPerChar);
+	if (!systemId)
+	  return XML_ERROR_NO_MEMORY;
+	*eventEndPP = s;
+	notationDeclHandler(handlerArg,
+			    declNotationName,
+			    curBase,
+			    systemId,
+			    declNotationPublicId);
+      }
+      poolClear(&tempPool);
+      break;
+    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
+      if (declNotationPublicId && notationDeclHandler) {
+	*eventEndPP = s;
+	notationDeclHandler(handlerArg,
+			    declNotationName,
+			    curBase,
+			    0,
+			    declNotationPublicId);
+      }
+      poolClear(&tempPool);
+      break;
+    case XML_ROLE_ERROR:
+      switch (tok) {
+      case XML_TOK_PARAM_ENTITY_REF:
+	return XML_ERROR_PARAM_ENTITY_REF;
+      case XML_TOK_XML_DECL:
+	return XML_ERROR_MISPLACED_XML_PI;
+      default:
+	return XML_ERROR_SYNTAX;
+      }
+#ifdef XML_DTD
+    case XML_ROLE_IGNORE_SECT:
+      {
+	enum XML_Error result;
+	if (defaultHandler)
+	  reportDefault(parser, enc, s, next);
+	result = doIgnoreSection(parser, enc, &next, end, nextPtr);
+	if (!next) {
+	  processor = ignoreSectionProcessor;
+	  return result;
+	}
+      }
+      break;
+#endif /* XML_DTD */
+    case XML_ROLE_GROUP_OPEN:
+      if (prologState.level >= groupSize) {

[... 1596 lines stripped ...]


Mime
View raw message