]> git.proxmox.com Git - mirror_edk2.git/commitdiff
AppPkg/Applications/Python: Add support for the pyexpat module.
authordarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 18 Jan 2013 20:36:27 +0000 (20:36 +0000)
committerdarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 18 Jan 2013 20:36:27 +0000 (20:36 +0000)
Add required flags to [BuildOptions] in PythonCore.inf.
Add initialization routine to Efi/config.c.
Alter #include targets if building for UEFI in expat_external.h and xmlparse.c.
Add expat modifications to PyMod-2.7.2/Modules/expat.

Contributed-under: TianoCore Contribution Agreement 1.0
Submitted-by: Duane Voth <duanev@gmail.com>
Signed-off-by: daryl.mcdaniel@intel.com
Reviewed-by: duanev@gmail.com
Reviewed-by: daryl.mcdaniel@intel.com
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14071 6f19259b-4bc3-4df7-8a09-765794883524

AppPkg/Applications/Python/Efi/config.c
AppPkg/Applications/Python/PyMod-2.7.2/Modules/expat/expat_external.h [new file with mode: 0644]
AppPkg/Applications/Python/PyMod-2.7.2/Modules/expat/xmlparse.c [new file with mode: 0644]
AppPkg/Applications/Python/Python-2.7.2/Modules/expat/expat_external.h
AppPkg/Applications/Python/Python-2.7.2/Modules/expat/xmlparse.c
AppPkg/Applications/Python/PythonCore.inf

index 7ae26319bd09c40a24e649cc0160dee3fb273851..7cc021c964b52287bd2c535412744c0473319186 100644 (file)
 #include "Python.h"\r
 \r
 extern void initarray(void);\r
+extern void init_ast(void);\r
 extern void initbinascii(void);\r
+extern void init_bisect(void);\r
 extern void initcmath(void);\r
+extern void init_codecs(void);\r
+extern void init_collections(void);\r
+extern void initcPickle(void);\r
+extern void initcStringIO(void);\r
+extern void init_csv(void);\r
+extern void init_ctypes(void);\r
+extern void initdatetime(void);\r
+extern void initedk2(void);\r
 extern void initerrno(void);\r
+extern void init_functools(void);\r
 extern void initfuture_builtins(void);\r
 extern void initgc(void);\r
+extern void init_heapq(void);\r
+extern void init_hotshot(void);\r
+extern void initimp(void);\r
+extern void init_io(void);\r
+extern void inititertools(void);\r
+extern void init_json(void);\r
+extern void init_lsprof(void);\r
 extern void initmath(void);\r
 extern void init_md5(void);\r
-extern void initedk2(void);\r
+extern void initmmap(void);\r
 extern void initoperator(void);\r
-extern void initsignal(void);\r
+extern void initparser(void);\r
+extern void initpyexpat(void);\r
+extern void init_random(void);\r
+extern void initselect(void);\r
 extern void init_sha(void);\r
 extern void init_sha256(void);\r
 extern void init_sha512(void);\r
+extern void initsignal(void);\r
+extern void init_socket(void);\r
+extern void init_sre(void);\r
 extern void initstrop(void);\r
-extern void inittime(void);\r
+extern void init_struct(void);\r
+extern void init_subprocess(void);\r
+extern void init_symtable(void);\r
 extern void initthread(void);\r
-extern void initcStringIO(void);\r
-extern void initcPickle(void);\r
-extern void init_codecs(void);\r
+extern void inittime(void);\r
+extern void initunicodedata(void);\r
 extern void init_weakref(void);\r
-extern void init_hotshot(void);\r
+extern void init_winreg(void);\r
 extern void initxxsubtype(void);\r
 extern void initzipimport(void);\r
-extern void init_random(void);\r
-extern void inititertools(void);\r
-extern void init_collections(void);\r
-extern void init_heapq(void);\r
-extern void init_bisect(void);\r
-extern void init_symtable(void);\r
-extern void initmmap(void);\r
-extern void init_csv(void);\r
-extern void init_sre(void);\r
-extern void initparser(void);\r
-extern void init_winreg(void);\r
-extern void init_struct(void);\r
-extern void initdatetime(void);\r
-extern void init_functools(void);\r
-extern void init_json(void);\r
 extern void initzlib(void);\r
 \r
+extern void PyMarshal_Init(void);\r
+extern void _PyWarnings_Init(void);\r
+\r
 extern void init_multibytecodec(void);\r
 extern void init_codecs_cn(void);\r
 extern void init_codecs_hk(void);\r
@@ -64,26 +77,13 @@ extern void init_codecs_iso2022(void);
 extern void init_codecs_jp(void);\r
 extern void init_codecs_kr(void);\r
 extern void init_codecs_tw(void);\r
-extern void init_subprocess(void);\r
-extern void init_lsprof(void);\r
-extern void init_ast(void);\r
-extern void init_io(void);\r
-extern void _PyWarnings_Init(void);\r
-\r
-extern void init_socket(void);\r
-extern void initselect(void);\r
-\r
-extern void PyMarshal_Init(void);\r
-extern void initimp(void);\r
-extern void initunicodedata(void);\r
-extern void init_ctypes(void);\r
 \r
 struct _inittab _PyImport_Inittab[] = {\r
 \r
     //{"_ast", init_ast},\r
-    //{"_bisect", init_bisect},                   /* A fast version of bisect.py */\r
+    //{"_bisect", init_bisect},               /* A fast version of bisect.py */\r
     //{"_csv", init_csv},\r
-    //{"_heapq", init_heapq},                     /* A fast version of heapq.py */\r
+    //{"_heapq", init_heapq},                 /* A fast version of heapq.py */\r
     //{"_io", init_io},\r
     //{"_json", init_json},\r
     //{"_md5", init_md5},\r
@@ -99,9 +99,10 @@ struct _inittab _PyImport_Inittab[] = {
     //{"datetime", initdatetime},\r
     //{"future_builtins", initfuture_builtins},\r
     //{"parser", initparser},\r
+    //{"pyexpat", initpyexpat},\r
     //{"select", initselect},\r
     //{"signal", initsignal},\r
-    //{"strop", initstrop},                       /* redefines some string operations that are 100-1000 times faster */\r
+    //{"strop", initstrop},                   /* redefines some string operations that are 100-1000 times faster */\r
     //{"unicodedata", initunicodedata},\r
     //{"xxsubtype", initxxsubtype},\r
     //{"zipimport", initzipimport},\r
diff --git a/AppPkg/Applications/Python/PyMod-2.7.2/Modules/expat/expat_external.h b/AppPkg/Applications/Python/PyMod-2.7.2/Modules/expat/expat_external.h
new file mode 100644 (file)
index 0000000..b739595
--- /dev/null
@@ -0,0 +1,121 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd\r
+   See the file COPYING for copying permission.\r
+*/\r
+\r
+#ifndef Expat_External_INCLUDED\r
+#define Expat_External_INCLUDED 1\r
+\r
+/* External API definitions */\r
+\r
+/* Namespace external symbols to allow multiple libexpat version to\r
+   co-exist. */\r
+#if !defined(UEFI_C_SOURCE)\r
+  #include "pyexpatns.h"\r
+#endif\r
+\r
+#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)\r
+#define XML_USE_MSC_EXTENSIONS 1\r
+#endif\r
+\r
+/* Expat tries very hard to make the API boundary very specifically\r
+   defined.  There are two macros defined to control this boundary;\r
+   each of these can be defined before including this header to\r
+   achieve some different behavior, but doing so it not recommended or\r
+   tested frequently.\r
+\r
+   XMLCALL    - The calling convention to use for all calls across the\r
+                "library boundary."  This will default to cdecl, and\r
+                try really hard to tell the compiler that's what we\r
+                want.\r
+\r
+   XMLIMPORT  - Whatever magic is needed to note that a function is\r
+                to be imported from a dynamically loaded library\r
+                (.dll, .so, or .sl, depending on your platform).\r
+\r
+   The XMLCALL macro was added in Expat 1.95.7.  The only one which is\r
+   expected to be directly useful in client code is XMLCALL.\r
+\r
+   Note that on at least some Unix versions, the Expat library must be\r
+   compiled with the cdecl calling convention as the default since\r
+   system headers may assume the cdecl convention.\r
+*/\r
+#ifndef XMLCALL\r
+#if defined(XML_USE_MSC_EXTENSIONS)\r
+#define XMLCALL __cdecl\r
+#elif defined(__GNUC__) && defined(__i386)\r
+#define XMLCALL __attribute__((cdecl))\r
+#else\r
+/* For any platform which uses this definition and supports more than\r
+   one calling convention, we need to extend this definition to\r
+   declare the convention used on that platform, if it's possible to\r
+   do so.\r
+\r
+   If this is the case for your platform, please file a bug report\r
+   with information on how to identify your platform via the C\r
+   pre-processor and how to specify the same calling convention as the\r
+   platform's malloc() implementation.\r
+*/\r
+#define XMLCALL\r
+#endif\r
+#endif  /* not defined XMLCALL */\r
+\r
+\r
+#if !defined(XML_STATIC) && !defined(XMLIMPORT)\r
+#ifndef XML_BUILDING_EXPAT\r
+/* using Expat from an application */\r
+\r
+#ifdef XML_USE_MSC_EXTENSIONS\r
+#define XMLIMPORT __declspec(dllimport)\r
+#endif\r
+\r
+#endif\r
+#endif  /* not defined XML_STATIC */\r
+\r
+\r
+/* If we didn't define it above, define it away: */\r
+#ifndef XMLIMPORT\r
+#define XMLIMPORT\r
+#endif\r
+\r
+\r
+#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#ifdef XML_UNICODE_WCHAR_T\r
+#define XML_UNICODE\r
+#endif\r
+\r
+#ifdef XML_UNICODE     /* Information is UTF-16 encoded. */\r
+#ifdef XML_UNICODE_WCHAR_T\r
+typedef wchar_t XML_Char;\r
+typedef wchar_t XML_LChar;\r
+#else\r
+typedef unsigned short XML_Char;\r
+typedef char XML_LChar;\r
+#endif /* XML_UNICODE_WCHAR_T */\r
+#else                  /* Information is UTF-8 encoded. */\r
+typedef char XML_Char;\r
+typedef char XML_LChar;\r
+#endif /* XML_UNICODE */\r
+\r
+#ifdef XML_LARGE_SIZE  /* Use large integers for file/stream positions. */\r
+#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400\r
+typedef __int64 XML_Index; \r
+typedef unsigned __int64 XML_Size;\r
+#else\r
+typedef long long XML_Index;\r
+typedef unsigned long long XML_Size;\r
+#endif\r
+#else\r
+typedef long XML_Index;\r
+typedef unsigned long XML_Size;\r
+#endif /* XML_LARGE_SIZE */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* not Expat_External_INCLUDED */\r
diff --git a/AppPkg/Applications/Python/PyMod-2.7.2/Modules/expat/xmlparse.c b/AppPkg/Applications/Python/PyMod-2.7.2/Modules/expat/xmlparse.c
new file mode 100644 (file)
index 0000000..e303c7a
--- /dev/null
@@ -0,0 +1,6279 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd\r
+   See the file COPYING for copying permission.\r
+*/\r
+\r
+#define XML_BUILDING_EXPAT 1\r
+\r
+#ifdef COMPILED_FROM_DSP\r
+#include "winconfig.h"\r
+#elif defined(MACOS_CLASSIC)\r
+#include "macconfig.h"\r
+#elif defined(__amigaos4__)\r
+#include "amigaconfig.h"\r
+#elif defined(HAVE_EXPAT_CONFIG_H)\r
+#include <expat_config.h>\r
+#endif /* ndef COMPILED_FROM_DSP */\r
+\r
+#include <stddef.h>\r
+#include <string.h>                     /* memset(), memcpy() */\r
+#include <assert.h>\r
+\r
+#if defined(UEFI_C_SOURCE)\r
+  #include <expat/expat.h>\r
+#else\r
+  #include "expat.h"\r
+#endif\r
+\r
+#ifdef XML_UNICODE\r
+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX\r
+#define XmlConvert XmlUtf16Convert\r
+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding\r
+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS\r
+#define XmlEncode XmlUtf16Encode\r
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))\r
+typedef unsigned short ICHAR;\r
+#else\r
+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX\r
+#define XmlConvert XmlUtf8Convert\r
+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding\r
+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS\r
+#define XmlEncode XmlUtf8Encode\r
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)\r
+typedef char ICHAR;\r
+#endif\r
+\r
+\r
+#ifndef XML_NS\r
+\r
+#define XmlInitEncodingNS XmlInitEncoding\r
+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding\r
+#undef XmlGetInternalEncodingNS\r
+#define XmlGetInternalEncodingNS XmlGetInternalEncoding\r
+#define XmlParseXmlDeclNS XmlParseXmlDecl\r
+\r
+#endif\r
+\r
+#ifdef XML_UNICODE\r
+\r
+#ifdef XML_UNICODE_WCHAR_T\r
+#define XML_T(x) (const wchar_t)x\r
+#define XML_L(x) L ## x\r
+#else\r
+#define XML_T(x) (const unsigned short)x\r
+#define XML_L(x) x\r
+#endif\r
+\r
+#else\r
+\r
+#define XML_T(x) x\r
+#define XML_L(x) x\r
+\r
+#endif\r
+\r
+/* Round up n to be a multiple of sz, where sz is a power of 2. */\r
+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))\r
+\r
+/* Handle the case where memmove() doesn't exist. */\r
+#ifndef HAVE_MEMMOVE\r
+#ifdef HAVE_BCOPY\r
+#define memmove(d,s,l) bcopy((s),(d),(l))\r
+#else\r
+#error memmove does not exist on this platform, nor is a substitute available\r
+#endif /* HAVE_BCOPY */\r
+#endif /* HAVE_MEMMOVE */\r
+\r
+#include "internal.h"\r
+#include "xmltok.h"\r
+#include "xmlrole.h"\r
+\r
+typedef const XML_Char *KEY;\r
+\r
+typedef struct {\r
+  KEY name;\r
+} NAMED;\r
+\r
+typedef struct {\r
+  NAMED **v;\r
+  unsigned char power;\r
+  size_t size;\r
+  size_t used;\r
+  const XML_Memory_Handling_Suite *mem;\r
+} HASH_TABLE;\r
+\r
+/* Basic character hash algorithm, taken from Python's string hash:\r
+   h = h * 1000003 ^ character, the constant being a prime number.\r
+\r
+*/\r
+#ifdef XML_UNICODE\r
+#define CHAR_HASH(h, c) \\r
+  (((h) * 0xF4243) ^ (unsigned short)(c))\r
+#else\r
+#define CHAR_HASH(h, c) \\r
+  (((h) * 0xF4243) ^ (unsigned char)(c))\r
+#endif\r
+\r
+/* For probing (after a collision) we need a step size relative prime\r
+   to the hash table size, which is a power of 2. We use double-hashing,\r
+   since we can calculate a second hash value cheaply by taking those bits\r
+   of the first hash value that were discarded (masked out) when the table\r
+   index was calculated: index = hash & mask, where mask = table->size - 1.\r
+   We limit the maximum step size to table->size / 4 (mask >> 2) and make\r
+   it odd, since odd numbers are always relative prime to a power of 2.\r
+*/\r
+#define SECOND_HASH(hash, mask, power) \\r
+  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))\r
+#define PROBE_STEP(hash, mask, power) \\r
+  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))\r
+\r
+typedef struct {\r
+  NAMED **p;\r
+  NAMED **end;\r
+} HASH_TABLE_ITER;\r
+\r
+#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */\r
+#define INIT_DATA_BUF_SIZE 1024\r
+#define INIT_ATTS_SIZE 16\r
+#define INIT_ATTS_VERSION 0xFFFFFFFF\r
+#define INIT_BLOCK_SIZE 1024\r
+#define INIT_BUFFER_SIZE 1024\r
+\r
+#define EXPAND_SPARE 24\r
+\r
+typedef struct binding {\r
+  struct prefix *prefix;\r
+  struct binding *nextTagBinding;\r
+  struct binding *prevPrefixBinding;\r
+  const struct attribute_id *attId;\r
+  XML_Char *uri;\r
+  int uriLen;\r
+  int uriAlloc;\r
+} BINDING;\r
+\r
+typedef struct prefix {\r
+  const XML_Char *name;\r
+  BINDING *binding;\r
+} PREFIX;\r
+\r
+typedef struct {\r
+  const XML_Char *str;\r
+  const XML_Char *localPart;\r
+  const XML_Char *prefix;\r
+  int strLen;\r
+  int uriLen;\r
+  int prefixLen;\r
+} TAG_NAME;\r
+\r
+/* TAG represents an open element.\r
+   The name of the element is stored in both the document and API\r
+   encodings.  The memory buffer 'buf' is a separately-allocated\r
+   memory area which stores the name.  During the XML_Parse()/\r
+   XMLParseBuffer() when the element is open, the memory for the 'raw'\r
+   version of the name (in the document encoding) is shared with the\r
+   document buffer.  If the element is open across calls to\r
+   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to\r
+   contain the 'raw' name as well.\r
+\r
+   A parser re-uses these structures, maintaining a list of allocated\r
+   TAG objects in a free list.\r
+*/\r
+typedef struct tag {\r
+  struct tag *parent;           /* parent of this element */\r
+  const char *rawName;          /* tagName in the original encoding */\r
+  int rawNameLength;\r
+  TAG_NAME name;                /* tagName in the API encoding */\r
+  char *buf;                    /* buffer for name components */\r
+  char *bufEnd;                 /* end of the buffer */\r
+  BINDING *bindings;\r
+} TAG;\r
+\r
+typedef struct {\r
+  const XML_Char *name;\r
+  const XML_Char *textPtr;\r
+  int textLen;                  /* length in XML_Chars */\r
+  int processed;                /* # of processed bytes - when suspended */\r
+  const XML_Char *systemId;\r
+  const XML_Char *base;\r
+  const XML_Char *publicId;\r
+  const XML_Char *notation;\r
+  XML_Bool open;\r
+  XML_Bool is_param;\r
+  XML_Bool is_internal; /* true if declared in internal subset outside PE */\r
+} ENTITY;\r
+\r
+typedef struct {\r
+  enum XML_Content_Type         type;\r
+  enum XML_Content_Quant        quant;\r
+  const XML_Char *              name;\r
+  int                           firstchild;\r
+  int                           lastchild;\r
+  int                           childcnt;\r
+  int                           nextsib;\r
+} CONTENT_SCAFFOLD;\r
+\r
+#define INIT_SCAFFOLD_ELEMENTS 32\r
+\r
+typedef struct block {\r
+  struct block *next;\r
+  int size;\r
+  XML_Char s[1];\r
+} BLOCK;\r
+\r
+typedef struct {\r
+  BLOCK *blocks;\r
+  BLOCK *freeBlocks;\r
+  const XML_Char *end;\r
+  XML_Char *ptr;\r
+  XML_Char *start;\r
+  const XML_Memory_Handling_Suite *mem;\r
+} STRING_POOL;\r
+\r
+/* The XML_Char before the name is used to determine whether\r
+   an attribute has been specified. */\r
+typedef struct attribute_id {\r
+  XML_Char *name;\r
+  PREFIX *prefix;\r
+  XML_Bool maybeTokenized;\r
+  XML_Bool xmlns;\r
+} ATTRIBUTE_ID;\r
+\r
+typedef struct {\r
+  const ATTRIBUTE_ID *id;\r
+  XML_Bool isCdata;\r
+  const XML_Char *value;\r
+} DEFAULT_ATTRIBUTE;\r
+\r
+typedef struct {\r
+  unsigned long version;\r
+  unsigned long hash;\r
+  const XML_Char *uriName;\r
+} NS_ATT;\r
+\r
+typedef struct {\r
+  const XML_Char *name;\r
+  PREFIX *prefix;\r
+  const ATTRIBUTE_ID *idAtt;\r
+  int nDefaultAtts;\r
+  int allocDefaultAtts;\r
+  DEFAULT_ATTRIBUTE *defaultAtts;\r
+} ELEMENT_TYPE;\r
+\r
+typedef struct {\r
+  HASH_TABLE generalEntities;\r
+  HASH_TABLE elementTypes;\r
+  HASH_TABLE attributeIds;\r
+  HASH_TABLE prefixes;\r
+  STRING_POOL pool;\r
+  STRING_POOL entityValuePool;\r
+  /* false once a parameter entity reference has been skipped */\r
+  XML_Bool keepProcessing;\r
+  /* true once an internal or external PE reference has been encountered;\r
+     this includes the reference to an external subset */\r
+  XML_Bool hasParamEntityRefs;\r
+  XML_Bool standalone;\r
+#ifdef XML_DTD\r
+  /* indicates if external PE has been read */\r
+  XML_Bool paramEntityRead;\r
+  HASH_TABLE paramEntities;\r
+#endif /* XML_DTD */\r
+  PREFIX defaultPrefix;\r
+  /* === scaffolding for building content model === */\r
+  XML_Bool in_eldecl;\r
+  CONTENT_SCAFFOLD *scaffold;\r
+  unsigned contentStringLen;\r
+  unsigned scaffSize;\r
+  unsigned scaffCount;\r
+  int scaffLevel;\r
+  int *scaffIndex;\r
+} DTD;\r
+\r
+typedef struct open_internal_entity {\r
+  const char *internalEventPtr;\r
+  const char *internalEventEndPtr;\r
+  struct open_internal_entity *next;\r
+  ENTITY *entity;\r
+  int startTagLevel;\r
+  XML_Bool betweenDecl; /* WFC: PE Between Declarations */\r
+} OPEN_INTERNAL_ENTITY;\r
+\r
+typedef enum XML_Error PTRCALL Processor(XML_Parser parser,\r
+                                         const char *start,\r
+                                         const char *end,\r
+                                         const char **endPtr);\r
+\r
+static Processor prologProcessor;\r
+static Processor prologInitProcessor;\r
+static Processor contentProcessor;\r
+static Processor cdataSectionProcessor;\r
+#ifdef XML_DTD\r
+static Processor ignoreSectionProcessor;\r
+static Processor externalParEntProcessor;\r
+static Processor externalParEntInitProcessor;\r
+static Processor entityValueProcessor;\r
+static Processor entityValueInitProcessor;\r
+#endif /* XML_DTD */\r
+static Processor epilogProcessor;\r
+static Processor errorProcessor;\r
+static Processor externalEntityInitProcessor;\r
+static Processor externalEntityInitProcessor2;\r
+static Processor externalEntityInitProcessor3;\r
+static Processor externalEntityContentProcessor;\r
+static Processor internalEntityProcessor;\r
+\r
+static enum XML_Error\r
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);\r
+static enum XML_Error\r
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,\r
+               const char *s, const char *next);\r
+static enum XML_Error\r
+initializeEncoding(XML_Parser parser);\r
+static enum XML_Error\r
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s,\r
+         const char *end, int tok, const char *next, const char **nextPtr,\r
+         XML_Bool haveMore);\r
+static enum XML_Error\r
+processInternalEntity(XML_Parser parser, ENTITY *entity,\r
+                      XML_Bool betweenDecl);\r
+static enum XML_Error\r
+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,\r
+          const char *start, const char *end, const char **endPtr,\r
+          XML_Bool haveMore);\r
+static enum XML_Error\r
+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,\r
+               const char *end, const char **nextPtr, XML_Bool haveMore);\r
+#ifdef XML_DTD\r
+static enum XML_Error\r
+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,\r
+                const char *end, const char **nextPtr, XML_Bool haveMore);\r
+#endif /* XML_DTD */\r
+\r
+static enum XML_Error\r
+storeAtts(XML_Parser parser, const ENCODING *, const char *s,\r
+          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);\r
+static enum XML_Error\r
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,\r
+           const XML_Char *uri, BINDING **bindingsPtr);\r
+static int\r
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,\r
+                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);\r
+static enum XML_Error\r
+storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,\r
+                    const char *, const char *, STRING_POOL *);\r
+static enum XML_Error\r
+appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,\r
+                     const char *, const char *, STRING_POOL *);\r
+static ATTRIBUTE_ID *\r
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,\r
+               const char *end);\r
+static int\r
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);\r
+static enum XML_Error\r
+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,\r
+                 const char *end);\r
+static int\r
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,\r
+                            const char *start, const char *end);\r
+static int\r
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start,\r
+              const char *end);\r
+static void\r
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,\r
+              const char *end);\r
+\r
+static const XML_Char * getContext(XML_Parser parser);\r
+static XML_Bool\r
+setContext(XML_Parser parser, const XML_Char *context);\r
+\r
+static void FASTCALL normalizePublicId(XML_Char *s);\r
+\r
+static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);\r
+/* do not call if parentParser != NULL */\r
+static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);\r
+static void\r
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);\r
+static int\r
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);\r
+static int\r
+copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);\r
+\r
+static NAMED *\r
+lookup(HASH_TABLE *table, KEY name, size_t createSize);\r
+static void FASTCALL\r
+hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);\r
+static void FASTCALL hashTableClear(HASH_TABLE *);\r
+static void FASTCALL hashTableDestroy(HASH_TABLE *);\r
+static void FASTCALL\r
+hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);\r
+static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);\r
+\r
+static void FASTCALL\r
+poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);\r
+static void FASTCALL poolClear(STRING_POOL *);\r
+static void FASTCALL poolDestroy(STRING_POOL *);\r
+static XML_Char *\r
+poolAppend(STRING_POOL *pool, const ENCODING *enc,\r
+           const char *ptr, const char *end);\r
+static XML_Char *\r
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,\r
+                const char *ptr, const char *end);\r
+static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);\r
+static const XML_Char * FASTCALL\r
+poolCopyString(STRING_POOL *pool, const XML_Char *s);\r
+static const XML_Char *\r
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);\r
+static const XML_Char * FASTCALL\r
+poolAppendString(STRING_POOL *pool, const XML_Char *s);\r
+\r
+static int FASTCALL nextScaffoldPart(XML_Parser parser);\r
+static XML_Content * build_model(XML_Parser parser);\r
+static ELEMENT_TYPE *\r
+getElementType(XML_Parser parser, const ENCODING *enc,\r
+               const char *ptr, const char *end);\r
+\r
+static XML_Parser\r
+parserCreate(const XML_Char *encodingName,\r
+             const XML_Memory_Handling_Suite *memsuite,\r
+             const XML_Char *nameSep,\r
+             DTD *dtd);\r
+static void\r
+parserInit(XML_Parser parser, const XML_Char *encodingName);\r
+\r
+#define poolStart(pool) ((pool)->start)\r
+#define poolEnd(pool) ((pool)->ptr)\r
+#define poolLength(pool) ((pool)->ptr - (pool)->start)\r
+#define poolChop(pool) ((void)--(pool->ptr))\r
+#define poolLastChar(pool) (((pool)->ptr)[-1])\r
+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)\r
+#define poolFinish(pool) ((pool)->start = (pool)->ptr)\r
+#define poolAppendChar(pool, c) \\r
+  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \\r
+   ? 0 \\r
+   : ((*((pool)->ptr)++ = c), 1))\r
+\r
+struct XML_ParserStruct {\r
+  /* The first member must be userData so that the XML_GetUserData\r
+     macro works. */\r
+  void *m_userData;\r
+  void *m_handlerArg;\r
+  char *m_buffer;\r
+  const XML_Memory_Handling_Suite m_mem;\r
+  /* first character to be parsed */\r
+  const char *m_bufferPtr;\r
+  /* past last character to be parsed */\r
+  char *m_bufferEnd;\r
+  /* allocated end of buffer */\r
+  const char *m_bufferLim;\r
+  XML_Index m_parseEndByteIndex;\r
+  const char *m_parseEndPtr;\r
+  XML_Char *m_dataBuf;\r
+  XML_Char *m_dataBufEnd;\r
+  XML_StartElementHandler m_startElementHandler;\r
+  XML_EndElementHandler m_endElementHandler;\r
+  XML_CharacterDataHandler m_characterDataHandler;\r
+  XML_ProcessingInstructionHandler m_processingInstructionHandler;\r
+  XML_CommentHandler m_commentHandler;\r
+  XML_StartCdataSectionHandler m_startCdataSectionHandler;\r
+  XML_EndCdataSectionHandler m_endCdataSectionHandler;\r
+  XML_DefaultHandler m_defaultHandler;\r
+  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;\r
+  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;\r
+  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;\r
+  XML_NotationDeclHandler m_notationDeclHandler;\r
+  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;\r
+  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;\r
+  XML_NotStandaloneHandler m_notStandaloneHandler;\r
+  XML_ExternalEntityRefHandler m_externalEntityRefHandler;\r
+  XML_Parser m_externalEntityRefHandlerArg;\r
+  XML_SkippedEntityHandler m_skippedEntityHandler;\r
+  XML_UnknownEncodingHandler m_unknownEncodingHandler;\r
+  XML_ElementDeclHandler m_elementDeclHandler;\r
+  XML_AttlistDeclHandler m_attlistDeclHandler;\r
+  XML_EntityDeclHandler m_entityDeclHandler;\r
+  XML_XmlDeclHandler m_xmlDeclHandler;\r
+  const ENCODING *m_encoding;\r
+  INIT_ENCODING m_initEncoding;\r
+  const ENCODING *m_internalEncoding;\r
+  const XML_Char *m_protocolEncodingName;\r
+  XML_Bool m_ns;\r
+  XML_Bool m_ns_triplets;\r
+  void *m_unknownEncodingMem;\r
+  void *m_unknownEncodingData;\r
+  void *m_unknownEncodingHandlerData;\r
+  void (XMLCALL *m_unknownEncodingRelease)(void *);\r
+  PROLOG_STATE m_prologState;\r
+  Processor *m_processor;\r
+  enum XML_Error m_errorCode;\r
+  const char *m_eventPtr;\r
+  const char *m_eventEndPtr;\r
+  const char *m_positionPtr;\r
+  OPEN_INTERNAL_ENTITY *m_openInternalEntities;\r
+  OPEN_INTERNAL_ENTITY *m_freeInternalEntities;\r
+  XML_Bool m_defaultExpandInternalEntities;\r
+  int m_tagLevel;\r
+  ENTITY *m_declEntity;\r
+  const XML_Char *m_doctypeName;\r
+  const XML_Char *m_doctypeSysid;\r
+  const XML_Char *m_doctypePubid;\r
+  const XML_Char *m_declAttributeType;\r
+  const XML_Char *m_declNotationName;\r
+  const XML_Char *m_declNotationPublicId;\r
+  ELEMENT_TYPE *m_declElementType;\r
+  ATTRIBUTE_ID *m_declAttributeId;\r
+  XML_Bool m_declAttributeIsCdata;\r
+  XML_Bool m_declAttributeIsId;\r
+  DTD *m_dtd;\r
+  const XML_Char *m_curBase;\r
+  TAG *m_tagStack;\r
+  TAG *m_freeTagList;\r
+  BINDING *m_inheritedBindings;\r
+  BINDING *m_freeBindingList;\r
+  int m_attsSize;\r
+  int m_nSpecifiedAtts;\r
+  int m_idAttIndex;\r
+  ATTRIBUTE *m_atts;\r
+  NS_ATT *m_nsAtts;\r
+  unsigned long m_nsAttsVersion;\r
+  unsigned char m_nsAttsPower;\r
+  POSITION m_position;\r
+  STRING_POOL m_tempPool;\r
+  STRING_POOL m_temp2Pool;\r
+  char *m_groupConnector;\r
+  unsigned int m_groupSize;\r
+  XML_Char m_namespaceSeparator;\r
+  XML_Parser m_parentParser;\r
+  XML_ParsingStatus m_parsingStatus;\r
+#ifdef XML_DTD\r
+  XML_Bool m_isParamEntity;\r
+  XML_Bool m_useForeignDTD;\r
+  enum XML_ParamEntityParsing m_paramEntityParsing;\r
+#endif\r
+};\r
+\r
+#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))\r
+#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))\r
+#define FREE(p) (parser->m_mem.free_fcn((p)))\r
+\r
+#define userData (parser->m_userData)\r
+#define handlerArg (parser->m_handlerArg)\r
+#define startElementHandler (parser->m_startElementHandler)\r
+#define endElementHandler (parser->m_endElementHandler)\r
+#define characterDataHandler (parser->m_characterDataHandler)\r
+#define processingInstructionHandler \\r
+        (parser->m_processingInstructionHandler)\r
+#define commentHandler (parser->m_commentHandler)\r
+#define startCdataSectionHandler \\r
+        (parser->m_startCdataSectionHandler)\r
+#define endCdataSectionHandler (parser->m_endCdataSectionHandler)\r
+#define defaultHandler (parser->m_defaultHandler)\r
+#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)\r
+#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)\r
+#define unparsedEntityDeclHandler \\r
+        (parser->m_unparsedEntityDeclHandler)\r
+#define notationDeclHandler (parser->m_notationDeclHandler)\r
+#define startNamespaceDeclHandler \\r
+        (parser->m_startNamespaceDeclHandler)\r
+#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)\r
+#define notStandaloneHandler (parser->m_notStandaloneHandler)\r
+#define externalEntityRefHandler \\r
+        (parser->m_externalEntityRefHandler)\r
+#define externalEntityRefHandlerArg \\r
+        (parser->m_externalEntityRefHandlerArg)\r
+#define internalEntityRefHandler \\r
+        (parser->m_internalEntityRefHandler)\r
+#define skippedEntityHandler (parser->m_skippedEntityHandler)\r
+#define unknownEncodingHandler (parser->m_unknownEncodingHandler)\r
+#define elementDeclHandler (parser->m_elementDeclHandler)\r
+#define attlistDeclHandler (parser->m_attlistDeclHandler)\r
+#define entityDeclHandler (parser->m_entityDeclHandler)\r
+#define xmlDeclHandler (parser->m_xmlDeclHandler)\r
+#define encoding (parser->m_encoding)\r
+#define initEncoding (parser->m_initEncoding)\r
+#define internalEncoding (parser->m_internalEncoding)\r
+#define unknownEncodingMem (parser->m_unknownEncodingMem)\r
+#define unknownEncodingData (parser->m_unknownEncodingData)\r
+#define unknownEncodingHandlerData \\r
+  (parser->m_unknownEncodingHandlerData)\r
+#define unknownEncodingRelease (parser->m_unknownEncodingRelease)\r
+#define protocolEncodingName (parser->m_protocolEncodingName)\r
+#define ns (parser->m_ns)\r
+#define ns_triplets (parser->m_ns_triplets)\r
+#define prologState (parser->m_prologState)\r
+#define processor (parser->m_processor)\r
+#define errorCode (parser->m_errorCode)\r
+#define eventPtr (parser->m_eventPtr)\r
+#define eventEndPtr (parser->m_eventEndPtr)\r
+#define positionPtr (parser->m_positionPtr)\r
+#define position (parser->m_position)\r
+#define openInternalEntities (parser->m_openInternalEntities)\r
+#define freeInternalEntities (parser->m_freeInternalEntities)\r
+#define defaultExpandInternalEntities \\r
+        (parser->m_defaultExpandInternalEntities)\r
+#define tagLevel (parser->m_tagLevel)\r
+#define buffer (parser->m_buffer)\r
+#define bufferPtr (parser->m_bufferPtr)\r
+#define bufferEnd (parser->m_bufferEnd)\r
+#define parseEndByteIndex (parser->m_parseEndByteIndex)\r
+#define parseEndPtr (parser->m_parseEndPtr)\r
+#define bufferLim (parser->m_bufferLim)\r
+#define dataBuf (parser->m_dataBuf)\r
+#define dataBufEnd (parser->m_dataBufEnd)\r
+#define _dtd (parser->m_dtd)\r
+#define curBase (parser->m_curBase)\r
+#define declEntity (parser->m_declEntity)\r
+#define doctypeName (parser->m_doctypeName)\r
+#define doctypeSysid (parser->m_doctypeSysid)\r
+#define doctypePubid (parser->m_doctypePubid)\r
+#define declAttributeType (parser->m_declAttributeType)\r
+#define declNotationName (parser->m_declNotationName)\r
+#define declNotationPublicId (parser->m_declNotationPublicId)\r
+#define declElementType (parser->m_declElementType)\r
+#define declAttributeId (parser->m_declAttributeId)\r
+#define declAttributeIsCdata (parser->m_declAttributeIsCdata)\r
+#define declAttributeIsId (parser->m_declAttributeIsId)\r
+#define freeTagList (parser->m_freeTagList)\r
+#define freeBindingList (parser->m_freeBindingList)\r
+#define inheritedBindings (parser->m_inheritedBindings)\r
+#define tagStack (parser->m_tagStack)\r
+#define atts (parser->m_atts)\r
+#define attsSize (parser->m_attsSize)\r
+#define nSpecifiedAtts (parser->m_nSpecifiedAtts)\r
+#define idAttIndex (parser->m_idAttIndex)\r
+#define nsAtts (parser->m_nsAtts)\r
+#define nsAttsVersion (parser->m_nsAttsVersion)\r
+#define nsAttsPower (parser->m_nsAttsPower)\r
+#define tempPool (parser->m_tempPool)\r
+#define temp2Pool (parser->m_temp2Pool)\r
+#define groupConnector (parser->m_groupConnector)\r
+#define groupSize (parser->m_groupSize)\r
+#define namespaceSeparator (parser->m_namespaceSeparator)\r
+#define parentParser (parser->m_parentParser)\r
+#define ps_parsing (parser->m_parsingStatus.parsing)\r
+#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)\r
+#ifdef XML_DTD\r
+#define isParamEntity (parser->m_isParamEntity)\r
+#define useForeignDTD (parser->m_useForeignDTD)\r
+#define paramEntityParsing (parser->m_paramEntityParsing)\r
+#endif /* XML_DTD */\r
+\r
+XML_Parser XMLCALL\r
+XML_ParserCreate(const XML_Char *encodingName)\r
+{\r
+  return XML_ParserCreate_MM(encodingName, NULL, NULL);\r
+}\r
+\r
+XML_Parser XMLCALL\r
+XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)\r
+{\r
+  XML_Char tmp[2];\r
+  *tmp = nsSep;\r
+  return XML_ParserCreate_MM(encodingName, NULL, tmp);\r
+}\r
+\r
+static const XML_Char implicitContext[] = {\r
+  'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',\r
+  'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',\r
+  'X', 'M', 'L', '/', '1', '9', '9', '8', '/',\r
+  'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'\r
+};\r
+\r
+XML_Parser XMLCALL\r
+XML_ParserCreate_MM(const XML_Char *encodingName,\r
+                    const XML_Memory_Handling_Suite *memsuite,\r
+                    const XML_Char *nameSep)\r
+{\r
+  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);\r
+  if (parser != NULL && ns) {\r
+    /* implicit context only set for root parser, since child\r
+       parsers (i.e. external entity parsers) will inherit it\r
+    */\r
+    if (!setContext(parser, implicitContext)) {\r
+      XML_ParserFree(parser);\r
+      return NULL;\r
+    }\r
+  }\r
+  return parser;\r
+}\r
+\r
+static XML_Parser\r
+parserCreate(const XML_Char *encodingName,\r
+             const XML_Memory_Handling_Suite *memsuite,\r
+             const XML_Char *nameSep,\r
+             DTD *dtd)\r
+{\r
+  XML_Parser parser;\r
+\r
+  if (memsuite) {\r
+    XML_Memory_Handling_Suite *mtemp;\r
+    parser = (XML_Parser)\r
+      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));\r
+    if (parser != NULL) {\r
+      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);\r
+      mtemp->malloc_fcn = memsuite->malloc_fcn;\r
+      mtemp->realloc_fcn = memsuite->realloc_fcn;\r
+      mtemp->free_fcn = memsuite->free_fcn;\r
+    }\r
+  }\r
+  else {\r
+    XML_Memory_Handling_Suite *mtemp;\r
+    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));\r
+    if (parser != NULL) {\r
+      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);\r
+      mtemp->malloc_fcn = malloc;\r
+      mtemp->realloc_fcn = realloc;\r
+      mtemp->free_fcn = free;\r
+    }\r
+  }\r
+\r
+  if (!parser)\r
+    return parser;\r
+\r
+  buffer = NULL;\r
+  bufferLim = NULL;\r
+\r
+  attsSize = INIT_ATTS_SIZE;\r
+  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));\r
+  if (atts == NULL) {\r
+    FREE(parser);\r
+    return NULL;\r
+  }\r
+  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));\r
+  if (dataBuf == NULL) {\r
+    FREE(atts);\r
+    FREE(parser);\r
+    return NULL;\r
+  }\r
+  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;\r
+\r
+  if (dtd)\r
+    _dtd = dtd;\r
+  else {\r
+    _dtd = dtdCreate(&parser->m_mem);\r
+    if (_dtd == NULL) {\r
+      FREE(dataBuf);\r
+      FREE(atts);\r
+      FREE(parser);\r
+      return NULL;\r
+    }\r
+  }\r
+\r
+  freeBindingList = NULL;\r
+  freeTagList = NULL;\r
+  freeInternalEntities = NULL;\r
+\r
+  groupSize = 0;\r
+  groupConnector = NULL;\r
+\r
+  unknownEncodingHandler = NULL;\r
+  unknownEncodingHandlerData = NULL;\r
+\r
+  namespaceSeparator = '!';\r
+  ns = XML_FALSE;\r
+  ns_triplets = XML_FALSE;\r
+\r
+  nsAtts = NULL;\r
+  nsAttsVersion = 0;\r
+  nsAttsPower = 0;\r
+\r
+  poolInit(&tempPool, &(parser->m_mem));\r
+  poolInit(&temp2Pool, &(parser->m_mem));\r
+  parserInit(parser, encodingName);\r
+\r
+  if (encodingName && !protocolEncodingName) {\r
+    XML_ParserFree(parser);\r
+    return NULL;\r
+  }\r
+\r
+  if (nameSep) {\r
+    ns = XML_TRUE;\r
+    internalEncoding = XmlGetInternalEncodingNS();\r
+    namespaceSeparator = *nameSep;\r
+  }\r
+  else {\r
+    internalEncoding = XmlGetInternalEncoding();\r
+  }\r
+\r
+  return parser;\r
+}\r
+\r
+static void\r
+parserInit(XML_Parser parser, const XML_Char *encodingName)\r
+{\r
+  processor = prologInitProcessor;\r
+  XmlPrologStateInit(&prologState);\r
+  protocolEncodingName = (encodingName != NULL\r
+                          ? poolCopyString(&tempPool, encodingName)\r
+                          : NULL);\r
+  curBase = NULL;\r
+  XmlInitEncoding(&initEncoding, &encoding, 0);\r
+  userData = NULL;\r
+  handlerArg = NULL;\r
+  startElementHandler = NULL;\r
+  endElementHandler = NULL;\r
+  characterDataHandler = NULL;\r
+  processingInstructionHandler = NULL;\r
+  commentHandler = NULL;\r
+  startCdataSectionHandler = NULL;\r
+  endCdataSectionHandler = NULL;\r
+  defaultHandler = NULL;\r
+  startDoctypeDeclHandler = NULL;\r
+  endDoctypeDeclHandler = NULL;\r
+  unparsedEntityDeclHandler = NULL;\r
+  notationDeclHandler = NULL;\r
+  startNamespaceDeclHandler = NULL;\r
+  endNamespaceDeclHandler = NULL;\r
+  notStandaloneHandler = NULL;\r
+  externalEntityRefHandler = NULL;\r
+  externalEntityRefHandlerArg = parser;\r
+  skippedEntityHandler = NULL;\r
+  elementDeclHandler = NULL;\r
+  attlistDeclHandler = NULL;\r
+  entityDeclHandler = NULL;\r
+  xmlDeclHandler = NULL;\r
+  bufferPtr = buffer;\r
+  bufferEnd = buffer;\r
+  parseEndByteIndex = 0;\r
+  parseEndPtr = NULL;\r
+  declElementType = NULL;\r
+  declAttributeId = NULL;\r
+  declEntity = NULL;\r
+  doctypeName = NULL;\r
+  doctypeSysid = NULL;\r
+  doctypePubid = NULL;\r
+  declAttributeType = NULL;\r
+  declNotationName = NULL;\r
+  declNotationPublicId = NULL;\r
+  declAttributeIsCdata = XML_FALSE;\r
+  declAttributeIsId = XML_FALSE;\r
+  memset(&position, 0, sizeof(POSITION));\r
+  errorCode = XML_ERROR_NONE;\r
+  eventPtr = NULL;\r
+  eventEndPtr = NULL;\r
+  positionPtr = NULL;\r
+  openInternalEntities = NULL;\r
+  defaultExpandInternalEntities = XML_TRUE;\r
+  tagLevel = 0;\r
+  tagStack = NULL;\r
+  inheritedBindings = NULL;\r
+  nSpecifiedAtts = 0;\r
+  unknownEncodingMem = NULL;\r
+  unknownEncodingRelease = NULL;\r
+  unknownEncodingData = NULL;\r
+  parentParser = NULL;\r
+  ps_parsing = XML_INITIALIZED;\r
+#ifdef XML_DTD\r
+  isParamEntity = XML_FALSE;\r
+  useForeignDTD = XML_FALSE;\r
+  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;\r
+#endif\r
+}\r
+\r
+/* moves list of bindings to freeBindingList */\r
+static void FASTCALL\r
+moveToFreeBindingList(XML_Parser parser, BINDING *bindings)\r
+{\r
+  while (bindings) {\r
+    BINDING *b = bindings;\r
+    bindings = bindings->nextTagBinding;\r
+    b->nextTagBinding = freeBindingList;\r
+    freeBindingList = b;\r
+  }\r
+}\r
+\r
+XML_Bool XMLCALL\r
+XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)\r
+{\r
+  TAG *tStk;\r
+  OPEN_INTERNAL_ENTITY *openEntityList;\r
+  if (parentParser)\r
+    return XML_FALSE;\r
+  /* move tagStack to freeTagList */\r
+  tStk = tagStack;\r
+  while (tStk) {\r
+    TAG *tag = tStk;\r
+    tStk = tStk->parent;\r
+    tag->parent = freeTagList;\r
+    moveToFreeBindingList(parser, tag->bindings);\r
+    tag->bindings = NULL;\r
+    freeTagList = tag;\r
+  }\r
+  /* move openInternalEntities to freeInternalEntities */\r
+  openEntityList = openInternalEntities;\r
+  while (openEntityList) {\r
+    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;\r
+    openEntityList = openEntity->next;\r
+    openEntity->next = freeInternalEntities;\r
+    freeInternalEntities = openEntity;\r
+  }\r
+  moveToFreeBindingList(parser, inheritedBindings);\r
+  FREE(unknownEncodingMem);\r
+  if (unknownEncodingRelease)\r
+    unknownEncodingRelease(unknownEncodingData);\r
+  poolClear(&tempPool);\r
+  poolClear(&temp2Pool);\r
+  parserInit(parser, encodingName);\r
+  dtdReset(_dtd, &parser->m_mem);\r
+  return setContext(parser, implicitContext);\r
+}\r
+\r
+enum XML_Status XMLCALL\r
+XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)\r
+{\r
+  /* Block after XML_Parse()/XML_ParseBuffer() has been called.\r
+     XXX There's no way for the caller to determine which of the\r
+     XXX possible error cases caused the XML_STATUS_ERROR return.\r
+  */\r
+  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)\r
+    return XML_STATUS_ERROR;\r
+  if (encodingName == NULL)\r
+    protocolEncodingName = NULL;\r
+  else {\r
+    protocolEncodingName = poolCopyString(&tempPool, encodingName);\r
+    if (!protocolEncodingName)\r
+      return XML_STATUS_ERROR;\r
+  }\r
+  return XML_STATUS_OK;\r
+}\r
+\r
+XML_Parser XMLCALL\r
+XML_ExternalEntityParserCreate(XML_Parser oldParser,\r
+                               const XML_Char *context,\r
+                               const XML_Char *encodingName)\r
+{\r
+  XML_Parser parser = oldParser;\r
+  DTD *newDtd = NULL;\r
+  DTD *oldDtd = _dtd;\r
+  XML_StartElementHandler oldStartElementHandler = startElementHandler;\r
+  XML_EndElementHandler oldEndElementHandler = endElementHandler;\r
+  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;\r
+  XML_ProcessingInstructionHandler oldProcessingInstructionHandler\r
+      = processingInstructionHandler;\r
+  XML_CommentHandler oldCommentHandler = commentHandler;\r
+  XML_StartCdataSectionHandler oldStartCdataSectionHandler\r
+      = startCdataSectionHandler;\r
+  XML_EndCdataSectionHandler oldEndCdataSectionHandler\r
+      = endCdataSectionHandler;\r
+  XML_DefaultHandler oldDefaultHandler = defaultHandler;\r
+  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler\r
+      = unparsedEntityDeclHandler;\r
+  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;\r
+  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler\r
+      = startNamespaceDeclHandler;\r
+  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler\r
+      = endNamespaceDeclHandler;\r
+  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;\r
+  XML_ExternalEntityRefHandler oldExternalEntityRefHandler\r
+      = externalEntityRefHandler;\r
+  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;\r
+  XML_UnknownEncodingHandler oldUnknownEncodingHandler\r
+      = unknownEncodingHandler;\r
+  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;\r
+  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;\r
+  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;\r
+  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;\r
+  ELEMENT_TYPE * oldDeclElementType = declElementType;\r
+\r
+  void *oldUserData = userData;\r
+  void *oldHandlerArg = handlerArg;\r
+  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;\r
+  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;\r
+#ifdef XML_DTD\r
+  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;\r
+  int oldInEntityValue = prologState.inEntityValue;\r
+#endif\r
+  XML_Bool oldns_triplets = ns_triplets;\r
+\r
+#ifdef XML_DTD\r
+  if (!context)\r
+    newDtd = oldDtd;\r
+#endif /* XML_DTD */\r
+\r
+  /* Note that the magical uses of the pre-processor to make field\r
+     access look more like C++ require that `parser' be overwritten\r
+     here.  This makes this function more painful to follow than it\r
+     would be otherwise.\r
+  */\r
+  if (ns) {\r
+    XML_Char tmp[2];\r
+    *tmp = namespaceSeparator;\r
+    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);\r
+  }\r
+  else {\r
+    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);\r
+  }\r
+\r
+  if (!parser)\r
+    return NULL;\r
+\r
+  startElementHandler = oldStartElementHandler;\r
+  endElementHandler = oldEndElementHandler;\r
+  characterDataHandler = oldCharacterDataHandler;\r
+  processingInstructionHandler = oldProcessingInstructionHandler;\r
+  commentHandler = oldCommentHandler;\r
+  startCdataSectionHandler = oldStartCdataSectionHandler;\r
+  endCdataSectionHandler = oldEndCdataSectionHandler;\r
+  defaultHandler = oldDefaultHandler;\r
+  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;\r
+  notationDeclHandler = oldNotationDeclHandler;\r
+  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;\r
+  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;\r
+  notStandaloneHandler = oldNotStandaloneHandler;\r
+  externalEntityRefHandler = oldExternalEntityRefHandler;\r
+  skippedEntityHandler = oldSkippedEntityHandler;\r
+  unknownEncodingHandler = oldUnknownEncodingHandler;\r
+  elementDeclHandler = oldElementDeclHandler;\r
+  attlistDeclHandler = oldAttlistDeclHandler;\r
+  entityDeclHandler = oldEntityDeclHandler;\r
+  xmlDeclHandler = oldXmlDeclHandler;\r
+  declElementType = oldDeclElementType;\r
+  userData = oldUserData;\r
+  if (oldUserData == oldHandlerArg)\r
+    handlerArg = userData;\r
+  else\r
+    handlerArg = parser;\r
+  if (oldExternalEntityRefHandlerArg != oldParser)\r
+    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;\r
+  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;\r
+  ns_triplets = oldns_triplets;\r
+  parentParser = oldParser;\r
+#ifdef XML_DTD\r
+  paramEntityParsing = oldParamEntityParsing;\r
+  prologState.inEntityValue = oldInEntityValue;\r
+  if (context) {\r
+#endif /* XML_DTD */\r
+    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)\r
+      || !setContext(parser, context)) {\r
+      XML_ParserFree(parser);\r
+      return NULL;\r
+    }\r
+    processor = externalEntityInitProcessor;\r
+#ifdef XML_DTD\r
+  }\r
+  else {\r
+    /* The DTD instance referenced by _dtd is shared between the document's\r
+       root parser and external PE parsers, therefore one does not need to\r
+       call setContext. In addition, one also *must* not call setContext,\r
+       because this would overwrite existing prefix->binding pointers in\r
+       _dtd with ones that get destroyed with the external PE parser.\r
+       This would leave those prefixes with dangling pointers.\r
+    */\r
+    isParamEntity = XML_TRUE;\r
+    XmlPrologStateInitExternalEntity(&prologState);\r
+    processor = externalParEntInitProcessor;\r
+  }\r
+#endif /* XML_DTD */\r
+  return parser;\r
+}\r
+\r
+static void FASTCALL\r
+destroyBindings(BINDING *bindings, XML_Parser parser)\r
+{\r
+  for (;;) {\r
+    BINDING *b = bindings;\r
+    if (!b)\r
+      break;\r
+    bindings = b->nextTagBinding;\r
+    FREE(b->uri);\r
+    FREE(b);\r
+  }\r
+}\r
+\r
+void XMLCALL\r
+XML_ParserFree(XML_Parser parser)\r
+{\r
+  TAG *tagList;\r
+  OPEN_INTERNAL_ENTITY *entityList;\r
+  if (parser == NULL)\r
+    return;\r
+  /* free tagStack and freeTagList */\r
+  tagList = tagStack;\r
+  for (;;) {\r
+    TAG *p;\r
+    if (tagList == NULL) {\r
+      if (freeTagList == NULL)\r
+        break;\r
+      tagList = freeTagList;\r
+      freeTagList = NULL;\r
+    }\r
+    p = tagList;\r
+    tagList = tagList->parent;\r
+    FREE(p->buf);\r
+    destroyBindings(p->bindings, parser);\r
+    FREE(p);\r
+  }\r
+  /* free openInternalEntities and freeInternalEntities */\r
+  entityList = openInternalEntities;\r
+  for (;;) {\r
+    OPEN_INTERNAL_ENTITY *openEntity;\r
+    if (entityList == NULL) {\r
+      if (freeInternalEntities == NULL)\r
+        break;\r
+      entityList = freeInternalEntities;\r
+      freeInternalEntities = NULL;\r
+    }\r
+    openEntity = entityList;\r
+    entityList = entityList->next;\r
+    FREE(openEntity);\r
+  }\r
+\r
+  destroyBindings(freeBindingList, parser);\r
+  destroyBindings(inheritedBindings, parser);\r
+  poolDestroy(&tempPool);\r
+  poolDestroy(&temp2Pool);\r
+#ifdef XML_DTD\r
+  /* external parameter entity parsers share the DTD structure\r
+     parser->m_dtd with the root parser, so we must not destroy it\r
+  */\r
+  if (!isParamEntity && _dtd)\r
+#else\r
+  if (_dtd)\r
+#endif /* XML_DTD */\r
+    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);\r
+  FREE((void *)atts);\r
+  FREE(groupConnector);\r
+  FREE(buffer);\r
+  FREE(dataBuf);\r
+  FREE(nsAtts);\r
+  FREE(unknownEncodingMem);\r
+  if (unknownEncodingRelease)\r
+    unknownEncodingRelease(unknownEncodingData);\r
+  FREE(parser);\r
+}\r
+\r
+void XMLCALL\r
+XML_UseParserAsHandlerArg(XML_Parser parser)\r
+{\r
+  handlerArg = parser;\r
+}\r
+\r
+enum XML_Error XMLCALL\r
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)\r
+{\r
+#ifdef XML_DTD\r
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */\r
+  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)\r
+    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;\r
+  useForeignDTD = useDTD;\r
+  return XML_ERROR_NONE;\r
+#else\r
+  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;\r
+#endif\r
+}\r
+\r
+void XMLCALL\r
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)\r
+{\r
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */\r
+  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)\r
+    return;\r
+  ns_triplets = do_nst ? XML_TRUE : XML_FALSE;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetUserData(XML_Parser parser, void *p)\r
+{\r
+  if (handlerArg == userData)\r
+    handlerArg = userData = p;\r
+  else\r
+    userData = p;\r
+}\r
+\r
+enum XML_Status XMLCALL\r
+XML_SetBase(XML_Parser parser, const XML_Char *p)\r
+{\r
+  if (p) {\r
+    p = poolCopyString(&_dtd->pool, p);\r
+    if (!p)\r
+      return XML_STATUS_ERROR;\r
+    curBase = p;\r
+  }\r
+  else\r
+    curBase = NULL;\r
+  return XML_STATUS_OK;\r
+}\r
+\r
+const XML_Char * XMLCALL\r
+XML_GetBase(XML_Parser parser)\r
+{\r
+  return curBase;\r
+}\r
+\r
+int XMLCALL\r
+XML_GetSpecifiedAttributeCount(XML_Parser parser)\r
+{\r
+  return nSpecifiedAtts;\r
+}\r
+\r
+int XMLCALL\r
+XML_GetIdAttributeIndex(XML_Parser parser)\r
+{\r
+  return idAttIndex;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetElementHandler(XML_Parser parser,\r
+                      XML_StartElementHandler start,\r
+                      XML_EndElementHandler end)\r
+{\r
+  startElementHandler = start;\r
+  endElementHandler = end;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetStartElementHandler(XML_Parser parser,\r
+                           XML_StartElementHandler start) {\r
+  startElementHandler = start;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetEndElementHandler(XML_Parser parser,\r
+                         XML_EndElementHandler end) {\r
+  endElementHandler = end;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetCharacterDataHandler(XML_Parser parser,\r
+                            XML_CharacterDataHandler handler)\r
+{\r
+  characterDataHandler = handler;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetProcessingInstructionHandler(XML_Parser parser,\r
+                                    XML_ProcessingInstructionHandler handler)\r
+{\r
+  processingInstructionHandler = handler;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetCommentHandler(XML_Parser parser,\r
+                      XML_CommentHandler handler)\r
+{\r
+  commentHandler = handler;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetCdataSectionHandler(XML_Parser parser,\r
+                           XML_StartCdataSectionHandler start,\r
+                           XML_EndCdataSectionHandler end)\r
+{\r
+  startCdataSectionHandler = start;\r
+  endCdataSectionHandler = end;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetStartCdataSectionHandler(XML_Parser parser,\r
+                                XML_StartCdataSectionHandler start) {\r
+  startCdataSectionHandler = start;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetEndCdataSectionHandler(XML_Parser parser,\r
+                              XML_EndCdataSectionHandler end) {\r
+  endCdataSectionHandler = end;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetDefaultHandler(XML_Parser parser,\r
+                      XML_DefaultHandler handler)\r
+{\r
+  defaultHandler = handler;\r
+  defaultExpandInternalEntities = XML_FALSE;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetDefaultHandlerExpand(XML_Parser parser,\r
+                            XML_DefaultHandler handler)\r
+{\r
+  defaultHandler = handler;\r
+  defaultExpandInternalEntities = XML_TRUE;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetDoctypeDeclHandler(XML_Parser parser,\r
+                          XML_StartDoctypeDeclHandler start,\r
+                          XML_EndDoctypeDeclHandler end)\r
+{\r
+  startDoctypeDeclHandler = start;\r
+  endDoctypeDeclHandler = end;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,\r
+                               XML_StartDoctypeDeclHandler start) {\r
+  startDoctypeDeclHandler = start;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,\r
+                             XML_EndDoctypeDeclHandler end) {\r
+  endDoctypeDeclHandler = end;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,\r
+                                 XML_UnparsedEntityDeclHandler handler)\r
+{\r
+  unparsedEntityDeclHandler = handler;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetNotationDeclHandler(XML_Parser parser,\r
+                           XML_NotationDeclHandler handler)\r
+{\r
+  notationDeclHandler = handler;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetNamespaceDeclHandler(XML_Parser parser,\r
+                            XML_StartNamespaceDeclHandler start,\r
+                            XML_EndNamespaceDeclHandler end)\r
+{\r
+  startNamespaceDeclHandler = start;\r
+  endNamespaceDeclHandler = end;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,\r
+                                 XML_StartNamespaceDeclHandler start) {\r
+  startNamespaceDeclHandler = start;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,\r
+                               XML_EndNamespaceDeclHandler end) {\r
+  endNamespaceDeclHandler = end;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetNotStandaloneHandler(XML_Parser parser,\r
+                            XML_NotStandaloneHandler handler)\r
+{\r
+  notStandaloneHandler = handler;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetExternalEntityRefHandler(XML_Parser parser,\r
+                                XML_ExternalEntityRefHandler handler)\r
+{\r
+  externalEntityRefHandler = handler;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)\r
+{\r
+  if (arg)\r
+    externalEntityRefHandlerArg = (XML_Parser)arg;\r
+  else\r
+    externalEntityRefHandlerArg = parser;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetSkippedEntityHandler(XML_Parser parser,\r
+                            XML_SkippedEntityHandler handler)\r
+{\r
+  skippedEntityHandler = handler;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetUnknownEncodingHandler(XML_Parser parser,\r
+                              XML_UnknownEncodingHandler handler,\r
+                              void *data)\r
+{\r
+  unknownEncodingHandler = handler;\r
+  unknownEncodingHandlerData = data;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetElementDeclHandler(XML_Parser parser,\r
+                          XML_ElementDeclHandler eldecl)\r
+{\r
+  elementDeclHandler = eldecl;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetAttlistDeclHandler(XML_Parser parser,\r
+                          XML_AttlistDeclHandler attdecl)\r
+{\r
+  attlistDeclHandler = attdecl;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetEntityDeclHandler(XML_Parser parser,\r
+                         XML_EntityDeclHandler handler)\r
+{\r
+  entityDeclHandler = handler;\r
+}\r
+\r
+void XMLCALL\r
+XML_SetXmlDeclHandler(XML_Parser parser,\r
+                      XML_XmlDeclHandler handler) {\r
+  xmlDeclHandler = handler;\r
+}\r
+\r
+int XMLCALL\r
+XML_SetParamEntityParsing(XML_Parser parser,\r
+                          enum XML_ParamEntityParsing peParsing)\r
+{\r
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */\r
+  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)\r
+    return 0;\r
+#ifdef XML_DTD\r
+  paramEntityParsing = peParsing;\r
+  return 1;\r
+#else\r
+  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;\r
+#endif\r
+}\r
+\r
+enum XML_Status XMLCALL\r
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)\r
+{\r
+  switch (ps_parsing) {\r
+  case XML_SUSPENDED:\r
+    errorCode = XML_ERROR_SUSPENDED;\r
+    return XML_STATUS_ERROR;\r
+  case XML_FINISHED:\r
+    errorCode = XML_ERROR_FINISHED;\r
+    return XML_STATUS_ERROR;\r
+  default:\r
+    ps_parsing = XML_PARSING;\r
+  }\r
+\r
+  if (len == 0) {\r
+    ps_finalBuffer = (XML_Bool)isFinal;\r
+    if (!isFinal)\r
+      return XML_STATUS_OK;\r
+    positionPtr = bufferPtr;\r
+    parseEndPtr = bufferEnd;\r
+\r
+    /* If data are left over from last buffer, and we now know that these\r
+       data are the final chunk of input, then we have to check them again\r
+       to detect errors based on that fact.\r
+    */\r
+    errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);\r
+\r
+    if (errorCode == XML_ERROR_NONE) {\r
+      switch (ps_parsing) {\r
+      case XML_SUSPENDED:\r
+        XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);\r
+        positionPtr = bufferPtr;\r
+        return XML_STATUS_SUSPENDED;\r
+      case XML_INITIALIZED:\r
+      case XML_PARSING:\r
+        ps_parsing = XML_FINISHED;\r
+        /* fall through */\r
+      default:\r
+        return XML_STATUS_OK;\r
+      }\r
+    }\r
+    eventEndPtr = eventPtr;\r
+    processor = errorProcessor;\r
+    return XML_STATUS_ERROR;\r
+  }\r
+#ifndef XML_CONTEXT_BYTES\r
+  else if (bufferPtr == bufferEnd) {\r
+    const char *end;\r
+    int nLeftOver;\r
+    enum XML_Error result;\r
+    parseEndByteIndex += len;\r
+    positionPtr = s;\r
+    ps_finalBuffer = (XML_Bool)isFinal;\r
+\r
+    errorCode = processor(parser, s, parseEndPtr = s + len, &end);\r
+\r
+    if (errorCode != XML_ERROR_NONE) {\r
+      eventEndPtr = eventPtr;\r
+      processor = errorProcessor;\r
+      return XML_STATUS_ERROR;\r
+    }\r
+    else {\r
+      switch (ps_parsing) {\r
+      case XML_SUSPENDED:\r
+        result = XML_STATUS_SUSPENDED;\r
+        break;\r
+      case XML_INITIALIZED:\r
+      case XML_PARSING:\r
+        result = XML_STATUS_OK;\r
+        if (isFinal) {\r
+          ps_parsing = XML_FINISHED;\r
+          return result;\r
+        }\r
+        break;\r
+      default:\r
+        /* XML_FINISHED case required by compiler - but not tested - djv */\r
+        return XML_STATUS_OK;\r
+      }\r
+    }\r
+\r
+    XmlUpdatePosition(encoding, positionPtr, end, &position);\r
+    nLeftOver = s + len - end;\r
+    if (nLeftOver) {\r
+      if (buffer == NULL || nLeftOver > bufferLim - buffer) {\r
+        /* FIXME avoid integer overflow */\r
+        char *temp;\r
+        temp = (buffer == NULL\r
+                ? (char *)MALLOC(len * 2)\r
+                : (char *)REALLOC(buffer, len * 2));\r
+        if (temp == NULL) {\r
+          errorCode = XML_ERROR_NO_MEMORY;\r
+          return XML_STATUS_ERROR;\r
+        }\r
+        buffer = temp;\r
+        if (!buffer) {\r
+          errorCode = XML_ERROR_NO_MEMORY;\r
+          eventPtr = eventEndPtr = NULL;\r
+          processor = errorProcessor;\r
+          return XML_STATUS_ERROR;\r
+        }\r
+        bufferLim = buffer + len * 2;\r
+      }\r
+      memcpy(buffer, end, nLeftOver);\r
+    }\r
+    bufferPtr = buffer;\r
+    bufferEnd = buffer + nLeftOver;\r
+    positionPtr = bufferPtr;\r
+    parseEndPtr = bufferEnd;\r
+    eventPtr = bufferPtr;\r
+    eventEndPtr = bufferPtr;\r
+    return result;\r
+  }\r
+#endif  /* not defined XML_CONTEXT_BYTES */\r
+  else {\r
+    void *buff = XML_GetBuffer(parser, len);\r
+    if (buff == NULL)\r
+      return XML_STATUS_ERROR;\r
+    else {\r
+      memcpy(buff, s, len);\r
+      return XML_ParseBuffer(parser, len, isFinal);\r
+    }\r
+  }\r
+}\r
+\r
+enum XML_Status XMLCALL\r
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal)\r
+{\r
+  const char *start;\r
+  enum XML_Status result = XML_STATUS_OK;\r
+\r
+  switch (ps_parsing) {\r
+  case XML_SUSPENDED:\r
+    errorCode = XML_ERROR_SUSPENDED;\r
+    return XML_STATUS_ERROR;\r
+  case XML_FINISHED:\r
+    errorCode = XML_ERROR_FINISHED;\r
+    return XML_STATUS_ERROR;\r
+  default:\r
+    ps_parsing = XML_PARSING;\r
+  }\r
+\r
+  start = bufferPtr;\r
+  positionPtr = start;\r
+  bufferEnd += len;\r
+  parseEndPtr = bufferEnd;\r
+  parseEndByteIndex += len;\r
+  ps_finalBuffer = (XML_Bool)isFinal;\r
+\r
+  errorCode = processor(parser, start, parseEndPtr, &bufferPtr);\r
+\r
+  if (errorCode != XML_ERROR_NONE) {\r
+    eventEndPtr = eventPtr;\r
+    processor = errorProcessor;\r
+    return XML_STATUS_ERROR;\r
+  }\r
+  else {\r
+    switch (ps_parsing) {\r
+    case XML_SUSPENDED:\r
+      result = XML_STATUS_SUSPENDED;\r
+      break;\r
+    case XML_INITIALIZED:\r
+    case XML_PARSING:\r
+      if (isFinal) {\r
+        ps_parsing = XML_FINISHED;\r
+        return result;\r
+      }\r
+    default: ;  /* should not happen */\r
+    }\r
+  }\r
+\r
+  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);\r
+  positionPtr = bufferPtr;\r
+  return result;\r
+}\r
+\r
+void * XMLCALL\r
+XML_GetBuffer(XML_Parser parser, int len)\r
+{\r
+  switch (ps_parsing) {\r
+  case XML_SUSPENDED:\r
+    errorCode = XML_ERROR_SUSPENDED;\r
+    return NULL;\r
+  case XML_FINISHED:\r
+    errorCode = XML_ERROR_FINISHED;\r
+    return NULL;\r
+  default: ;\r
+  }\r
+\r
+  if (len > bufferLim - bufferEnd) {\r
+    /* FIXME avoid integer overflow */\r
+    int neededSize = len + (int)(bufferEnd - bufferPtr);\r
+#ifdef XML_CONTEXT_BYTES\r
+    int keep = (int)(bufferPtr - buffer);\r
+\r
+    if (keep > XML_CONTEXT_BYTES)\r
+      keep = XML_CONTEXT_BYTES;\r
+    neededSize += keep;\r
+#endif  /* defined XML_CONTEXT_BYTES */\r
+    if (neededSize  <= bufferLim - buffer) {\r
+#ifdef XML_CONTEXT_BYTES\r
+      if (keep < bufferPtr - buffer) {\r
+        int offset = (int)(bufferPtr - buffer) - keep;\r
+        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);\r
+        bufferEnd -= offset;\r
+        bufferPtr -= offset;\r
+      }\r
+#else\r
+      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);\r
+      bufferEnd = buffer + (bufferEnd - bufferPtr);\r
+      bufferPtr = buffer;\r
+#endif  /* not defined XML_CONTEXT_BYTES */\r
+    }\r
+    else {\r
+      char *newBuf;\r
+      int bufferSize = (int)(bufferLim - bufferPtr);\r
+      if (bufferSize == 0)\r
+        bufferSize = INIT_BUFFER_SIZE;\r
+      do {\r
+        bufferSize *= 2;\r
+      } while (bufferSize < neededSize);\r
+      newBuf = (char *)MALLOC(bufferSize);\r
+      if (newBuf == 0) {\r
+        errorCode = XML_ERROR_NO_MEMORY;\r
+        return NULL;\r
+      }\r
+      bufferLim = newBuf + bufferSize;\r
+#ifdef XML_CONTEXT_BYTES\r
+      if (bufferPtr) {\r
+        int keep = (int)(bufferPtr - buffer);\r
+        if (keep > XML_CONTEXT_BYTES)\r
+          keep = XML_CONTEXT_BYTES;\r
+        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);\r
+        FREE(buffer);\r
+        buffer = newBuf;\r
+        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;\r
+        bufferPtr = buffer + keep;\r
+      }\r
+      else {\r
+        bufferEnd = newBuf + (bufferEnd - bufferPtr);\r
+        bufferPtr = buffer = newBuf;\r
+      }\r
+#else\r
+      if (bufferPtr) {\r
+        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);\r
+        FREE(buffer);\r
+      }\r
+      bufferEnd = newBuf + (bufferEnd - bufferPtr);\r
+      bufferPtr = buffer = newBuf;\r
+#endif  /* not defined XML_CONTEXT_BYTES */\r
+    }\r
+  }\r
+  return bufferEnd;\r
+}\r
+\r
+enum XML_Status XMLCALL\r
+XML_StopParser(XML_Parser parser, XML_Bool resumable)\r
+{\r
+  switch (ps_parsing) {\r
+  case XML_SUSPENDED:\r
+    if (resumable) {\r
+      errorCode = XML_ERROR_SUSPENDED;\r
+      return XML_STATUS_ERROR;\r
+    }\r
+    ps_parsing = XML_FINISHED;\r
+    break;\r
+  case XML_FINISHED:\r
+    errorCode = XML_ERROR_FINISHED;\r
+    return XML_STATUS_ERROR;\r
+  default:\r
+    if (resumable) {\r
+#ifdef XML_DTD\r
+      if (isParamEntity) {\r
+        errorCode = XML_ERROR_SUSPEND_PE;\r
+        return XML_STATUS_ERROR;\r
+      }\r
+#endif\r
+      ps_parsing = XML_SUSPENDED;\r
+    }\r
+    else\r
+      ps_parsing = XML_FINISHED;\r
+  }\r
+  return XML_STATUS_OK;\r
+}\r
+\r
+enum XML_Status XMLCALL\r
+XML_ResumeParser(XML_Parser parser)\r
+{\r
+  enum XML_Status result = XML_STATUS_OK;\r
+\r
+  if (ps_parsing != XML_SUSPENDED) {\r
+    errorCode = XML_ERROR_NOT_SUSPENDED;\r
+    return XML_STATUS_ERROR;\r
+  }\r
+  ps_parsing = XML_PARSING;\r
+\r
+  errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);\r
+\r
+  if (errorCode != XML_ERROR_NONE) {\r
+    eventEndPtr = eventPtr;\r
+    processor = errorProcessor;\r
+    return XML_STATUS_ERROR;\r
+  }\r
+  else {\r
+    switch (ps_parsing) {\r
+    case XML_SUSPENDED:\r
+      result = XML_STATUS_SUSPENDED;\r
+      break;\r
+    case XML_INITIALIZED:\r
+    case XML_PARSING:\r
+      if (ps_finalBuffer) {\r
+        ps_parsing = XML_FINISHED;\r
+        return result;\r
+      }\r
+    default: ;\r
+    }\r
+  }\r
+\r
+  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);\r
+  positionPtr = bufferPtr;\r
+  return result;\r
+}\r
+\r
+void XMLCALL\r
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)\r
+{\r
+  assert(status != NULL);\r
+  *status = parser->m_parsingStatus;\r
+}\r
+\r
+enum XML_Error XMLCALL\r
+XML_GetErrorCode(XML_Parser parser)\r
+{\r
+  return errorCode;\r
+}\r
+\r
+XML_Index XMLCALL\r
+XML_GetCurrentByteIndex(XML_Parser parser)\r
+{\r
+  if (eventPtr)\r
+    return parseEndByteIndex - (parseEndPtr - eventPtr);\r
+  return -1;\r
+}\r
+\r
+int XMLCALL\r
+XML_GetCurrentByteCount(XML_Parser parser)\r
+{\r
+  if (eventEndPtr && eventPtr)\r
+    return (int)(eventEndPtr - eventPtr);\r
+  return 0;\r
+}\r
+\r
+const char * XMLCALL\r
+XML_GetInputContext(XML_Parser parser, int *offset, int *size)\r
+{\r
+#ifdef XML_CONTEXT_BYTES\r
+  if (eventPtr && buffer) {\r
+    *offset = (int)(eventPtr - buffer);\r
+    *size   = (int)(bufferEnd - buffer);\r
+    return buffer;\r
+  }\r
+#endif /* defined XML_CONTEXT_BYTES */\r
+  return (char *) 0;\r
+}\r
+\r
+XML_Size XMLCALL\r
+XML_GetCurrentLineNumber(XML_Parser parser)\r
+{\r
+  if (eventPtr && eventPtr >= positionPtr) {\r
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);\r
+    positionPtr = eventPtr;\r
+  }\r
+  return position.lineNumber + 1;\r
+}\r
+\r
+XML_Size XMLCALL\r
+XML_GetCurrentColumnNumber(XML_Parser parser)\r
+{\r
+  if (eventPtr && eventPtr >= positionPtr) {\r
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);\r
+    positionPtr = eventPtr;\r
+  }\r
+  return position.columnNumber;\r
+}\r
+\r
+void XMLCALL\r
+XML_FreeContentModel(XML_Parser parser, XML_Content *model)\r
+{\r
+  FREE(model);\r
+}\r
+\r
+void * XMLCALL\r
+XML_MemMalloc(XML_Parser parser, size_t size)\r
+{\r
+  return MALLOC(size);\r
+}\r
+\r
+void * XMLCALL\r
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)\r
+{\r
+  return REALLOC(ptr, size);\r
+}\r
+\r
+void XMLCALL\r
+XML_MemFree(XML_Parser parser, void *ptr)\r
+{\r
+  FREE(ptr);\r
+}\r
+\r
+void XMLCALL\r
+XML_DefaultCurrent(XML_Parser parser)\r
+{\r
+  if (defaultHandler) {\r
+    if (openInternalEntities)\r
+      reportDefault(parser,\r
+                    internalEncoding,\r
+                    openInternalEntities->internalEventPtr,\r
+                    openInternalEntities->internalEventEndPtr);\r
+    else\r
+      reportDefault(parser, encoding, eventPtr, eventEndPtr);\r
+  }\r
+}\r
+\r
+const XML_LChar * XMLCALL\r
+XML_ErrorString(enum XML_Error code)\r
+{\r
+  static const XML_LChar* const message[] = {\r
+    0,\r
+    XML_L("out of memory"),\r
+    XML_L("syntax error"),\r
+    XML_L("no element found"),\r
+    XML_L("not well-formed (invalid token)"),\r
+    XML_L("unclosed token"),\r
+    XML_L("partial character"),\r
+    XML_L("mismatched tag"),\r
+    XML_L("duplicate attribute"),\r
+    XML_L("junk after document element"),\r
+    XML_L("illegal parameter entity reference"),\r
+    XML_L("undefined entity"),\r
+    XML_L("recursive entity reference"),\r
+    XML_L("asynchronous entity"),\r
+    XML_L("reference to invalid character number"),\r
+    XML_L("reference to binary entity"),\r
+    XML_L("reference to external entity in attribute"),\r
+    XML_L("XML or text declaration not at start of entity"),\r
+    XML_L("unknown encoding"),\r
+    XML_L("encoding specified in XML declaration is incorrect"),\r
+    XML_L("unclosed CDATA section"),\r
+    XML_L("error in processing external entity reference"),\r
+    XML_L("document is not standalone"),\r
+    XML_L("unexpected parser state - please send a bug report"),\r
+    XML_L("entity declared in parameter entity"),\r
+    XML_L("requested feature requires XML_DTD support in Expat"),\r
+    XML_L("cannot change setting once parsing has begun"),\r
+    XML_L("unbound prefix"),\r
+    XML_L("must not undeclare prefix"),\r
+    XML_L("incomplete markup in parameter entity"),\r
+    XML_L("XML declaration not well-formed"),\r
+    XML_L("text declaration not well-formed"),\r
+    XML_L("illegal character(s) in public id"),\r
+    XML_L("parser suspended"),\r
+    XML_L("parser not suspended"),\r
+    XML_L("parsing aborted"),\r
+    XML_L("parsing finished"),\r
+    XML_L("cannot suspend in external parameter entity"),\r
+    XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),\r
+    XML_L("reserved prefix (xmlns) must not be declared or undeclared"),\r
+    XML_L("prefix must not be bound to one of the reserved namespace names")\r
+  };\r
+  if (code > 0 && code < sizeof(message)/sizeof(message[0]))\r
+    return message[code];\r
+  return NULL;\r
+}\r
+\r
+const XML_LChar * XMLCALL\r
+XML_ExpatVersion(void) {\r
+\r
+  /* V1 is used to string-ize the version number. However, it would\r
+     string-ize the actual version macro *names* unless we get them\r
+     substituted before being passed to V1. CPP is defined to expand\r
+     a macro, then rescan for more expansions. Thus, we use V2 to expand\r
+     the version macros, then CPP will expand the resulting V1() macro\r
+     with the correct numerals. */\r
+  /* ### I'm assuming cpp is portable in this respect... */\r
+\r
+#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)\r
+#define V2(a,b,c) XML_L("expat_")V1(a,b,c)\r
+\r
+  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);\r
+\r
+#undef V1\r
+#undef V2\r
+}\r
+\r
+XML_Expat_Version XMLCALL\r
+XML_ExpatVersionInfo(void)\r
+{\r
+  XML_Expat_Version version;\r
+\r
+  version.major = XML_MAJOR_VERSION;\r
+  version.minor = XML_MINOR_VERSION;\r
+  version.micro = XML_MICRO_VERSION;\r
+\r
+  return version;\r
+}\r
+\r
+const XML_Feature * XMLCALL\r
+XML_GetFeatureList(void)\r
+{\r
+  static const XML_Feature features[] = {\r
+    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),\r
+     sizeof(XML_Char)},\r
+    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),\r
+     sizeof(XML_LChar)},\r
+#ifdef XML_UNICODE\r
+    {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},\r
+#endif\r
+#ifdef XML_UNICODE_WCHAR_T\r
+    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},\r
+#endif\r
+#ifdef XML_DTD\r
+    {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},\r
+#endif\r
+#ifdef XML_CONTEXT_BYTES\r
+    {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),\r
+     XML_CONTEXT_BYTES},\r
+#endif\r
+#ifdef XML_MIN_SIZE\r
+    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},\r
+#endif\r
+#ifdef XML_NS\r
+    {XML_FEATURE_NS,               XML_L("XML_NS"), 0},\r
+#endif\r
+    {XML_FEATURE_END,              NULL, 0}\r
+  };\r
+\r
+  return features;\r
+}\r
+\r
+/* Initially tag->rawName always points into the parse buffer;\r
+   for those TAG instances opened while the current parse buffer was\r
+   processed, and not yet closed, we need to store tag->rawName in a more\r
+   permanent location, since the parse buffer is about to be discarded.\r
+*/\r
+static XML_Bool\r
+storeRawNames(XML_Parser parser)\r
+{\r
+  TAG *tag = tagStack;\r
+  while (tag) {\r
+    int bufSize;\r
+    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);\r
+    char *rawNameBuf = tag->buf + nameLen;\r
+    /* Stop if already stored.  Since tagStack is a stack, we can stop\r
+       at the first entry that has already been copied; everything\r
+       below it in the stack is already been accounted for in a\r
+       previous call to this function.\r
+    */\r
+    if (tag->rawName == rawNameBuf)\r
+      break;\r
+    /* For re-use purposes we need to ensure that the\r
+       size of tag->buf is a multiple of sizeof(XML_Char).\r
+    */\r
+    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));\r
+    if (bufSize > tag->bufEnd - tag->buf) {\r
+      char *temp = (char *)REALLOC(tag->buf, bufSize);\r
+      if (temp == NULL)\r
+        return XML_FALSE;\r
+      /* if tag->name.str points to tag->buf (only when namespace\r
+         processing is off) then we have to update it\r
+      */\r
+      if (tag->name.str == (XML_Char *)tag->buf)\r
+        tag->name.str = (XML_Char *)temp;\r
+      /* if tag->name.localPart is set (when namespace processing is on)\r
+         then update it as well, since it will always point into tag->buf\r
+      */\r
+      if (tag->name.localPart)\r
+        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -\r
+                                                  (XML_Char *)tag->buf);\r
+      tag->buf = temp;\r
+      tag->bufEnd = temp + bufSize;\r
+      rawNameBuf = temp + nameLen;\r
+    }\r
+    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);\r
+    tag->rawName = rawNameBuf;\r
+    tag = tag->parent;\r
+  }\r
+  return XML_TRUE;\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+contentProcessor(XML_Parser parser,\r
+                 const char *start,\r
+                 const char *end,\r
+                 const char **endPtr)\r
+{\r
+  enum XML_Error result = doContent(parser, 0, encoding, start, end,\r
+                                    endPtr, (XML_Bool)!ps_finalBuffer);\r
+  if (result == XML_ERROR_NONE) {\r
+    if (!storeRawNames(parser))\r
+      return XML_ERROR_NO_MEMORY;\r
+  }\r
+  return result;\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+externalEntityInitProcessor(XML_Parser parser,\r
+                            const char *start,\r
+                            const char *end,\r
+                            const char **endPtr)\r
+{\r
+  enum XML_Error result = initializeEncoding(parser);\r
+  if (result != XML_ERROR_NONE)\r
+    return result;\r
+  processor = externalEntityInitProcessor2;\r
+  return externalEntityInitProcessor2(parser, start, end, endPtr);\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+externalEntityInitProcessor2(XML_Parser parser,\r
+                             const char *start,\r
+                             const char *end,\r
+                             const char **endPtr)\r
+{\r
+  const char *next = start; /* XmlContentTok doesn't always set the last arg */\r
+  int tok = XmlContentTok(encoding, start, end, &next);\r
+  switch (tok) {\r
+  case XML_TOK_BOM:\r
+    /* If we are at the end of the buffer, this would cause the next stage,\r
+       i.e. externalEntityInitProcessor3, to pass control directly to\r
+       doContent (by detecting XML_TOK_NONE) without processing any xml text\r
+       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.\r
+    */\r
+    if (next == end && !ps_finalBuffer) {\r
+      *endPtr = next;\r
+      return XML_ERROR_NONE;\r
+    }\r
+    start = next;\r
+    break;\r
+  case XML_TOK_PARTIAL:\r
+    if (!ps_finalBuffer) {\r
+      *endPtr = start;\r
+      return XML_ERROR_NONE;\r
+    }\r
+    eventPtr = start;\r
+    return XML_ERROR_UNCLOSED_TOKEN;\r
+  case XML_TOK_PARTIAL_CHAR:\r
+    if (!ps_finalBuffer) {\r
+      *endPtr = start;\r
+      return XML_ERROR_NONE;\r
+    }\r
+    eventPtr = start;\r
+    return XML_ERROR_PARTIAL_CHAR;\r
+  }\r
+  processor = externalEntityInitProcessor3;\r
+  return externalEntityInitProcessor3(parser, start, end, endPtr);\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+externalEntityInitProcessor3(XML_Parser parser,\r
+                             const char *start,\r
+                             const char *end,\r
+                             const char **endPtr)\r
+{\r
+  int tok;\r
+  const char *next = start; /* XmlContentTok doesn't always set the last arg */\r
+  eventPtr = start;\r
+  tok = XmlContentTok(encoding, start, end, &next);\r
+  eventEndPtr = next;\r
+\r
+  switch (tok) {\r
+  case XML_TOK_XML_DECL:\r
+    {\r
+      enum XML_Error result;\r
+      result = processXmlDecl(parser, 1, start, next);\r
+      if (result != XML_ERROR_NONE)\r
+        return result;\r
+      switch (ps_parsing) {\r
+      case XML_SUSPENDED:\r
+        *endPtr = next;\r
+        return XML_ERROR_NONE;\r
+      case XML_FINISHED:\r
+        return XML_ERROR_ABORTED;\r
+      default:\r
+        start = next;\r
+      }\r
+    }\r
+    break;\r
+  case XML_TOK_PARTIAL:\r
+    if (!ps_finalBuffer) {\r
+      *endPtr = start;\r
+      return XML_ERROR_NONE;\r
+    }\r
+    return XML_ERROR_UNCLOSED_TOKEN;\r
+  case XML_TOK_PARTIAL_CHAR:\r
+    if (!ps_finalBuffer) {\r
+      *endPtr = start;\r
+      return XML_ERROR_NONE;\r
+    }\r
+    return XML_ERROR_PARTIAL_CHAR;\r
+  }\r
+  processor = externalEntityContentProcessor;\r
+  tagLevel = 1;\r
+  return externalEntityContentProcessor(parser, start, end, endPtr);\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+externalEntityContentProcessor(XML_Parser parser,\r
+                               const char *start,\r
+                               const char *end,\r
+                               const char **endPtr)\r
+{\r
+  enum XML_Error result = doContent(parser, 1, encoding, start, end,\r
+                                    endPtr, (XML_Bool)!ps_finalBuffer);\r
+  if (result == XML_ERROR_NONE) {\r
+    if (!storeRawNames(parser))\r
+      return XML_ERROR_NO_MEMORY;\r
+  }\r
+  return result;\r
+}\r
+\r
+static enum XML_Error\r
+doContent(XML_Parser parser,\r
+          int startTagLevel,\r
+          const ENCODING *enc,\r
+          const char *s,\r
+          const char *end,\r
+          const char **nextPtr,\r
+          XML_Bool haveMore)\r
+{\r
+  /* save one level of indirection */\r
+  DTD * const dtd = _dtd;\r
+\r
+  const char **eventPP;\r
+  const char **eventEndPP;\r
+  if (enc == encoding) {\r
+    eventPP = &eventPtr;\r
+    eventEndPP = &eventEndPtr;\r
+  }\r
+  else {\r
+    eventPP = &(openInternalEntities->internalEventPtr);\r
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);\r
+  }\r
+  *eventPP = s;\r
+\r
+  for (;;) {\r
+    const char *next = s; /* XmlContentTok doesn't always set the last arg */\r
+    int tok = XmlContentTok(enc, s, end, &next);\r
+    *eventEndPP = next;\r
+    switch (tok) {\r
+    case XML_TOK_TRAILING_CR:\r
+      if (haveMore) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      *eventEndPP = end;\r
+      if (characterDataHandler) {\r
+        XML_Char c = 0xA;\r
+        characterDataHandler(handlerArg, &c, 1);\r
+      }\r
+      else if (defaultHandler)\r
+        reportDefault(parser, enc, s, end);\r
+      /* We are at the end of the final buffer, should we check for\r
+         XML_SUSPENDED, XML_FINISHED?\r
+      */\r
+      if (startTagLevel == 0)\r
+        return XML_ERROR_NO_ELEMENTS;\r
+      if (tagLevel != startTagLevel)\r
+        return XML_ERROR_ASYNC_ENTITY;\r
+      *nextPtr = end;\r
+      return XML_ERROR_NONE;\r
+    case XML_TOK_NONE:\r
+      if (haveMore) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      if (startTagLevel > 0) {\r
+        if (tagLevel != startTagLevel)\r
+          return XML_ERROR_ASYNC_ENTITY;\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      return XML_ERROR_NO_ELEMENTS;\r
+    case XML_TOK_INVALID:\r
+      *eventPP = next;\r
+      return XML_ERROR_INVALID_TOKEN;\r
+    case XML_TOK_PARTIAL:\r
+      if (haveMore) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      return XML_ERROR_UNCLOSED_TOKEN;\r
+    case XML_TOK_PARTIAL_CHAR:\r
+      if (haveMore) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      return XML_ERROR_PARTIAL_CHAR;\r
+    case XML_TOK_ENTITY_REF:\r
+      {\r
+        const XML_Char *name;\r
+        ENTITY *entity;\r
+        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,\r
+                                              s + enc->minBytesPerChar,\r
+                                              next - enc->minBytesPerChar);\r
+        if (ch) {\r
+          if (characterDataHandler)\r
+            characterDataHandler(handlerArg, &ch, 1);\r
+          else if (defaultHandler)\r
+            reportDefault(parser, enc, s, next);\r
+          break;\r
+        }\r
+        name = poolStoreString(&dtd->pool, enc,\r
+                                s + enc->minBytesPerChar,\r
+                                next - enc->minBytesPerChar);\r
+        if (!name)\r
+          return XML_ERROR_NO_MEMORY;\r
+        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);\r
+        poolDiscard(&dtd->pool);\r
+        /* First, determine if a check for an existing declaration is needed;\r
+           if yes, check that the entity exists, and that it is internal,\r
+           otherwise call the skipped entity or default handler.\r
+        */\r
+        if (!dtd->hasParamEntityRefs || dtd->standalone) {\r
+          if (!entity)\r
+            return XML_ERROR_UNDEFINED_ENTITY;\r
+          else if (!entity->is_internal)\r
+            return XML_ERROR_ENTITY_DECLARED_IN_PE;\r
+        }\r
+        else if (!entity) {\r
+          if (skippedEntityHandler)\r
+            skippedEntityHandler(handlerArg, name, 0);\r
+          else if (defaultHandler)\r
+            reportDefault(parser, enc, s, next);\r
+          break;\r
+        }\r
+        if (entity->open)\r
+          return XML_ERROR_RECURSIVE_ENTITY_REF;\r
+        if (entity->notation)\r
+          return XML_ERROR_BINARY_ENTITY_REF;\r
+        if (entity->textPtr) {\r
+          enum XML_Error result;\r
+          if (!defaultExpandInternalEntities) {\r
+            if (skippedEntityHandler)\r
+              skippedEntityHandler(handlerArg, entity->name, 0);\r
+            else if (defaultHandler)\r
+              reportDefault(parser, enc, s, next);\r
+            break;\r
+          }\r
+          result = processInternalEntity(parser, entity, XML_FALSE);\r
+          if (result != XML_ERROR_NONE)\r
+            return result;\r
+        }\r
+        else if (externalEntityRefHandler) {\r
+          const XML_Char *context;\r
+          entity->open = XML_TRUE;\r
+          context = getContext(parser);\r
+          entity->open = XML_FALSE;\r
+          if (!context)\r
+            return XML_ERROR_NO_MEMORY;\r
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,\r
+                                        context,\r
+                                        entity->base,\r
+                                        entity->systemId,\r
+                                        entity->publicId))\r
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;\r
+          poolDiscard(&tempPool);\r
+        }\r
+        else if (defaultHandler)\r
+          reportDefault(parser, enc, s, next);\r
+        break;\r
+      }\r
+    case XML_TOK_START_TAG_NO_ATTS:\r
+      /* fall through */\r
+    case XML_TOK_START_TAG_WITH_ATTS:\r
+      {\r
+        TAG *tag;\r
+        enum XML_Error result;\r
+        XML_Char *toPtr;\r
+        if (freeTagList) {\r
+          tag = freeTagList;\r
+          freeTagList = freeTagList->parent;\r
+        }\r
+        else {\r
+          tag = (TAG *)MALLOC(sizeof(TAG));\r
+          if (!tag)\r
+            return XML_ERROR_NO_MEMORY;\r
+          tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);\r
+          if (!tag->buf) {\r
+            FREE(tag);\r
+            return XML_ERROR_NO_MEMORY;\r
+          }\r
+          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;\r
+        }\r
+        tag->bindings = NULL;\r
+        tag->parent = tagStack;\r
+        tagStack = tag;\r
+        tag->name.localPart = NULL;\r
+        tag->name.prefix = NULL;\r
+        tag->rawName = s + enc->minBytesPerChar;\r
+        tag->rawNameLength = XmlNameLength(enc, tag->rawName);\r
+        ++tagLevel;\r
+        {\r
+          const char *rawNameEnd = tag->rawName + tag->rawNameLength;\r
+          const char *fromPtr = tag->rawName;\r
+          toPtr = (XML_Char *)tag->buf;\r
+          for (;;) {\r
+            int bufSize;\r
+            int convLen;\r
+            XmlConvert(enc,\r
+                       &fromPtr, rawNameEnd,\r
+                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);\r
+            convLen = (int)(toPtr - (XML_Char *)tag->buf);\r
+            if (fromPtr == rawNameEnd) {\r
+              tag->name.strLen = convLen;\r
+              break;\r
+            }\r
+            bufSize = (int)(tag->bufEnd - tag->buf) << 1;\r
+            {\r
+              char *temp = (char *)REALLOC(tag->buf, bufSize);\r
+              if (temp == NULL)\r
+                return XML_ERROR_NO_MEMORY;\r
+              tag->buf = temp;\r
+              tag->bufEnd = temp + bufSize;\r
+              toPtr = (XML_Char *)temp + convLen;\r
+            }\r
+          }\r
+        }\r
+        tag->name.str = (XML_Char *)tag->buf;\r
+        *toPtr = XML_T('\0');\r
+        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));\r
+        if (result)\r
+          return result;\r
+        if (startElementHandler)\r
+          startElementHandler(handlerArg, tag->name.str,\r
+                              (const XML_Char **)atts);\r
+        else if (defaultHandler)\r
+          reportDefault(parser, enc, s, next);\r
+        poolClear(&tempPool);\r
+        break;\r
+      }\r
+    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:\r
+      /* fall through */\r
+    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:\r
+      {\r
+        const char *rawName = s + enc->minBytesPerChar;\r
+        enum XML_Error result;\r
+        BINDING *bindings = NULL;\r
+        XML_Bool noElmHandlers = XML_TRUE;\r
+        TAG_NAME name;\r
+        name.str = poolStoreString(&tempPool, enc, rawName,\r
+                                   rawName + XmlNameLength(enc, rawName));\r
+        if (!name.str)\r
+          return XML_ERROR_NO_MEMORY;\r
+        poolFinish(&tempPool);\r
+        result = storeAtts(parser, enc, s, &name, &bindings);\r
+        if (result)\r
+          return result;\r
+        poolFinish(&tempPool);\r
+        if (startElementHandler) {\r
+          startElementHandler(handlerArg, name.str, (const XML_Char **)atts);\r
+          noElmHandlers = XML_FALSE;\r
+        }\r
+        if (endElementHandler) {\r
+          if (startElementHandler)\r
+            *eventPP = *eventEndPP;\r
+          endElementHandler(handlerArg, name.str);\r
+          noElmHandlers = XML_FALSE;\r
+        }\r
+        if (noElmHandlers && defaultHandler)\r
+          reportDefault(parser, enc, s, next);\r
+        poolClear(&tempPool);\r
+        while (bindings) {\r
+          BINDING *b = bindings;\r
+          if (endNamespaceDeclHandler)\r
+            endNamespaceDeclHandler(handlerArg, b->prefix->name);\r
+          bindings = bindings->nextTagBinding;\r
+          b->nextTagBinding = freeBindingList;\r
+          freeBindingList = b;\r
+          b->prefix->binding = b->prevPrefixBinding;\r
+        }\r
+      }\r
+      if (tagLevel == 0)\r
+        return epilogProcessor(parser, next, end, nextPtr);\r
+      break;\r
+    case XML_TOK_END_TAG:\r
+      if (tagLevel == startTagLevel)\r
+        return XML_ERROR_ASYNC_ENTITY;\r
+      else {\r
+        int len;\r
+        const char *rawName;\r
+        TAG *tag = tagStack;\r
+        tagStack = tag->parent;\r
+        tag->parent = freeTagList;\r
+        freeTagList = tag;\r
+        rawName = s + enc->minBytesPerChar*2;\r
+        len = XmlNameLength(enc, rawName);\r
+        if (len != tag->rawNameLength\r
+            || memcmp(tag->rawName, rawName, len) != 0) {\r
+          *eventPP = rawName;\r
+          return XML_ERROR_TAG_MISMATCH;\r
+        }\r
+        --tagLevel;\r
+        if (endElementHandler) {\r
+          const XML_Char *localPart;\r
+          const XML_Char *prefix;\r
+          XML_Char *uri;\r
+          localPart = tag->name.localPart;\r
+          if (ns && localPart) {\r
+            /* localPart and prefix may have been overwritten in\r
+               tag->name.str, since this points to the binding->uri\r
+               buffer which gets re-used; so we have to add them again\r
+            */\r
+            uri = (XML_Char *)tag->name.str + tag->name.uriLen;\r
+            /* don't need to check for space - already done in storeAtts() */\r
+            while (*localPart) *uri++ = *localPart++;\r
+            prefix = (XML_Char *)tag->name.prefix;\r
+            if (ns_triplets && prefix) {\r
+              *uri++ = namespaceSeparator;\r
+              while (*prefix) *uri++ = *prefix++;\r
+             }\r
+            *uri = XML_T('\0');\r
+          }\r
+          endElementHandler(handlerArg, tag->name.str);\r
+        }\r
+        else if (defaultHandler)\r
+          reportDefault(parser, enc, s, next);\r
+        while (tag->bindings) {\r
+          BINDING *b = tag->bindings;\r
+          if (endNamespaceDeclHandler)\r
+            endNamespaceDeclHandler(handlerArg, b->prefix->name);\r
+          tag->bindings = tag->bindings->nextTagBinding;\r
+          b->nextTagBinding = freeBindingList;\r
+          freeBindingList = b;\r
+          b->prefix->binding = b->prevPrefixBinding;\r
+        }\r
+        if (tagLevel == 0)\r
+          return epilogProcessor(parser, next, end, nextPtr);\r
+      }\r
+      break;\r
+    case XML_TOK_CHAR_REF:\r
+      {\r
+        int n = XmlCharRefNumber(enc, s);\r
+        if (n < 0)\r
+          return XML_ERROR_BAD_CHAR_REF;\r
+        if (characterDataHandler) {\r
+          XML_Char buf[XML_ENCODE_MAX];\r
+          characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));\r
+        }\r
+        else if (defaultHandler)\r
+          reportDefault(parser, enc, s, next);\r
+      }\r
+      break;\r
+    case XML_TOK_XML_DECL:\r
+      return XML_ERROR_MISPLACED_XML_PI;\r
+    case XML_TOK_DATA_NEWLINE:\r
+      if (characterDataHandler) {\r
+        XML_Char c = 0xA;\r
+        characterDataHandler(handlerArg, &c, 1);\r
+      }\r
+      else if (defaultHandler)\r
+        reportDefault(parser, enc, s, next);\r
+      break;\r
+    case XML_TOK_CDATA_SECT_OPEN:\r
+      {\r
+        enum XML_Error result;\r
+        if (startCdataSectionHandler)\r
+          startCdataSectionHandler(handlerArg);\r
+#if 0\r
+        /* Suppose you doing a transformation on a document that involves\r
+           changing only the character data.  You set up a defaultHandler\r
+           and a characterDataHandler.  The defaultHandler simply copies\r
+           characters through.  The characterDataHandler does the\r
+           transformation and writes the characters out escaping them as\r
+           necessary.  This case will fail to work if we leave out the\r
+           following two lines (because & and < inside CDATA sections will\r
+           be incorrectly escaped).\r
+\r
+           However, now we have a start/endCdataSectionHandler, so it seems\r
+           easier to let the user deal with this.\r
+        */\r
+        else if (characterDataHandler)\r
+          characterDataHandler(handlerArg, dataBuf, 0);\r
+#endif\r
+        else if (defaultHandler)\r
+          reportDefault(parser, enc, s, next);\r
+        result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);\r
+        if (result != XML_ERROR_NONE)\r
+          return result;\r
+        else if (!next) {\r
+          processor = cdataSectionProcessor;\r
+          return result;\r
+        }\r
+      }\r
+      break;\r
+    case XML_TOK_TRAILING_RSQB:\r
+      if (haveMore) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      if (characterDataHandler) {\r
+        if (MUST_CONVERT(enc, s)) {\r
+          ICHAR *dataPtr = (ICHAR *)dataBuf;\r
+          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);\r
+          characterDataHandler(handlerArg, dataBuf,\r
+                               (int)(dataPtr - (ICHAR *)dataBuf));\r
+        }\r
+        else\r
+          characterDataHandler(handlerArg,\r
+                               (XML_Char *)s,\r
+                               (int)((XML_Char *)end - (XML_Char *)s));\r
+      }\r
+      else if (defaultHandler)\r
+        reportDefault(parser, enc, s, end);\r
+      /* We are at the end of the final buffer, should we check for\r
+         XML_SUSPENDED, XML_FINISHED?\r
+      */\r
+      if (startTagLevel == 0) {\r
+        *eventPP = end;\r
+        return XML_ERROR_NO_ELEMENTS;\r
+      }\r
+      if (tagLevel != startTagLevel) {\r
+        *eventPP = end;\r
+        return XML_ERROR_ASYNC_ENTITY;\r
+      }\r
+      *nextPtr = end;\r
+      return XML_ERROR_NONE;\r
+    case XML_TOK_DATA_CHARS:\r
+      if (characterDataHandler) {\r
+        if (MUST_CONVERT(enc, s)) {\r
+          for (;;) {\r
+            ICHAR *dataPtr = (ICHAR *)dataBuf;\r
+            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);\r
+            *eventEndPP = s;\r
+            characterDataHandler(handlerArg, dataBuf,\r
+                                 (int)(dataPtr - (ICHAR *)dataBuf));\r
+            if (s == next)\r
+              break;\r
+            *eventPP = s;\r
+          }\r
+        }\r
+        else\r
+          characterDataHandler(handlerArg,\r
+                               (XML_Char *)s,\r
+                               (int)((XML_Char *)next - (XML_Char *)s));\r
+      }\r
+      else if (defaultHandler)\r
+        reportDefault(parser, enc, s, next);\r
+      break;\r
+    case XML_TOK_PI:\r
+      if (!reportProcessingInstruction(parser, enc, s, next))\r
+        return XML_ERROR_NO_MEMORY;\r
+      break;\r
+    case XML_TOK_COMMENT:\r
+      if (!reportComment(parser, enc, s, next))\r
+        return XML_ERROR_NO_MEMORY;\r
+      break;\r
+    default:\r
+      if (defaultHandler)\r
+        reportDefault(parser, enc, s, next);\r
+      break;\r
+    }\r
+    *eventPP = s = next;\r
+    switch (ps_parsing) {\r
+    case XML_SUSPENDED:\r
+      *nextPtr = next;\r
+      return XML_ERROR_NONE;\r
+    case XML_FINISHED:\r
+      return XML_ERROR_ABORTED;\r
+    default: ;\r
+    }\r
+  }\r
+  /* not reached */\r
+}\r
+\r
+/* Precondition: all arguments must be non-NULL;\r
+   Purpose:\r
+   - normalize attributes\r
+   - check attributes for well-formedness\r
+   - generate namespace aware attribute names (URI, prefix)\r
+   - build list of attributes for startElementHandler\r
+   - default attributes\r
+   - process namespace declarations (check and report them)\r
+   - generate namespace aware element name (URI, prefix)\r
+*/\r
+static enum XML_Error\r
+storeAtts(XML_Parser parser, const ENCODING *enc,\r
+          const char *attStr, TAG_NAME *tagNamePtr,\r
+          BINDING **bindingsPtr)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  ELEMENT_TYPE *elementType;\r
+  int nDefaultAtts;\r
+  const XML_Char **appAtts;   /* the attribute list for the application */\r
+  int attIndex = 0;\r
+  int prefixLen;\r
+  int i;\r
+  int n;\r
+  XML_Char *uri;\r
+  int nPrefixes = 0;\r
+  BINDING *binding;\r
+  const XML_Char *localPart;\r
+\r
+  /* lookup the element type name */\r
+  elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);\r
+  if (!elementType) {\r
+    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);\r
+    if (!name)\r
+      return XML_ERROR_NO_MEMORY;\r
+    elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,\r
+                                         sizeof(ELEMENT_TYPE));\r
+    if (!elementType)\r
+      return XML_ERROR_NO_MEMORY;\r
+    if (ns && !setElementTypePrefix(parser, elementType))\r
+      return XML_ERROR_NO_MEMORY;\r
+  }\r
+  nDefaultAtts = elementType->nDefaultAtts;\r
+\r
+  /* get the attributes from the tokenizer */\r
+  n = XmlGetAttributes(enc, attStr, attsSize, atts);\r
+  if (n + nDefaultAtts > attsSize) {\r
+    int oldAttsSize = attsSize;\r
+    ATTRIBUTE *temp;\r
+    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;\r
+    temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));\r
+    if (temp == NULL)\r
+      return XML_ERROR_NO_MEMORY;\r
+    atts = temp;\r
+    if (n > oldAttsSize)\r
+      XmlGetAttributes(enc, attStr, n, atts);\r
+  }\r
+\r
+  appAtts = (const XML_Char **)atts;\r
+  for (i = 0; i < n; i++) {\r
+    /* add the name and value to the attribute list */\r
+    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,\r
+                                         atts[i].name\r
+                                         + XmlNameLength(enc, atts[i].name));\r
+    if (!attId)\r
+      return XML_ERROR_NO_MEMORY;\r
+    /* Detect duplicate attributes by their QNames. This does not work when\r
+       namespace processing is turned on and different prefixes for the same\r
+       namespace are used. For this case we have a check further down.\r
+    */\r
+    if ((attId->name)[-1]) {\r
+      if (enc == encoding)\r
+        eventPtr = atts[i].name;\r
+      return XML_ERROR_DUPLICATE_ATTRIBUTE;\r
+    }\r
+    (attId->name)[-1] = 1;\r
+    appAtts[attIndex++] = attId->name;\r
+    if (!atts[i].normalized) {\r
+      enum XML_Error result;\r
+      XML_Bool isCdata = XML_TRUE;\r
+\r
+      /* figure out whether declared as other than CDATA */\r
+      if (attId->maybeTokenized) {\r
+        int j;\r
+        for (j = 0; j < nDefaultAtts; j++) {\r
+          if (attId == elementType->defaultAtts[j].id) {\r
+            isCdata = elementType->defaultAtts[j].isCdata;\r
+            break;\r
+          }\r
+        }\r
+      }\r
+\r
+      /* normalize the attribute value */\r
+      result = storeAttributeValue(parser, enc, isCdata,\r
+                                   atts[i].valuePtr, atts[i].valueEnd,\r
+                                   &tempPool);\r
+      if (result)\r
+        return result;\r
+      appAtts[attIndex] = poolStart(&tempPool);\r
+      poolFinish(&tempPool);\r
+    }\r
+    else {\r
+      /* the value did not need normalizing */\r
+      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,\r
+                                          atts[i].valueEnd);\r
+      if (appAtts[attIndex] == 0)\r
+        return XML_ERROR_NO_MEMORY;\r
+      poolFinish(&tempPool);\r
+    }\r
+    /* handle prefixed attribute names */\r
+    if (attId->prefix) {\r
+      if (attId->xmlns) {\r
+        /* deal with namespace declarations here */\r
+        enum XML_Error result = addBinding(parser, attId->prefix, attId,\r
+                                           appAtts[attIndex], bindingsPtr);\r
+        if (result)\r
+          return result;\r
+        --attIndex;\r
+      }\r
+      else {\r
+        /* deal with other prefixed names later */\r
+        attIndex++;\r
+        nPrefixes++;\r
+        (attId->name)[-1] = 2;\r
+      }\r
+    }\r
+    else\r
+      attIndex++;\r
+  }\r
+\r
+  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */\r
+  nSpecifiedAtts = attIndex;\r
+  if (elementType->idAtt && (elementType->idAtt->name)[-1]) {\r
+    for (i = 0; i < attIndex; i += 2)\r
+      if (appAtts[i] == elementType->idAtt->name) {\r
+        idAttIndex = i;\r
+        break;\r
+      }\r
+  }\r
+  else\r
+    idAttIndex = -1;\r
+\r
+  /* do attribute defaulting */\r
+  for (i = 0; i < nDefaultAtts; i++) {\r
+    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;\r
+    if (!(da->id->name)[-1] && da->value) {\r
+      if (da->id->prefix) {\r
+        if (da->id->xmlns) {\r
+          enum XML_Error result = addBinding(parser, da->id->prefix, da->id,\r
+                                             da->value, bindingsPtr);\r
+          if (result)\r
+            return result;\r
+        }\r
+        else {\r
+          (da->id->name)[-1] = 2;\r
+          nPrefixes++;\r
+          appAtts[attIndex++] = da->id->name;\r
+          appAtts[attIndex++] = da->value;\r
+        }\r
+      }\r
+      else {\r
+        (da->id->name)[-1] = 1;\r
+        appAtts[attIndex++] = da->id->name;\r
+        appAtts[attIndex++] = da->value;\r
+      }\r
+    }\r
+  }\r
+  appAtts[attIndex] = 0;\r
+\r
+  /* expand prefixed attribute names, check for duplicates,\r
+     and clear flags that say whether attributes were specified */\r
+  i = 0;\r
+  if (nPrefixes) {\r
+    int j;  /* hash table index */\r
+    unsigned long version = nsAttsVersion;\r
+    int nsAttsSize = (int)1 << nsAttsPower;\r
+    /* size of hash table must be at least 2 * (# of prefixed attributes) */\r
+    if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */\r
+      NS_ATT *temp;\r
+      /* hash table size must also be a power of 2 and >= 8 */\r
+      while (nPrefixes >> nsAttsPower++);\r
+      if (nsAttsPower < 3)\r
+        nsAttsPower = 3;\r
+      nsAttsSize = (int)1 << nsAttsPower;\r
+      temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));\r
+      if (!temp)\r
+        return XML_ERROR_NO_MEMORY;\r
+      nsAtts = temp;\r
+      version = 0;  /* force re-initialization of nsAtts hash table */\r
+    }\r
+    /* using a version flag saves us from initializing nsAtts every time */\r
+    if (!version) {  /* initialize version flags when version wraps around */\r
+      version = INIT_ATTS_VERSION;\r
+      for (j = nsAttsSize; j != 0; )\r
+        nsAtts[--j].version = version;\r
+    }\r
+    nsAttsVersion = --version;\r
+\r
+    /* expand prefixed names and check for duplicates */\r
+    for (; i < attIndex; i += 2) {\r
+      const XML_Char *s = appAtts[i];\r
+      if (s[-1] == 2) {  /* prefixed */\r
+        ATTRIBUTE_ID *id;\r
+        const BINDING *b;\r
+        unsigned long uriHash = 0;\r
+        ((XML_Char *)s)[-1] = 0;  /* clear flag */\r
+        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);\r
+        if (!id)\r
+          return XML_ERROR_NO_MEMORY;\r
+        b = id->prefix->binding;\r
+        if (!b)\r
+          return XML_ERROR_UNBOUND_PREFIX;\r
+\r
+        /* as we expand the name we also calculate its hash value */\r
+        for (j = 0; j < b->uriLen; j++) {\r
+          const XML_Char c = b->uri[j];\r
+          if (!poolAppendChar(&tempPool, c))\r
+            return XML_ERROR_NO_MEMORY;\r
+          uriHash = CHAR_HASH(uriHash, c);\r
+        }\r
+        while (*s++ != XML_T(':'))\r
+          ;\r
+        do {  /* copies null terminator */\r
+          const XML_Char c = *s;\r
+          if (!poolAppendChar(&tempPool, *s))\r
+            return XML_ERROR_NO_MEMORY;\r
+          uriHash = CHAR_HASH(uriHash, c);\r
+        } while (*s++);\r
+\r
+        { /* Check hash table for duplicate of expanded name (uriName).\r
+             Derived from code in lookup(HASH_TABLE *table, ...).\r
+          */\r
+          unsigned char step = 0;\r
+          unsigned long mask = nsAttsSize - 1;\r
+          j = uriHash & mask;  /* index into hash table */\r
+          while (nsAtts[j].version == version) {\r
+            /* for speed we compare stored hash values first */\r
+            if (uriHash == nsAtts[j].hash) {\r
+              const XML_Char *s1 = poolStart(&tempPool);\r
+              const XML_Char *s2 = nsAtts[j].uriName;\r
+              /* s1 is null terminated, but not s2 */\r
+              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);\r
+              if (*s1 == 0)\r
+                return XML_ERROR_DUPLICATE_ATTRIBUTE;\r
+            }\r
+            if (!step)\r
+              step = PROBE_STEP(uriHash, mask, nsAttsPower);\r
+            j < step ? (j += nsAttsSize - step) : (j -= step);\r
+          }\r
+        }\r
+\r
+        if (ns_triplets) {  /* append namespace separator and prefix */\r
+          tempPool.ptr[-1] = namespaceSeparator;\r
+          s = b->prefix->name;\r
+          do {\r
+            if (!poolAppendChar(&tempPool, *s))\r
+              return XML_ERROR_NO_MEMORY;\r
+          } while (*s++);\r
+        }\r
+\r
+        /* store expanded name in attribute list */\r
+        s = poolStart(&tempPool);\r
+        poolFinish(&tempPool);\r
+        appAtts[i] = s;\r
+\r
+        /* fill empty slot with new version, uriName and hash value */\r
+        nsAtts[j].version = version;\r
+        nsAtts[j].hash = uriHash;\r
+        nsAtts[j].uriName = s;\r
+\r
+        if (!--nPrefixes) {\r
+          i += 2;\r
+          break;\r
+        }\r
+      }\r
+      else  /* not prefixed */\r
+        ((XML_Char *)s)[-1] = 0;  /* clear flag */\r
+    }\r
+  }\r
+  /* clear flags for the remaining attributes */\r
+  for (; i < attIndex; i += 2)\r
+    ((XML_Char *)(appAtts[i]))[-1] = 0;\r
+  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)\r
+    binding->attId->name[-1] = 0;\r
+\r
+  if (!ns)\r
+    return XML_ERROR_NONE;\r
+\r
+  /* expand the element type name */\r
+  if (elementType->prefix) {\r
+    binding = elementType->prefix->binding;\r
+    if (!binding)\r
+      return XML_ERROR_UNBOUND_PREFIX;\r
+    localPart = tagNamePtr->str;\r
+    while (*localPart++ != XML_T(':'))\r
+      ;\r
+  }\r
+  else if (dtd->defaultPrefix.binding) {\r
+    binding = dtd->defaultPrefix.binding;\r
+    localPart = tagNamePtr->str;\r
+  }\r
+  else\r
+    return XML_ERROR_NONE;\r
+  prefixLen = 0;\r
+  if (ns_triplets && binding->prefix->name) {\r
+    for (; binding->prefix->name[prefixLen++];)\r
+      ;  /* prefixLen includes null terminator */\r
+  }\r
+  tagNamePtr->localPart = localPart;\r
+  tagNamePtr->uriLen = binding->uriLen;\r
+  tagNamePtr->prefix = binding->prefix->name;\r
+  tagNamePtr->prefixLen = prefixLen;\r
+  for (i = 0; localPart[i++];)\r
+    ;  /* i includes null terminator */\r
+  n = i + binding->uriLen + prefixLen;\r
+  if (n > binding->uriAlloc) {\r
+    TAG *p;\r
+    uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));\r
+    if (!uri)\r
+      return XML_ERROR_NO_MEMORY;\r
+    binding->uriAlloc = n + EXPAND_SPARE;\r
+    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));\r
+    for (p = tagStack; p; p = p->parent)\r
+      if (p->name.str == binding->uri)\r
+        p->name.str = uri;\r
+    FREE(binding->uri);\r
+    binding->uri = uri;\r
+  }\r
+  /* if namespaceSeparator != '\0' then uri includes it already */\r
+  uri = binding->uri + binding->uriLen;\r
+  memcpy(uri, localPart, i * sizeof(XML_Char));\r
+  /* we always have a namespace separator between localPart and prefix */\r
+  if (prefixLen) {\r
+    uri += i - 1;\r
+    *uri = namespaceSeparator;  /* replace null terminator */\r
+    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));\r
+  }\r
+  tagNamePtr->str = binding->uri;\r
+  return XML_ERROR_NONE;\r
+}\r
+\r
+/* addBinding() overwrites the value of prefix->binding without checking.\r
+   Therefore one must keep track of the old value outside of addBinding().\r
+*/\r
+static enum XML_Error\r
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,\r
+           const XML_Char *uri, BINDING **bindingsPtr)\r
+{\r
+  static const XML_Char xmlNamespace[] = {\r
+    'h', 't', 't', 'p', ':', '/', '/',\r
+    'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',\r
+    'X', 'M', 'L', '/', '1', '9', '9', '8', '/',\r
+    'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'\r
+  };\r
+  static const int xmlLen =\r
+    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;\r
+  static const XML_Char xmlnsNamespace[] = {\r
+    'h', 't', 't', 'p', ':', '/', '/',\r
+    'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',\r
+    '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'\r
+  };\r
+  static const int xmlnsLen =\r
+    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;\r
+\r
+  XML_Bool mustBeXML = XML_FALSE;\r
+  XML_Bool isXML = XML_TRUE;\r
+  XML_Bool isXMLNS = XML_TRUE;\r
+\r
+  BINDING *b;\r
+  int len;\r
+\r
+  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */\r
+  if (*uri == XML_T('\0') && prefix->name)\r
+    return XML_ERROR_UNDECLARING_PREFIX;\r
+\r
+  if (prefix->name\r
+      && prefix->name[0] == XML_T('x')\r
+      && prefix->name[1] == XML_T('m')\r
+      && prefix->name[2] == XML_T('l')) {\r
+\r
+    /* Not allowed to bind xmlns */\r
+    if (prefix->name[3] == XML_T('n')\r
+        && prefix->name[4] == XML_T('s')\r
+        && prefix->name[5] == XML_T('\0'))\r
+      return XML_ERROR_RESERVED_PREFIX_XMLNS;\r
+\r
+    if (prefix->name[3] == XML_T('\0'))\r
+      mustBeXML = XML_TRUE;\r
+  }\r
+\r
+  for (len = 0; uri[len]; len++) {\r
+    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))\r
+      isXML = XML_FALSE;\r
+\r
+    if (!mustBeXML && isXMLNS\r
+        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))\r
+      isXMLNS = XML_FALSE;\r
+  }\r
+  isXML = isXML && len == xmlLen;\r
+  isXMLNS = isXMLNS && len == xmlnsLen;\r
+\r
+  if (mustBeXML != isXML)\r
+    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML\r
+                     : XML_ERROR_RESERVED_NAMESPACE_URI;\r
+\r
+  if (isXMLNS)\r
+    return XML_ERROR_RESERVED_NAMESPACE_URI;\r
+\r
+  if (namespaceSeparator)\r
+    len++;\r
+  if (freeBindingList) {\r
+    b = freeBindingList;\r
+    if (len > b->uriAlloc) {\r
+      XML_Char *temp = (XML_Char *)REALLOC(b->uri,\r
+                          sizeof(XML_Char) * (len + EXPAND_SPARE));\r
+      if (temp == NULL)\r
+        return XML_ERROR_NO_MEMORY;\r
+      b->uri = temp;\r
+      b->uriAlloc = len + EXPAND_SPARE;\r
+    }\r
+    freeBindingList = b->nextTagBinding;\r
+  }\r
+  else {\r
+    b = (BINDING *)MALLOC(sizeof(BINDING));\r
+    if (!b)\r
+      return XML_ERROR_NO_MEMORY;\r
+    b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));\r
+    if (!b->uri) {\r
+      FREE(b);\r
+      return XML_ERROR_NO_MEMORY;\r
+    }\r
+    b->uriAlloc = len + EXPAND_SPARE;\r
+  }\r
+  b->uriLen = len;\r
+  memcpy(b->uri, uri, len * sizeof(XML_Char));\r
+  if (namespaceSeparator)\r
+    b->uri[len - 1] = namespaceSeparator;\r
+  b->prefix = prefix;\r
+  b->attId = attId;\r
+  b->prevPrefixBinding = prefix->binding;\r
+  /* NULL binding when default namespace undeclared */\r
+  if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)\r
+    prefix->binding = NULL;\r
+  else\r
+    prefix->binding = b;\r
+  b->nextTagBinding = *bindingsPtr;\r
+  *bindingsPtr = b;\r
+  /* if attId == NULL then we are not starting a namespace scope */\r
+  if (attId && startNamespaceDeclHandler)\r
+    startNamespaceDeclHandler(handlerArg, prefix->name,\r
+                              prefix->binding ? uri : 0);\r
+  return XML_ERROR_NONE;\r
+}\r
+\r
+/* The idea here is to avoid using stack for each CDATA section when\r
+   the whole file is parsed with one call.\r
+*/\r
+static enum XML_Error PTRCALL\r
+cdataSectionProcessor(XML_Parser parser,\r
+                      const char *start,\r
+                      const char *end,\r
+                      const char **endPtr)\r
+{\r
+  enum XML_Error result = doCdataSection(parser, encoding, &start, end,\r
+                                         endPtr, (XML_Bool)!ps_finalBuffer);\r
+  if (result != XML_ERROR_NONE)\r
+    return result;\r
+  if (start) {\r
+    if (parentParser) {  /* we are parsing an external entity */\r
+      processor = externalEntityContentProcessor;\r
+      return externalEntityContentProcessor(parser, start, end, endPtr);\r
+    }\r
+    else {\r
+      processor = contentProcessor;\r
+      return contentProcessor(parser, start, end, endPtr);\r
+    }\r
+  }\r
+  return result;\r
+}\r
+\r
+/* startPtr gets set to non-null if the section is closed, and to null if\r
+   the section is not yet closed.\r
+*/\r
+static enum XML_Error\r
+doCdataSection(XML_Parser parser,\r
+               const ENCODING *enc,\r
+               const char **startPtr,\r
+               const char *end,\r
+               const char **nextPtr,\r
+               XML_Bool haveMore)\r
+{\r
+  const char *s = *startPtr;\r
+  const char **eventPP;\r
+  const char **eventEndPP;\r
+  if (enc == encoding) {\r
+    eventPP = &eventPtr;\r
+    *eventPP = s;\r
+    eventEndPP = &eventEndPtr;\r
+  }\r
+  else {\r
+    eventPP = &(openInternalEntities->internalEventPtr);\r
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);\r
+  }\r
+  *eventPP = s;\r
+  *startPtr = NULL;\r
+\r
+  for (;;) {\r
+    const char *next;\r
+    int tok = XmlCdataSectionTok(enc, s, end, &next);\r
+    *eventEndPP = next;\r
+    switch (tok) {\r
+    case XML_TOK_CDATA_SECT_CLOSE:\r
+      if (endCdataSectionHandler)\r
+        endCdataSectionHandler(handlerArg);\r
+#if 0\r
+      /* see comment under XML_TOK_CDATA_SECT_OPEN */\r
+      else if (characterDataHandler)\r
+        characterDataHandler(handlerArg, dataBuf, 0);\r
+#endif\r
+      else if (defaultHandler)\r
+        reportDefault(parser, enc, s, next);\r
+      *startPtr = next;\r
+      *nextPtr = next;\r
+      if (ps_parsing == XML_FINISHED)\r
+        return XML_ERROR_ABORTED;\r
+      else\r
+        return XML_ERROR_NONE;\r
+    case XML_TOK_DATA_NEWLINE:\r
+      if (characterDataHandler) {\r
+        XML_Char c = 0xA;\r
+        characterDataHandler(handlerArg, &c, 1);\r
+      }\r
+      else if (defaultHandler)\r
+        reportDefault(parser, enc, s, next);\r
+      break;\r
+    case XML_TOK_DATA_CHARS:\r
+      if (characterDataHandler) {\r
+        if (MUST_CONVERT(enc, s)) {\r
+          for (;;) {\r
+            ICHAR *dataPtr = (ICHAR *)dataBuf;\r
+            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);\r
+            *eventEndPP = next;\r
+            characterDataHandler(handlerArg, dataBuf,\r
+                                 (int)(dataPtr - (ICHAR *)dataBuf));\r
+            if (s == next)\r
+              break;\r
+            *eventPP = s;\r
+          }\r
+        }\r
+        else\r
+          characterDataHandler(handlerArg,\r
+                               (XML_Char *)s,\r
+                               (int)((XML_Char *)next - (XML_Char *)s));\r
+      }\r
+      else if (defaultHandler)\r
+        reportDefault(parser, enc, s, next);\r
+      break;\r
+    case XML_TOK_INVALID:\r
+      *eventPP = next;\r
+      return XML_ERROR_INVALID_TOKEN;\r
+    case XML_TOK_PARTIAL_CHAR:\r
+      if (haveMore) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      return XML_ERROR_PARTIAL_CHAR;\r
+    case XML_TOK_PARTIAL:\r
+    case XML_TOK_NONE:\r
+      if (haveMore) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      return XML_ERROR_UNCLOSED_CDATA_SECTION;\r
+    default:\r
+      *eventPP = next;\r
+      return XML_ERROR_UNEXPECTED_STATE;\r
+    }\r
+\r
+    *eventPP = s = next;\r
+    switch (ps_parsing) {\r
+    case XML_SUSPENDED:\r
+      *nextPtr = next;\r
+      return XML_ERROR_NONE;\r
+    case XML_FINISHED:\r
+      return XML_ERROR_ABORTED;\r
+    default: ;\r
+    }\r
+  }\r
+  /* not reached */\r
+}\r
+\r
+#ifdef XML_DTD\r
+\r
+/* The idea here is to avoid using stack for each IGNORE section when\r
+   the whole file is parsed with one call.\r
+*/\r
+static enum XML_Error PTRCALL\r
+ignoreSectionProcessor(XML_Parser parser,\r
+                       const char *start,\r
+                       const char *end,\r
+                       const char **endPtr)\r
+{\r
+  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,\r
+                                          endPtr, (XML_Bool)!ps_finalBuffer);\r
+  if (result != XML_ERROR_NONE)\r
+    return result;\r
+  if (start) {\r
+    processor = prologProcessor;\r
+    return prologProcessor(parser, start, end, endPtr);\r
+  }\r
+  return result;\r
+}\r
+\r
+/* startPtr gets set to non-null is the section is closed, and to null\r
+   if the section is not yet closed.\r
+*/\r
+static enum XML_Error\r
+doIgnoreSection(XML_Parser parser,\r
+                const ENCODING *enc,\r
+                const char **startPtr,\r
+                const char *end,\r
+                const char **nextPtr,\r
+                XML_Bool haveMore)\r
+{\r
+  const char *next;\r
+  int tok;\r
+  const char *s = *startPtr;\r
+  const char **eventPP;\r
+  const char **eventEndPP;\r
+  if (enc == encoding) {\r
+    eventPP = &eventPtr;\r
+    *eventPP = s;\r
+    eventEndPP = &eventEndPtr;\r
+  }\r
+  else {\r
+    eventPP = &(openInternalEntities->internalEventPtr);\r
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);\r
+  }\r
+  *eventPP = s;\r
+  *startPtr = NULL;\r
+  tok = XmlIgnoreSectionTok(enc, s, end, &next);\r
+  *eventEndPP = next;\r
+  switch (tok) {\r
+  case XML_TOK_IGNORE_SECT:\r
+    if (defaultHandler)\r
+      reportDefault(parser, enc, s, next);\r
+    *startPtr = next;\r
+    *nextPtr = next;\r
+    if (ps_parsing == XML_FINISHED)\r
+      return XML_ERROR_ABORTED;\r
+    else\r
+      return XML_ERROR_NONE;\r
+  case XML_TOK_INVALID:\r
+    *eventPP = next;\r
+    return XML_ERROR_INVALID_TOKEN;\r
+  case XML_TOK_PARTIAL_CHAR:\r
+    if (haveMore) {\r
+      *nextPtr = s;\r
+      return XML_ERROR_NONE;\r
+    }\r
+    return XML_ERROR_PARTIAL_CHAR;\r
+  case XML_TOK_PARTIAL:\r
+  case XML_TOK_NONE:\r
+    if (haveMore) {\r
+      *nextPtr = s;\r
+      return XML_ERROR_NONE;\r
+    }\r
+    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */\r
+  default:\r
+    *eventPP = next;\r
+    return XML_ERROR_UNEXPECTED_STATE;\r
+  }\r
+  /* not reached */\r
+}\r
+\r
+#endif /* XML_DTD */\r
+\r
+static enum XML_Error\r
+initializeEncoding(XML_Parser parser)\r
+{\r
+  const char *s;\r
+#ifdef XML_UNICODE\r
+  char encodingBuf[128];\r
+  if (!protocolEncodingName)\r
+    s = NULL;\r
+  else {\r
+    int i;\r
+    for (i = 0; protocolEncodingName[i]; i++) {\r
+      if (i == sizeof(encodingBuf) - 1\r
+          || (protocolEncodingName[i] & ~0x7f) != 0) {\r
+        encodingBuf[0] = '\0';\r
+        break;\r
+      }\r
+      encodingBuf[i] = (char)protocolEncodingName[i];\r
+    }\r
+    encodingBuf[i] = '\0';\r
+    s = encodingBuf;\r
+  }\r
+#else\r
+  s = protocolEncodingName;\r
+#endif\r
+  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))\r
+    return XML_ERROR_NONE;\r
+  return handleUnknownEncoding(parser, protocolEncodingName);\r
+}\r
+\r
+static enum XML_Error\r
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,\r
+               const char *s, const char *next)\r
+{\r
+  const char *encodingName = NULL;\r
+  const XML_Char *storedEncName = NULL;\r
+  const ENCODING *newEncoding = NULL;\r
+  const char *version = NULL;\r
+  const char *versionend;\r
+  const XML_Char *storedversion = NULL;\r
+  int standalone = -1;\r
+  if (!(ns\r
+        ? XmlParseXmlDeclNS\r
+        : XmlParseXmlDecl)(isGeneralTextEntity,\r
+                           encoding,\r
+                           s,\r
+                           next,\r
+                           &eventPtr,\r
+                           &version,\r
+                           &versionend,\r
+                           &encodingName,\r
+                           &newEncoding,\r
+                           &standalone)) {\r
+    if (isGeneralTextEntity)\r
+      return XML_ERROR_TEXT_DECL;\r
+    else\r
+      return XML_ERROR_XML_DECL;\r
+  }\r
+  if (!isGeneralTextEntity && standalone == 1) {\r
+    _dtd->standalone = XML_TRUE;\r
+#ifdef XML_DTD\r
+    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)\r
+      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;\r
+#endif /* XML_DTD */\r
+  }\r
+  if (xmlDeclHandler) {\r
+    if (encodingName != NULL) {\r
+      storedEncName = poolStoreString(&temp2Pool,\r
+                                      encoding,\r
+                                      encodingName,\r
+                                      encodingName\r
+                                      + XmlNameLength(encoding, encodingName));\r
+      if (!storedEncName)\r
+              return XML_ERROR_NO_MEMORY;\r
+      poolFinish(&temp2Pool);\r
+    }\r
+    if (version) {\r
+      storedversion = poolStoreString(&temp2Pool,\r
+                                      encoding,\r
+                                      version,\r
+                                      versionend - encoding->minBytesPerChar);\r
+      if (!storedversion)\r
+        return XML_ERROR_NO_MEMORY;\r
+    }\r
+    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);\r
+  }\r
+  else if (defaultHandler)\r
+    reportDefault(parser, encoding, s, next);\r
+  if (protocolEncodingName == NULL) {\r
+    if (newEncoding) {\r
+      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {\r
+        eventPtr = encodingName;\r
+        return XML_ERROR_INCORRECT_ENCODING;\r
+      }\r
+      encoding = newEncoding;\r
+    }\r
+    else if (encodingName) {\r
+      enum XML_Error result;\r
+      if (!storedEncName) {\r
+        storedEncName = poolStoreString(\r
+          &temp2Pool, encoding, encodingName,\r
+          encodingName + XmlNameLength(encoding, encodingName));\r
+        if (!storedEncName)\r
+          return XML_ERROR_NO_MEMORY;\r
+      }\r
+      result = handleUnknownEncoding(parser, storedEncName);\r
+      poolClear(&temp2Pool);\r
+      if (result == XML_ERROR_UNKNOWN_ENCODING)\r
+        eventPtr = encodingName;\r
+      return result;\r
+    }\r
+  }\r
+\r
+  if (storedEncName || storedversion)\r
+    poolClear(&temp2Pool);\r
+\r
+  return XML_ERROR_NONE;\r
+}\r
+\r
+static enum XML_Error\r
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)\r
+{\r
+  if (unknownEncodingHandler) {\r
+    XML_Encoding info;\r
+    int i;\r
+    for (i = 0; i < 256; i++)\r
+      info.map[i] = -1;\r
+    info.convert = NULL;\r
+    info.data = NULL;\r
+    info.release = NULL;\r
+    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,\r
+                               &info)) {\r
+      ENCODING *enc;\r
+      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());\r
+      if (!unknownEncodingMem) {\r
+        if (info.release)\r
+          info.release(info.data);\r
+        return XML_ERROR_NO_MEMORY;\r
+      }\r
+      enc = (ns\r
+             ? XmlInitUnknownEncodingNS\r
+             : XmlInitUnknownEncoding)(unknownEncodingMem,\r
+                                       info.map,\r
+                                       info.convert,\r
+                                       info.data);\r
+      if (enc) {\r
+        unknownEncodingData = info.data;\r
+        unknownEncodingRelease = info.release;\r
+        encoding = enc;\r
+        return XML_ERROR_NONE;\r
+      }\r
+    }\r
+    if (info.release != NULL)\r
+      info.release(info.data);\r
+  }\r
+  return XML_ERROR_UNKNOWN_ENCODING;\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+prologInitProcessor(XML_Parser parser,\r
+                    const char *s,\r
+                    const char *end,\r
+                    const char **nextPtr)\r
+{\r
+  enum XML_Error result = initializeEncoding(parser);\r
+  if (result != XML_ERROR_NONE)\r
+    return result;\r
+  processor = prologProcessor;\r
+  return prologProcessor(parser, s, end, nextPtr);\r
+}\r
+\r
+#ifdef XML_DTD\r
+\r
+static enum XML_Error PTRCALL\r
+externalParEntInitProcessor(XML_Parser parser,\r
+                            const char *s,\r
+                            const char *end,\r
+                            const char **nextPtr)\r
+{\r
+  enum XML_Error result = initializeEncoding(parser);\r
+  if (result != XML_ERROR_NONE)\r
+    return result;\r
+\r
+  /* we know now that XML_Parse(Buffer) has been called,\r
+     so we consider the external parameter entity read */\r
+  _dtd->paramEntityRead = XML_TRUE;\r
+\r
+  if (prologState.inEntityValue) {\r
+    processor = entityValueInitProcessor;\r
+    return entityValueInitProcessor(parser, s, end, nextPtr);\r
+  }\r
+  else {\r
+    processor = externalParEntProcessor;\r
+    return externalParEntProcessor(parser, s, end, nextPtr);\r
+  }\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+entityValueInitProcessor(XML_Parser parser,\r
+                         const char *s,\r
+                         const char *end,\r
+                         const char **nextPtr)\r
+{\r
+  int tok;\r
+  const char *start = s;\r
+  const char *next = start;\r
+  eventPtr = start;\r
+\r
+  for (;;) {\r
+    tok = XmlPrologTok(encoding, start, end, &next);\r
+    eventEndPtr = next;\r
+    if (tok <= 0) {\r
+      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      switch (tok) {\r
+      case XML_TOK_INVALID:\r
+        return XML_ERROR_INVALID_TOKEN;\r
+      case XML_TOK_PARTIAL:\r
+        return XML_ERROR_UNCLOSED_TOKEN;\r
+      case XML_TOK_PARTIAL_CHAR:\r
+        return XML_ERROR_PARTIAL_CHAR;\r
+      case XML_TOK_NONE:   /* start == end */\r
+      default:\r
+        break;\r
+      }\r
+      /* found end of entity value - can store it now */\r
+      return storeEntityValue(parser, encoding, s, end);\r
+    }\r
+    else if (tok == XML_TOK_XML_DECL) {\r
+      enum XML_Error result;\r
+      result = processXmlDecl(parser, 0, start, next);\r
+      if (result != XML_ERROR_NONE)\r
+        return result;\r
+      switch (ps_parsing) {\r
+      case XML_SUSPENDED:\r
+        *nextPtr = next;\r
+        return XML_ERROR_NONE;\r
+      case XML_FINISHED:\r
+        return XML_ERROR_ABORTED;\r
+      default:\r
+        *nextPtr = next;\r
+      }\r
+      /* stop scanning for text declaration - we found one */\r
+      processor = entityValueProcessor;\r
+      return entityValueProcessor(parser, next, end, nextPtr);\r
+    }\r
+    /* If we are at the end of the buffer, this would cause XmlPrologTok to\r
+       return XML_TOK_NONE on the next call, which would then cause the\r
+       function to exit with *nextPtr set to s - that is what we want for other\r
+       tokens, but not for the BOM - we would rather like to skip it;\r
+       then, when this routine is entered the next time, XmlPrologTok will\r
+       return XML_TOK_INVALID, since the BOM is still in the buffer\r
+    */\r
+    else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {\r
+      *nextPtr = next;\r
+      return XML_ERROR_NONE;\r
+    }\r
+    start = next;\r
+    eventPtr = start;\r
+  }\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+externalParEntProcessor(XML_Parser parser,\r
+                        const char *s,\r
+                        const char *end,\r
+                        const char **nextPtr)\r
+{\r
+  const char *next = s;\r
+  int tok;\r
+\r
+  tok = XmlPrologTok(encoding, s, end, &next);\r
+  if (tok <= 0) {\r
+    if (!ps_finalBuffer && tok != XML_TOK_INVALID) {\r
+      *nextPtr = s;\r
+      return XML_ERROR_NONE;\r
+    }\r
+    switch (tok) {\r
+    case XML_TOK_INVALID:\r
+      return XML_ERROR_INVALID_TOKEN;\r
+    case XML_TOK_PARTIAL:\r
+      return XML_ERROR_UNCLOSED_TOKEN;\r
+    case XML_TOK_PARTIAL_CHAR:\r
+      return XML_ERROR_PARTIAL_CHAR;\r
+    case XML_TOK_NONE:   /* start == end */\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.\r
+     However, when parsing an external subset, doProlog will not accept a BOM\r
+     as valid, and report a syntax error, so we have to skip the BOM\r
+  */\r
+  else if (tok == XML_TOK_BOM) {\r
+    s = next;\r
+    tok = XmlPrologTok(encoding, s, end, &next);\r
+  }\r
+\r
+  processor = prologProcessor;\r
+  return doProlog(parser, encoding, s, end, tok, next,\r
+                  nextPtr, (XML_Bool)!ps_finalBuffer);\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+entityValueProcessor(XML_Parser parser,\r
+                     const char *s,\r
+                     const char *end,\r
+                     const char **nextPtr)\r
+{\r
+  const char *start = s;\r
+  const char *next = s;\r
+  const ENCODING *enc = encoding;\r
+  int tok;\r
+\r
+  for (;;) {\r
+    tok = XmlPrologTok(enc, start, end, &next);\r
+    if (tok <= 0) {\r
+      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      switch (tok) {\r
+      case XML_TOK_INVALID:\r
+        return XML_ERROR_INVALID_TOKEN;\r
+      case XML_TOK_PARTIAL:\r
+        return XML_ERROR_UNCLOSED_TOKEN;\r
+      case XML_TOK_PARTIAL_CHAR:\r
+        return XML_ERROR_PARTIAL_CHAR;\r
+      case XML_TOK_NONE:   /* start == end */\r
+      default:\r
+        break;\r
+      }\r
+      /* found end of entity value - can store it now */\r
+      return storeEntityValue(parser, enc, s, end);\r
+    }\r
+    start = next;\r
+  }\r
+}\r
+\r
+#endif /* XML_DTD */\r
+\r
+static enum XML_Error PTRCALL\r
+prologProcessor(XML_Parser parser,\r
+                const char *s,\r
+                const char *end,\r
+                const char **nextPtr)\r
+{\r
+  const char *next = s;\r
+  int tok = XmlPrologTok(encoding, s, end, &next);\r
+  return doProlog(parser, encoding, s, end, tok, next,\r
+                  nextPtr, (XML_Bool)!ps_finalBuffer);\r
+}\r
+\r
+static enum XML_Error\r
+doProlog(XML_Parser parser,\r
+         const ENCODING *enc,\r
+         const char *s,\r
+         const char *end,\r
+         int tok,\r
+         const char *next,\r
+         const char **nextPtr,\r
+         XML_Bool haveMore)\r
+{\r
+#ifdef XML_DTD\r
+  static const XML_Char externalSubsetName[] = { '#' , '\0' };\r
+#endif /* XML_DTD */\r
+  static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };\r
+  static const XML_Char atypeID[] = { 'I', 'D', '\0' };\r
+  static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };\r
+  static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };\r
+  static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };\r
+  static const XML_Char atypeENTITIES[] =\r
+      { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };\r
+  static const XML_Char atypeNMTOKEN[] = {\r
+      'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };\r
+  static const XML_Char atypeNMTOKENS[] = {\r
+      'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };\r
+  static const XML_Char notationPrefix[] = {\r
+      'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };\r
+  static const XML_Char enumValueSep[] = { '|', '\0' };\r
+  static const XML_Char enumValueStart[] = { '(', '\0' };\r
+\r
+  /* save one level of indirection */\r
+  DTD * const dtd = _dtd;\r
+\r
+  const char **eventPP;\r
+  const char **eventEndPP;\r
+  enum XML_Content_Quant quant;\r
+\r
+  if (enc == encoding) {\r
+    eventPP = &eventPtr;\r
+    eventEndPP = &eventEndPtr;\r
+  }\r
+  else {\r
+    eventPP = &(openInternalEntities->internalEventPtr);\r
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);\r
+  }\r
+\r
+  for (;;) {\r
+    int role;\r
+    XML_Bool handleDefault = XML_TRUE;\r
+    *eventPP = s;\r
+    *eventEndPP = next;\r
+    if (tok <= 0) {\r
+      if (haveMore && tok != XML_TOK_INVALID) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      switch (tok) {\r
+      case XML_TOK_INVALID:\r
+        *eventPP = next;\r
+        return XML_ERROR_INVALID_TOKEN;\r
+      case XML_TOK_PARTIAL:\r
+        return XML_ERROR_UNCLOSED_TOKEN;\r
+      case XML_TOK_PARTIAL_CHAR:\r
+        return XML_ERROR_PARTIAL_CHAR;\r
+      case -XML_TOK_PROLOG_S:\r
+        tok = -tok;\r
+        break;\r
+      case XML_TOK_NONE:\r
+#ifdef XML_DTD\r
+        /* for internal PE NOT referenced between declarations */\r
+        if (enc != encoding && !openInternalEntities->betweenDecl) {\r
+          *nextPtr = s;\r
+          return XML_ERROR_NONE;\r
+        }\r
+        /* WFC: PE Between Declarations - must check that PE contains\r
+           complete markup, not only for external PEs, but also for\r
+           internal PEs if the reference occurs between declarations.\r
+        */\r
+        if (isParamEntity || enc != encoding) {\r
+          if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)\r
+              == XML_ROLE_ERROR)\r
+            return XML_ERROR_INCOMPLETE_PE;\r
+          *nextPtr = s;\r
+          return XML_ERROR_NONE;\r
+        }\r
+#endif /* XML_DTD */\r
+        return XML_ERROR_NO_ELEMENTS;\r
+      default:\r
+        tok = -tok;\r
+        next = end;\r
+        break;\r
+      }\r
+    }\r
+    role = XmlTokenRole(&prologState, tok, s, next, enc);\r
+    switch (role) {\r
+    case XML_ROLE_XML_DECL:\r
+      {\r
+        enum XML_Error result = processXmlDecl(parser, 0, s, next);\r
+        if (result != XML_ERROR_NONE)\r
+          return result;\r
+        enc = encoding;\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+    case XML_ROLE_DOCTYPE_NAME:\r
+      if (startDoctypeDeclHandler) {\r
+        doctypeName = poolStoreString(&tempPool, enc, s, next);\r
+        if (!doctypeName)\r
+          return XML_ERROR_NO_MEMORY;\r
+        poolFinish(&tempPool);\r
+        doctypePubid = NULL;\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      doctypeSysid = NULL; /* always initialize to NULL */\r
+      break;\r
+    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:\r
+      if (startDoctypeDeclHandler) {\r
+        startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,\r
+                                doctypePubid, 1);\r
+        doctypeName = NULL;\r
+        poolClear(&tempPool);\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+#ifdef XML_DTD\r
+    case XML_ROLE_TEXT_DECL:\r
+      {\r
+        enum XML_Error result = processXmlDecl(parser, 1, s, next);\r
+        if (result != XML_ERROR_NONE)\r
+          return result;\r
+        enc = encoding;\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+#endif /* XML_DTD */\r
+    case XML_ROLE_DOCTYPE_PUBLIC_ID:\r
+#ifdef XML_DTD\r
+      useForeignDTD = XML_FALSE;\r
+      declEntity = (ENTITY *)lookup(&dtd->paramEntities,\r
+                                    externalSubsetName,\r
+                                    sizeof(ENTITY));\r
+      if (!declEntity)\r
+        return XML_ERROR_NO_MEMORY;\r
+#endif /* XML_DTD */\r
+      dtd->hasParamEntityRefs = XML_TRUE;\r
+      if (startDoctypeDeclHandler) {\r
+        if (!XmlIsPublicId(enc, s, next, eventPP))\r
+          return XML_ERROR_PUBLICID;\r
+        doctypePubid = poolStoreString(&tempPool, enc,\r
+                                       s + enc->minBytesPerChar,\r
+                                       next - enc->minBytesPerChar);\r
+        if (!doctypePubid)\r
+          return XML_ERROR_NO_MEMORY;\r
+        normalizePublicId((XML_Char *)doctypePubid);\r
+        poolFinish(&tempPool);\r
+        handleDefault = XML_FALSE;\r
+        goto alreadyChecked;\r
+      }\r
+      /* fall through */\r
+    case XML_ROLE_ENTITY_PUBLIC_ID:\r
+      if (!XmlIsPublicId(enc, s, next, eventPP))\r
+        return XML_ERROR_PUBLICID;\r
+    alreadyChecked:\r
+      if (dtd->keepProcessing && declEntity) {\r
+        XML_Char *tem = poolStoreString(&dtd->pool,\r
+                                        enc,\r
+                                        s + enc->minBytesPerChar,\r
+                                        next - enc->minBytesPerChar);\r
+        if (!tem)\r
+          return XML_ERROR_NO_MEMORY;\r
+        normalizePublicId(tem);\r
+        declEntity->publicId = tem;\r
+        poolFinish(&dtd->pool);\r
+        if (entityDeclHandler)\r
+          handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+    case XML_ROLE_DOCTYPE_CLOSE:\r
+      if (doctypeName) {\r
+        startDoctypeDeclHandler(handlerArg, doctypeName,\r
+                                doctypeSysid, doctypePubid, 0);\r
+        poolClear(&tempPool);\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      /* doctypeSysid will be non-NULL in the case of a previous\r
+         XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler\r
+         was not set, indicating an external subset\r
+      */\r
+#ifdef XML_DTD\r
+      if (doctypeSysid || useForeignDTD) {\r
+        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;\r
+        dtd->hasParamEntityRefs = XML_TRUE;\r
+        if (paramEntityParsing && externalEntityRefHandler) {\r
+          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,\r
+                                            externalSubsetName,\r
+                                            sizeof(ENTITY));\r
+          if (!entity)\r
+            return XML_ERROR_NO_MEMORY;\r
+          if (useForeignDTD)\r
+            entity->base = curBase;\r
+          dtd->paramEntityRead = XML_FALSE;\r
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,\r
+                                        0,\r
+                                        entity->base,\r
+                                        entity->systemId,\r
+                                        entity->publicId))\r
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;\r
+          if (dtd->paramEntityRead) {\r
+            if (!dtd->standalone &&\r
+                notStandaloneHandler &&\r
+                !notStandaloneHandler(handlerArg))\r
+              return XML_ERROR_NOT_STANDALONE;\r
+          }\r
+          /* if we didn't read the foreign DTD then this means that there\r
+             is no external subset and we must reset dtd->hasParamEntityRefs\r
+          */\r
+          else if (!doctypeSysid)\r
+            dtd->hasParamEntityRefs = hadParamEntityRefs;\r
+          /* end of DTD - no need to update dtd->keepProcessing */\r
+        }\r
+        useForeignDTD = XML_FALSE;\r
+      }\r
+#endif /* XML_DTD */\r
+      if (endDoctypeDeclHandler) {\r
+        endDoctypeDeclHandler(handlerArg);\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+    case XML_ROLE_INSTANCE_START:\r
+#ifdef XML_DTD\r
+      /* if there is no DOCTYPE declaration then now is the\r
+         last chance to read the foreign DTD\r
+      */\r
+      if (useForeignDTD) {\r
+        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;\r
+        dtd->hasParamEntityRefs = XML_TRUE;\r
+        if (paramEntityParsing && externalEntityRefHandler) {\r
+          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,\r
+                                            externalSubsetName,\r
+                                            sizeof(ENTITY));\r
+          if (!entity)\r
+            return XML_ERROR_NO_MEMORY;\r
+          entity->base = curBase;\r
+          dtd->paramEntityRead = XML_FALSE;\r
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,\r
+                                        0,\r
+                                        entity->base,\r
+                                        entity->systemId,\r
+                                        entity->publicId))\r
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;\r
+          if (dtd->paramEntityRead) {\r
+            if (!dtd->standalone &&\r
+                notStandaloneHandler &&\r
+                !notStandaloneHandler(handlerArg))\r
+              return XML_ERROR_NOT_STANDALONE;\r
+          }\r
+          /* if we didn't read the foreign DTD then this means that there\r
+             is no external subset and we must reset dtd->hasParamEntityRefs\r
+          */\r
+          else\r
+            dtd->hasParamEntityRefs = hadParamEntityRefs;\r
+          /* end of DTD - no need to update dtd->keepProcessing */\r
+        }\r
+      }\r
+#endif /* XML_DTD */\r
+      processor = contentProcessor;\r
+      return contentProcessor(parser, s, end, nextPtr);\r
+    case XML_ROLE_ATTLIST_ELEMENT_NAME:\r
+      declElementType = getElementType(parser, enc, s, next);\r
+      if (!declElementType)\r
+        return XML_ERROR_NO_MEMORY;\r
+      goto checkAttListDeclHandler;\r
+    case XML_ROLE_ATTRIBUTE_NAME:\r
+      declAttributeId = getAttributeId(parser, enc, s, next);\r
+      if (!declAttributeId)\r
+        return XML_ERROR_NO_MEMORY;\r
+      declAttributeIsCdata = XML_FALSE;\r
+      declAttributeType = NULL;\r
+      declAttributeIsId = XML_FALSE;\r
+      goto checkAttListDeclHandler;\r
+    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:\r
+      declAttributeIsCdata = XML_TRUE;\r
+      declAttributeType = atypeCDATA;\r
+      goto checkAttListDeclHandler;\r
+    case XML_ROLE_ATTRIBUTE_TYPE_ID:\r
+      declAttributeIsId = XML_TRUE;\r
+      declAttributeType = atypeID;\r
+      goto checkAttListDeclHandler;\r
+    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:\r
+      declAttributeType = atypeIDREF;\r
+      goto checkAttListDeclHandler;\r
+    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:\r
+      declAttributeType = atypeIDREFS;\r
+      goto checkAttListDeclHandler;\r
+    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:\r
+      declAttributeType = atypeENTITY;\r
+      goto checkAttListDeclHandler;\r
+    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:\r
+      declAttributeType = atypeENTITIES;\r
+      goto checkAttListDeclHandler;\r
+    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:\r
+      declAttributeType = atypeNMTOKEN;\r
+      goto checkAttListDeclHandler;\r
+    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:\r
+      declAttributeType = atypeNMTOKENS;\r
+    checkAttListDeclHandler:\r
+      if (dtd->keepProcessing && attlistDeclHandler)\r
+        handleDefault = XML_FALSE;\r
+      break;\r
+    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:\r
+    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:\r
+      if (dtd->keepProcessing && attlistDeclHandler) {\r
+        const XML_Char *prefix;\r
+        if (declAttributeType) {\r
+          prefix = enumValueSep;\r
+        }\r
+        else {\r
+          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE\r
+                    ? notationPrefix\r
+                    : enumValueStart);\r
+        }\r
+        if (!poolAppendString(&tempPool, prefix))\r
+          return XML_ERROR_NO_MEMORY;\r
+        if (!poolAppend(&tempPool, enc, s, next))\r
+          return XML_ERROR_NO_MEMORY;\r
+        declAttributeType = tempPool.start;\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:\r
+    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:\r
+      if (dtd->keepProcessing) {\r
+        if (!defineAttribute(declElementType, declAttributeId,\r
+                             declAttributeIsCdata, declAttributeIsId,\r
+                             0, parser))\r
+          return XML_ERROR_NO_MEMORY;\r
+        if (attlistDeclHandler && declAttributeType) {\r
+          if (*declAttributeType == XML_T('(')\r
+              || (*declAttributeType == XML_T('N')\r
+                  && declAttributeType[1] == XML_T('O'))) {\r
+            /* Enumerated or Notation type */\r
+            if (!poolAppendChar(&tempPool, XML_T(')'))\r
+                || !poolAppendChar(&tempPool, XML_T('\0')))\r
+              return XML_ERROR_NO_MEMORY;\r
+            declAttributeType = tempPool.start;\r
+            poolFinish(&tempPool);\r
+          }\r
+          *eventEndPP = s;\r
+          attlistDeclHandler(handlerArg, declElementType->name,\r
+                             declAttributeId->name, declAttributeType,\r
+                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);\r
+          poolClear(&tempPool);\r
+          handleDefault = XML_FALSE;\r
+        }\r
+      }\r
+      break;\r
+    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:\r
+    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:\r
+      if (dtd->keepProcessing) {\r
+        const XML_Char *attVal;\r
+        enum XML_Error result =\r
+          storeAttributeValue(parser, enc, declAttributeIsCdata,\r
+                              s + enc->minBytesPerChar,\r
+                              next - enc->minBytesPerChar,\r
+                              &dtd->pool);\r
+        if (result)\r
+          return result;\r
+        attVal = poolStart(&dtd->pool);\r
+        poolFinish(&dtd->pool);\r
+        /* ID attributes aren't allowed to have a default */\r
+        if (!defineAttribute(declElementType, declAttributeId,\r
+                             declAttributeIsCdata, XML_FALSE, attVal, parser))\r
+          return XML_ERROR_NO_MEMORY;\r
+        if (attlistDeclHandler && declAttributeType) {\r
+          if (*declAttributeType == XML_T('(')\r
+              || (*declAttributeType == XML_T('N')\r
+                  && declAttributeType[1] == XML_T('O'))) {\r
+            /* Enumerated or Notation type */\r
+            if (!poolAppendChar(&tempPool, XML_T(')'))\r
+                || !poolAppendChar(&tempPool, XML_T('\0')))\r
+              return XML_ERROR_NO_MEMORY;\r
+            declAttributeType = tempPool.start;\r
+            poolFinish(&tempPool);\r
+          }\r
+          *eventEndPP = s;\r
+          attlistDeclHandler(handlerArg, declElementType->name,\r
+                             declAttributeId->name, declAttributeType,\r
+                             attVal,\r
+                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);\r
+          poolClear(&tempPool);\r
+          handleDefault = XML_FALSE;\r
+        }\r
+      }\r
+      break;\r
+    case XML_ROLE_ENTITY_VALUE:\r
+      if (dtd->keepProcessing) {\r
+        enum XML_Error result = storeEntityValue(parser, enc,\r
+                                            s + enc->minBytesPerChar,\r
+                                            next - enc->minBytesPerChar);\r
+        if (declEntity) {\r
+          declEntity->textPtr = poolStart(&dtd->entityValuePool);\r
+          declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));\r
+          poolFinish(&dtd->entityValuePool);\r
+          if (entityDeclHandler) {\r
+            *eventEndPP = s;\r
+            entityDeclHandler(handlerArg,\r
+                              declEntity->name,\r
+                              declEntity->is_param,\r
+                              declEntity->textPtr,\r
+                              declEntity->textLen,\r
+                              curBase, 0, 0, 0);\r
+            handleDefault = XML_FALSE;\r
+          }\r
+        }\r
+        else\r
+          poolDiscard(&dtd->entityValuePool);\r
+        if (result != XML_ERROR_NONE)\r
+          return result;\r
+      }\r
+      break;\r
+    case XML_ROLE_DOCTYPE_SYSTEM_ID:\r
+#ifdef XML_DTD\r
+      useForeignDTD = XML_FALSE;\r
+#endif /* XML_DTD */\r
+      dtd->hasParamEntityRefs = XML_TRUE;\r
+      if (startDoctypeDeclHandler) {\r
+        doctypeSysid = poolStoreString(&tempPool, enc,\r
+                                       s + enc->minBytesPerChar,\r
+                                       next - enc->minBytesPerChar);\r
+        if (doctypeSysid == NULL)\r
+          return XML_ERROR_NO_MEMORY;\r
+        poolFinish(&tempPool);\r
+        handleDefault = XML_FALSE;\r
+      }\r
+#ifdef XML_DTD\r
+      else\r
+        /* use externalSubsetName to make doctypeSysid non-NULL\r
+           for the case where no startDoctypeDeclHandler is set */\r
+        doctypeSysid = externalSubsetName;\r
+#endif /* XML_DTD */\r
+      if (!dtd->standalone\r
+#ifdef XML_DTD\r
+          && !paramEntityParsing\r
+#endif /* XML_DTD */\r
+          && notStandaloneHandler\r
+          && !notStandaloneHandler(handlerArg))\r
+        return XML_ERROR_NOT_STANDALONE;\r
+#ifndef XML_DTD\r
+      break;\r
+#else /* XML_DTD */\r
+      if (!declEntity) {\r
+        declEntity = (ENTITY *)lookup(&dtd->paramEntities,\r
+                                      externalSubsetName,\r
+                                      sizeof(ENTITY));\r
+        if (!declEntity)\r
+          return XML_ERROR_NO_MEMORY;\r
+        declEntity->publicId = NULL;\r
+      }\r
+      /* fall through */\r
+#endif /* XML_DTD */\r
+    case XML_ROLE_ENTITY_SYSTEM_ID:\r
+      if (dtd->keepProcessing && declEntity) {\r
+        declEntity->systemId = poolStoreString(&dtd->pool, enc,\r
+                                               s + enc->minBytesPerChar,\r
+                                               next - enc->minBytesPerChar);\r
+        if (!declEntity->systemId)\r
+          return XML_ERROR_NO_MEMORY;\r
+        declEntity->base = curBase;\r
+        poolFinish(&dtd->pool);\r
+        if (entityDeclHandler)\r
+          handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+    case XML_ROLE_ENTITY_COMPLETE:\r
+      if (dtd->keepProcessing && declEntity && entityDeclHandler) {\r
+        *eventEndPP = s;\r
+        entityDeclHandler(handlerArg,\r
+                          declEntity->name,\r
+                          declEntity->is_param,\r
+                          0,0,\r
+                          declEntity->base,\r
+                          declEntity->systemId,\r
+                          declEntity->publicId,\r
+                          0);\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+    case XML_ROLE_ENTITY_NOTATION_NAME:\r
+      if (dtd->keepProcessing && declEntity) {\r
+        declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);\r
+        if (!declEntity->notation)\r
+          return XML_ERROR_NO_MEMORY;\r
+        poolFinish(&dtd->pool);\r
+        if (unparsedEntityDeclHandler) {\r
+          *eventEndPP = s;\r
+          unparsedEntityDeclHandler(handlerArg,\r
+                                    declEntity->name,\r
+                                    declEntity->base,\r
+                                    declEntity->systemId,\r
+                                    declEntity->publicId,\r
+                                    declEntity->notation);\r
+          handleDefault = XML_FALSE;\r
+        }\r
+        else if (entityDeclHandler) {\r
+          *eventEndPP = s;\r
+          entityDeclHandler(handlerArg,\r
+                            declEntity->name,\r
+                            0,0,0,\r
+                            declEntity->base,\r
+                            declEntity->systemId,\r
+                            declEntity->publicId,\r
+                            declEntity->notation);\r
+          handleDefault = XML_FALSE;\r
+        }\r
+      }\r
+      break;\r
+    case XML_ROLE_GENERAL_ENTITY_NAME:\r
+      {\r
+        if (XmlPredefinedEntityName(enc, s, next)) {\r
+          declEntity = NULL;\r
+          break;\r
+        }\r
+        if (dtd->keepProcessing) {\r
+          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);\r
+          if (!name)\r
+            return XML_ERROR_NO_MEMORY;\r
+          declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,\r
+                                        sizeof(ENTITY));\r
+          if (!declEntity)\r
+            return XML_ERROR_NO_MEMORY;\r
+          if (declEntity->name != name) {\r
+            poolDiscard(&dtd->pool);\r
+            declEntity = NULL;\r
+          }\r
+          else {\r
+            poolFinish(&dtd->pool);\r
+            declEntity->publicId = NULL;\r
+            declEntity->is_param = XML_FALSE;\r
+            /* if we have a parent parser or are reading an internal parameter\r
+               entity, then the entity declaration is not considered "internal"\r
+            */\r
+            declEntity->is_internal = !(parentParser || openInternalEntities);\r
+            if (entityDeclHandler)\r
+              handleDefault = XML_FALSE;\r
+          }\r
+        }\r
+        else {\r
+          poolDiscard(&dtd->pool);\r
+          declEntity = NULL;\r
+        }\r
+      }\r
+      break;\r
+    case XML_ROLE_PARAM_ENTITY_NAME:\r
+#ifdef XML_DTD\r
+      if (dtd->keepProcessing) {\r
+        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);\r
+        if (!name)\r
+          return XML_ERROR_NO_MEMORY;\r
+        declEntity = (ENTITY *)lookup(&dtd->paramEntities,\r
+                                           name, sizeof(ENTITY));\r
+        if (!declEntity)\r
+          return XML_ERROR_NO_MEMORY;\r
+        if (declEntity->name != name) {\r
+          poolDiscard(&dtd->pool);\r
+          declEntity = NULL;\r
+        }\r
+        else {\r
+          poolFinish(&dtd->pool);\r
+          declEntity->publicId = NULL;\r
+          declEntity->is_param = XML_TRUE;\r
+          /* if we have a parent parser or are reading an internal parameter\r
+             entity, then the entity declaration is not considered "internal"\r
+          */\r
+          declEntity->is_internal = !(parentParser || openInternalEntities);\r
+          if (entityDeclHandler)\r
+            handleDefault = XML_FALSE;\r
+        }\r
+      }\r
+      else {\r
+        poolDiscard(&dtd->pool);\r
+        declEntity = NULL;\r
+      }\r
+#else /* not XML_DTD */\r
+      declEntity = NULL;\r
+#endif /* XML_DTD */\r
+      break;\r
+    case XML_ROLE_NOTATION_NAME:\r
+      declNotationPublicId = NULL;\r
+      declNotationName = NULL;\r
+      if (notationDeclHandler) {\r
+        declNotationName = poolStoreString(&tempPool, enc, s, next);\r
+        if (!declNotationName)\r
+          return XML_ERROR_NO_MEMORY;\r
+        poolFinish(&tempPool);\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+    case XML_ROLE_NOTATION_PUBLIC_ID:\r
+      if (!XmlIsPublicId(enc, s, next, eventPP))\r
+        return XML_ERROR_PUBLICID;\r
+      if (declNotationName) {  /* means notationDeclHandler != NULL */\r
+        XML_Char *tem = poolStoreString(&tempPool,\r
+                                        enc,\r
+                                        s + enc->minBytesPerChar,\r
+                                        next - enc->minBytesPerChar);\r
+        if (!tem)\r
+          return XML_ERROR_NO_MEMORY;\r
+        normalizePublicId(tem);\r
+        declNotationPublicId = tem;\r
+        poolFinish(&tempPool);\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+    case XML_ROLE_NOTATION_SYSTEM_ID:\r
+      if (declNotationName && notationDeclHandler) {\r
+        const XML_Char *systemId\r
+          = poolStoreString(&tempPool, enc,\r
+                            s + enc->minBytesPerChar,\r
+                            next - enc->minBytesPerChar);\r
+        if (!systemId)\r
+          return XML_ERROR_NO_MEMORY;\r
+        *eventEndPP = s;\r
+        notationDeclHandler(handlerArg,\r
+                            declNotationName,\r
+                            curBase,\r
+                            systemId,\r
+                            declNotationPublicId);\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      poolClear(&tempPool);\r
+      break;\r
+    case XML_ROLE_NOTATION_NO_SYSTEM_ID:\r
+      if (declNotationPublicId && notationDeclHandler) {\r
+        *eventEndPP = s;\r
+        notationDeclHandler(handlerArg,\r
+                            declNotationName,\r
+                            curBase,\r
+                            0,\r
+                            declNotationPublicId);\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      poolClear(&tempPool);\r
+      break;\r
+    case XML_ROLE_ERROR:\r
+      switch (tok) {\r
+      case XML_TOK_PARAM_ENTITY_REF:\r
+        /* PE references in internal subset are\r
+           not allowed within declarations. */\r
+        return XML_ERROR_PARAM_ENTITY_REF;\r
+      case XML_TOK_XML_DECL:\r
+        return XML_ERROR_MISPLACED_XML_PI;\r
+      default:\r
+        return XML_ERROR_SYNTAX;\r
+      }\r
+#ifdef XML_DTD\r
+    case XML_ROLE_IGNORE_SECT:\r
+      {\r
+        enum XML_Error result;\r
+        if (defaultHandler)\r
+          reportDefault(parser, enc, s, next);\r
+        handleDefault = XML_FALSE;\r
+        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);\r
+        if (result != XML_ERROR_NONE)\r
+          return result;\r
+        else if (!next) {\r
+          processor = ignoreSectionProcessor;\r
+          return result;\r
+        }\r
+      }\r
+      break;\r
+#endif /* XML_DTD */\r
+    case XML_ROLE_GROUP_OPEN:\r
+      if (prologState.level >= groupSize) {\r
+        if (groupSize) {\r
+          char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);\r
+          if (temp == NULL)\r
+            return XML_ERROR_NO_MEMORY;\r
+          groupConnector = temp;\r
+          if (dtd->scaffIndex) {\r
+            int *temp = (int *)REALLOC(dtd->scaffIndex,\r
+                          groupSize * sizeof(int));\r
+            if (temp == NULL)\r
+              return XML_ERROR_NO_MEMORY;\r
+            dtd->scaffIndex = temp;\r
+          }\r
+        }\r
+        else {\r
+          groupConnector = (char *)MALLOC(groupSize = 32);\r
+          if (!groupConnector)\r
+            return XML_ERROR_NO_MEMORY;\r
+        }\r
+      }\r
+      groupConnector[prologState.level] = 0;\r
+      if (dtd->in_eldecl) {\r
+        int myindex = nextScaffoldPart(parser);\r
+        if (myindex < 0)\r
+          return XML_ERROR_NO_MEMORY;\r
+        dtd->scaffIndex[dtd->scaffLevel] = myindex;\r
+        dtd->scaffLevel++;\r
+        dtd->scaffold[myindex].type = XML_CTYPE_SEQ;\r
+        if (elementDeclHandler)\r
+          handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+    case XML_ROLE_GROUP_SEQUENCE:\r
+      if (groupConnector[prologState.level] == '|')\r
+        return XML_ERROR_SYNTAX;\r
+      groupConnector[prologState.level] = ',';\r
+      if (dtd->in_eldecl && elementDeclHandler)\r
+        handleDefault = XML_FALSE;\r
+      break;\r
+    case XML_ROLE_GROUP_CHOICE:\r
+      if (groupConnector[prologState.level] == ',')\r
+        return XML_ERROR_SYNTAX;\r
+      if (dtd->in_eldecl\r
+          && !groupConnector[prologState.level]\r
+          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type\r
+              != XML_CTYPE_MIXED)\r
+          ) {\r
+        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type\r
+            = XML_CTYPE_CHOICE;\r
+        if (elementDeclHandler)\r
+          handleDefault = XML_FALSE;\r
+      }\r
+      groupConnector[prologState.level] = '|';\r
+      break;\r
+    case XML_ROLE_PARAM_ENTITY_REF:\r
+#ifdef XML_DTD\r
+    case XML_ROLE_INNER_PARAM_ENTITY_REF:\r
+      dtd->hasParamEntityRefs = XML_TRUE;\r
+      if (!paramEntityParsing)\r
+        dtd->keepProcessing = dtd->standalone;\r
+      else {\r
+        const XML_Char *name;\r
+        ENTITY *entity;\r
+        name = poolStoreString(&dtd->pool, enc,\r
+                                s + enc->minBytesPerChar,\r
+                                next - enc->minBytesPerChar);\r
+        if (!name)\r
+          return XML_ERROR_NO_MEMORY;\r
+        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);\r
+        poolDiscard(&dtd->pool);\r
+        /* first, determine if a check for an existing declaration is needed;\r
+           if yes, check that the entity exists, and that it is internal,\r
+           otherwise call the skipped entity handler\r
+        */\r
+        if (prologState.documentEntity &&\r
+            (dtd->standalone\r
+             ? !openInternalEntities\r
+             : !dtd->hasParamEntityRefs)) {\r
+          if (!entity)\r
+            return XML_ERROR_UNDEFINED_ENTITY;\r
+          else if (!entity->is_internal)\r
+            return XML_ERROR_ENTITY_DECLARED_IN_PE;\r
+        }\r
+        else if (!entity) {\r
+          dtd->keepProcessing = dtd->standalone;\r
+          /* cannot report skipped entities in declarations */\r
+          if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {\r
+            skippedEntityHandler(handlerArg, name, 1);\r
+            handleDefault = XML_FALSE;\r
+          }\r
+          break;\r
+        }\r
+        if (entity->open)\r
+          return XML_ERROR_RECURSIVE_ENTITY_REF;\r
+        if (entity->textPtr) {\r
+          enum XML_Error result;\r
+          XML_Bool betweenDecl =\r
+            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);\r
+          result = processInternalEntity(parser, entity, betweenDecl);\r
+          if (result != XML_ERROR_NONE)\r
+            return result;\r
+          handleDefault = XML_FALSE;\r
+          break;\r
+        }\r
+        if (externalEntityRefHandler) {\r
+          dtd->paramEntityRead = XML_FALSE;\r
+          entity->open = XML_TRUE;\r
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,\r
+                                        0,\r
+                                        entity->base,\r
+                                        entity->systemId,\r
+                                        entity->publicId)) {\r
+            entity->open = XML_FALSE;\r
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;\r
+          }\r
+          entity->open = XML_FALSE;\r
+          handleDefault = XML_FALSE;\r
+          if (!dtd->paramEntityRead) {\r
+            dtd->keepProcessing = dtd->standalone;\r
+            break;\r
+          }\r
+        }\r
+        else {\r
+          dtd->keepProcessing = dtd->standalone;\r
+          break;\r
+        }\r
+      }\r
+#endif /* XML_DTD */\r
+      if (!dtd->standalone &&\r
+          notStandaloneHandler &&\r
+          !notStandaloneHandler(handlerArg))\r
+        return XML_ERROR_NOT_STANDALONE;\r
+      break;\r
+\r
+    /* Element declaration stuff */\r
+\r
+    case XML_ROLE_ELEMENT_NAME:\r
+      if (elementDeclHandler) {\r
+        declElementType = getElementType(parser, enc, s, next);\r
+        if (!declElementType)\r
+          return XML_ERROR_NO_MEMORY;\r
+        dtd->scaffLevel = 0;\r
+        dtd->scaffCount = 0;\r
+        dtd->in_eldecl = XML_TRUE;\r
+        handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+\r
+    case XML_ROLE_CONTENT_ANY:\r
+    case XML_ROLE_CONTENT_EMPTY:\r
+      if (dtd->in_eldecl) {\r
+        if (elementDeclHandler) {\r
+          XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));\r
+          if (!content)\r
+            return XML_ERROR_NO_MEMORY;\r
+          content->quant = XML_CQUANT_NONE;\r
+          content->name = NULL;\r
+          content->numchildren = 0;\r
+          content->children = NULL;\r
+          content->type = ((role == XML_ROLE_CONTENT_ANY) ?\r
+                           XML_CTYPE_ANY :\r
+                           XML_CTYPE_EMPTY);\r
+          *eventEndPP = s;\r
+          elementDeclHandler(handlerArg, declElementType->name, content);\r
+          handleDefault = XML_FALSE;\r
+        }\r
+        dtd->in_eldecl = XML_FALSE;\r
+      }\r
+      break;\r
+\r
+    case XML_ROLE_CONTENT_PCDATA:\r
+      if (dtd->in_eldecl) {\r
+        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type\r
+            = XML_CTYPE_MIXED;\r
+        if (elementDeclHandler)\r
+          handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+\r
+    case XML_ROLE_CONTENT_ELEMENT:\r
+      quant = XML_CQUANT_NONE;\r
+      goto elementContent;\r
+    case XML_ROLE_CONTENT_ELEMENT_OPT:\r
+      quant = XML_CQUANT_OPT;\r
+      goto elementContent;\r
+    case XML_ROLE_CONTENT_ELEMENT_REP:\r
+      quant = XML_CQUANT_REP;\r
+      goto elementContent;\r
+    case XML_ROLE_CONTENT_ELEMENT_PLUS:\r
+      quant = XML_CQUANT_PLUS;\r
+    elementContent:\r
+      if (dtd->in_eldecl) {\r
+        ELEMENT_TYPE *el;\r
+        const XML_Char *name;\r
+        int nameLen;\r
+        const char *nxt = (quant == XML_CQUANT_NONE\r
+                           ? next\r
+                           : next - enc->minBytesPerChar);\r
+        int myindex = nextScaffoldPart(parser);\r
+        if (myindex < 0)\r
+          return XML_ERROR_NO_MEMORY;\r
+        dtd->scaffold[myindex].type = XML_CTYPE_NAME;\r
+        dtd->scaffold[myindex].quant = quant;\r
+        el = getElementType(parser, enc, s, nxt);\r
+        if (!el)\r
+          return XML_ERROR_NO_MEMORY;\r
+        name = el->name;\r
+        dtd->scaffold[myindex].name = name;\r
+        nameLen = 0;\r
+        for (; name[nameLen++]; );\r
+        dtd->contentStringLen +=  nameLen;\r
+        if (elementDeclHandler)\r
+          handleDefault = XML_FALSE;\r
+      }\r
+      break;\r
+\r
+    case XML_ROLE_GROUP_CLOSE:\r
+      quant = XML_CQUANT_NONE;\r
+      goto closeGroup;\r
+    case XML_ROLE_GROUP_CLOSE_OPT:\r
+      quant = XML_CQUANT_OPT;\r
+      goto closeGroup;\r
+    case XML_ROLE_GROUP_CLOSE_REP:\r
+      quant = XML_CQUANT_REP;\r
+      goto closeGroup;\r
+    case XML_ROLE_GROUP_CLOSE_PLUS:\r
+      quant = XML_CQUANT_PLUS;\r
+    closeGroup:\r
+      if (dtd->in_eldecl) {\r
+        if (elementDeclHandler)\r
+          handleDefault = XML_FALSE;\r
+        dtd->scaffLevel--;\r
+        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;\r
+        if (dtd->scaffLevel == 0) {\r
+          if (!handleDefault) {\r
+            XML_Content *model = build_model(parser);\r
+            if (!model)\r
+              return XML_ERROR_NO_MEMORY;\r
+            *eventEndPP = s;\r
+            elementDeclHandler(handlerArg, declElementType->name, model);\r
+          }\r
+          dtd->in_eldecl = XML_FALSE;\r
+          dtd->contentStringLen = 0;\r
+        }\r
+      }\r
+      break;\r
+      /* End element declaration stuff */\r
+\r
+    case XML_ROLE_PI:\r
+      if (!reportProcessingInstruction(parser, enc, s, next))\r
+        return XML_ERROR_NO_MEMORY;\r
+      handleDefault = XML_FALSE;\r
+      break;\r
+    case XML_ROLE_COMMENT:\r
+      if (!reportComment(parser, enc, s, next))\r
+        return XML_ERROR_NO_MEMORY;\r
+      handleDefault = XML_FALSE;\r
+      break;\r
+    case XML_ROLE_NONE:\r
+      switch (tok) {\r
+      case XML_TOK_BOM:\r
+        handleDefault = XML_FALSE;\r
+        break;\r
+      }\r
+      break;\r
+    case XML_ROLE_DOCTYPE_NONE:\r
+      if (startDoctypeDeclHandler)\r
+        handleDefault = XML_FALSE;\r
+      break;\r
+    case XML_ROLE_ENTITY_NONE:\r
+      if (dtd->keepProcessing && entityDeclHandler)\r
+        handleDefault = XML_FALSE;\r
+      break;\r
+    case XML_ROLE_NOTATION_NONE:\r
+      if (notationDeclHandler)\r
+        handleDefault = XML_FALSE;\r
+      break;\r
+    case XML_ROLE_ATTLIST_NONE:\r
+      if (dtd->keepProcessing && attlistDeclHandler)\r
+        handleDefault = XML_FALSE;\r
+      break;\r
+    case XML_ROLE_ELEMENT_NONE:\r
+      if (elementDeclHandler)\r
+        handleDefault = XML_FALSE;\r
+      break;\r
+    } /* end of big switch */\r
+\r
+    if (handleDefault && defaultHandler)\r
+      reportDefault(parser, enc, s, next);\r
+\r
+    switch (ps_parsing) {\r
+    case XML_SUSPENDED:\r
+      *nextPtr = next;\r
+      return XML_ERROR_NONE;\r
+    case XML_FINISHED:\r
+      return XML_ERROR_ABORTED;\r
+    default:\r
+      s = next;\r
+      tok = XmlPrologTok(enc, s, end, &next);\r
+    }\r
+  }\r
+  /* not reached */\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+epilogProcessor(XML_Parser parser,\r
+                const char *s,\r
+                const char *end,\r
+                const char **nextPtr)\r
+{\r
+  processor = epilogProcessor;\r
+  eventPtr = s;\r
+  for (;;) {\r
+    const char *next = NULL;\r
+    int tok = XmlPrologTok(encoding, s, end, &next);\r
+    eventEndPtr = next;\r
+    switch (tok) {\r
+    /* report partial linebreak - it might be the last token */\r
+    case -XML_TOK_PROLOG_S:\r
+      if (defaultHandler) {\r
+        reportDefault(parser, encoding, s, next);\r
+        if (ps_parsing == XML_FINISHED)\r
+          return XML_ERROR_ABORTED;\r
+      }\r
+      *nextPtr = next;\r
+      return XML_ERROR_NONE;\r
+    case XML_TOK_NONE:\r
+      *nextPtr = s;\r
+      return XML_ERROR_NONE;\r
+    case XML_TOK_PROLOG_S:\r
+      if (defaultHandler)\r
+        reportDefault(parser, encoding, s, next);\r
+      break;\r
+    case XML_TOK_PI:\r
+      if (!reportProcessingInstruction(parser, encoding, s, next))\r
+        return XML_ERROR_NO_MEMORY;\r
+      break;\r
+    case XML_TOK_COMMENT:\r
+      if (!reportComment(parser, encoding, s, next))\r
+        return XML_ERROR_NO_MEMORY;\r
+      break;\r
+    case XML_TOK_INVALID:\r
+      eventPtr = next;\r
+      return XML_ERROR_INVALID_TOKEN;\r
+    case XML_TOK_PARTIAL:\r
+      if (!ps_finalBuffer) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      return XML_ERROR_UNCLOSED_TOKEN;\r
+    case XML_TOK_PARTIAL_CHAR:\r
+      if (!ps_finalBuffer) {\r
+        *nextPtr = s;\r
+        return XML_ERROR_NONE;\r
+      }\r
+      return XML_ERROR_PARTIAL_CHAR;\r
+    default:\r
+      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;\r
+    }\r
+    eventPtr = s = next;\r
+    switch (ps_parsing) {\r
+    case XML_SUSPENDED:\r
+      *nextPtr = next;\r
+      return XML_ERROR_NONE;\r
+    case XML_FINISHED:\r
+      return XML_ERROR_ABORTED;\r
+    default: ;\r
+    }\r
+  }\r
+}\r
+\r
+static enum XML_Error\r
+processInternalEntity(XML_Parser parser, ENTITY *entity,\r
+                      XML_Bool betweenDecl)\r
+{\r
+  const char *textStart, *textEnd;\r
+  const char *next;\r
+  enum XML_Error result;\r
+  OPEN_INTERNAL_ENTITY *openEntity;\r
+\r
+  if (freeInternalEntities) {\r
+    openEntity = freeInternalEntities;\r
+    freeInternalEntities = openEntity->next;\r
+  }\r
+  else {\r
+    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));\r
+    if (!openEntity)\r
+      return XML_ERROR_NO_MEMORY;\r
+  }\r
+  entity->open = XML_TRUE;\r
+  entity->processed = 0;\r
+  openEntity->next = openInternalEntities;\r
+  openInternalEntities = openEntity;\r
+  openEntity->entity = entity;\r
+  openEntity->startTagLevel = tagLevel;\r
+  openEntity->betweenDecl = betweenDecl;\r
+  openEntity->internalEventPtr = NULL;\r
+  openEntity->internalEventEndPtr = NULL;\r
+  textStart = (char *)entity->textPtr;\r
+  textEnd = (char *)(entity->textPtr + entity->textLen);\r
+\r
+#ifdef XML_DTD\r
+  if (entity->is_param) {\r
+    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);\r
+    result = doProlog(parser, internalEncoding, textStart, textEnd, tok,\r
+                      next, &next, XML_FALSE);\r
+  }\r
+  else\r
+#endif /* XML_DTD */\r
+    result = doContent(parser, tagLevel, internalEncoding, textStart,\r
+                       textEnd, &next, XML_FALSE);\r
+\r
+  if (result == XML_ERROR_NONE) {\r
+    if (textEnd != next && ps_parsing == XML_SUSPENDED) {\r
+      entity->processed = (int)(next - textStart);\r
+      processor = internalEntityProcessor;\r
+    }\r
+    else {\r
+      entity->open = XML_FALSE;\r
+      openInternalEntities = openEntity->next;\r
+      /* put openEntity back in list of free instances */\r
+      openEntity->next = freeInternalEntities;\r
+      freeInternalEntities = openEntity;\r
+    }\r
+  }\r
+  return result;\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+internalEntityProcessor(XML_Parser parser,\r
+                        const char *s,\r
+                        const char *end,\r
+                        const char **nextPtr)\r
+{\r
+  ENTITY *entity;\r
+  const char *textStart, *textEnd;\r
+  const char *next;\r
+  enum XML_Error result;\r
+  OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;\r
+  if (!openEntity)\r
+    return XML_ERROR_UNEXPECTED_STATE;\r
+\r
+  entity = openEntity->entity;\r
+  textStart = ((char *)entity->textPtr) + entity->processed;\r
+  textEnd = (char *)(entity->textPtr + entity->textLen);\r
+\r
+#ifdef XML_DTD\r
+  if (entity->is_param) {\r
+    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);\r
+    result = doProlog(parser, internalEncoding, textStart, textEnd, tok,\r
+                      next, &next, XML_FALSE);\r
+  }\r
+  else\r
+#endif /* XML_DTD */\r
+    result = doContent(parser, openEntity->startTagLevel, internalEncoding,\r
+                       textStart, textEnd, &next, XML_FALSE);\r
+\r
+  if (result != XML_ERROR_NONE)\r
+    return result;\r
+  else if (textEnd != next && ps_parsing == XML_SUSPENDED) {\r
+    entity->processed = (int)(next - (char *)entity->textPtr);\r
+    return result;\r
+  }\r
+  else {\r
+    entity->open = XML_FALSE;\r
+    openInternalEntities = openEntity->next;\r
+    /* put openEntity back in list of free instances */\r
+    openEntity->next = freeInternalEntities;\r
+    freeInternalEntities = openEntity;\r
+  }\r
+\r
+#ifdef XML_DTD\r
+  if (entity->is_param) {\r
+    int tok;\r
+    processor = prologProcessor;\r
+    tok = XmlPrologTok(encoding, s, end, &next);\r
+    return doProlog(parser, encoding, s, end, tok, next, nextPtr,\r
+                    (XML_Bool)!ps_finalBuffer);\r
+  }\r
+  else\r
+#endif /* XML_DTD */\r
+  {\r
+    processor = contentProcessor;\r
+    /* see externalEntityContentProcessor vs contentProcessor */\r
+    return doContent(parser, parentParser ? 1 : 0, encoding, s, end,\r
+                     nextPtr, (XML_Bool)!ps_finalBuffer);\r
+  }\r
+}\r
+\r
+static enum XML_Error PTRCALL\r
+errorProcessor(XML_Parser parser,\r
+               const char *s,\r
+               const char *end,\r
+               const char **nextPtr)\r
+{\r
+  return errorCode;\r
+}\r
+\r
+static enum XML_Error\r
+storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,\r
+                    const char *ptr, const char *end,\r
+                    STRING_POOL *pool)\r
+{\r
+  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,\r
+                                               end, pool);\r
+  if (result)\r
+    return result;\r
+  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)\r
+    poolChop(pool);\r
+  if (!poolAppendChar(pool, XML_T('\0')))\r
+    return XML_ERROR_NO_MEMORY;\r
+  return XML_ERROR_NONE;\r
+}\r
+\r
+static enum XML_Error\r
+appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,\r
+                     const char *ptr, const char *end,\r
+                     STRING_POOL *pool)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  for (;;) {\r
+    const char *next;\r
+    int tok = XmlAttributeValueTok(enc, ptr, end, &next);\r
+    switch (tok) {\r
+    case XML_TOK_NONE:\r
+      return XML_ERROR_NONE;\r
+    case XML_TOK_INVALID:\r
+      if (enc == encoding)\r
+        eventPtr = next;\r
+      return XML_ERROR_INVALID_TOKEN;\r
+    case XML_TOK_PARTIAL:\r
+      if (enc == encoding)\r
+        eventPtr = ptr;\r
+      return XML_ERROR_INVALID_TOKEN;\r
+    case XML_TOK_CHAR_REF:\r
+      {\r
+        XML_Char buf[XML_ENCODE_MAX];\r
+        int i;\r
+        int n = XmlCharRefNumber(enc, ptr);\r
+        if (n < 0) {\r
+          if (enc == encoding)\r
+            eventPtr = ptr;\r
+          return XML_ERROR_BAD_CHAR_REF;\r
+        }\r
+        if (!isCdata\r
+            && n == 0x20 /* space */\r
+            && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))\r
+          break;\r
+        n = XmlEncode(n, (ICHAR *)buf);\r
+        if (!n) {\r
+          if (enc == encoding)\r
+            eventPtr = ptr;\r
+          return XML_ERROR_BAD_CHAR_REF;\r
+        }\r
+        for (i = 0; i < n; i++) {\r
+          if (!poolAppendChar(pool, buf[i]))\r
+            return XML_ERROR_NO_MEMORY;\r
+        }\r
+      }\r
+      break;\r
+    case XML_TOK_DATA_CHARS:\r
+      if (!poolAppend(pool, enc, ptr, next))\r
+        return XML_ERROR_NO_MEMORY;\r
+      break;\r
+    case XML_TOK_TRAILING_CR:\r
+      next = ptr + enc->minBytesPerChar;\r
+      /* fall through */\r
+    case XML_TOK_ATTRIBUTE_VALUE_S:\r
+    case XML_TOK_DATA_NEWLINE:\r
+      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))\r
+        break;\r
+      if (!poolAppendChar(pool, 0x20))\r
+        return XML_ERROR_NO_MEMORY;\r
+      break;\r
+    case XML_TOK_ENTITY_REF:\r
+      {\r
+        const XML_Char *name;\r
+        ENTITY *entity;\r
+        char checkEntityDecl;\r
+        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,\r
+                                              ptr + enc->minBytesPerChar,\r
+                                              next - enc->minBytesPerChar);\r
+        if (ch) {\r
+          if (!poolAppendChar(pool, ch))\r
+                return XML_ERROR_NO_MEMORY;\r
+          break;\r
+        }\r
+        name = poolStoreString(&temp2Pool, enc,\r
+                               ptr + enc->minBytesPerChar,\r
+                               next - enc->minBytesPerChar);\r
+        if (!name)\r
+          return XML_ERROR_NO_MEMORY;\r
+        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);\r
+        poolDiscard(&temp2Pool);\r
+        /* First, determine if a check for an existing declaration is needed;\r
+           if yes, check that the entity exists, and that it is internal.\r
+        */\r
+        if (pool == &dtd->pool)  /* are we called from prolog? */\r
+          checkEntityDecl =\r
+#ifdef XML_DTD\r
+              prologState.documentEntity &&\r
+#endif /* XML_DTD */\r
+              (dtd->standalone\r
+               ? !openInternalEntities\r
+               : !dtd->hasParamEntityRefs);\r
+        else /* if (pool == &tempPool): we are called from content */\r
+          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;\r
+        if (checkEntityDecl) {\r
+          if (!entity)\r
+            return XML_ERROR_UNDEFINED_ENTITY;\r
+          else if (!entity->is_internal)\r
+            return XML_ERROR_ENTITY_DECLARED_IN_PE;\r
+        }\r
+        else if (!entity) {\r
+          /* Cannot report skipped entity here - see comments on\r
+             skippedEntityHandler.\r
+          if (skippedEntityHandler)\r
+            skippedEntityHandler(handlerArg, name, 0);\r
+          */\r
+          /* Cannot call the default handler because this would be\r
+             out of sync with the call to the startElementHandler.\r
+          if ((pool == &tempPool) && defaultHandler)\r
+            reportDefault(parser, enc, ptr, next);\r
+          */\r
+          break;\r
+        }\r
+        if (entity->open) {\r
+          if (enc == encoding)\r
+            eventPtr = ptr;\r
+          return XML_ERROR_RECURSIVE_ENTITY_REF;\r
+        }\r
+        if (entity->notation) {\r
+          if (enc == encoding)\r
+            eventPtr = ptr;\r
+          return XML_ERROR_BINARY_ENTITY_REF;\r
+        }\r
+        if (!entity->textPtr) {\r
+          if (enc == encoding)\r
+            eventPtr = ptr;\r
+              return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;\r
+        }\r
+        else {\r
+          enum XML_Error result;\r
+          const XML_Char *textEnd = entity->textPtr + entity->textLen;\r
+          entity->open = XML_TRUE;\r
+          result = appendAttributeValue(parser, internalEncoding, isCdata,\r
+                                        (char *)entity->textPtr,\r
+                                        (char *)textEnd, pool);\r
+          entity->open = XML_FALSE;\r
+          if (result)\r
+            return result;\r
+        }\r
+      }\r
+      break;\r
+    default:\r
+      if (enc == encoding)\r
+        eventPtr = ptr;\r
+      return XML_ERROR_UNEXPECTED_STATE;\r
+    }\r
+    ptr = next;\r
+  }\r
+  /* not reached */\r
+}\r
+\r
+static enum XML_Error\r
+storeEntityValue(XML_Parser parser,\r
+                 const ENCODING *enc,\r
+                 const char *entityTextPtr,\r
+                 const char *entityTextEnd)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  STRING_POOL *pool = &(dtd->entityValuePool);\r
+  enum XML_Error result = XML_ERROR_NONE;\r
+#ifdef XML_DTD\r
+  int oldInEntityValue = prologState.inEntityValue;\r
+  prologState.inEntityValue = 1;\r
+#endif /* XML_DTD */\r
+  /* never return Null for the value argument in EntityDeclHandler,\r
+     since this would indicate an external entity; therefore we\r
+     have to make sure that entityValuePool.start is not null */\r
+  if (!pool->blocks) {\r
+    if (!poolGrow(pool))\r
+      return XML_ERROR_NO_MEMORY;\r
+  }\r
+\r
+  for (;;) {\r
+    const char *next;\r
+    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);\r
+    switch (tok) {\r
+    case XML_TOK_PARAM_ENTITY_REF:\r
+#ifdef XML_DTD\r
+      if (isParamEntity || enc != encoding) {\r
+        const XML_Char *name;\r
+        ENTITY *entity;\r
+        name = poolStoreString(&tempPool, enc,\r
+                               entityTextPtr + enc->minBytesPerChar,\r
+                               next - enc->minBytesPerChar);\r
+        if (!name) {\r
+          result = XML_ERROR_NO_MEMORY;\r
+          goto endEntityValue;\r
+        }\r
+        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);\r
+        poolDiscard(&tempPool);\r
+        if (!entity) {\r
+          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */\r
+          /* cannot report skipped entity here - see comments on\r
+             skippedEntityHandler\r
+          if (skippedEntityHandler)\r
+            skippedEntityHandler(handlerArg, name, 0);\r
+          */\r
+          dtd->keepProcessing = dtd->standalone;\r
+          goto endEntityValue;\r
+        }\r
+        if (entity->open) {\r
+          if (enc == encoding)\r
+            eventPtr = entityTextPtr;\r
+          result = XML_ERROR_RECURSIVE_ENTITY_REF;\r
+          goto endEntityValue;\r
+        }\r
+        if (entity->systemId) {\r
+          if (externalEntityRefHandler) {\r
+            dtd->paramEntityRead = XML_FALSE;\r
+            entity->open = XML_TRUE;\r
+            if (!externalEntityRefHandler(externalEntityRefHandlerArg,\r
+                                          0,\r
+                                          entity->base,\r
+                                          entity->systemId,\r
+                                          entity->publicId)) {\r
+              entity->open = XML_FALSE;\r
+              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;\r
+              goto endEntityValue;\r
+            }\r
+            entity->open = XML_FALSE;\r
+            if (!dtd->paramEntityRead)\r
+              dtd->keepProcessing = dtd->standalone;\r
+          }\r
+          else\r
+            dtd->keepProcessing = dtd->standalone;\r
+        }\r
+        else {\r
+          entity->open = XML_TRUE;\r
+          result = storeEntityValue(parser,\r
+                                    internalEncoding,\r
+                                    (char *)entity->textPtr,\r
+                                    (char *)(entity->textPtr\r
+                                             + entity->textLen));\r
+          entity->open = XML_FALSE;\r
+          if (result)\r
+            goto endEntityValue;\r
+        }\r
+        break;\r
+      }\r
+#endif /* XML_DTD */\r
+      /* In the internal subset, PE references are not legal\r
+         within markup declarations, e.g entity values in this case. */\r
+      eventPtr = entityTextPtr;\r
+      result = XML_ERROR_PARAM_ENTITY_REF;\r
+      goto endEntityValue;\r
+    case XML_TOK_NONE:\r
+      result = XML_ERROR_NONE;\r
+      goto endEntityValue;\r
+    case XML_TOK_ENTITY_REF:\r
+    case XML_TOK_DATA_CHARS:\r
+      if (!poolAppend(pool, enc, entityTextPtr, next)) {\r
+        result = XML_ERROR_NO_MEMORY;\r
+        goto endEntityValue;\r
+      }\r
+      break;\r
+    case XML_TOK_TRAILING_CR:\r
+      next = entityTextPtr + enc->minBytesPerChar;\r
+      /* fall through */\r
+    case XML_TOK_DATA_NEWLINE:\r
+      if (pool->end == pool->ptr && !poolGrow(pool)) {\r
+              result = XML_ERROR_NO_MEMORY;\r
+        goto endEntityValue;\r
+      }\r
+      *(pool->ptr)++ = 0xA;\r
+      break;\r
+    case XML_TOK_CHAR_REF:\r
+      {\r
+        XML_Char buf[XML_ENCODE_MAX];\r
+        int i;\r
+        int n = XmlCharRefNumber(enc, entityTextPtr);\r
+        if (n < 0) {\r
+          if (enc == encoding)\r
+            eventPtr = entityTextPtr;\r
+          result = XML_ERROR_BAD_CHAR_REF;\r
+          goto endEntityValue;\r
+        }\r
+        n = XmlEncode(n, (ICHAR *)buf);\r
+        if (!n) {\r
+          if (enc == encoding)\r
+            eventPtr = entityTextPtr;\r
+          result = XML_ERROR_BAD_CHAR_REF;\r
+          goto endEntityValue;\r
+        }\r
+        for (i = 0; i < n; i++) {\r
+          if (pool->end == pool->ptr && !poolGrow(pool)) {\r
+            result = XML_ERROR_NO_MEMORY;\r
+            goto endEntityValue;\r
+          }\r
+          *(pool->ptr)++ = buf[i];\r
+        }\r
+      }\r
+      break;\r
+    case XML_TOK_PARTIAL:\r
+      if (enc == encoding)\r
+        eventPtr = entityTextPtr;\r
+      result = XML_ERROR_INVALID_TOKEN;\r
+      goto endEntityValue;\r
+    case XML_TOK_INVALID:\r
+      if (enc == encoding)\r
+        eventPtr = next;\r
+      result = XML_ERROR_INVALID_TOKEN;\r
+      goto endEntityValue;\r
+    default:\r
+      if (enc == encoding)\r
+        eventPtr = entityTextPtr;\r
+      result = XML_ERROR_UNEXPECTED_STATE;\r
+      goto endEntityValue;\r
+    }\r
+    entityTextPtr = next;\r
+  }\r
+endEntityValue:\r
+#ifdef XML_DTD\r
+  prologState.inEntityValue = oldInEntityValue;\r
+#endif /* XML_DTD */\r
+  return result;\r
+}\r
+\r
+static void FASTCALL\r
+normalizeLines(XML_Char *s)\r
+{\r
+  XML_Char *p;\r
+  for (;; s++) {\r
+    if (*s == XML_T('\0'))\r
+      return;\r
+    if (*s == 0xD)\r
+      break;\r
+  }\r
+  p = s;\r
+  do {\r
+    if (*s == 0xD) {\r
+      *p++ = 0xA;\r
+      if (*++s == 0xA)\r
+        s++;\r
+    }\r
+    else\r
+      *p++ = *s++;\r
+  } while (*s);\r
+  *p = XML_T('\0');\r
+}\r
+\r
+static int\r
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,\r
+                            const char *start, const char *end)\r
+{\r
+  const XML_Char *target;\r
+  XML_Char *data;\r
+  const char *tem;\r
+  if (!processingInstructionHandler) {\r
+    if (defaultHandler)\r
+      reportDefault(parser, enc, start, end);\r
+    return 1;\r
+  }\r
+  start += enc->minBytesPerChar * 2;\r
+  tem = start + XmlNameLength(enc, start);\r
+  target = poolStoreString(&tempPool, enc, start, tem);\r
+  if (!target)\r
+    return 0;\r
+  poolFinish(&tempPool);\r
+  data = poolStoreString(&tempPool, enc,\r
+                        XmlSkipS(enc, tem),\r
+                        end - enc->minBytesPerChar*2);\r
+  if (!data)\r
+    return 0;\r
+  normalizeLines(data);\r
+  processingInstructionHandler(handlerArg, target, data);\r
+  poolClear(&tempPool);\r
+  return 1;\r
+}\r
+\r
+static int\r
+reportComment(XML_Parser parser, const ENCODING *enc,\r
+              const char *start, const char *end)\r
+{\r
+  XML_Char *data;\r
+  if (!commentHandler) {\r
+    if (defaultHandler)\r
+      reportDefault(parser, enc, start, end);\r
+    return 1;\r
+  }\r
+  data = poolStoreString(&tempPool,\r
+                         enc,\r
+                         start + enc->minBytesPerChar * 4,\r
+                         end - enc->minBytesPerChar * 3);\r
+  if (!data)\r
+    return 0;\r
+  normalizeLines(data);\r
+  commentHandler(handlerArg, data);\r
+  poolClear(&tempPool);\r
+  return 1;\r
+}\r
+\r
+static void\r
+reportDefault(XML_Parser parser, const ENCODING *enc,\r
+              const char *s, const char *end)\r
+{\r
+  if (MUST_CONVERT(enc, s)) {\r
+    const char **eventPP;\r
+    const char **eventEndPP;\r
+    if (enc == encoding) {\r
+      eventPP = &eventPtr;\r
+      eventEndPP = &eventEndPtr;\r
+    }\r
+    else {\r
+      eventPP = &(openInternalEntities->internalEventPtr);\r
+      eventEndPP = &(openInternalEntities->internalEventEndPtr);\r
+    }\r
+    do {\r
+      ICHAR *dataPtr = (ICHAR *)dataBuf;\r
+      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);\r
+      *eventEndPP = s;\r
+      defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));\r
+      *eventPP = s;\r
+    } while (s != end);\r
+  }\r
+  else\r
+    defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));\r
+}\r
+\r
+\r
+static int\r
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,\r
+                XML_Bool isId, const XML_Char *value, XML_Parser parser)\r
+{\r
+  DEFAULT_ATTRIBUTE *att;\r
+  if (value || isId) {\r
+    /* The handling of default attributes gets messed up if we have\r
+       a default which duplicates a non-default. */\r
+    int i;\r
+    for (i = 0; i < type->nDefaultAtts; i++)\r
+      if (attId == type->defaultAtts[i].id)\r
+        return 1;\r
+    if (isId && !type->idAtt && !attId->xmlns)\r
+      type->idAtt = attId;\r
+  }\r
+  if (type->nDefaultAtts == type->allocDefaultAtts) {\r
+    if (type->allocDefaultAtts == 0) {\r
+      type->allocDefaultAtts = 8;\r
+      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts\r
+                            * sizeof(DEFAULT_ATTRIBUTE));\r
+      if (!type->defaultAtts)\r
+        return 0;\r
+    }\r
+    else {\r
+      DEFAULT_ATTRIBUTE *temp;\r
+      int count = type->allocDefaultAtts * 2;\r
+      temp = (DEFAULT_ATTRIBUTE *)\r
+        REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));\r
+      if (temp == NULL)\r
+        return 0;\r
+      type->allocDefaultAtts = count;\r
+      type->defaultAtts = temp;\r
+    }\r
+  }\r
+  att = type->defaultAtts + type->nDefaultAtts;\r
+  att->id = attId;\r
+  att->value = value;\r
+  att->isCdata = isCdata;\r
+  if (!isCdata)\r
+    attId->maybeTokenized = XML_TRUE;\r
+  type->nDefaultAtts += 1;\r
+  return 1;\r
+}\r
+\r
+static int\r
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  const XML_Char *name;\r
+  for (name = elementType->name; *name; name++) {\r
+    if (*name == XML_T(':')) {\r
+      PREFIX *prefix;\r
+      const XML_Char *s;\r
+      for (s = elementType->name; s != name; s++) {\r
+        if (!poolAppendChar(&dtd->pool, *s))\r
+          return 0;\r
+      }\r
+      if (!poolAppendChar(&dtd->pool, XML_T('\0')))\r
+        return 0;\r
+      prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),\r
+                                sizeof(PREFIX));\r
+      if (!prefix)\r
+        return 0;\r
+      if (prefix->name == poolStart(&dtd->pool))\r
+        poolFinish(&dtd->pool);\r
+      else\r
+        poolDiscard(&dtd->pool);\r
+      elementType->prefix = prefix;\r
+\r
+    }\r
+  }\r
+  return 1;\r
+}\r
+\r
+static ATTRIBUTE_ID *\r
+getAttributeId(XML_Parser parser, const ENCODING *enc,\r
+               const char *start, const char *end)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  ATTRIBUTE_ID *id;\r
+  const XML_Char *name;\r
+  if (!poolAppendChar(&dtd->pool, XML_T('\0')))\r
+    return NULL;\r
+  name = poolStoreString(&dtd->pool, enc, start, end);\r
+  if (!name)\r
+    return NULL;\r
+  /* skip quotation mark - its storage will be re-used (like in name[-1]) */\r
+  ++name;\r
+  id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));\r
+  if (!id)\r
+    return NULL;\r
+  if (id->name != name)\r
+    poolDiscard(&dtd->pool);\r
+  else {\r
+    poolFinish(&dtd->pool);\r
+    if (!ns)\r
+      ;\r
+    else if (name[0] == XML_T('x')\r
+        && name[1] == XML_T('m')\r
+        && name[2] == XML_T('l')\r
+        && name[3] == XML_T('n')\r
+        && name[4] == XML_T('s')\r
+        && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {\r
+      if (name[5] == XML_T('\0'))\r
+        id->prefix = &dtd->defaultPrefix;\r
+      else\r
+        id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));\r
+      id->xmlns = XML_TRUE;\r
+    }\r
+    else {\r
+      int i;\r
+      for (i = 0; name[i]; i++) {\r
+        /* attributes without prefix are *not* in the default namespace */\r
+        if (name[i] == XML_T(':')) {\r
+          int j;\r
+          for (j = 0; j < i; j++) {\r
+            if (!poolAppendChar(&dtd->pool, name[j]))\r
+              return NULL;\r
+          }\r
+          if (!poolAppendChar(&dtd->pool, XML_T('\0')))\r
+            return NULL;\r
+          id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),\r
+                                        sizeof(PREFIX));\r
+          if (!id->prefix)\r
+            return NULL;\r
+          if (id->prefix->name == poolStart(&dtd->pool))\r
+            poolFinish(&dtd->pool);\r
+          else\r
+            poolDiscard(&dtd->pool);\r
+          break;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  return id;\r
+}\r
+\r
+#define CONTEXT_SEP XML_T('\f')\r
+\r
+static const XML_Char *\r
+getContext(XML_Parser parser)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  HASH_TABLE_ITER iter;\r
+  XML_Bool needSep = XML_FALSE;\r
+\r
+  if (dtd->defaultPrefix.binding) {\r
+    int i;\r
+    int len;\r
+    if (!poolAppendChar(&tempPool, XML_T('=')))\r
+      return NULL;\r
+    len = dtd->defaultPrefix.binding->uriLen;\r
+    if (namespaceSeparator)\r
+      len--;\r
+    for (i = 0; i < len; i++)\r
+      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))\r
+        return NULL;\r
+    needSep = XML_TRUE;\r
+  }\r
+\r
+  hashTableIterInit(&iter, &(dtd->prefixes));\r
+  for (;;) {\r
+    int i;\r
+    int len;\r
+    const XML_Char *s;\r
+    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);\r
+    if (!prefix)\r
+      break;\r
+    if (!prefix->binding)\r
+      continue;\r
+    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))\r
+      return NULL;\r
+    for (s = prefix->name; *s; s++)\r
+      if (!poolAppendChar(&tempPool, *s))\r
+        return NULL;\r
+    if (!poolAppendChar(&tempPool, XML_T('=')))\r
+      return NULL;\r
+    len = prefix->binding->uriLen;\r
+    if (namespaceSeparator)\r
+      len--;\r
+    for (i = 0; i < len; i++)\r
+      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))\r
+        return NULL;\r
+    needSep = XML_TRUE;\r
+  }\r
+\r
+\r
+  hashTableIterInit(&iter, &(dtd->generalEntities));\r
+  for (;;) {\r
+    const XML_Char *s;\r
+    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);\r
+    if (!e)\r
+      break;\r
+    if (!e->open)\r
+      continue;\r
+    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))\r
+      return NULL;\r
+    for (s = e->name; *s; s++)\r
+      if (!poolAppendChar(&tempPool, *s))\r
+        return 0;\r
+    needSep = XML_TRUE;\r
+  }\r
+\r
+  if (!poolAppendChar(&tempPool, XML_T('\0')))\r
+    return NULL;\r
+  return tempPool.start;\r
+}\r
+\r
+static XML_Bool\r
+setContext(XML_Parser parser, const XML_Char *context)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  const XML_Char *s = context;\r
+\r
+  while (*context != XML_T('\0')) {\r
+    if (*s == CONTEXT_SEP || *s == XML_T('\0')) {\r
+      ENTITY *e;\r
+      if (!poolAppendChar(&tempPool, XML_T('\0')))\r
+        return XML_FALSE;\r
+      e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);\r
+      if (e)\r
+        e->open = XML_TRUE;\r
+      if (*s != XML_T('\0'))\r
+        s++;\r
+      context = s;\r
+      poolDiscard(&tempPool);\r
+    }\r
+    else if (*s == XML_T('=')) {\r
+      PREFIX *prefix;\r
+      if (poolLength(&tempPool) == 0)\r
+        prefix = &dtd->defaultPrefix;\r
+      else {\r
+        if (!poolAppendChar(&tempPool, XML_T('\0')))\r
+          return XML_FALSE;\r
+        prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),\r
+                                  sizeof(PREFIX));\r
+        if (!prefix)\r
+          return XML_FALSE;\r
+        if (prefix->name == poolStart(&tempPool)) {\r
+          prefix->name = poolCopyString(&dtd->pool, prefix->name);\r
+          if (!prefix->name)\r
+            return XML_FALSE;\r
+        }\r
+        poolDiscard(&tempPool);\r
+      }\r
+      for (context = s + 1;\r
+           *context != CONTEXT_SEP && *context != XML_T('\0');\r
+           context++)\r
+        if (!poolAppendChar(&tempPool, *context))\r
+          return XML_FALSE;\r
+      if (!poolAppendChar(&tempPool, XML_T('\0')))\r
+        return XML_FALSE;\r
+      if (addBinding(parser, prefix, NULL, poolStart(&tempPool),\r
+                     &inheritedBindings) != XML_ERROR_NONE)\r
+        return XML_FALSE;\r
+      poolDiscard(&tempPool);\r
+      if (*context != XML_T('\0'))\r
+        ++context;\r
+      s = context;\r
+    }\r
+    else {\r
+      if (!poolAppendChar(&tempPool, *s))\r
+        return XML_FALSE;\r
+      s++;\r
+    }\r
+  }\r
+  return XML_TRUE;\r
+}\r
+\r
+static void FASTCALL\r
+normalizePublicId(XML_Char *publicId)\r
+{\r
+  XML_Char *p = publicId;\r
+  XML_Char *s;\r
+  for (s = publicId; *s; s++) {\r
+    switch (*s) {\r
+    case 0x20:\r
+    case 0xD:\r
+    case 0xA:\r
+      if (p != publicId && p[-1] != 0x20)\r
+        *p++ = 0x20;\r
+      break;\r
+    default:\r
+      *p++ = *s;\r
+    }\r
+  }\r
+  if (p != publicId && p[-1] == 0x20)\r
+    --p;\r
+  *p = XML_T('\0');\r
+}\r
+\r
+static DTD *\r
+dtdCreate(const XML_Memory_Handling_Suite *ms)\r
+{\r
+  DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));\r
+  if (p == NULL)\r
+    return p;\r
+  poolInit(&(p->pool), ms);\r
+  poolInit(&(p->entityValuePool), ms);\r
+  hashTableInit(&(p->generalEntities), ms);\r
+  hashTableInit(&(p->elementTypes), ms);\r
+  hashTableInit(&(p->attributeIds), ms);\r
+  hashTableInit(&(p->prefixes), ms);\r
+#ifdef XML_DTD\r
+  p->paramEntityRead = XML_FALSE;\r
+  hashTableInit(&(p->paramEntities), ms);\r
+#endif /* XML_DTD */\r
+  p->defaultPrefix.name = NULL;\r
+  p->defaultPrefix.binding = NULL;\r
+\r
+  p->in_eldecl = XML_FALSE;\r
+  p->scaffIndex = NULL;\r
+  p->scaffold = NULL;\r
+  p->scaffLevel = 0;\r
+  p->scaffSize = 0;\r
+  p->scaffCount = 0;\r
+  p->contentStringLen = 0;\r
+\r
+  p->keepProcessing = XML_TRUE;\r
+  p->hasParamEntityRefs = XML_FALSE;\r
+  p->standalone = XML_FALSE;\r
+  return p;\r
+}\r
+\r
+static void\r
+dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)\r
+{\r
+  HASH_TABLE_ITER iter;\r
+  hashTableIterInit(&iter, &(p->elementTypes));\r
+  for (;;) {\r
+    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);\r
+    if (!e)\r
+      break;\r
+    if (e->allocDefaultAtts != 0)\r
+      ms->free_fcn(e->defaultAtts);\r
+  }\r
+  hashTableClear(&(p->generalEntities));\r
+#ifdef XML_DTD\r
+  p->paramEntityRead = XML_FALSE;\r
+  hashTableClear(&(p->paramEntities));\r
+#endif /* XML_DTD */\r
+  hashTableClear(&(p->elementTypes));\r
+  hashTableClear(&(p->attributeIds));\r
+  hashTableClear(&(p->prefixes));\r
+  poolClear(&(p->pool));\r
+  poolClear(&(p->entityValuePool));\r
+  p->defaultPrefix.name = NULL;\r
+  p->defaultPrefix.binding = NULL;\r
+\r
+  p->in_eldecl = XML_FALSE;\r
+\r
+  ms->free_fcn(p->scaffIndex);\r
+  p->scaffIndex = NULL;\r
+  ms->free_fcn(p->scaffold);\r
+  p->scaffold = NULL;\r
+\r
+  p->scaffLevel = 0;\r
+  p->scaffSize = 0;\r
+  p->scaffCount = 0;\r
+  p->contentStringLen = 0;\r
+\r
+  p->keepProcessing = XML_TRUE;\r
+  p->hasParamEntityRefs = XML_FALSE;\r
+  p->standalone = XML_FALSE;\r
+}\r
+\r
+static void\r
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)\r
+{\r
+  HASH_TABLE_ITER iter;\r
+  hashTableIterInit(&iter, &(p->elementTypes));\r
+  for (;;) {\r
+    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);\r
+    if (!e)\r
+      break;\r
+    if (e->allocDefaultAtts != 0)\r
+      ms->free_fcn(e->defaultAtts);\r
+  }\r
+  hashTableDestroy(&(p->generalEntities));\r
+#ifdef XML_DTD\r
+  hashTableDestroy(&(p->paramEntities));\r
+#endif /* XML_DTD */\r
+  hashTableDestroy(&(p->elementTypes));\r
+  hashTableDestroy(&(p->attributeIds));\r
+  hashTableDestroy(&(p->prefixes));\r
+  poolDestroy(&(p->pool));\r
+  poolDestroy(&(p->entityValuePool));\r
+  if (isDocEntity) {\r
+    ms->free_fcn(p->scaffIndex);\r
+    ms->free_fcn(p->scaffold);\r
+  }\r
+  ms->free_fcn(p);\r
+}\r
+\r
+/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.\r
+   The new DTD has already been initialized.\r
+*/\r
+static int\r
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)\r
+{\r
+  HASH_TABLE_ITER iter;\r
+\r
+  /* Copy the prefix table. */\r
+\r
+  hashTableIterInit(&iter, &(oldDtd->prefixes));\r
+  for (;;) {\r
+    const XML_Char *name;\r
+    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);\r
+    if (!oldP)\r
+      break;\r
+    name = poolCopyString(&(newDtd->pool), oldP->name);\r
+    if (!name)\r
+      return 0;\r
+    if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))\r
+      return 0;\r
+  }\r
+\r
+  hashTableIterInit(&iter, &(oldDtd->attributeIds));\r
+\r
+  /* Copy the attribute id table. */\r
+\r
+  for (;;) {\r
+    ATTRIBUTE_ID *newA;\r
+    const XML_Char *name;\r
+    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);\r
+\r
+    if (!oldA)\r
+      break;\r
+    /* Remember to allocate the scratch byte before the name. */\r
+    if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))\r
+      return 0;\r
+    name = poolCopyString(&(newDtd->pool), oldA->name);\r
+    if (!name)\r
+      return 0;\r
+    ++name;\r
+    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,\r
+                                  sizeof(ATTRIBUTE_ID));\r
+    if (!newA)\r
+      return 0;\r
+    newA->maybeTokenized = oldA->maybeTokenized;\r
+    if (oldA->prefix) {\r
+      newA->xmlns = oldA->xmlns;\r
+      if (oldA->prefix == &oldDtd->defaultPrefix)\r
+        newA->prefix = &newDtd->defaultPrefix;\r
+      else\r
+        newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),\r
+                                        oldA->prefix->name, 0);\r
+    }\r
+  }\r
+\r
+  /* Copy the element type table. */\r
+\r
+  hashTableIterInit(&iter, &(oldDtd->elementTypes));\r
+\r
+  for (;;) {\r
+    int i;\r
+    ELEMENT_TYPE *newE;\r
+    const XML_Char *name;\r
+    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);\r
+    if (!oldE)\r
+      break;\r
+    name = poolCopyString(&(newDtd->pool), oldE->name);\r
+    if (!name)\r
+      return 0;\r
+    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,\r
+                                  sizeof(ELEMENT_TYPE));\r
+    if (!newE)\r
+      return 0;\r
+    if (oldE->nDefaultAtts) {\r
+      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)\r
+          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));\r
+      if (!newE->defaultAtts) {\r
+        ms->free_fcn(newE);\r
+        return 0;\r
+      }\r
+    }\r
+    if (oldE->idAtt)\r
+      newE->idAtt = (ATTRIBUTE_ID *)\r
+          lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);\r
+    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;\r
+    if (oldE->prefix)\r
+      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),\r
+                                      oldE->prefix->name, 0);\r
+    for (i = 0; i < newE->nDefaultAtts; i++) {\r
+      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)\r
+          lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);\r
+      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;\r
+      if (oldE->defaultAtts[i].value) {\r
+        newE->defaultAtts[i].value\r
+            = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);\r
+        if (!newE->defaultAtts[i].value)\r
+          return 0;\r
+      }\r
+      else\r
+        newE->defaultAtts[i].value = NULL;\r
+    }\r
+  }\r
+\r
+  /* Copy the entity tables. */\r
+  if (!copyEntityTable(&(newDtd->generalEntities),\r
+                       &(newDtd->pool),\r
+                       &(oldDtd->generalEntities)))\r
+      return 0;\r
+\r
+#ifdef XML_DTD\r
+  if (!copyEntityTable(&(newDtd->paramEntities),\r
+                       &(newDtd->pool),\r
+                       &(oldDtd->paramEntities)))\r
+      return 0;\r
+  newDtd->paramEntityRead = oldDtd->paramEntityRead;\r
+#endif /* XML_DTD */\r
+\r
+  newDtd->keepProcessing = oldDtd->keepProcessing;\r
+  newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;\r
+  newDtd->standalone = oldDtd->standalone;\r
+\r
+  /* Don't want deep copying for scaffolding */\r
+  newDtd->in_eldecl = oldDtd->in_eldecl;\r
+  newDtd->scaffold = oldDtd->scaffold;\r
+  newDtd->contentStringLen = oldDtd->contentStringLen;\r
+  newDtd->scaffSize = oldDtd->scaffSize;\r
+  newDtd->scaffLevel = oldDtd->scaffLevel;\r
+  newDtd->scaffIndex = oldDtd->scaffIndex;\r
+\r
+  return 1;\r
+}  /* End dtdCopy */\r
+\r
+static int\r
+copyEntityTable(HASH_TABLE *newTable,\r
+                STRING_POOL *newPool,\r
+                const HASH_TABLE *oldTable)\r
+{\r
+  HASH_TABLE_ITER iter;\r
+  const XML_Char *cachedOldBase = NULL;\r
+  const XML_Char *cachedNewBase = NULL;\r
+\r
+  hashTableIterInit(&iter, oldTable);\r
+\r
+  for (;;) {\r
+    ENTITY *newE;\r
+    const XML_Char *name;\r
+    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);\r
+    if (!oldE)\r
+      break;\r
+    name = poolCopyString(newPool, oldE->name);\r
+    if (!name)\r
+      return 0;\r
+    newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));\r
+    if (!newE)\r
+      return 0;\r
+    if (oldE->systemId) {\r
+      const XML_Char *tem = poolCopyString(newPool, oldE->systemId);\r
+      if (!tem)\r
+        return 0;\r
+      newE->systemId = tem;\r
+      if (oldE->base) {\r
+        if (oldE->base == cachedOldBase)\r
+          newE->base = cachedNewBase;\r
+        else {\r
+          cachedOldBase = oldE->base;\r
+          tem = poolCopyString(newPool, cachedOldBase);\r
+          if (!tem)\r
+            return 0;\r
+          cachedNewBase = newE->base = tem;\r
+        }\r
+      }\r
+      if (oldE->publicId) {\r
+        tem = poolCopyString(newPool, oldE->publicId);\r
+        if (!tem)\r
+          return 0;\r
+        newE->publicId = tem;\r
+      }\r
+    }\r
+    else {\r
+      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,\r
+                                            oldE->textLen);\r
+      if (!tem)\r
+        return 0;\r
+      newE->textPtr = tem;\r
+      newE->textLen = oldE->textLen;\r
+    }\r
+    if (oldE->notation) {\r
+      const XML_Char *tem = poolCopyString(newPool, oldE->notation);\r
+      if (!tem)\r
+        return 0;\r
+      newE->notation = tem;\r
+    }\r
+    newE->is_param = oldE->is_param;\r
+    newE->is_internal = oldE->is_internal;\r
+  }\r
+  return 1;\r
+}\r
+\r
+#define INIT_POWER 6\r
+\r
+static XML_Bool FASTCALL\r
+keyeq(KEY s1, KEY s2)\r
+{\r
+  for (; *s1 == *s2; s1++, s2++)\r
+    if (*s1 == 0)\r
+      return XML_TRUE;\r
+  return XML_FALSE;\r
+}\r
+\r
+static unsigned long FASTCALL\r
+hash(KEY s)\r
+{\r
+  unsigned long h = 0;\r
+  while (*s)\r
+    h = CHAR_HASH(h, *s++);\r
+  return h;\r
+}\r
+\r
+static NAMED *\r
+lookup(HASH_TABLE *table, KEY name, size_t createSize)\r
+{\r
+  size_t i;\r
+  if (table->size == 0) {\r
+    size_t tsize;\r
+    if (!createSize)\r
+      return NULL;\r
+    table->power = INIT_POWER;\r
+    /* table->size is a power of 2 */\r
+    table->size = (size_t)1 << INIT_POWER;\r
+    tsize = table->size * sizeof(NAMED *);\r
+    table->v = (NAMED **)table->mem->malloc_fcn(tsize);\r
+    if (!table->v) {\r
+      table->size = 0;\r
+      return NULL;\r
+    }\r
+    memset(table->v, 0, tsize);\r
+    i = hash(name) & ((unsigned long)table->size - 1);\r
+  }\r
+  else {\r
+    unsigned long h = hash(name);\r
+    unsigned long mask = (unsigned long)table->size - 1;\r
+    unsigned char step = 0;\r
+    i = h & mask;\r
+    while (table->v[i]) {\r
+      if (keyeq(name, table->v[i]->name))\r
+        return table->v[i];\r
+      if (!step)\r
+        step = PROBE_STEP(h, mask, table->power);\r
+      i < step ? (i += table->size - step) : (i -= step);\r
+    }\r
+    if (!createSize)\r
+      return NULL;\r
+\r
+    /* check for overflow (table is half full) */\r
+    if (table->used >> (table->power - 1)) {\r
+      unsigned char newPower = table->power + 1;\r
+      size_t newSize = (size_t)1 << newPower;\r
+      unsigned long newMask = (unsigned long)newSize - 1;\r
+      size_t tsize = newSize * sizeof(NAMED *);\r
+      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);\r
+      if (!newV)\r
+        return NULL;\r
+      memset(newV, 0, tsize);\r
+      for (i = 0; i < table->size; i++)\r
+        if (table->v[i]) {\r
+          unsigned long newHash = hash(table->v[i]->name);\r
+          size_t j = newHash & newMask;\r
+          step = 0;\r
+          while (newV[j]) {\r
+            if (!step)\r
+              step = PROBE_STEP(newHash, newMask, newPower);\r
+            j < step ? (j += newSize - step) : (j -= step);\r
+          }\r
+          newV[j] = table->v[i];\r
+        }\r
+      table->mem->free_fcn(table->v);\r
+      table->v = newV;\r
+      table->power = newPower;\r
+      table->size = newSize;\r
+      i = h & newMask;\r
+      step = 0;\r
+      while (table->v[i]) {\r
+        if (!step)\r
+          step = PROBE_STEP(h, newMask, newPower);\r
+        i < step ? (i += newSize - step) : (i -= step);\r
+      }\r
+    }\r
+  }\r
+  table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);\r
+  if (!table->v[i])\r
+    return NULL;\r
+  memset(table->v[i], 0, createSize);\r
+  table->v[i]->name = name;\r
+  (table->used)++;\r
+  return table->v[i];\r
+}\r
+\r
+static void FASTCALL\r
+hashTableClear(HASH_TABLE *table)\r
+{\r
+  size_t i;\r
+  for (i = 0; i < table->size; i++) {\r
+    table->mem->free_fcn(table->v[i]);\r
+    table->v[i] = NULL;\r
+  }\r
+  table->used = 0;\r
+}\r
+\r
+static void FASTCALL\r
+hashTableDestroy(HASH_TABLE *table)\r
+{\r
+  size_t i;\r
+  for (i = 0; i < table->size; i++)\r
+    table->mem->free_fcn(table->v[i]);\r
+  table->mem->free_fcn(table->v);\r
+}\r
+\r
+static void FASTCALL\r
+hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)\r
+{\r
+  p->power = 0;\r
+  p->size = 0;\r
+  p->used = 0;\r
+  p->v = NULL;\r
+  p->mem = ms;\r
+}\r
+\r
+static void FASTCALL\r
+hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)\r
+{\r
+  iter->p = table->v;\r
+  iter->end = iter->p + table->size;\r
+}\r
+\r
+static NAMED * FASTCALL\r
+hashTableIterNext(HASH_TABLE_ITER *iter)\r
+{\r
+  while (iter->p != iter->end) {\r
+    NAMED *tem = *(iter->p)++;\r
+    if (tem)\r
+      return tem;\r
+  }\r
+  return NULL;\r
+}\r
+\r
+static void FASTCALL\r
+poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)\r
+{\r
+  pool->blocks = NULL;\r
+  pool->freeBlocks = NULL;\r
+  pool->start = NULL;\r
+  pool->ptr = NULL;\r
+  pool->end = NULL;\r
+  pool->mem = ms;\r
+}\r
+\r
+static void FASTCALL\r
+poolClear(STRING_POOL *pool)\r
+{\r
+  if (!pool->freeBlocks)\r
+    pool->freeBlocks = pool->blocks;\r
+  else {\r
+    BLOCK *p = pool->blocks;\r
+    while (p) {\r
+      BLOCK *tem = p->next;\r
+      p->next = pool->freeBlocks;\r
+      pool->freeBlocks = p;\r
+      p = tem;\r
+    }\r
+  }\r
+  pool->blocks = NULL;\r
+  pool->start = NULL;\r
+  pool->ptr = NULL;\r
+  pool->end = NULL;\r
+}\r
+\r
+static void FASTCALL\r
+poolDestroy(STRING_POOL *pool)\r
+{\r
+  BLOCK *p = pool->blocks;\r
+  while (p) {\r
+    BLOCK *tem = p->next;\r
+    pool->mem->free_fcn(p);\r
+    p = tem;\r
+  }\r
+  p = pool->freeBlocks;\r
+  while (p) {\r
+    BLOCK *tem = p->next;\r
+    pool->mem->free_fcn(p);\r
+    p = tem;\r
+  }\r
+}\r
+\r
+static XML_Char *\r
+poolAppend(STRING_POOL *pool, const ENCODING *enc,\r
+           const char *ptr, const char *end)\r
+{\r
+  if (!pool->ptr && !poolGrow(pool))\r
+    return NULL;\r
+  for (;;) {\r
+    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);\r
+    if (ptr == end)\r
+      break;\r
+    if (!poolGrow(pool))\r
+      return NULL;\r
+  }\r
+  return pool->start;\r
+}\r
+\r
+static const XML_Char * FASTCALL\r
+poolCopyString(STRING_POOL *pool, const XML_Char *s)\r
+{\r
+  do {\r
+    if (!poolAppendChar(pool, *s))\r
+      return NULL;\r
+  } while (*s++);\r
+  s = pool->start;\r
+  poolFinish(pool);\r
+  return s;\r
+}\r
+\r
+static const XML_Char *\r
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)\r
+{\r
+  if (!pool->ptr && !poolGrow(pool))\r
+    return NULL;\r
+  for (; n > 0; --n, s++) {\r
+    if (!poolAppendChar(pool, *s))\r
+      return NULL;\r
+  }\r
+  s = pool->start;\r
+  poolFinish(pool);\r
+  return s;\r
+}\r
+\r
+static const XML_Char * FASTCALL\r
+poolAppendString(STRING_POOL *pool, const XML_Char *s)\r
+{\r
+  while (*s) {\r
+    if (!poolAppendChar(pool, *s))\r
+      return NULL;\r
+    s++;\r
+  }\r
+  return pool->start;\r
+}\r
+\r
+static XML_Char *\r
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,\r
+                const char *ptr, const char *end)\r
+{\r
+  if (!poolAppend(pool, enc, ptr, end))\r
+    return NULL;\r
+  if (pool->ptr == pool->end && !poolGrow(pool))\r
+    return NULL;\r
+  *(pool->ptr)++ = 0;\r
+  return pool->start;\r
+}\r
+\r
+static XML_Bool FASTCALL\r
+poolGrow(STRING_POOL *pool)\r
+{\r
+  if (pool->freeBlocks) {\r
+    if (pool->start == 0) {\r
+      pool->blocks = pool->freeBlocks;\r
+      pool->freeBlocks = pool->freeBlocks->next;\r
+      pool->blocks->next = NULL;\r
+      pool->start = pool->blocks->s;\r
+      pool->end = pool->start + pool->blocks->size;\r
+      pool->ptr = pool->start;\r
+      return XML_TRUE;\r
+    }\r
+    if (pool->end - pool->start < pool->freeBlocks->size) {\r
+      BLOCK *tem = pool->freeBlocks->next;\r
+      pool->freeBlocks->next = pool->blocks;\r
+      pool->blocks = pool->freeBlocks;\r
+      pool->freeBlocks = tem;\r
+      memcpy(pool->blocks->s, pool->start,\r
+             (pool->end - pool->start) * sizeof(XML_Char));\r
+      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);\r
+      pool->start = pool->blocks->s;\r
+      pool->end = pool->start + pool->blocks->size;\r
+      return XML_TRUE;\r
+    }\r
+  }\r
+  if (pool->blocks && pool->start == pool->blocks->s) {\r
+    int blockSize = (int)(pool->end - pool->start)*2;\r
+    pool->blocks = (BLOCK *)\r
+      pool->mem->realloc_fcn(pool->blocks,\r
+                             (offsetof(BLOCK, s)\r
+                              + blockSize * sizeof(XML_Char)));\r
+    if (pool->blocks == NULL)\r
+      return XML_FALSE;\r
+    pool->blocks->size = blockSize;\r
+    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);\r
+    pool->start = pool->blocks->s;\r
+    pool->end = pool->start + blockSize;\r
+  }\r
+  else {\r
+    BLOCK *tem;\r
+    int blockSize = (int)(pool->end - pool->start);\r
+    if (blockSize < INIT_BLOCK_SIZE)\r
+      blockSize = INIT_BLOCK_SIZE;\r
+    else\r
+      blockSize *= 2;\r
+    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)\r
+                                        + blockSize * sizeof(XML_Char));\r
+    if (!tem)\r
+      return XML_FALSE;\r
+    tem->size = blockSize;\r
+    tem->next = pool->blocks;\r
+    pool->blocks = tem;\r
+    if (pool->ptr != pool->start)\r
+      memcpy(tem->s, pool->start,\r
+             (pool->ptr - pool->start) * sizeof(XML_Char));\r
+    pool->ptr = tem->s + (pool->ptr - pool->start);\r
+    pool->start = tem->s;\r
+    pool->end = tem->s + blockSize;\r
+  }\r
+  return XML_TRUE;\r
+}\r
+\r
+static int FASTCALL\r
+nextScaffoldPart(XML_Parser parser)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  CONTENT_SCAFFOLD * me;\r
+  int next;\r
+\r
+  if (!dtd->scaffIndex) {\r
+    dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));\r
+    if (!dtd->scaffIndex)\r
+      return -1;\r
+    dtd->scaffIndex[0] = 0;\r
+  }\r
+\r
+  if (dtd->scaffCount >= dtd->scaffSize) {\r
+    CONTENT_SCAFFOLD *temp;\r
+    if (dtd->scaffold) {\r
+      temp = (CONTENT_SCAFFOLD *)\r
+        REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));\r
+      if (temp == NULL)\r
+        return -1;\r
+      dtd->scaffSize *= 2;\r
+    }\r
+    else {\r
+      temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS\r
+                                        * sizeof(CONTENT_SCAFFOLD));\r
+      if (temp == NULL)\r
+        return -1;\r
+      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;\r
+    }\r
+    dtd->scaffold = temp;\r
+  }\r
+  next = dtd->scaffCount++;\r
+  me = &dtd->scaffold[next];\r
+  if (dtd->scaffLevel) {\r
+    CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];\r
+    if (parent->lastchild) {\r
+      dtd->scaffold[parent->lastchild].nextsib = next;\r
+    }\r
+    if (!parent->childcnt)\r
+      parent->firstchild = next;\r
+    parent->lastchild = next;\r
+    parent->childcnt++;\r
+  }\r
+  me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;\r
+  return next;\r
+}\r
+\r
+static void\r
+build_node(XML_Parser parser,\r
+           int src_node,\r
+           XML_Content *dest,\r
+           XML_Content **contpos,\r
+           XML_Char **strpos)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  dest->type = dtd->scaffold[src_node].type;\r
+  dest->quant = dtd->scaffold[src_node].quant;\r
+  if (dest->type == XML_CTYPE_NAME) {\r
+    const XML_Char *src;\r
+    dest->name = *strpos;\r
+    src = dtd->scaffold[src_node].name;\r
+    for (;;) {\r
+      *(*strpos)++ = *src;\r
+      if (!*src)\r
+        break;\r
+      src++;\r
+    }\r
+    dest->numchildren = 0;\r
+    dest->children = NULL;\r
+  }\r
+  else {\r
+    unsigned int i;\r
+    int cn;\r
+    dest->numchildren = dtd->scaffold[src_node].childcnt;\r
+    dest->children = *contpos;\r
+    *contpos += dest->numchildren;\r
+    for (i = 0, cn = dtd->scaffold[src_node].firstchild;\r
+         i < dest->numchildren;\r
+         i++, cn = dtd->scaffold[cn].nextsib) {\r
+      build_node(parser, cn, &(dest->children[i]), contpos, strpos);\r
+    }\r
+    dest->name = NULL;\r
+  }\r
+}\r
+\r
+static XML_Content *\r
+build_model (XML_Parser parser)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  XML_Content *ret;\r
+  XML_Content *cpos;\r
+  XML_Char * str;\r
+  int allocsize = (dtd->scaffCount * sizeof(XML_Content)\r
+                   + (dtd->contentStringLen * sizeof(XML_Char)));\r
+\r
+  ret = (XML_Content *)MALLOC(allocsize);\r
+  if (!ret)\r
+    return NULL;\r
+\r
+  str =  (XML_Char *) (&ret[dtd->scaffCount]);\r
+  cpos = &ret[1];\r
+\r
+  build_node(parser, 0, ret, &cpos, &str);\r
+  return ret;\r
+}\r
+\r
+static ELEMENT_TYPE *\r
+getElementType(XML_Parser parser,\r
+               const ENCODING *enc,\r
+               const char *ptr,\r
+               const char *end)\r
+{\r
+  DTD * const dtd = _dtd;  /* save one level of indirection */\r
+  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);\r
+  ELEMENT_TYPE *ret;\r
+\r
+  if (!name)\r
+    return NULL;\r
+  ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));\r
+  if (!ret)\r
+    return NULL;\r
+  if (ret->name != name)\r
+    poolDiscard(&dtd->pool);\r
+  else {\r
+    poolFinish(&dtd->pool);\r
+    if (!setElementTypePrefix(parser, ret))\r
+      return NULL;\r
+  }\r
+  return ret;\r
+}\r
index 5246622bf5312deac9fffe0b186155c43c5fbc1a..d71d051a69a2be284ebb8d6fd05022f6cf7fbe8c 100644 (file)
@@ -9,7 +9,9 @@
 \r
 /* Namespace external symbols to allow multiple libexpat version to\r
    co-exist. */\r
-#include "pyexpatns.h"\r
+#if !defined(UEFI_C_SOURCE)\r
+  #include "pyexpatns.h"\r
+#endif\r
 \r
 #if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)\r
 #define XML_USE_MSC_EXTENSIONS 1\r
@@ -101,7 +103,7 @@ typedef char XML_LChar;
 \r
 #ifdef XML_LARGE_SIZE  /* Use large integers for file/stream positions. */\r
 #if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400\r
-typedef __int64 XML_Index; \r
+typedef __int64 XML_Index;\r
 typedef unsigned __int64 XML_Size;\r
 #else\r
 typedef long long XML_Index;\r
index cb84274d0ac4954744fa914c376984944ef36b9a..87ee2ea126d93d50985ea2064e5d29849b262843 100644 (file)
 #include <string.h>                     /* memset(), memcpy() */\r
 #include <assert.h>\r
 \r
+#if defined(UEFI_C_SOURCE)\r
+  #include <expat/expat.h>\r
+#else\r
 #include "expat.h"\r
+#endif\r
 \r
 #ifdef XML_UNICODE\r
 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX\r
@@ -1493,6 +1497,10 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
           ps_parsing = XML_FINISHED;\r
           return result;\r
         }\r
+        break;\r
+      default:\r
+        /* XML_FINISHED case required by compiler - but not tested - djv */\r
+        return XML_STATUS_OK;\r
       }\r
     }\r
 \r
index 630986587733f15eaf36a3d14e141bd1a6b15a11..91c3afa22b8de743cebe35f3811e8e9b52e25910 100644 (file)
   LibWchar\r
   LibGen\r
   LibNetUtil\r
-  BsdSocketLib\r
-  EfiSocketLib\r
   DevShell\r
+  #\r
+  # Comment out the following two library classes if socket support is\r
+  # NOT being built in to Python.\r
+  #BsdSocketLib\r
+  #EfiSocketLib\r
 \r
 [FixedPcd]\r
   gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0F\r
 #Python\r
   PyMod-$(PYTHON_VERSION)/Python/getcopyright.c\r
   PyMod-$(PYTHON_VERSION)/Python/marshal.c\r
+  PyMod-$(PYTHON_VERSION)/Python/import.c\r
 \r
   Python-$(PYTHON_VERSION)/Python/_warnings.c\r
+  Python-$(PYTHON_VERSION)/Python/Python-ast.c\r
   Python-$(PYTHON_VERSION)/Python/asdl.c\r
   Python-$(PYTHON_VERSION)/Python/ast.c\r
   Python-$(PYTHON_VERSION)/Python/bltinmodule.c\r
@@ -93,7 +98,6 @@
   Python-$(PYTHON_VERSION)/Python/getplatform.c\r
   Python-$(PYTHON_VERSION)/Python/getversion.c\r
   Python-$(PYTHON_VERSION)/Python/graminit.c\r
-  Python-$(PYTHON_VERSION)/Python/import.c\r
   Python-$(PYTHON_VERSION)/Python/importdl.c\r
   Python-$(PYTHON_VERSION)/Python/modsupport.c\r
   Python-$(PYTHON_VERSION)/Python/mysnprintf.c\r
   Python-$(PYTHON_VERSION)/Python/pystate.c\r
   Python-$(PYTHON_VERSION)/Python/pystrcmp.c\r
   Python-$(PYTHON_VERSION)/Python/pystrtod.c\r
-  Python-$(PYTHON_VERSION)/Python/Python-ast.c\r
   Python-$(PYTHON_VERSION)/Python/pythonrun.c\r
   Python-$(PYTHON_VERSION)/Python/structmember.c\r
   Python-$(PYTHON_VERSION)/Python/symtable.c\r
   Python-$(PYTHON_VERSION)/Python/traceback.c\r
 \r
 #Objects\r
+  PyMod-$(PYTHON_VERSION)/Objects/longobject.c\r
+\r
   Python-$(PYTHON_VERSION)/Objects/abstract.c\r
   Python-$(PYTHON_VERSION)/Objects/boolobject.c\r
   Python-$(PYTHON_VERSION)/Objects/bufferobject.c\r
   Python-$(PYTHON_VERSION)/Objects/intobject.c\r
   Python-$(PYTHON_VERSION)/Objects/iterobject.c\r
   Python-$(PYTHON_VERSION)/Objects/listobject.c\r
-  Python-$(PYTHON_VERSION)/Objects/longobject.c\r
   Python-$(PYTHON_VERSION)/Objects/memoryobject.c\r
   Python-$(PYTHON_VERSION)/Objects/methodobject.c\r
   Python-$(PYTHON_VERSION)/Objects/moduleobject.c\r
   Python-$(PYTHON_VERSION)/Modules/_bisectmodule.c              #\r
   Python-$(PYTHON_VERSION)/Modules/_codecsmodule.c              #\r
   Python-$(PYTHON_VERSION)/Modules/_collectionsmodule.c         #\r
+  Python-$(PYTHON_VERSION)/Modules/_csv.c                       #\r
   Python-$(PYTHON_VERSION)/Modules/_heapqmodule.c               #\r
   Python-$(PYTHON_VERSION)/Modules/_json.c                      #\r
   Python-$(PYTHON_VERSION)/Modules/_localemodule.c              #\r
   Python-$(PYTHON_VERSION)/Modules/md5module.c                  #\r
   Python-$(PYTHON_VERSION)/Modules/operator.c                   #\r
   Python-$(PYTHON_VERSION)/Modules/parsermodule.c               #\r
-  Python-$(PYTHON_VERSION)/Modules/shamodule.c                  #\r
   Python-$(PYTHON_VERSION)/Modules/sha256module.c               #\r
   Python-$(PYTHON_VERSION)/Modules/sha512module.c               #\r
+  Python-$(PYTHON_VERSION)/Modules/shamodule.c                  #\r
   Python-$(PYTHON_VERSION)/Modules/signalmodule.c               #\r
   Python-$(PYTHON_VERSION)/Modules/socketmodule.c               #\r
   Python-$(PYTHON_VERSION)/Modules/stropmodule.c                #\r
+  Python-$(PYTHON_VERSION)/Modules/symtablemodule.c             #\r
   Python-$(PYTHON_VERSION)/Modules/timemodule.c                 #\r
   Python-$(PYTHON_VERSION)/Modules/unicodedata.c                #\r
   Python-$(PYTHON_VERSION)/Modules/xxsubtype.c                  #\r
   Python-$(PYTHON_VERSION)/Modules/zipimport.c                  #\r
   Python-$(PYTHON_VERSION)/Modules/zlibmodule.c                 #\r
 \r
-  Python-$(PYTHON_VERSION)/Modules/_csv.c                       #\r
-  Python-$(PYTHON_VERSION)/Modules/symtablemodule.c             #\r
+#Modules/_io\r
+  Python-$(PYTHON_VERSION)/Modules/_io/_iomodule.c              #\r
+  Python-$(PYTHON_VERSION)/Modules/_io/bufferedio.c             #\r
+  Python-$(PYTHON_VERSION)/Modules/_io/bytesio.c                #\r
+  Python-$(PYTHON_VERSION)/Modules/_io/fileio.c                 #\r
+  Python-$(PYTHON_VERSION)/Modules/_io/iobase.c                 #\r
+  Python-$(PYTHON_VERSION)/Modules/_io/stringio.c               #\r
+  Python-$(PYTHON_VERSION)/Modules/_io/textio.c                 #\r
 \r
 #Modules/cjkcodecs\r
   Python-$(PYTHON_VERSION)/Modules/cjkcodecs/multibytecodec.c   #\r
   Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_kr.c       #\r
   Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_tw.c       #\r
 \r
-#Modules/_io\r
-  Python-$(PYTHON_VERSION)/Modules/_io/_iomodule.c              #\r
-  Python-$(PYTHON_VERSION)/Modules/_io/bufferedio.c             #\r
-  Python-$(PYTHON_VERSION)/Modules/_io/bytesio.c                #\r
-  Python-$(PYTHON_VERSION)/Modules/_io/fileio.c                 #\r
-  Python-$(PYTHON_VERSION)/Modules/_io/iobase.c                 #\r
-  Python-$(PYTHON_VERSION)/Modules/_io/stringio.c               #\r
-  Python-$(PYTHON_VERSION)/Modules/_io/textio.c                 #\r
+#Modules/expat\r
+  Python-$(PYTHON_VERSION)/Modules/pyexpat.c                    #\r
+  PyMod-$(PYTHON_VERSION)/Modules/expat/xmlparse.c              #\r
+  Python-$(PYTHON_VERSION)/Modules/expat/xmlrole.c              #\r
+  Python-$(PYTHON_VERSION)/Modules/expat/xmltok.c               #\r
 \r
 #Modules/zlib\r
   Python-$(PYTHON_VERSION)/Modules/zlib/adler32.c               #\r
   Python-$(PYTHON_VERSION)/Modules/zlib/zutil.c                 #\r
 \r
 [BuildOptions]\r
-   MSFT:*_*_IA32_CC_FLAGS         = /Oi- /wd4018 /wd4054 /wd4055 /wd4101 /wd4131 /wd4152 /wd4204 /wd4210 /wd4244 /wd4267 /wd4305 /wd4310 /wd4389 /wd4701 /wd4702 /wd4706 /I$(WORKSPACE)\AppPkg\Applications\Python\Ia32 /I$(WORKSPACE)\AppPkg\Applications\Python\Efi /I$(WORKSPACE)\AppPkg\Applications\Python\Python-$(PYTHON_VERSION)\Include\r
-   MSFT:*_*_X64_CC_FLAGS          = /Oi- /wd4018 /wd4054 /wd4055 /wd4101 /wd4131 /wd4152 /wd4204 /wd4210 /wd4244 /wd4267 /wd4305 /wd4310 /wd4389 /wd4701 /wd4702 /wd4706 /I$(WORKSPACE)\AppPkg\Applications\Python\X64 /I$(WORKSPACE)\AppPkg\Applications\Python\Efi /I$(WORKSPACE)\AppPkg\Applications\Python\Python-$(PYTHON_VERSION)\Include\r
-    GCC:*_*_IA32_CC_FLAGS         = -fno-builtin -Wno-format -I$(WORKSPACE)/AppPkg/Applications/Python/Ia32 -I$(WORKSPACE)/AppPkg/Applications/Python/Python-$(PYTHON_VERSION)/Include\r
-    GCC:*_*_X64_CC_FLAGS          = -Wno-format -I$(WORKSPACE)/AppPkg/Applications/Python/X64 -I$(WORKSPACE)/AppPkg/Applications/Python/Python-$(PYTHON_VERSION)/Include\r
+   MSFT:*_*_IA32_CC_FLAGS         = /Oi- /wd4018 /wd4054 /wd4055 /wd4101 /wd4131 /wd4152 /wd4204 /wd4210 /wd4244 /wd4267 /wd4305 /wd4310 /wd4389 /wd4701 /wd4702 /wd4706 /I$(WORKSPACE)\AppPkg\Applications\Python\Ia32 /I$(WORKSPACE)\AppPkg\Applications\Python\Efi /I$(WORKSPACE)\AppPkg\Applications\Python\Python-$(PYTHON_VERSION)\Include /DHAVE_MEMMOVE /DUSE_PYEXPAT_CAPI /DXML_STATIC\r
+   MSFT:*_*_X64_CC_FLAGS          = /Oi- /wd4018 /wd4054 /wd4055 /wd4101 /wd4131 /wd4152 /wd4204 /wd4210 /wd4244 /wd4267 /wd4305 /wd4310 /wd4389 /wd4701 /wd4702 /wd4706 /I$(WORKSPACE)\AppPkg\Applications\Python\X64 /I$(WORKSPACE)\AppPkg\Applications\Python\Efi /I$(WORKSPACE)\AppPkg\Applications\Python\Python-$(PYTHON_VERSION)\Include /DHAVE_MEMMOVE /DUSE_PYEXPAT_CAPI /DXML_STATIC\r
+    GCC:*_*_IA32_CC_FLAGS         = -fno-builtin -Wno-format -I$(WORKSPACE)/AppPkg/Applications/Python/Ia32 -I$(WORKSPACE)/AppPkg/Applications/Python/Python-$(PYTHON_VERSION)/Include -DHAVE_MEMMOVE -DUSE_PYEXPAT_CAPI -DXML_STATIC\r
+    GCC:*_*_X64_CC_FLAGS          = -Wno-format -I$(WORKSPACE)/AppPkg/Applications/Python/X64 -I$(WORKSPACE)/AppPkg/Applications/Python/Python-$(PYTHON_VERSION)/Include -DHAVE_MEMMOVE -DUSE_PYEXPAT_CAPI -DXML_STATIC\r
     GCC:*_*_IPF_SYMRENAME_FLAGS   = --redefine-syms=$(WORKSPACE)/StdLib/GccSymRename.txt\r