symbian-qemu-0.9.1-12/python-2.6.1/Modules/expat/xmlparse.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
       
     2    See the file COPYING for copying permission.
       
     3 */
       
     4 
       
     5 #define XML_BUILDING_EXPAT 1
       
     6 
       
     7 #ifdef COMPILED_FROM_DSP
       
     8 #include "winconfig.h"
       
     9 #elif defined(MACOS_CLASSIC)
       
    10 #include "macconfig.h"
       
    11 #elif defined(__amigaos4__)
       
    12 #include "amigaconfig.h"
       
    13 #elif defined(HAVE_EXPAT_CONFIG_H)
       
    14 #include <expat_config.h>
       
    15 #endif /* ndef COMPILED_FROM_DSP */
       
    16 
       
    17 #include <stddef.h>
       
    18 #include <string.h>                     /* memset(), memcpy() */
       
    19 #include <assert.h>
       
    20 
       
    21 #include "expat.h"
       
    22 
       
    23 #ifdef XML_UNICODE
       
    24 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
       
    25 #define XmlConvert XmlUtf16Convert
       
    26 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
       
    27 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
       
    28 #define XmlEncode XmlUtf16Encode
       
    29 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
       
    30 typedef unsigned short ICHAR;
       
    31 #else
       
    32 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
       
    33 #define XmlConvert XmlUtf8Convert
       
    34 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
       
    35 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
       
    36 #define XmlEncode XmlUtf8Encode
       
    37 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
       
    38 typedef char ICHAR;
       
    39 #endif
       
    40 
       
    41 
       
    42 #ifndef XML_NS
       
    43 
       
    44 #define XmlInitEncodingNS XmlInitEncoding
       
    45 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
       
    46 #undef XmlGetInternalEncodingNS
       
    47 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
       
    48 #define XmlParseXmlDeclNS XmlParseXmlDecl
       
    49 
       
    50 #endif
       
    51 
       
    52 #ifdef XML_UNICODE
       
    53 
       
    54 #ifdef XML_UNICODE_WCHAR_T
       
    55 #define XML_T(x) (const wchar_t)x
       
    56 #define XML_L(x) L ## x
       
    57 #else
       
    58 #define XML_T(x) (const unsigned short)x
       
    59 #define XML_L(x) x
       
    60 #endif
       
    61 
       
    62 #else
       
    63 
       
    64 #define XML_T(x) x
       
    65 #define XML_L(x) x
       
    66 
       
    67 #endif
       
    68 
       
    69 /* Round up n to be a multiple of sz, where sz is a power of 2. */
       
    70 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
       
    71 
       
    72 /* Handle the case where memmove() doesn't exist. */
       
    73 #ifndef HAVE_MEMMOVE
       
    74 #ifdef HAVE_BCOPY
       
    75 #define memmove(d,s,l) bcopy((s),(d),(l))
       
    76 #else
       
    77 #error memmove does not exist on this platform, nor is a substitute available
       
    78 #endif /* HAVE_BCOPY */
       
    79 #endif /* HAVE_MEMMOVE */
       
    80 
       
    81 #include "internal.h"
       
    82 #include "xmltok.h"
       
    83 #include "xmlrole.h"
       
    84 
       
    85 typedef const XML_Char *KEY;
       
    86 
       
    87 typedef struct {
       
    88   KEY name;
       
    89 } NAMED;
       
    90 
       
    91 typedef struct {
       
    92   NAMED **v;
       
    93   unsigned char power;
       
    94   size_t size;
       
    95   size_t used;
       
    96   const XML_Memory_Handling_Suite *mem;
       
    97 } HASH_TABLE;
       
    98 
       
    99 /* Basic character hash algorithm, taken from Python's string hash:
       
   100    h = h * 1000003 ^ character, the constant being a prime number.
       
   101 
       
   102 */
       
   103 #ifdef XML_UNICODE
       
   104 #define CHAR_HASH(h, c) \
       
   105   (((h) * 0xF4243) ^ (unsigned short)(c))
       
   106 #else
       
   107 #define CHAR_HASH(h, c) \
       
   108   (((h) * 0xF4243) ^ (unsigned char)(c))
       
   109 #endif
       
   110 
       
   111 /* For probing (after a collision) we need a step size relative prime
       
   112    to the hash table size, which is a power of 2. We use double-hashing,
       
   113    since we can calculate a second hash value cheaply by taking those bits
       
   114    of the first hash value that were discarded (masked out) when the table
       
   115    index was calculated: index = hash & mask, where mask = table->size - 1.
       
   116    We limit the maximum step size to table->size / 4 (mask >> 2) and make
       
   117    it odd, since odd numbers are always relative prime to a power of 2.
       
   118 */
       
   119 #define SECOND_HASH(hash, mask, power) \
       
   120   ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
       
   121 #define PROBE_STEP(hash, mask, power) \
       
   122   ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
       
   123 
       
   124 typedef struct {
       
   125   NAMED **p;
       
   126   NAMED **end;
       
   127 } HASH_TABLE_ITER;
       
   128 
       
   129 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
       
   130 #define INIT_DATA_BUF_SIZE 1024
       
   131 #define INIT_ATTS_SIZE 16
       
   132 #define INIT_ATTS_VERSION 0xFFFFFFFF
       
   133 #define INIT_BLOCK_SIZE 1024
       
   134 #define INIT_BUFFER_SIZE 1024
       
   135 
       
   136 #define EXPAND_SPARE 24
       
   137 
       
   138 typedef struct binding {
       
   139   struct prefix *prefix;
       
   140   struct binding *nextTagBinding;
       
   141   struct binding *prevPrefixBinding;
       
   142   const struct attribute_id *attId;
       
   143   XML_Char *uri;
       
   144   int uriLen;
       
   145   int uriAlloc;
       
   146 } BINDING;
       
   147 
       
   148 typedef struct prefix {
       
   149   const XML_Char *name;
       
   150   BINDING *binding;
       
   151 } PREFIX;
       
   152 
       
   153 typedef struct {
       
   154   const XML_Char *str;
       
   155   const XML_Char *localPart;
       
   156   const XML_Char *prefix;
       
   157   int strLen;
       
   158   int uriLen;
       
   159   int prefixLen;
       
   160 } TAG_NAME;
       
   161 
       
   162 /* TAG represents an open element.
       
   163    The name of the element is stored in both the document and API
       
   164    encodings.  The memory buffer 'buf' is a separately-allocated
       
   165    memory area which stores the name.  During the XML_Parse()/
       
   166    XMLParseBuffer() when the element is open, the memory for the 'raw'
       
   167    version of the name (in the document encoding) is shared with the
       
   168    document buffer.  If the element is open across calls to
       
   169    XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
       
   170    contain the 'raw' name as well.
       
   171 
       
   172    A parser re-uses these structures, maintaining a list of allocated
       
   173    TAG objects in a free list.
       
   174 */
       
   175 typedef struct tag {
       
   176   struct tag *parent;           /* parent of this element */
       
   177   const char *rawName;          /* tagName in the original encoding */
       
   178   int rawNameLength;
       
   179   TAG_NAME name;                /* tagName in the API encoding */
       
   180   char *buf;                    /* buffer for name components */
       
   181   char *bufEnd;                 /* end of the buffer */
       
   182   BINDING *bindings;
       
   183 } TAG;
       
   184 
       
   185 typedef struct {
       
   186   const XML_Char *name;
       
   187   const XML_Char *textPtr;
       
   188   int textLen;                  /* length in XML_Chars */
       
   189   int processed;                /* # of processed bytes - when suspended */
       
   190   const XML_Char *systemId;
       
   191   const XML_Char *base;
       
   192   const XML_Char *publicId;
       
   193   const XML_Char *notation;
       
   194   XML_Bool open;
       
   195   XML_Bool is_param;
       
   196   XML_Bool is_internal; /* true if declared in internal subset outside PE */
       
   197 } ENTITY;
       
   198 
       
   199 typedef struct {
       
   200   enum XML_Content_Type         type;
       
   201   enum XML_Content_Quant        quant;
       
   202   const XML_Char *              name;
       
   203   int                           firstchild;
       
   204   int                           lastchild;
       
   205   int                           childcnt;
       
   206   int                           nextsib;
       
   207 } CONTENT_SCAFFOLD;
       
   208 
       
   209 #define INIT_SCAFFOLD_ELEMENTS 32
       
   210 
       
   211 typedef struct block {
       
   212   struct block *next;
       
   213   int size;
       
   214   XML_Char s[1];
       
   215 } BLOCK;
       
   216 
       
   217 typedef struct {
       
   218   BLOCK *blocks;
       
   219   BLOCK *freeBlocks;
       
   220   const XML_Char *end;
       
   221   XML_Char *ptr;
       
   222   XML_Char *start;
       
   223   const XML_Memory_Handling_Suite *mem;
       
   224 } STRING_POOL;
       
   225 
       
   226 /* The XML_Char before the name is used to determine whether
       
   227    an attribute has been specified. */
       
   228 typedef struct attribute_id {
       
   229   XML_Char *name;
       
   230   PREFIX *prefix;
       
   231   XML_Bool maybeTokenized;
       
   232   XML_Bool xmlns;
       
   233 } ATTRIBUTE_ID;
       
   234 
       
   235 typedef struct {
       
   236   const ATTRIBUTE_ID *id;
       
   237   XML_Bool isCdata;
       
   238   const XML_Char *value;
       
   239 } DEFAULT_ATTRIBUTE;
       
   240 
       
   241 typedef struct {
       
   242   unsigned long version;
       
   243   unsigned long hash;
       
   244   const XML_Char *uriName;
       
   245 } NS_ATT;
       
   246 
       
   247 typedef struct {
       
   248   const XML_Char *name;
       
   249   PREFIX *prefix;
       
   250   const ATTRIBUTE_ID *idAtt;
       
   251   int nDefaultAtts;
       
   252   int allocDefaultAtts;
       
   253   DEFAULT_ATTRIBUTE *defaultAtts;
       
   254 } ELEMENT_TYPE;
       
   255 
       
   256 typedef struct {
       
   257   HASH_TABLE generalEntities;
       
   258   HASH_TABLE elementTypes;
       
   259   HASH_TABLE attributeIds;
       
   260   HASH_TABLE prefixes;
       
   261   STRING_POOL pool;
       
   262   STRING_POOL entityValuePool;
       
   263   /* false once a parameter entity reference has been skipped */
       
   264   XML_Bool keepProcessing;
       
   265   /* true once an internal or external PE reference has been encountered;
       
   266      this includes the reference to an external subset */
       
   267   XML_Bool hasParamEntityRefs;
       
   268   XML_Bool standalone;
       
   269 #ifdef XML_DTD
       
   270   /* indicates if external PE has been read */
       
   271   XML_Bool paramEntityRead;
       
   272   HASH_TABLE paramEntities;
       
   273 #endif /* XML_DTD */
       
   274   PREFIX defaultPrefix;
       
   275   /* === scaffolding for building content model === */
       
   276   XML_Bool in_eldecl;
       
   277   CONTENT_SCAFFOLD *scaffold;
       
   278   unsigned contentStringLen;
       
   279   unsigned scaffSize;
       
   280   unsigned scaffCount;
       
   281   int scaffLevel;
       
   282   int *scaffIndex;
       
   283 } DTD;
       
   284 
       
   285 typedef struct open_internal_entity {
       
   286   const char *internalEventPtr;
       
   287   const char *internalEventEndPtr;
       
   288   struct open_internal_entity *next;
       
   289   ENTITY *entity;
       
   290   int startTagLevel;
       
   291   XML_Bool betweenDecl; /* WFC: PE Between Declarations */
       
   292 } OPEN_INTERNAL_ENTITY;
       
   293 
       
   294 typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
       
   295                                          const char *start,
       
   296                                          const char *end,
       
   297                                          const char **endPtr);
       
   298 
       
   299 static Processor prologProcessor;
       
   300 static Processor prologInitProcessor;
       
   301 static Processor contentProcessor;
       
   302 static Processor cdataSectionProcessor;
       
   303 #ifdef XML_DTD
       
   304 static Processor ignoreSectionProcessor;
       
   305 static Processor externalParEntProcessor;
       
   306 static Processor externalParEntInitProcessor;
       
   307 static Processor entityValueProcessor;
       
   308 static Processor entityValueInitProcessor;
       
   309 #endif /* XML_DTD */
       
   310 static Processor epilogProcessor;
       
   311 static Processor errorProcessor;
       
   312 static Processor externalEntityInitProcessor;
       
   313 static Processor externalEntityInitProcessor2;
       
   314 static Processor externalEntityInitProcessor3;
       
   315 static Processor externalEntityContentProcessor;
       
   316 static Processor internalEntityProcessor;
       
   317 
       
   318 static enum XML_Error
       
   319 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
       
   320 static enum XML_Error
       
   321 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
       
   322                const char *s, const char *next);
       
   323 static enum XML_Error
       
   324 initializeEncoding(XML_Parser parser);
       
   325 static enum XML_Error
       
   326 doProlog(XML_Parser parser, const ENCODING *enc, const char *s, 
       
   327          const char *end, int tok, const char *next, const char **nextPtr, 
       
   328          XML_Bool haveMore);
       
   329 static enum XML_Error
       
   330 processInternalEntity(XML_Parser parser, ENTITY *entity, 
       
   331                       XML_Bool betweenDecl);
       
   332 static enum XML_Error
       
   333 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
       
   334           const char *start, const char *end, const char **endPtr, 
       
   335           XML_Bool haveMore);
       
   336 static enum XML_Error
       
   337 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
       
   338                const char *end, const char **nextPtr, XML_Bool haveMore);
       
   339 #ifdef XML_DTD
       
   340 static enum XML_Error
       
   341 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
       
   342                 const char *end, const char **nextPtr, XML_Bool haveMore);
       
   343 #endif /* XML_DTD */
       
   344 
       
   345 static enum XML_Error
       
   346 storeAtts(XML_Parser parser, const ENCODING *, const char *s,
       
   347           TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
       
   348 static enum XML_Error
       
   349 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
       
   350            const XML_Char *uri, BINDING **bindingsPtr);
       
   351 static int
       
   352 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 
       
   353                 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
       
   354 static enum XML_Error
       
   355 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
       
   356                     const char *, const char *, STRING_POOL *);
       
   357 static enum XML_Error
       
   358 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
       
   359                      const char *, const char *, STRING_POOL *);
       
   360 static ATTRIBUTE_ID *
       
   361 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
       
   362                const char *end);
       
   363 static int
       
   364 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
       
   365 static enum XML_Error
       
   366 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
       
   367                  const char *end);
       
   368 static int
       
   369 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
       
   370                             const char *start, const char *end);
       
   371 static int
       
   372 reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
       
   373               const char *end);
       
   374 static void
       
   375 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
       
   376               const char *end);
       
   377 
       
   378 static const XML_Char * getContext(XML_Parser parser);
       
   379 static XML_Bool
       
   380 setContext(XML_Parser parser, const XML_Char *context);
       
   381 
       
   382 static void FASTCALL normalizePublicId(XML_Char *s);
       
   383 
       
   384 static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
       
   385 /* do not call if parentParser != NULL */
       
   386 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
       
   387 static void
       
   388 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
       
   389 static int
       
   390 dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
       
   391 static int
       
   392 copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
       
   393 
       
   394 static NAMED *
       
   395 lookup(HASH_TABLE *table, KEY name, size_t createSize);
       
   396 static void FASTCALL
       
   397 hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
       
   398 static void FASTCALL hashTableClear(HASH_TABLE *);
       
   399 static void FASTCALL hashTableDestroy(HASH_TABLE *);
       
   400 static void FASTCALL
       
   401 hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
       
   402 static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
       
   403 
       
   404 static void FASTCALL
       
   405 poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
       
   406 static void FASTCALL poolClear(STRING_POOL *);
       
   407 static void FASTCALL poolDestroy(STRING_POOL *);
       
   408 static XML_Char *
       
   409 poolAppend(STRING_POOL *pool, const ENCODING *enc,
       
   410            const char *ptr, const char *end);
       
   411 static XML_Char *
       
   412 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
       
   413                 const char *ptr, const char *end);
       
   414 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
       
   415 static const XML_Char * FASTCALL
       
   416 poolCopyString(STRING_POOL *pool, const XML_Char *s);
       
   417 static const XML_Char *
       
   418 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
       
   419 static const XML_Char * FASTCALL
       
   420 poolAppendString(STRING_POOL *pool, const XML_Char *s);
       
   421 
       
   422 static int FASTCALL nextScaffoldPart(XML_Parser parser);
       
   423 static XML_Content * build_model(XML_Parser parser);
       
   424 static ELEMENT_TYPE *
       
   425 getElementType(XML_Parser parser, const ENCODING *enc,
       
   426                const char *ptr, const char *end);
       
   427 
       
   428 static XML_Parser
       
   429 parserCreate(const XML_Char *encodingName,
       
   430              const XML_Memory_Handling_Suite *memsuite,
       
   431              const XML_Char *nameSep,
       
   432              DTD *dtd);
       
   433 static void
       
   434 parserInit(XML_Parser parser, const XML_Char *encodingName);
       
   435 
       
   436 #define poolStart(pool) ((pool)->start)
       
   437 #define poolEnd(pool) ((pool)->ptr)
       
   438 #define poolLength(pool) ((pool)->ptr - (pool)->start)
       
   439 #define poolChop(pool) ((void)--(pool->ptr))
       
   440 #define poolLastChar(pool) (((pool)->ptr)[-1])
       
   441 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
       
   442 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
       
   443 #define poolAppendChar(pool, c) \
       
   444   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
       
   445    ? 0 \
       
   446    : ((*((pool)->ptr)++ = c), 1))
       
   447 
       
   448 struct XML_ParserStruct {
       
   449   /* The first member must be userData so that the XML_GetUserData
       
   450      macro works. */
       
   451   void *m_userData;
       
   452   void *m_handlerArg;
       
   453   char *m_buffer;
       
   454   const XML_Memory_Handling_Suite m_mem;
       
   455   /* first character to be parsed */
       
   456   const char *m_bufferPtr;
       
   457   /* past last character to be parsed */
       
   458   char *m_bufferEnd;
       
   459   /* allocated end of buffer */
       
   460   const char *m_bufferLim;
       
   461   XML_Index m_parseEndByteIndex;
       
   462   const char *m_parseEndPtr;
       
   463   XML_Char *m_dataBuf;
       
   464   XML_Char *m_dataBufEnd;
       
   465   XML_StartElementHandler m_startElementHandler;
       
   466   XML_EndElementHandler m_endElementHandler;
       
   467   XML_CharacterDataHandler m_characterDataHandler;
       
   468   XML_ProcessingInstructionHandler m_processingInstructionHandler;
       
   469   XML_CommentHandler m_commentHandler;
       
   470   XML_StartCdataSectionHandler m_startCdataSectionHandler;
       
   471   XML_EndCdataSectionHandler m_endCdataSectionHandler;
       
   472   XML_DefaultHandler m_defaultHandler;
       
   473   XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
       
   474   XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
       
   475   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
       
   476   XML_NotationDeclHandler m_notationDeclHandler;
       
   477   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
       
   478   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
       
   479   XML_NotStandaloneHandler m_notStandaloneHandler;
       
   480   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
       
   481   XML_Parser m_externalEntityRefHandlerArg;
       
   482   XML_SkippedEntityHandler m_skippedEntityHandler;
       
   483   XML_UnknownEncodingHandler m_unknownEncodingHandler;
       
   484   XML_ElementDeclHandler m_elementDeclHandler;
       
   485   XML_AttlistDeclHandler m_attlistDeclHandler;
       
   486   XML_EntityDeclHandler m_entityDeclHandler;
       
   487   XML_XmlDeclHandler m_xmlDeclHandler;
       
   488   const ENCODING *m_encoding;
       
   489   INIT_ENCODING m_initEncoding;
       
   490   const ENCODING *m_internalEncoding;
       
   491   const XML_Char *m_protocolEncodingName;
       
   492   XML_Bool m_ns;
       
   493   XML_Bool m_ns_triplets;
       
   494   void *m_unknownEncodingMem;
       
   495   void *m_unknownEncodingData;
       
   496   void *m_unknownEncodingHandlerData;
       
   497   void (XMLCALL *m_unknownEncodingRelease)(void *);
       
   498   PROLOG_STATE m_prologState;
       
   499   Processor *m_processor;
       
   500   enum XML_Error m_errorCode;
       
   501   const char *m_eventPtr;
       
   502   const char *m_eventEndPtr;
       
   503   const char *m_positionPtr;
       
   504   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
       
   505   OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
       
   506   XML_Bool m_defaultExpandInternalEntities;
       
   507   int m_tagLevel;
       
   508   ENTITY *m_declEntity;
       
   509   const XML_Char *m_doctypeName;
       
   510   const XML_Char *m_doctypeSysid;
       
   511   const XML_Char *m_doctypePubid;
       
   512   const XML_Char *m_declAttributeType;
       
   513   const XML_Char *m_declNotationName;
       
   514   const XML_Char *m_declNotationPublicId;
       
   515   ELEMENT_TYPE *m_declElementType;
       
   516   ATTRIBUTE_ID *m_declAttributeId;
       
   517   XML_Bool m_declAttributeIsCdata;
       
   518   XML_Bool m_declAttributeIsId;
       
   519   DTD *m_dtd;
       
   520   const XML_Char *m_curBase;
       
   521   TAG *m_tagStack;
       
   522   TAG *m_freeTagList;
       
   523   BINDING *m_inheritedBindings;
       
   524   BINDING *m_freeBindingList;
       
   525   int m_attsSize;
       
   526   int m_nSpecifiedAtts;
       
   527   int m_idAttIndex;
       
   528   ATTRIBUTE *m_atts;
       
   529   NS_ATT *m_nsAtts;
       
   530   unsigned long m_nsAttsVersion;
       
   531   unsigned char m_nsAttsPower;
       
   532   POSITION m_position;
       
   533   STRING_POOL m_tempPool;
       
   534   STRING_POOL m_temp2Pool;
       
   535   char *m_groupConnector;
       
   536   unsigned int m_groupSize;
       
   537   XML_Char m_namespaceSeparator;
       
   538   XML_Parser m_parentParser;
       
   539   XML_ParsingStatus m_parsingStatus;
       
   540 #ifdef XML_DTD
       
   541   XML_Bool m_isParamEntity;
       
   542   XML_Bool m_useForeignDTD;
       
   543   enum XML_ParamEntityParsing m_paramEntityParsing;
       
   544 #endif
       
   545 };
       
   546 
       
   547 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
       
   548 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
       
   549 #define FREE(p) (parser->m_mem.free_fcn((p)))
       
   550 
       
   551 #define userData (parser->m_userData)
       
   552 #define handlerArg (parser->m_handlerArg)
       
   553 #define startElementHandler (parser->m_startElementHandler)
       
   554 #define endElementHandler (parser->m_endElementHandler)
       
   555 #define characterDataHandler (parser->m_characterDataHandler)
       
   556 #define processingInstructionHandler \
       
   557         (parser->m_processingInstructionHandler)
       
   558 #define commentHandler (parser->m_commentHandler)
       
   559 #define startCdataSectionHandler \
       
   560         (parser->m_startCdataSectionHandler)
       
   561 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
       
   562 #define defaultHandler (parser->m_defaultHandler)
       
   563 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
       
   564 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
       
   565 #define unparsedEntityDeclHandler \
       
   566         (parser->m_unparsedEntityDeclHandler)
       
   567 #define notationDeclHandler (parser->m_notationDeclHandler)
       
   568 #define startNamespaceDeclHandler \
       
   569         (parser->m_startNamespaceDeclHandler)
       
   570 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
       
   571 #define notStandaloneHandler (parser->m_notStandaloneHandler)
       
   572 #define externalEntityRefHandler \
       
   573         (parser->m_externalEntityRefHandler)
       
   574 #define externalEntityRefHandlerArg \
       
   575         (parser->m_externalEntityRefHandlerArg)
       
   576 #define internalEntityRefHandler \
       
   577         (parser->m_internalEntityRefHandler)
       
   578 #define skippedEntityHandler (parser->m_skippedEntityHandler)
       
   579 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
       
   580 #define elementDeclHandler (parser->m_elementDeclHandler)
       
   581 #define attlistDeclHandler (parser->m_attlistDeclHandler)
       
   582 #define entityDeclHandler (parser->m_entityDeclHandler)
       
   583 #define xmlDeclHandler (parser->m_xmlDeclHandler)
       
   584 #define encoding (parser->m_encoding)
       
   585 #define initEncoding (parser->m_initEncoding)
       
   586 #define internalEncoding (parser->m_internalEncoding)
       
   587 #define unknownEncodingMem (parser->m_unknownEncodingMem)
       
   588 #define unknownEncodingData (parser->m_unknownEncodingData)
       
   589 #define unknownEncodingHandlerData \
       
   590   (parser->m_unknownEncodingHandlerData)
       
   591 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
       
   592 #define protocolEncodingName (parser->m_protocolEncodingName)
       
   593 #define ns (parser->m_ns)
       
   594 #define ns_triplets (parser->m_ns_triplets)
       
   595 #define prologState (parser->m_prologState)
       
   596 #define processor (parser->m_processor)
       
   597 #define errorCode (parser->m_errorCode)
       
   598 #define eventPtr (parser->m_eventPtr)
       
   599 #define eventEndPtr (parser->m_eventEndPtr)
       
   600 #define positionPtr (parser->m_positionPtr)
       
   601 #define position (parser->m_position)
       
   602 #define openInternalEntities (parser->m_openInternalEntities)
       
   603 #define freeInternalEntities (parser->m_freeInternalEntities)
       
   604 #define defaultExpandInternalEntities \
       
   605         (parser->m_defaultExpandInternalEntities)
       
   606 #define tagLevel (parser->m_tagLevel)
       
   607 #define buffer (parser->m_buffer)
       
   608 #define bufferPtr (parser->m_bufferPtr)
       
   609 #define bufferEnd (parser->m_bufferEnd)
       
   610 #define parseEndByteIndex (parser->m_parseEndByteIndex)
       
   611 #define parseEndPtr (parser->m_parseEndPtr)
       
   612 #define bufferLim (parser->m_bufferLim)
       
   613 #define dataBuf (parser->m_dataBuf)
       
   614 #define dataBufEnd (parser->m_dataBufEnd)
       
   615 #define _dtd (parser->m_dtd)
       
   616 #define curBase (parser->m_curBase)
       
   617 #define declEntity (parser->m_declEntity)
       
   618 #define doctypeName (parser->m_doctypeName)
       
   619 #define doctypeSysid (parser->m_doctypeSysid)
       
   620 #define doctypePubid (parser->m_doctypePubid)
       
   621 #define declAttributeType (parser->m_declAttributeType)
       
   622 #define declNotationName (parser->m_declNotationName)
       
   623 #define declNotationPublicId (parser->m_declNotationPublicId)
       
   624 #define declElementType (parser->m_declElementType)
       
   625 #define declAttributeId (parser->m_declAttributeId)
       
   626 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
       
   627 #define declAttributeIsId (parser->m_declAttributeIsId)
       
   628 #define freeTagList (parser->m_freeTagList)
       
   629 #define freeBindingList (parser->m_freeBindingList)
       
   630 #define inheritedBindings (parser->m_inheritedBindings)
       
   631 #define tagStack (parser->m_tagStack)
       
   632 #define atts (parser->m_atts)
       
   633 #define attsSize (parser->m_attsSize)
       
   634 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
       
   635 #define idAttIndex (parser->m_idAttIndex)
       
   636 #define nsAtts (parser->m_nsAtts)
       
   637 #define nsAttsVersion (parser->m_nsAttsVersion)
       
   638 #define nsAttsPower (parser->m_nsAttsPower)
       
   639 #define tempPool (parser->m_tempPool)
       
   640 #define temp2Pool (parser->m_temp2Pool)
       
   641 #define groupConnector (parser->m_groupConnector)
       
   642 #define groupSize (parser->m_groupSize)
       
   643 #define namespaceSeparator (parser->m_namespaceSeparator)
       
   644 #define parentParser (parser->m_parentParser)
       
   645 #define ps_parsing (parser->m_parsingStatus.parsing)
       
   646 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
       
   647 #ifdef XML_DTD
       
   648 #define isParamEntity (parser->m_isParamEntity)
       
   649 #define useForeignDTD (parser->m_useForeignDTD)
       
   650 #define paramEntityParsing (parser->m_paramEntityParsing)
       
   651 #endif /* XML_DTD */
       
   652 
       
   653 XML_Parser XMLCALL
       
   654 XML_ParserCreate(const XML_Char *encodingName)
       
   655 {
       
   656   return XML_ParserCreate_MM(encodingName, NULL, NULL);
       
   657 }
       
   658 
       
   659 XML_Parser XMLCALL
       
   660 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
       
   661 {
       
   662   XML_Char tmp[2];
       
   663   *tmp = nsSep;
       
   664   return XML_ParserCreate_MM(encodingName, NULL, tmp);
       
   665 }
       
   666 
       
   667 static const XML_Char implicitContext[] = {
       
   668   'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
       
   669   'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
       
   670   'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
       
   671   'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
       
   672 };
       
   673 
       
   674 XML_Parser XMLCALL
       
   675 XML_ParserCreate_MM(const XML_Char *encodingName,
       
   676                     const XML_Memory_Handling_Suite *memsuite,
       
   677                     const XML_Char *nameSep)
       
   678 {
       
   679   XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
       
   680   if (parser != NULL && ns) {
       
   681     /* implicit context only set for root parser, since child
       
   682        parsers (i.e. external entity parsers) will inherit it
       
   683     */
       
   684     if (!setContext(parser, implicitContext)) {
       
   685       XML_ParserFree(parser);
       
   686       return NULL;
       
   687     }
       
   688   }
       
   689   return parser;
       
   690 }
       
   691 
       
   692 static XML_Parser
       
   693 parserCreate(const XML_Char *encodingName,
       
   694              const XML_Memory_Handling_Suite *memsuite,
       
   695              const XML_Char *nameSep,
       
   696              DTD *dtd)
       
   697 {
       
   698   XML_Parser parser;
       
   699 
       
   700   if (memsuite) {
       
   701     XML_Memory_Handling_Suite *mtemp;
       
   702     parser = (XML_Parser)
       
   703       memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
       
   704     if (parser != NULL) {
       
   705       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
       
   706       mtemp->malloc_fcn = memsuite->malloc_fcn;
       
   707       mtemp->realloc_fcn = memsuite->realloc_fcn;
       
   708       mtemp->free_fcn = memsuite->free_fcn;
       
   709     }
       
   710   }
       
   711   else {
       
   712     XML_Memory_Handling_Suite *mtemp;
       
   713     parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
       
   714     if (parser != NULL) {
       
   715       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
       
   716       mtemp->malloc_fcn = malloc;
       
   717       mtemp->realloc_fcn = realloc;
       
   718       mtemp->free_fcn = free;
       
   719     }
       
   720   }
       
   721 
       
   722   if (!parser)
       
   723     return parser;
       
   724 
       
   725   buffer = NULL;
       
   726   bufferLim = NULL;
       
   727 
       
   728   attsSize = INIT_ATTS_SIZE;
       
   729   atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
       
   730   if (atts == NULL) {
       
   731     FREE(parser);
       
   732     return NULL;
       
   733   }
       
   734   dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
       
   735   if (dataBuf == NULL) {
       
   736     FREE(atts);
       
   737     FREE(parser);
       
   738     return NULL;
       
   739   }
       
   740   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
       
   741 
       
   742   if (dtd)
       
   743     _dtd = dtd;
       
   744   else {
       
   745     _dtd = dtdCreate(&parser->m_mem);
       
   746     if (_dtd == NULL) {
       
   747       FREE(dataBuf);
       
   748       FREE(atts);
       
   749       FREE(parser);
       
   750       return NULL;
       
   751     }
       
   752   }
       
   753 
       
   754   freeBindingList = NULL;
       
   755   freeTagList = NULL;
       
   756   freeInternalEntities = NULL;
       
   757 
       
   758   groupSize = 0;
       
   759   groupConnector = NULL;
       
   760 
       
   761   unknownEncodingHandler = NULL;
       
   762   unknownEncodingHandlerData = NULL;
       
   763 
       
   764   namespaceSeparator = '!';
       
   765   ns = XML_FALSE;
       
   766   ns_triplets = XML_FALSE;
       
   767 
       
   768   nsAtts = NULL;
       
   769   nsAttsVersion = 0;
       
   770   nsAttsPower = 0;
       
   771 
       
   772   poolInit(&tempPool, &(parser->m_mem));
       
   773   poolInit(&temp2Pool, &(parser->m_mem));
       
   774   parserInit(parser, encodingName);
       
   775 
       
   776   if (encodingName && !protocolEncodingName) {
       
   777     XML_ParserFree(parser);
       
   778     return NULL;
       
   779   }
       
   780 
       
   781   if (nameSep) {
       
   782     ns = XML_TRUE;
       
   783     internalEncoding = XmlGetInternalEncodingNS();
       
   784     namespaceSeparator = *nameSep;
       
   785   }
       
   786   else {
       
   787     internalEncoding = XmlGetInternalEncoding();
       
   788   }
       
   789 
       
   790   return parser;
       
   791 }
       
   792 
       
   793 static void
       
   794 parserInit(XML_Parser parser, const XML_Char *encodingName)
       
   795 {
       
   796   processor = prologInitProcessor;
       
   797   XmlPrologStateInit(&prologState);
       
   798   protocolEncodingName = (encodingName != NULL
       
   799                           ? poolCopyString(&tempPool, encodingName)
       
   800                           : NULL);
       
   801   curBase = NULL;
       
   802   XmlInitEncoding(&initEncoding, &encoding, 0);
       
   803   userData = NULL;
       
   804   handlerArg = NULL;
       
   805   startElementHandler = NULL;
       
   806   endElementHandler = NULL;
       
   807   characterDataHandler = NULL;
       
   808   processingInstructionHandler = NULL;
       
   809   commentHandler = NULL;
       
   810   startCdataSectionHandler = NULL;
       
   811   endCdataSectionHandler = NULL;
       
   812   defaultHandler = NULL;
       
   813   startDoctypeDeclHandler = NULL;
       
   814   endDoctypeDeclHandler = NULL;
       
   815   unparsedEntityDeclHandler = NULL;
       
   816   notationDeclHandler = NULL;
       
   817   startNamespaceDeclHandler = NULL;
       
   818   endNamespaceDeclHandler = NULL;
       
   819   notStandaloneHandler = NULL;
       
   820   externalEntityRefHandler = NULL;
       
   821   externalEntityRefHandlerArg = parser;
       
   822   skippedEntityHandler = NULL;
       
   823   elementDeclHandler = NULL;
       
   824   attlistDeclHandler = NULL;
       
   825   entityDeclHandler = NULL;
       
   826   xmlDeclHandler = NULL;
       
   827   bufferPtr = buffer;
       
   828   bufferEnd = buffer;
       
   829   parseEndByteIndex = 0;
       
   830   parseEndPtr = NULL;
       
   831   declElementType = NULL;
       
   832   declAttributeId = NULL;
       
   833   declEntity = NULL;
       
   834   doctypeName = NULL;
       
   835   doctypeSysid = NULL;
       
   836   doctypePubid = NULL;
       
   837   declAttributeType = NULL;
       
   838   declNotationName = NULL;
       
   839   declNotationPublicId = NULL;
       
   840   declAttributeIsCdata = XML_FALSE;
       
   841   declAttributeIsId = XML_FALSE;
       
   842   memset(&position, 0, sizeof(POSITION));
       
   843   errorCode = XML_ERROR_NONE;
       
   844   eventPtr = NULL;
       
   845   eventEndPtr = NULL;
       
   846   positionPtr = NULL;
       
   847   openInternalEntities = NULL;
       
   848   defaultExpandInternalEntities = XML_TRUE;
       
   849   tagLevel = 0;
       
   850   tagStack = NULL;
       
   851   inheritedBindings = NULL;
       
   852   nSpecifiedAtts = 0;
       
   853   unknownEncodingMem = NULL;
       
   854   unknownEncodingRelease = NULL;
       
   855   unknownEncodingData = NULL;
       
   856   parentParser = NULL;
       
   857   ps_parsing = XML_INITIALIZED;
       
   858 #ifdef XML_DTD
       
   859   isParamEntity = XML_FALSE;
       
   860   useForeignDTD = XML_FALSE;
       
   861   paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
       
   862 #endif
       
   863 }
       
   864 
       
   865 /* moves list of bindings to freeBindingList */
       
   866 static void FASTCALL
       
   867 moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
       
   868 {
       
   869   while (bindings) {
       
   870     BINDING *b = bindings;
       
   871     bindings = bindings->nextTagBinding;
       
   872     b->nextTagBinding = freeBindingList;
       
   873     freeBindingList = b;
       
   874   }
       
   875 }
       
   876 
       
   877 XML_Bool XMLCALL
       
   878 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
       
   879 {
       
   880   TAG *tStk;
       
   881   OPEN_INTERNAL_ENTITY *openEntityList;
       
   882   if (parentParser)
       
   883     return XML_FALSE;
       
   884   /* move tagStack to freeTagList */
       
   885   tStk = tagStack;
       
   886   while (tStk) {
       
   887     TAG *tag = tStk;
       
   888     tStk = tStk->parent;
       
   889     tag->parent = freeTagList;
       
   890     moveToFreeBindingList(parser, tag->bindings);
       
   891     tag->bindings = NULL;
       
   892     freeTagList = tag;
       
   893   }
       
   894   /* move openInternalEntities to freeInternalEntities */
       
   895   openEntityList = openInternalEntities;
       
   896   while (openEntityList) {
       
   897     OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
       
   898     openEntityList = openEntity->next;
       
   899     openEntity->next = freeInternalEntities;
       
   900     freeInternalEntities = openEntity;
       
   901   }
       
   902   moveToFreeBindingList(parser, inheritedBindings);
       
   903   FREE(unknownEncodingMem);
       
   904   if (unknownEncodingRelease)
       
   905     unknownEncodingRelease(unknownEncodingData);
       
   906   poolClear(&tempPool);
       
   907   poolClear(&temp2Pool);
       
   908   parserInit(parser, encodingName);
       
   909   dtdReset(_dtd, &parser->m_mem);
       
   910   return setContext(parser, implicitContext);
       
   911 }
       
   912 
       
   913 enum XML_Status XMLCALL
       
   914 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
       
   915 {
       
   916   /* Block after XML_Parse()/XML_ParseBuffer() has been called.
       
   917      XXX There's no way for the caller to determine which of the
       
   918      XXX possible error cases caused the XML_STATUS_ERROR return.
       
   919   */
       
   920   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
       
   921     return XML_STATUS_ERROR;
       
   922   if (encodingName == NULL)
       
   923     protocolEncodingName = NULL;
       
   924   else {
       
   925     protocolEncodingName = poolCopyString(&tempPool, encodingName);
       
   926     if (!protocolEncodingName)
       
   927       return XML_STATUS_ERROR;
       
   928   }
       
   929   return XML_STATUS_OK;
       
   930 }
       
   931 
       
   932 XML_Parser XMLCALL
       
   933 XML_ExternalEntityParserCreate(XML_Parser oldParser,
       
   934                                const XML_Char *context,
       
   935                                const XML_Char *encodingName)
       
   936 {
       
   937   XML_Parser parser = oldParser;
       
   938   DTD *newDtd = NULL;
       
   939   DTD *oldDtd = _dtd;
       
   940   XML_StartElementHandler oldStartElementHandler = startElementHandler;
       
   941   XML_EndElementHandler oldEndElementHandler = endElementHandler;
       
   942   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
       
   943   XML_ProcessingInstructionHandler oldProcessingInstructionHandler
       
   944       = processingInstructionHandler;
       
   945   XML_CommentHandler oldCommentHandler = commentHandler;
       
   946   XML_StartCdataSectionHandler oldStartCdataSectionHandler
       
   947       = startCdataSectionHandler;
       
   948   XML_EndCdataSectionHandler oldEndCdataSectionHandler
       
   949       = endCdataSectionHandler;
       
   950   XML_DefaultHandler oldDefaultHandler = defaultHandler;
       
   951   XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
       
   952       = unparsedEntityDeclHandler;
       
   953   XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
       
   954   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
       
   955       = startNamespaceDeclHandler;
       
   956   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
       
   957       = endNamespaceDeclHandler;
       
   958   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
       
   959   XML_ExternalEntityRefHandler oldExternalEntityRefHandler
       
   960       = externalEntityRefHandler;
       
   961   XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
       
   962   XML_UnknownEncodingHandler oldUnknownEncodingHandler
       
   963       = unknownEncodingHandler;
       
   964   XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
       
   965   XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
       
   966   XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
       
   967   XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
       
   968   ELEMENT_TYPE * oldDeclElementType = declElementType;
       
   969 
       
   970   void *oldUserData = userData;
       
   971   void *oldHandlerArg = handlerArg;
       
   972   XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
       
   973   XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
       
   974 #ifdef XML_DTD
       
   975   enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
       
   976   int oldInEntityValue = prologState.inEntityValue;
       
   977 #endif
       
   978   XML_Bool oldns_triplets = ns_triplets;
       
   979 
       
   980 #ifdef XML_DTD
       
   981   if (!context)
       
   982     newDtd = oldDtd;
       
   983 #endif /* XML_DTD */
       
   984 
       
   985   /* Note that the magical uses of the pre-processor to make field
       
   986      access look more like C++ require that `parser' be overwritten
       
   987      here.  This makes this function more painful to follow than it
       
   988      would be otherwise.
       
   989   */
       
   990   if (ns) {
       
   991     XML_Char tmp[2];
       
   992     *tmp = namespaceSeparator;
       
   993     parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
       
   994   }
       
   995   else {
       
   996     parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
       
   997   }
       
   998 
       
   999   if (!parser)
       
  1000     return NULL;
       
  1001 
       
  1002   startElementHandler = oldStartElementHandler;
       
  1003   endElementHandler = oldEndElementHandler;
       
  1004   characterDataHandler = oldCharacterDataHandler;
       
  1005   processingInstructionHandler = oldProcessingInstructionHandler;
       
  1006   commentHandler = oldCommentHandler;
       
  1007   startCdataSectionHandler = oldStartCdataSectionHandler;
       
  1008   endCdataSectionHandler = oldEndCdataSectionHandler;
       
  1009   defaultHandler = oldDefaultHandler;
       
  1010   unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
       
  1011   notationDeclHandler = oldNotationDeclHandler;
       
  1012   startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
       
  1013   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
       
  1014   notStandaloneHandler = oldNotStandaloneHandler;
       
  1015   externalEntityRefHandler = oldExternalEntityRefHandler;
       
  1016   skippedEntityHandler = oldSkippedEntityHandler;
       
  1017   unknownEncodingHandler = oldUnknownEncodingHandler;
       
  1018   elementDeclHandler = oldElementDeclHandler;
       
  1019   attlistDeclHandler = oldAttlistDeclHandler;
       
  1020   entityDeclHandler = oldEntityDeclHandler;
       
  1021   xmlDeclHandler = oldXmlDeclHandler;
       
  1022   declElementType = oldDeclElementType;
       
  1023   userData = oldUserData;
       
  1024   if (oldUserData == oldHandlerArg)
       
  1025     handlerArg = userData;
       
  1026   else
       
  1027     handlerArg = parser;
       
  1028   if (oldExternalEntityRefHandlerArg != oldParser)
       
  1029     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
       
  1030   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
       
  1031   ns_triplets = oldns_triplets;
       
  1032   parentParser = oldParser;
       
  1033 #ifdef XML_DTD
       
  1034   paramEntityParsing = oldParamEntityParsing;
       
  1035   prologState.inEntityValue = oldInEntityValue;
       
  1036   if (context) {
       
  1037 #endif /* XML_DTD */
       
  1038     if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
       
  1039       || !setContext(parser, context)) {
       
  1040       XML_ParserFree(parser);
       
  1041       return NULL;
       
  1042     }
       
  1043     processor = externalEntityInitProcessor;
       
  1044 #ifdef XML_DTD
       
  1045   }
       
  1046   else {
       
  1047     /* The DTD instance referenced by _dtd is shared between the document's
       
  1048        root parser and external PE parsers, therefore one does not need to
       
  1049        call setContext. In addition, one also *must* not call setContext,
       
  1050        because this would overwrite existing prefix->binding pointers in
       
  1051        _dtd with ones that get destroyed with the external PE parser.
       
  1052        This would leave those prefixes with dangling pointers.
       
  1053     */
       
  1054     isParamEntity = XML_TRUE;
       
  1055     XmlPrologStateInitExternalEntity(&prologState);
       
  1056     processor = externalParEntInitProcessor;
       
  1057   }
       
  1058 #endif /* XML_DTD */
       
  1059   return parser;
       
  1060 }
       
  1061 
       
  1062 static void FASTCALL
       
  1063 destroyBindings(BINDING *bindings, XML_Parser parser)
       
  1064 {
       
  1065   for (;;) {
       
  1066     BINDING *b = bindings;
       
  1067     if (!b)
       
  1068       break;
       
  1069     bindings = b->nextTagBinding;
       
  1070     FREE(b->uri);
       
  1071     FREE(b);
       
  1072   }
       
  1073 }
       
  1074 
       
  1075 void XMLCALL
       
  1076 XML_ParserFree(XML_Parser parser)
       
  1077 {
       
  1078   TAG *tagList;
       
  1079   OPEN_INTERNAL_ENTITY *entityList;
       
  1080   if (parser == NULL)
       
  1081     return;
       
  1082   /* free tagStack and freeTagList */
       
  1083   tagList = tagStack;
       
  1084   for (;;) {
       
  1085     TAG *p;
       
  1086     if (tagList == NULL) {
       
  1087       if (freeTagList == NULL)
       
  1088         break;
       
  1089       tagList = freeTagList;
       
  1090       freeTagList = NULL;
       
  1091     }
       
  1092     p = tagList;
       
  1093     tagList = tagList->parent;
       
  1094     FREE(p->buf);
       
  1095     destroyBindings(p->bindings, parser);
       
  1096     FREE(p);
       
  1097   }
       
  1098   /* free openInternalEntities and freeInternalEntities */
       
  1099   entityList = openInternalEntities;
       
  1100   for (;;) {
       
  1101     OPEN_INTERNAL_ENTITY *openEntity;
       
  1102     if (entityList == NULL) {
       
  1103       if (freeInternalEntities == NULL)
       
  1104         break;
       
  1105       entityList = freeInternalEntities;
       
  1106       freeInternalEntities = NULL;
       
  1107     }
       
  1108     openEntity = entityList;
       
  1109     entityList = entityList->next;
       
  1110     FREE(openEntity);
       
  1111   }
       
  1112 
       
  1113   destroyBindings(freeBindingList, parser);
       
  1114   destroyBindings(inheritedBindings, parser);
       
  1115   poolDestroy(&tempPool);
       
  1116   poolDestroy(&temp2Pool);
       
  1117 #ifdef XML_DTD
       
  1118   /* external parameter entity parsers share the DTD structure
       
  1119      parser->m_dtd with the root parser, so we must not destroy it
       
  1120   */
       
  1121   if (!isParamEntity && _dtd)
       
  1122 #else
       
  1123   if (_dtd)
       
  1124 #endif /* XML_DTD */
       
  1125     dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
       
  1126   FREE((void *)atts);
       
  1127   FREE(groupConnector);
       
  1128   FREE(buffer);
       
  1129   FREE(dataBuf);
       
  1130   FREE(nsAtts);
       
  1131   FREE(unknownEncodingMem);
       
  1132   if (unknownEncodingRelease)
       
  1133     unknownEncodingRelease(unknownEncodingData);
       
  1134   FREE(parser);
       
  1135 }
       
  1136 
       
  1137 void XMLCALL
       
  1138 XML_UseParserAsHandlerArg(XML_Parser parser)
       
  1139 {
       
  1140   handlerArg = parser;
       
  1141 }
       
  1142 
       
  1143 enum XML_Error XMLCALL
       
  1144 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
       
  1145 {
       
  1146 #ifdef XML_DTD
       
  1147   /* block after XML_Parse()/XML_ParseBuffer() has been called */
       
  1148   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
       
  1149     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
       
  1150   useForeignDTD = useDTD;
       
  1151   return XML_ERROR_NONE;
       
  1152 #else
       
  1153   return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
       
  1154 #endif
       
  1155 }
       
  1156 
       
  1157 void XMLCALL
       
  1158 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
       
  1159 {
       
  1160   /* block after XML_Parse()/XML_ParseBuffer() has been called */
       
  1161   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
       
  1162     return;
       
  1163   ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
       
  1164 }
       
  1165 
       
  1166 void XMLCALL
       
  1167 XML_SetUserData(XML_Parser parser, void *p)
       
  1168 {
       
  1169   if (handlerArg == userData)
       
  1170     handlerArg = userData = p;
       
  1171   else
       
  1172     userData = p;
       
  1173 }
       
  1174 
       
  1175 enum XML_Status XMLCALL
       
  1176 XML_SetBase(XML_Parser parser, const XML_Char *p)
       
  1177 {
       
  1178   if (p) {
       
  1179     p = poolCopyString(&_dtd->pool, p);
       
  1180     if (!p)
       
  1181       return XML_STATUS_ERROR;
       
  1182     curBase = p;
       
  1183   }
       
  1184   else
       
  1185     curBase = NULL;
       
  1186   return XML_STATUS_OK;
       
  1187 }
       
  1188 
       
  1189 const XML_Char * XMLCALL
       
  1190 XML_GetBase(XML_Parser parser)
       
  1191 {
       
  1192   return curBase;
       
  1193 }
       
  1194 
       
  1195 int XMLCALL
       
  1196 XML_GetSpecifiedAttributeCount(XML_Parser parser)
       
  1197 {
       
  1198   return nSpecifiedAtts;
       
  1199 }
       
  1200 
       
  1201 int XMLCALL
       
  1202 XML_GetIdAttributeIndex(XML_Parser parser)
       
  1203 {
       
  1204   return idAttIndex;
       
  1205 }
       
  1206 
       
  1207 void XMLCALL
       
  1208 XML_SetElementHandler(XML_Parser parser,
       
  1209                       XML_StartElementHandler start,
       
  1210                       XML_EndElementHandler end)
       
  1211 {
       
  1212   startElementHandler = start;
       
  1213   endElementHandler = end;
       
  1214 }
       
  1215 
       
  1216 void XMLCALL
       
  1217 XML_SetStartElementHandler(XML_Parser parser,
       
  1218                            XML_StartElementHandler start) {
       
  1219   startElementHandler = start;
       
  1220 }
       
  1221 
       
  1222 void XMLCALL
       
  1223 XML_SetEndElementHandler(XML_Parser parser,
       
  1224                          XML_EndElementHandler end) {
       
  1225   endElementHandler = end;
       
  1226 }
       
  1227 
       
  1228 void XMLCALL
       
  1229 XML_SetCharacterDataHandler(XML_Parser parser,
       
  1230                             XML_CharacterDataHandler handler)
       
  1231 {
       
  1232   characterDataHandler = handler;
       
  1233 }
       
  1234 
       
  1235 void XMLCALL
       
  1236 XML_SetProcessingInstructionHandler(XML_Parser parser,
       
  1237                                     XML_ProcessingInstructionHandler handler)
       
  1238 {
       
  1239   processingInstructionHandler = handler;
       
  1240 }
       
  1241 
       
  1242 void XMLCALL
       
  1243 XML_SetCommentHandler(XML_Parser parser,
       
  1244                       XML_CommentHandler handler)
       
  1245 {
       
  1246   commentHandler = handler;
       
  1247 }
       
  1248 
       
  1249 void XMLCALL
       
  1250 XML_SetCdataSectionHandler(XML_Parser parser,
       
  1251                            XML_StartCdataSectionHandler start,
       
  1252                            XML_EndCdataSectionHandler end)
       
  1253 {
       
  1254   startCdataSectionHandler = start;
       
  1255   endCdataSectionHandler = end;
       
  1256 }
       
  1257 
       
  1258 void XMLCALL
       
  1259 XML_SetStartCdataSectionHandler(XML_Parser parser,
       
  1260                                 XML_StartCdataSectionHandler start) {
       
  1261   startCdataSectionHandler = start;
       
  1262 }
       
  1263 
       
  1264 void XMLCALL
       
  1265 XML_SetEndCdataSectionHandler(XML_Parser parser,
       
  1266                               XML_EndCdataSectionHandler end) {
       
  1267   endCdataSectionHandler = end;
       
  1268 }
       
  1269 
       
  1270 void XMLCALL
       
  1271 XML_SetDefaultHandler(XML_Parser parser,
       
  1272                       XML_DefaultHandler handler)
       
  1273 {
       
  1274   defaultHandler = handler;
       
  1275   defaultExpandInternalEntities = XML_FALSE;
       
  1276 }
       
  1277 
       
  1278 void XMLCALL
       
  1279 XML_SetDefaultHandlerExpand(XML_Parser parser,
       
  1280                             XML_DefaultHandler handler)
       
  1281 {
       
  1282   defaultHandler = handler;
       
  1283   defaultExpandInternalEntities = XML_TRUE;
       
  1284 }
       
  1285 
       
  1286 void XMLCALL
       
  1287 XML_SetDoctypeDeclHandler(XML_Parser parser,
       
  1288                           XML_StartDoctypeDeclHandler start,
       
  1289                           XML_EndDoctypeDeclHandler end)
       
  1290 {
       
  1291   startDoctypeDeclHandler = start;
       
  1292   endDoctypeDeclHandler = end;
       
  1293 }
       
  1294 
       
  1295 void XMLCALL
       
  1296 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
       
  1297                                XML_StartDoctypeDeclHandler start) {
       
  1298   startDoctypeDeclHandler = start;
       
  1299 }
       
  1300 
       
  1301 void XMLCALL
       
  1302 XML_SetEndDoctypeDeclHandler(XML_Parser parser,
       
  1303                              XML_EndDoctypeDeclHandler end) {
       
  1304   endDoctypeDeclHandler = end;
       
  1305 }
       
  1306 
       
  1307 void XMLCALL
       
  1308 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
       
  1309                                  XML_UnparsedEntityDeclHandler handler)
       
  1310 {
       
  1311   unparsedEntityDeclHandler = handler;
       
  1312 }
       
  1313 
       
  1314 void XMLCALL
       
  1315 XML_SetNotationDeclHandler(XML_Parser parser,
       
  1316                            XML_NotationDeclHandler handler)
       
  1317 {
       
  1318   notationDeclHandler = handler;
       
  1319 }
       
  1320 
       
  1321 void XMLCALL
       
  1322 XML_SetNamespaceDeclHandler(XML_Parser parser,
       
  1323                             XML_StartNamespaceDeclHandler start,
       
  1324                             XML_EndNamespaceDeclHandler end)
       
  1325 {
       
  1326   startNamespaceDeclHandler = start;
       
  1327   endNamespaceDeclHandler = end;
       
  1328 }
       
  1329 
       
  1330 void XMLCALL
       
  1331 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
       
  1332                                  XML_StartNamespaceDeclHandler start) {
       
  1333   startNamespaceDeclHandler = start;
       
  1334 }
       
  1335 
       
  1336 void XMLCALL
       
  1337 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
       
  1338                                XML_EndNamespaceDeclHandler end) {
       
  1339   endNamespaceDeclHandler = end;
       
  1340 }
       
  1341 
       
  1342 void XMLCALL
       
  1343 XML_SetNotStandaloneHandler(XML_Parser parser,
       
  1344                             XML_NotStandaloneHandler handler)
       
  1345 {
       
  1346   notStandaloneHandler = handler;
       
  1347 }
       
  1348 
       
  1349 void XMLCALL
       
  1350 XML_SetExternalEntityRefHandler(XML_Parser parser,
       
  1351                                 XML_ExternalEntityRefHandler handler)
       
  1352 {
       
  1353   externalEntityRefHandler = handler;
       
  1354 }
       
  1355 
       
  1356 void XMLCALL
       
  1357 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
       
  1358 {
       
  1359   if (arg)
       
  1360     externalEntityRefHandlerArg = (XML_Parser)arg;
       
  1361   else
       
  1362     externalEntityRefHandlerArg = parser;
       
  1363 }
       
  1364 
       
  1365 void XMLCALL
       
  1366 XML_SetSkippedEntityHandler(XML_Parser parser,
       
  1367                             XML_SkippedEntityHandler handler)
       
  1368 {
       
  1369   skippedEntityHandler = handler;
       
  1370 }
       
  1371 
       
  1372 void XMLCALL
       
  1373 XML_SetUnknownEncodingHandler(XML_Parser parser,
       
  1374                               XML_UnknownEncodingHandler handler,
       
  1375                               void *data)
       
  1376 {
       
  1377   unknownEncodingHandler = handler;
       
  1378   unknownEncodingHandlerData = data;
       
  1379 }
       
  1380 
       
  1381 void XMLCALL
       
  1382 XML_SetElementDeclHandler(XML_Parser parser,
       
  1383                           XML_ElementDeclHandler eldecl)
       
  1384 {
       
  1385   elementDeclHandler = eldecl;
       
  1386 }
       
  1387 
       
  1388 void XMLCALL
       
  1389 XML_SetAttlistDeclHandler(XML_Parser parser,
       
  1390                           XML_AttlistDeclHandler attdecl)
       
  1391 {
       
  1392   attlistDeclHandler = attdecl;
       
  1393 }
       
  1394 
       
  1395 void XMLCALL
       
  1396 XML_SetEntityDeclHandler(XML_Parser parser,
       
  1397                          XML_EntityDeclHandler handler)
       
  1398 {
       
  1399   entityDeclHandler = handler;
       
  1400 }
       
  1401 
       
  1402 void XMLCALL
       
  1403 XML_SetXmlDeclHandler(XML_Parser parser,
       
  1404                       XML_XmlDeclHandler handler) {
       
  1405   xmlDeclHandler = handler;
       
  1406 }
       
  1407 
       
  1408 int XMLCALL
       
  1409 XML_SetParamEntityParsing(XML_Parser parser,
       
  1410                           enum XML_ParamEntityParsing peParsing)
       
  1411 {
       
  1412   /* block after XML_Parse()/XML_ParseBuffer() has been called */
       
  1413   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
       
  1414     return 0;
       
  1415 #ifdef XML_DTD
       
  1416   paramEntityParsing = peParsing;
       
  1417   return 1;
       
  1418 #else
       
  1419   return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
       
  1420 #endif
       
  1421 }
       
  1422 
       
  1423 enum XML_Status XMLCALL
       
  1424 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
       
  1425 {
       
  1426   switch (ps_parsing) {
       
  1427   case XML_SUSPENDED:
       
  1428     errorCode = XML_ERROR_SUSPENDED;
       
  1429     return XML_STATUS_ERROR;
       
  1430   case XML_FINISHED:
       
  1431     errorCode = XML_ERROR_FINISHED;
       
  1432     return XML_STATUS_ERROR;
       
  1433   default:
       
  1434     ps_parsing = XML_PARSING;
       
  1435   }
       
  1436 
       
  1437   if (len == 0) {
       
  1438     ps_finalBuffer = (XML_Bool)isFinal;
       
  1439     if (!isFinal)
       
  1440       return XML_STATUS_OK;
       
  1441     positionPtr = bufferPtr;
       
  1442     parseEndPtr = bufferEnd;
       
  1443 
       
  1444     /* If data are left over from last buffer, and we now know that these
       
  1445        data are the final chunk of input, then we have to check them again
       
  1446        to detect errors based on that fact.
       
  1447     */
       
  1448     errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
       
  1449 
       
  1450     if (errorCode == XML_ERROR_NONE) {
       
  1451       switch (ps_parsing) {
       
  1452       case XML_SUSPENDED:
       
  1453         XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
       
  1454         positionPtr = bufferPtr;
       
  1455         return XML_STATUS_SUSPENDED;
       
  1456       case XML_INITIALIZED: 
       
  1457       case XML_PARSING:
       
  1458         ps_parsing = XML_FINISHED;
       
  1459         /* fall through */
       
  1460       default:
       
  1461         return XML_STATUS_OK;
       
  1462       }
       
  1463     }
       
  1464     eventEndPtr = eventPtr;
       
  1465     processor = errorProcessor;
       
  1466     return XML_STATUS_ERROR;
       
  1467   }
       
  1468 #ifndef XML_CONTEXT_BYTES
       
  1469   else if (bufferPtr == bufferEnd) {
       
  1470     const char *end;
       
  1471     int nLeftOver;
       
  1472     enum XML_Error result;
       
  1473     parseEndByteIndex += len;
       
  1474     positionPtr = s;
       
  1475     ps_finalBuffer = (XML_Bool)isFinal;
       
  1476 
       
  1477     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
       
  1478 
       
  1479     if (errorCode != XML_ERROR_NONE) {
       
  1480       eventEndPtr = eventPtr;
       
  1481       processor = errorProcessor;
       
  1482       return XML_STATUS_ERROR;
       
  1483     }
       
  1484     else {
       
  1485       switch (ps_parsing) {
       
  1486       case XML_SUSPENDED:
       
  1487         result = XML_STATUS_SUSPENDED;
       
  1488         break;
       
  1489       case XML_INITIALIZED:
       
  1490       case XML_PARSING:
       
  1491         result = XML_STATUS_OK;
       
  1492         if (isFinal) {
       
  1493           ps_parsing = XML_FINISHED;
       
  1494           return result;
       
  1495         }
       
  1496       }
       
  1497     }
       
  1498 
       
  1499     XmlUpdatePosition(encoding, positionPtr, end, &position);
       
  1500     nLeftOver = s + len - end;
       
  1501     if (nLeftOver) {
       
  1502       if (buffer == NULL || nLeftOver > bufferLim - buffer) {
       
  1503         /* FIXME avoid integer overflow */
       
  1504         char *temp;
       
  1505         temp = (buffer == NULL
       
  1506                 ? (char *)MALLOC(len * 2)
       
  1507                 : (char *)REALLOC(buffer, len * 2));
       
  1508         if (temp == NULL) {
       
  1509           errorCode = XML_ERROR_NO_MEMORY;
       
  1510           return XML_STATUS_ERROR;
       
  1511         }
       
  1512         buffer = temp;
       
  1513         if (!buffer) {
       
  1514           errorCode = XML_ERROR_NO_MEMORY;
       
  1515           eventPtr = eventEndPtr = NULL;
       
  1516           processor = errorProcessor;
       
  1517           return XML_STATUS_ERROR;
       
  1518         }
       
  1519         bufferLim = buffer + len * 2;
       
  1520       }
       
  1521       memcpy(buffer, end, nLeftOver);
       
  1522     }
       
  1523     bufferPtr = buffer;
       
  1524     bufferEnd = buffer + nLeftOver;
       
  1525     positionPtr = bufferPtr;
       
  1526     parseEndPtr = bufferEnd;
       
  1527     eventPtr = bufferPtr;
       
  1528     eventEndPtr = bufferPtr;
       
  1529     return result;
       
  1530   }
       
  1531 #endif  /* not defined XML_CONTEXT_BYTES */
       
  1532   else {
       
  1533     void *buff = XML_GetBuffer(parser, len);
       
  1534     if (buff == NULL)
       
  1535       return XML_STATUS_ERROR;
       
  1536     else {
       
  1537       memcpy(buff, s, len);
       
  1538       return XML_ParseBuffer(parser, len, isFinal);
       
  1539     }
       
  1540   }
       
  1541 }
       
  1542 
       
  1543 enum XML_Status XMLCALL
       
  1544 XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
       
  1545 {
       
  1546   const char *start;
       
  1547   enum XML_Status result = XML_STATUS_OK;
       
  1548 
       
  1549   switch (ps_parsing) {
       
  1550   case XML_SUSPENDED:
       
  1551     errorCode = XML_ERROR_SUSPENDED;
       
  1552     return XML_STATUS_ERROR;
       
  1553   case XML_FINISHED:
       
  1554     errorCode = XML_ERROR_FINISHED;
       
  1555     return XML_STATUS_ERROR;
       
  1556   default:
       
  1557     ps_parsing = XML_PARSING;
       
  1558   }
       
  1559 
       
  1560   start = bufferPtr;
       
  1561   positionPtr = start;
       
  1562   bufferEnd += len;
       
  1563   parseEndPtr = bufferEnd;
       
  1564   parseEndByteIndex += len;
       
  1565   ps_finalBuffer = (XML_Bool)isFinal;
       
  1566 
       
  1567   errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
       
  1568 
       
  1569   if (errorCode != XML_ERROR_NONE) {
       
  1570     eventEndPtr = eventPtr;
       
  1571     processor = errorProcessor;
       
  1572     return XML_STATUS_ERROR;
       
  1573   }
       
  1574   else {
       
  1575     switch (ps_parsing) {
       
  1576     case XML_SUSPENDED:
       
  1577       result = XML_STATUS_SUSPENDED;
       
  1578       break;
       
  1579     case XML_INITIALIZED: 
       
  1580     case XML_PARSING:
       
  1581       if (isFinal) {
       
  1582         ps_parsing = XML_FINISHED;
       
  1583         return result;
       
  1584       }
       
  1585     default: ;  /* should not happen */
       
  1586     }
       
  1587   }
       
  1588 
       
  1589   XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
       
  1590   positionPtr = bufferPtr;
       
  1591   return result;
       
  1592 }
       
  1593 
       
  1594 void * XMLCALL
       
  1595 XML_GetBuffer(XML_Parser parser, int len)
       
  1596 {
       
  1597   switch (ps_parsing) {
       
  1598   case XML_SUSPENDED:
       
  1599     errorCode = XML_ERROR_SUSPENDED;
       
  1600     return NULL;
       
  1601   case XML_FINISHED:
       
  1602     errorCode = XML_ERROR_FINISHED;
       
  1603     return NULL;
       
  1604   default: ;
       
  1605   }
       
  1606 
       
  1607   if (len > bufferLim - bufferEnd) {
       
  1608     /* FIXME avoid integer overflow */
       
  1609     int neededSize = len + (int)(bufferEnd - bufferPtr);
       
  1610 #ifdef XML_CONTEXT_BYTES
       
  1611     int keep = (int)(bufferPtr - buffer);
       
  1612 
       
  1613     if (keep > XML_CONTEXT_BYTES)
       
  1614       keep = XML_CONTEXT_BYTES;
       
  1615     neededSize += keep;
       
  1616 #endif  /* defined XML_CONTEXT_BYTES */
       
  1617     if (neededSize  <= bufferLim - buffer) {
       
  1618 #ifdef XML_CONTEXT_BYTES
       
  1619       if (keep < bufferPtr - buffer) {
       
  1620         int offset = (int)(bufferPtr - buffer) - keep;
       
  1621         memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
       
  1622         bufferEnd -= offset;
       
  1623         bufferPtr -= offset;
       
  1624       }
       
  1625 #else
       
  1626       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
       
  1627       bufferEnd = buffer + (bufferEnd - bufferPtr);
       
  1628       bufferPtr = buffer;
       
  1629 #endif  /* not defined XML_CONTEXT_BYTES */
       
  1630     }
       
  1631     else {
       
  1632       char *newBuf;
       
  1633       int bufferSize = (int)(bufferLim - bufferPtr);
       
  1634       if (bufferSize == 0)
       
  1635         bufferSize = INIT_BUFFER_SIZE;
       
  1636       do {
       
  1637         bufferSize *= 2;
       
  1638       } while (bufferSize < neededSize);
       
  1639       newBuf = (char *)MALLOC(bufferSize);
       
  1640       if (newBuf == 0) {
       
  1641         errorCode = XML_ERROR_NO_MEMORY;
       
  1642         return NULL;
       
  1643       }
       
  1644       bufferLim = newBuf + bufferSize;
       
  1645 #ifdef XML_CONTEXT_BYTES
       
  1646       if (bufferPtr) {
       
  1647         int keep = (int)(bufferPtr - buffer);
       
  1648         if (keep > XML_CONTEXT_BYTES)
       
  1649           keep = XML_CONTEXT_BYTES;
       
  1650         memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
       
  1651         FREE(buffer);
       
  1652         buffer = newBuf;
       
  1653         bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
       
  1654         bufferPtr = buffer + keep;
       
  1655       }
       
  1656       else {
       
  1657         bufferEnd = newBuf + (bufferEnd - bufferPtr);
       
  1658         bufferPtr = buffer = newBuf;
       
  1659       }
       
  1660 #else
       
  1661       if (bufferPtr) {
       
  1662         memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
       
  1663         FREE(buffer);
       
  1664       }
       
  1665       bufferEnd = newBuf + (bufferEnd - bufferPtr);
       
  1666       bufferPtr = buffer = newBuf;
       
  1667 #endif  /* not defined XML_CONTEXT_BYTES */
       
  1668     }
       
  1669   }
       
  1670   return bufferEnd;
       
  1671 }
       
  1672 
       
  1673 enum XML_Status XMLCALL
       
  1674 XML_StopParser(XML_Parser parser, XML_Bool resumable)
       
  1675 {
       
  1676   switch (ps_parsing) {
       
  1677   case XML_SUSPENDED:
       
  1678     if (resumable) {
       
  1679       errorCode = XML_ERROR_SUSPENDED;
       
  1680       return XML_STATUS_ERROR;
       
  1681     }
       
  1682     ps_parsing = XML_FINISHED;
       
  1683     break;
       
  1684   case XML_FINISHED:
       
  1685     errorCode = XML_ERROR_FINISHED;
       
  1686     return XML_STATUS_ERROR;
       
  1687   default:
       
  1688     if (resumable) {
       
  1689 #ifdef XML_DTD
       
  1690       if (isParamEntity) {
       
  1691         errorCode = XML_ERROR_SUSPEND_PE;
       
  1692         return XML_STATUS_ERROR;
       
  1693       }
       
  1694 #endif
       
  1695       ps_parsing = XML_SUSPENDED;
       
  1696     }
       
  1697     else
       
  1698       ps_parsing = XML_FINISHED;
       
  1699   }
       
  1700   return XML_STATUS_OK;
       
  1701 }
       
  1702 
       
  1703 enum XML_Status XMLCALL
       
  1704 XML_ResumeParser(XML_Parser parser)
       
  1705 {
       
  1706   enum XML_Status result = XML_STATUS_OK;
       
  1707 
       
  1708   if (ps_parsing != XML_SUSPENDED) {
       
  1709     errorCode = XML_ERROR_NOT_SUSPENDED;
       
  1710     return XML_STATUS_ERROR;
       
  1711   }
       
  1712   ps_parsing = XML_PARSING;
       
  1713 
       
  1714   errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
       
  1715 
       
  1716   if (errorCode != XML_ERROR_NONE) {
       
  1717     eventEndPtr = eventPtr;
       
  1718     processor = errorProcessor;
       
  1719     return XML_STATUS_ERROR;
       
  1720   }
       
  1721   else {
       
  1722     switch (ps_parsing) {
       
  1723     case XML_SUSPENDED:
       
  1724       result = XML_STATUS_SUSPENDED;
       
  1725       break;
       
  1726     case XML_INITIALIZED: 
       
  1727     case XML_PARSING:
       
  1728       if (ps_finalBuffer) {
       
  1729         ps_parsing = XML_FINISHED;
       
  1730         return result;
       
  1731       }
       
  1732     default: ;
       
  1733     }
       
  1734   }
       
  1735 
       
  1736   XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
       
  1737   positionPtr = bufferPtr;
       
  1738   return result;
       
  1739 }
       
  1740 
       
  1741 void XMLCALL
       
  1742 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
       
  1743 {
       
  1744   assert(status != NULL);
       
  1745   *status = parser->m_parsingStatus;
       
  1746 }
       
  1747 
       
  1748 enum XML_Error XMLCALL
       
  1749 XML_GetErrorCode(XML_Parser parser)
       
  1750 {
       
  1751   return errorCode;
       
  1752 }
       
  1753 
       
  1754 XML_Index XMLCALL
       
  1755 XML_GetCurrentByteIndex(XML_Parser parser)
       
  1756 {
       
  1757   if (eventPtr)
       
  1758     return parseEndByteIndex - (parseEndPtr - eventPtr);
       
  1759   return -1;
       
  1760 }
       
  1761 
       
  1762 int XMLCALL
       
  1763 XML_GetCurrentByteCount(XML_Parser parser)
       
  1764 {
       
  1765   if (eventEndPtr && eventPtr)
       
  1766     return (int)(eventEndPtr - eventPtr);
       
  1767   return 0;
       
  1768 }
       
  1769 
       
  1770 const char * XMLCALL
       
  1771 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
       
  1772 {
       
  1773 #ifdef XML_CONTEXT_BYTES
       
  1774   if (eventPtr && buffer) {
       
  1775     *offset = (int)(eventPtr - buffer);
       
  1776     *size   = (int)(bufferEnd - buffer);
       
  1777     return buffer;
       
  1778   }
       
  1779 #endif /* defined XML_CONTEXT_BYTES */
       
  1780   return (char *) 0;
       
  1781 }
       
  1782 
       
  1783 XML_Size XMLCALL
       
  1784 XML_GetCurrentLineNumber(XML_Parser parser)
       
  1785 {
       
  1786   if (eventPtr && eventPtr >= positionPtr) {
       
  1787     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
       
  1788     positionPtr = eventPtr;
       
  1789   }
       
  1790   return position.lineNumber + 1;
       
  1791 }
       
  1792 
       
  1793 XML_Size XMLCALL
       
  1794 XML_GetCurrentColumnNumber(XML_Parser parser)
       
  1795 {
       
  1796   if (eventPtr && eventPtr >= positionPtr) {
       
  1797     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
       
  1798     positionPtr = eventPtr;
       
  1799   }
       
  1800   return position.columnNumber;
       
  1801 }
       
  1802 
       
  1803 void XMLCALL
       
  1804 XML_FreeContentModel(XML_Parser parser, XML_Content *model)
       
  1805 {
       
  1806   FREE(model);
       
  1807 }
       
  1808 
       
  1809 void * XMLCALL
       
  1810 XML_MemMalloc(XML_Parser parser, size_t size)
       
  1811 {
       
  1812   return MALLOC(size);
       
  1813 }
       
  1814 
       
  1815 void * XMLCALL
       
  1816 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
       
  1817 {
       
  1818   return REALLOC(ptr, size);
       
  1819 }
       
  1820 
       
  1821 void XMLCALL
       
  1822 XML_MemFree(XML_Parser parser, void *ptr)
       
  1823 {
       
  1824   FREE(ptr);
       
  1825 }
       
  1826 
       
  1827 void XMLCALL
       
  1828 XML_DefaultCurrent(XML_Parser parser)
       
  1829 {
       
  1830   if (defaultHandler) {
       
  1831     if (openInternalEntities)
       
  1832       reportDefault(parser,
       
  1833                     internalEncoding,
       
  1834                     openInternalEntities->internalEventPtr,
       
  1835                     openInternalEntities->internalEventEndPtr);
       
  1836     else
       
  1837       reportDefault(parser, encoding, eventPtr, eventEndPtr);
       
  1838   }
       
  1839 }
       
  1840 
       
  1841 const XML_LChar * XMLCALL
       
  1842 XML_ErrorString(enum XML_Error code)
       
  1843 {
       
  1844   static const XML_LChar* const message[] = {
       
  1845     0,
       
  1846     XML_L("out of memory"),
       
  1847     XML_L("syntax error"),
       
  1848     XML_L("no element found"),
       
  1849     XML_L("not well-formed (invalid token)"),
       
  1850     XML_L("unclosed token"),
       
  1851     XML_L("partial character"),
       
  1852     XML_L("mismatched tag"),
       
  1853     XML_L("duplicate attribute"),
       
  1854     XML_L("junk after document element"),
       
  1855     XML_L("illegal parameter entity reference"),
       
  1856     XML_L("undefined entity"),
       
  1857     XML_L("recursive entity reference"),
       
  1858     XML_L("asynchronous entity"),
       
  1859     XML_L("reference to invalid character number"),
       
  1860     XML_L("reference to binary entity"),
       
  1861     XML_L("reference to external entity in attribute"),
       
  1862     XML_L("XML or text declaration not at start of entity"),
       
  1863     XML_L("unknown encoding"),
       
  1864     XML_L("encoding specified in XML declaration is incorrect"),
       
  1865     XML_L("unclosed CDATA section"),
       
  1866     XML_L("error in processing external entity reference"),
       
  1867     XML_L("document is not standalone"),
       
  1868     XML_L("unexpected parser state - please send a bug report"),
       
  1869     XML_L("entity declared in parameter entity"),
       
  1870     XML_L("requested feature requires XML_DTD support in Expat"),
       
  1871     XML_L("cannot change setting once parsing has begun"),
       
  1872     XML_L("unbound prefix"),
       
  1873     XML_L("must not undeclare prefix"),
       
  1874     XML_L("incomplete markup in parameter entity"),
       
  1875     XML_L("XML declaration not well-formed"),
       
  1876     XML_L("text declaration not well-formed"),
       
  1877     XML_L("illegal character(s) in public id"),
       
  1878     XML_L("parser suspended"),
       
  1879     XML_L("parser not suspended"),
       
  1880     XML_L("parsing aborted"),
       
  1881     XML_L("parsing finished"),
       
  1882     XML_L("cannot suspend in external parameter entity"),
       
  1883     XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
       
  1884     XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
       
  1885     XML_L("prefix must not be bound to one of the reserved namespace names")
       
  1886   };
       
  1887   if (code > 0 && code < sizeof(message)/sizeof(message[0]))
       
  1888     return message[code];
       
  1889   return NULL;
       
  1890 }
       
  1891 
       
  1892 const XML_LChar * XMLCALL
       
  1893 XML_ExpatVersion(void) {
       
  1894 
       
  1895   /* V1 is used to string-ize the version number. However, it would
       
  1896      string-ize the actual version macro *names* unless we get them
       
  1897      substituted before being passed to V1. CPP is defined to expand
       
  1898      a macro, then rescan for more expansions. Thus, we use V2 to expand
       
  1899      the version macros, then CPP will expand the resulting V1() macro
       
  1900      with the correct numerals. */
       
  1901   /* ### I'm assuming cpp is portable in this respect... */
       
  1902 
       
  1903 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
       
  1904 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
       
  1905 
       
  1906   return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
       
  1907 
       
  1908 #undef V1
       
  1909 #undef V2
       
  1910 }
       
  1911 
       
  1912 XML_Expat_Version XMLCALL
       
  1913 XML_ExpatVersionInfo(void)
       
  1914 {
       
  1915   XML_Expat_Version version;
       
  1916 
       
  1917   version.major = XML_MAJOR_VERSION;
       
  1918   version.minor = XML_MINOR_VERSION;
       
  1919   version.micro = XML_MICRO_VERSION;
       
  1920 
       
  1921   return version;
       
  1922 }
       
  1923 
       
  1924 const XML_Feature * XMLCALL
       
  1925 XML_GetFeatureList(void)
       
  1926 {
       
  1927   static const XML_Feature features[] = {
       
  1928     {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),
       
  1929      sizeof(XML_Char)},
       
  1930     {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
       
  1931      sizeof(XML_LChar)},
       
  1932 #ifdef XML_UNICODE
       
  1933     {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
       
  1934 #endif
       
  1935 #ifdef XML_UNICODE_WCHAR_T
       
  1936     {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
       
  1937 #endif
       
  1938 #ifdef XML_DTD
       
  1939     {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
       
  1940 #endif
       
  1941 #ifdef XML_CONTEXT_BYTES
       
  1942     {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
       
  1943      XML_CONTEXT_BYTES},
       
  1944 #endif
       
  1945 #ifdef XML_MIN_SIZE
       
  1946     {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
       
  1947 #endif
       
  1948 #ifdef XML_NS
       
  1949     {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
       
  1950 #endif
       
  1951     {XML_FEATURE_END,              NULL, 0}
       
  1952   };
       
  1953 
       
  1954   return features;
       
  1955 }
       
  1956 
       
  1957 /* Initially tag->rawName always points into the parse buffer;
       
  1958    for those TAG instances opened while the current parse buffer was
       
  1959    processed, and not yet closed, we need to store tag->rawName in a more
       
  1960    permanent location, since the parse buffer is about to be discarded.
       
  1961 */
       
  1962 static XML_Bool
       
  1963 storeRawNames(XML_Parser parser)
       
  1964 {
       
  1965   TAG *tag = tagStack;
       
  1966   while (tag) {
       
  1967     int bufSize;
       
  1968     int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
       
  1969     char *rawNameBuf = tag->buf + nameLen;
       
  1970     /* Stop if already stored.  Since tagStack is a stack, we can stop
       
  1971        at the first entry that has already been copied; everything
       
  1972        below it in the stack is already been accounted for in a
       
  1973        previous call to this function.
       
  1974     */
       
  1975     if (tag->rawName == rawNameBuf)
       
  1976       break;
       
  1977     /* For re-use purposes we need to ensure that the
       
  1978        size of tag->buf is a multiple of sizeof(XML_Char).
       
  1979     */
       
  1980     bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
       
  1981     if (bufSize > tag->bufEnd - tag->buf) {
       
  1982       char *temp = (char *)REALLOC(tag->buf, bufSize);
       
  1983       if (temp == NULL)
       
  1984         return XML_FALSE;
       
  1985       /* if tag->name.str points to tag->buf (only when namespace
       
  1986          processing is off) then we have to update it
       
  1987       */
       
  1988       if (tag->name.str == (XML_Char *)tag->buf)
       
  1989         tag->name.str = (XML_Char *)temp;
       
  1990       /* if tag->name.localPart is set (when namespace processing is on)
       
  1991          then update it as well, since it will always point into tag->buf
       
  1992       */
       
  1993       if (tag->name.localPart)
       
  1994         tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
       
  1995                                                   (XML_Char *)tag->buf);
       
  1996       tag->buf = temp;
       
  1997       tag->bufEnd = temp + bufSize;
       
  1998       rawNameBuf = temp + nameLen;
       
  1999     }
       
  2000     memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
       
  2001     tag->rawName = rawNameBuf;
       
  2002     tag = tag->parent;
       
  2003   }
       
  2004   return XML_TRUE;
       
  2005 }
       
  2006 
       
  2007 static enum XML_Error PTRCALL
       
  2008 contentProcessor(XML_Parser parser,
       
  2009                  const char *start,
       
  2010                  const char *end,
       
  2011                  const char **endPtr)
       
  2012 {
       
  2013   enum XML_Error result = doContent(parser, 0, encoding, start, end, 
       
  2014                                     endPtr, (XML_Bool)!ps_finalBuffer);
       
  2015   if (result == XML_ERROR_NONE) {
       
  2016     if (!storeRawNames(parser))
       
  2017       return XML_ERROR_NO_MEMORY;
       
  2018   }
       
  2019   return result;
       
  2020 }
       
  2021 
       
  2022 static enum XML_Error PTRCALL
       
  2023 externalEntityInitProcessor(XML_Parser parser,
       
  2024                             const char *start,
       
  2025                             const char *end,
       
  2026                             const char **endPtr)
       
  2027 {
       
  2028   enum XML_Error result = initializeEncoding(parser);
       
  2029   if (result != XML_ERROR_NONE)
       
  2030     return result;
       
  2031   processor = externalEntityInitProcessor2;
       
  2032   return externalEntityInitProcessor2(parser, start, end, endPtr);
       
  2033 }
       
  2034 
       
  2035 static enum XML_Error PTRCALL
       
  2036 externalEntityInitProcessor2(XML_Parser parser,
       
  2037                              const char *start,
       
  2038                              const char *end,
       
  2039                              const char **endPtr)
       
  2040 {
       
  2041   const char *next = start; /* XmlContentTok doesn't always set the last arg */
       
  2042   int tok = XmlContentTok(encoding, start, end, &next);
       
  2043   switch (tok) {
       
  2044   case XML_TOK_BOM:
       
  2045     /* If we are at the end of the buffer, this would cause the next stage,
       
  2046        i.e. externalEntityInitProcessor3, to pass control directly to
       
  2047        doContent (by detecting XML_TOK_NONE) without processing any xml text
       
  2048        declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
       
  2049     */
       
  2050     if (next == end && !ps_finalBuffer) {
       
  2051       *endPtr = next;
       
  2052       return XML_ERROR_NONE;
       
  2053     }
       
  2054     start = next;
       
  2055     break;
       
  2056   case XML_TOK_PARTIAL:
       
  2057     if (!ps_finalBuffer) {
       
  2058       *endPtr = start;
       
  2059       return XML_ERROR_NONE;
       
  2060     }
       
  2061     eventPtr = start;
       
  2062     return XML_ERROR_UNCLOSED_TOKEN;
       
  2063   case XML_TOK_PARTIAL_CHAR:
       
  2064     if (!ps_finalBuffer) {
       
  2065       *endPtr = start;
       
  2066       return XML_ERROR_NONE;
       
  2067     }
       
  2068     eventPtr = start;
       
  2069     return XML_ERROR_PARTIAL_CHAR;
       
  2070   }
       
  2071   processor = externalEntityInitProcessor3;
       
  2072   return externalEntityInitProcessor3(parser, start, end, endPtr);
       
  2073 }
       
  2074 
       
  2075 static enum XML_Error PTRCALL
       
  2076 externalEntityInitProcessor3(XML_Parser parser,
       
  2077                              const char *start,
       
  2078                              const char *end,
       
  2079                              const char **endPtr)
       
  2080 {
       
  2081   int tok;
       
  2082   const char *next = start; /* XmlContentTok doesn't always set the last arg */
       
  2083   eventPtr = start;
       
  2084   tok = XmlContentTok(encoding, start, end, &next);
       
  2085   eventEndPtr = next;
       
  2086 
       
  2087   switch (tok) {
       
  2088   case XML_TOK_XML_DECL:
       
  2089     {
       
  2090       enum XML_Error result;
       
  2091       result = processXmlDecl(parser, 1, start, next);
       
  2092       if (result != XML_ERROR_NONE)
       
  2093         return result;
       
  2094       switch (ps_parsing) {
       
  2095       case XML_SUSPENDED: 
       
  2096         *endPtr = next;
       
  2097         return XML_ERROR_NONE;
       
  2098       case XML_FINISHED:
       
  2099         return XML_ERROR_ABORTED;
       
  2100       default:
       
  2101         start = next;
       
  2102       }
       
  2103     }
       
  2104     break;
       
  2105   case XML_TOK_PARTIAL:
       
  2106     if (!ps_finalBuffer) {
       
  2107       *endPtr = start;
       
  2108       return XML_ERROR_NONE;
       
  2109     }
       
  2110     return XML_ERROR_UNCLOSED_TOKEN;
       
  2111   case XML_TOK_PARTIAL_CHAR:
       
  2112     if (!ps_finalBuffer) {
       
  2113       *endPtr = start;
       
  2114       return XML_ERROR_NONE;
       
  2115     }
       
  2116     return XML_ERROR_PARTIAL_CHAR;
       
  2117   }
       
  2118   processor = externalEntityContentProcessor;
       
  2119   tagLevel = 1;
       
  2120   return externalEntityContentProcessor(parser, start, end, endPtr);
       
  2121 }
       
  2122 
       
  2123 static enum XML_Error PTRCALL
       
  2124 externalEntityContentProcessor(XML_Parser parser,
       
  2125                                const char *start,
       
  2126                                const char *end,
       
  2127                                const char **endPtr)
       
  2128 {
       
  2129   enum XML_Error result = doContent(parser, 1, encoding, start, end, 
       
  2130                                     endPtr, (XML_Bool)!ps_finalBuffer);
       
  2131   if (result == XML_ERROR_NONE) {
       
  2132     if (!storeRawNames(parser))
       
  2133       return XML_ERROR_NO_MEMORY;
       
  2134   }
       
  2135   return result;
       
  2136 }
       
  2137 
       
  2138 static enum XML_Error
       
  2139 doContent(XML_Parser parser,
       
  2140           int startTagLevel,
       
  2141           const ENCODING *enc,
       
  2142           const char *s,
       
  2143           const char *end,
       
  2144           const char **nextPtr,
       
  2145           XML_Bool haveMore)
       
  2146 {
       
  2147   /* save one level of indirection */
       
  2148   DTD * const dtd = _dtd;  
       
  2149 
       
  2150   const char **eventPP;
       
  2151   const char **eventEndPP;
       
  2152   if (enc == encoding) {
       
  2153     eventPP = &eventPtr;
       
  2154     eventEndPP = &eventEndPtr;
       
  2155   }
       
  2156   else {
       
  2157     eventPP = &(openInternalEntities->internalEventPtr);
       
  2158     eventEndPP = &(openInternalEntities->internalEventEndPtr);
       
  2159   }
       
  2160   *eventPP = s;
       
  2161 
       
  2162   for (;;) {
       
  2163     const char *next = s; /* XmlContentTok doesn't always set the last arg */
       
  2164     int tok = XmlContentTok(enc, s, end, &next);
       
  2165     *eventEndPP = next;
       
  2166     switch (tok) {
       
  2167     case XML_TOK_TRAILING_CR:
       
  2168       if (haveMore) {
       
  2169         *nextPtr = s;
       
  2170         return XML_ERROR_NONE;
       
  2171       }
       
  2172       *eventEndPP = end;
       
  2173       if (characterDataHandler) {
       
  2174         XML_Char c = 0xA;
       
  2175         characterDataHandler(handlerArg, &c, 1);
       
  2176       }
       
  2177       else if (defaultHandler)
       
  2178         reportDefault(parser, enc, s, end);
       
  2179       /* We are at the end of the final buffer, should we check for 
       
  2180          XML_SUSPENDED, XML_FINISHED? 
       
  2181       */
       
  2182       if (startTagLevel == 0)
       
  2183         return XML_ERROR_NO_ELEMENTS;
       
  2184       if (tagLevel != startTagLevel)
       
  2185         return XML_ERROR_ASYNC_ENTITY;
       
  2186       *nextPtr = end;
       
  2187       return XML_ERROR_NONE;
       
  2188     case XML_TOK_NONE:
       
  2189       if (haveMore) {
       
  2190         *nextPtr = s;
       
  2191         return XML_ERROR_NONE;
       
  2192       }
       
  2193       if (startTagLevel > 0) {
       
  2194         if (tagLevel != startTagLevel)
       
  2195           return XML_ERROR_ASYNC_ENTITY;
       
  2196         *nextPtr = s;
       
  2197         return XML_ERROR_NONE;
       
  2198       }
       
  2199       return XML_ERROR_NO_ELEMENTS;
       
  2200     case XML_TOK_INVALID:
       
  2201       *eventPP = next;
       
  2202       return XML_ERROR_INVALID_TOKEN;
       
  2203     case XML_TOK_PARTIAL:
       
  2204       if (haveMore) {
       
  2205         *nextPtr = s;
       
  2206         return XML_ERROR_NONE;
       
  2207       }
       
  2208       return XML_ERROR_UNCLOSED_TOKEN;
       
  2209     case XML_TOK_PARTIAL_CHAR:
       
  2210       if (haveMore) {
       
  2211         *nextPtr = s;
       
  2212         return XML_ERROR_NONE;
       
  2213       }
       
  2214       return XML_ERROR_PARTIAL_CHAR;
       
  2215     case XML_TOK_ENTITY_REF:
       
  2216       {
       
  2217         const XML_Char *name;
       
  2218         ENTITY *entity;
       
  2219         XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
       
  2220                                               s + enc->minBytesPerChar,
       
  2221                                               next - enc->minBytesPerChar);
       
  2222         if (ch) {
       
  2223           if (characterDataHandler)
       
  2224             characterDataHandler(handlerArg, &ch, 1);
       
  2225           else if (defaultHandler)
       
  2226             reportDefault(parser, enc, s, next);
       
  2227           break;
       
  2228         }
       
  2229         name = poolStoreString(&dtd->pool, enc,
       
  2230                                 s + enc->minBytesPerChar,
       
  2231                                 next - enc->minBytesPerChar);
       
  2232         if (!name)
       
  2233           return XML_ERROR_NO_MEMORY;
       
  2234         entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
       
  2235         poolDiscard(&dtd->pool);
       
  2236         /* First, determine if a check for an existing declaration is needed;
       
  2237            if yes, check that the entity exists, and that it is internal,
       
  2238            otherwise call the skipped entity or default handler.
       
  2239         */
       
  2240         if (!dtd->hasParamEntityRefs || dtd->standalone) {
       
  2241           if (!entity)
       
  2242             return XML_ERROR_UNDEFINED_ENTITY;
       
  2243           else if (!entity->is_internal)
       
  2244             return XML_ERROR_ENTITY_DECLARED_IN_PE;
       
  2245         }
       
  2246         else if (!entity) {
       
  2247           if (skippedEntityHandler)
       
  2248             skippedEntityHandler(handlerArg, name, 0);
       
  2249           else if (defaultHandler)
       
  2250             reportDefault(parser, enc, s, next);
       
  2251           break;
       
  2252         }
       
  2253         if (entity->open)
       
  2254           return XML_ERROR_RECURSIVE_ENTITY_REF;
       
  2255         if (entity->notation)
       
  2256           return XML_ERROR_BINARY_ENTITY_REF;
       
  2257         if (entity->textPtr) {
       
  2258           enum XML_Error result;
       
  2259           if (!defaultExpandInternalEntities) {
       
  2260             if (skippedEntityHandler)
       
  2261               skippedEntityHandler(handlerArg, entity->name, 0);
       
  2262             else if (defaultHandler)
       
  2263               reportDefault(parser, enc, s, next);
       
  2264             break;
       
  2265           }
       
  2266           result = processInternalEntity(parser, entity, XML_FALSE);
       
  2267           if (result != XML_ERROR_NONE)
       
  2268             return result;
       
  2269         }
       
  2270         else if (externalEntityRefHandler) {
       
  2271           const XML_Char *context;
       
  2272           entity->open = XML_TRUE;
       
  2273           context = getContext(parser);
       
  2274           entity->open = XML_FALSE;
       
  2275           if (!context)
       
  2276             return XML_ERROR_NO_MEMORY;
       
  2277           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
       
  2278                                         context,
       
  2279                                         entity->base,
       
  2280                                         entity->systemId,
       
  2281                                         entity->publicId))
       
  2282             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
       
  2283           poolDiscard(&tempPool);
       
  2284         }
       
  2285         else if (defaultHandler)
       
  2286           reportDefault(parser, enc, s, next);
       
  2287         break;
       
  2288       }
       
  2289     case XML_TOK_START_TAG_NO_ATTS:
       
  2290       /* fall through */
       
  2291     case XML_TOK_START_TAG_WITH_ATTS:
       
  2292       {
       
  2293         TAG *tag;
       
  2294         enum XML_Error result;
       
  2295         XML_Char *toPtr;
       
  2296         if (freeTagList) {
       
  2297           tag = freeTagList;
       
  2298           freeTagList = freeTagList->parent;
       
  2299         }
       
  2300         else {
       
  2301           tag = (TAG *)MALLOC(sizeof(TAG));
       
  2302           if (!tag)
       
  2303             return XML_ERROR_NO_MEMORY;
       
  2304           tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
       
  2305           if (!tag->buf) {
       
  2306             FREE(tag);
       
  2307             return XML_ERROR_NO_MEMORY;
       
  2308           }
       
  2309           tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
       
  2310         }
       
  2311         tag->bindings = NULL;
       
  2312         tag->parent = tagStack;
       
  2313         tagStack = tag;
       
  2314         tag->name.localPart = NULL;
       
  2315         tag->name.prefix = NULL;
       
  2316         tag->rawName = s + enc->minBytesPerChar;
       
  2317         tag->rawNameLength = XmlNameLength(enc, tag->rawName);
       
  2318         ++tagLevel;
       
  2319         {
       
  2320           const char *rawNameEnd = tag->rawName + tag->rawNameLength;
       
  2321           const char *fromPtr = tag->rawName;
       
  2322           toPtr = (XML_Char *)tag->buf;
       
  2323           for (;;) {
       
  2324             int bufSize;
       
  2325             int convLen;
       
  2326             XmlConvert(enc,
       
  2327                        &fromPtr, rawNameEnd,
       
  2328                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
       
  2329             convLen = (int)(toPtr - (XML_Char *)tag->buf);
       
  2330             if (fromPtr == rawNameEnd) {
       
  2331               tag->name.strLen = convLen;
       
  2332               break;
       
  2333             }
       
  2334             bufSize = (int)(tag->bufEnd - tag->buf) << 1;
       
  2335             {
       
  2336               char *temp = (char *)REALLOC(tag->buf, bufSize);
       
  2337               if (temp == NULL)
       
  2338                 return XML_ERROR_NO_MEMORY;
       
  2339               tag->buf = temp;
       
  2340               tag->bufEnd = temp + bufSize;
       
  2341               toPtr = (XML_Char *)temp + convLen;
       
  2342             }
       
  2343           }
       
  2344         }
       
  2345         tag->name.str = (XML_Char *)tag->buf;
       
  2346         *toPtr = XML_T('\0');
       
  2347         result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
       
  2348         if (result)
       
  2349           return result;
       
  2350         if (startElementHandler)
       
  2351           startElementHandler(handlerArg, tag->name.str,
       
  2352                               (const XML_Char **)atts);
       
  2353         else if (defaultHandler)
       
  2354           reportDefault(parser, enc, s, next);
       
  2355         poolClear(&tempPool);
       
  2356         break;
       
  2357       }
       
  2358     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
       
  2359       /* fall through */
       
  2360     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
       
  2361       {
       
  2362         const char *rawName = s + enc->minBytesPerChar;
       
  2363         enum XML_Error result;
       
  2364         BINDING *bindings = NULL;
       
  2365         XML_Bool noElmHandlers = XML_TRUE;
       
  2366         TAG_NAME name;
       
  2367         name.str = poolStoreString(&tempPool, enc, rawName,
       
  2368                                    rawName + XmlNameLength(enc, rawName));
       
  2369         if (!name.str)
       
  2370           return XML_ERROR_NO_MEMORY;
       
  2371         poolFinish(&tempPool);
       
  2372         result = storeAtts(parser, enc, s, &name, &bindings);
       
  2373         if (result)
       
  2374           return result;
       
  2375         poolFinish(&tempPool);
       
  2376         if (startElementHandler) {
       
  2377           startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
       
  2378           noElmHandlers = XML_FALSE;
       
  2379         }
       
  2380         if (endElementHandler) {
       
  2381           if (startElementHandler)
       
  2382             *eventPP = *eventEndPP;
       
  2383           endElementHandler(handlerArg, name.str);
       
  2384           noElmHandlers = XML_FALSE;
       
  2385         }
       
  2386         if (noElmHandlers && defaultHandler)
       
  2387           reportDefault(parser, enc, s, next);
       
  2388         poolClear(&tempPool);
       
  2389         while (bindings) {
       
  2390           BINDING *b = bindings;
       
  2391           if (endNamespaceDeclHandler)
       
  2392             endNamespaceDeclHandler(handlerArg, b->prefix->name);
       
  2393           bindings = bindings->nextTagBinding;
       
  2394           b->nextTagBinding = freeBindingList;
       
  2395           freeBindingList = b;
       
  2396           b->prefix->binding = b->prevPrefixBinding;
       
  2397         }
       
  2398       }
       
  2399       if (tagLevel == 0)
       
  2400         return epilogProcessor(parser, next, end, nextPtr);
       
  2401       break;
       
  2402     case XML_TOK_END_TAG:
       
  2403       if (tagLevel == startTagLevel)
       
  2404         return XML_ERROR_ASYNC_ENTITY;
       
  2405       else {
       
  2406         int len;
       
  2407         const char *rawName;
       
  2408         TAG *tag = tagStack;
       
  2409         tagStack = tag->parent;
       
  2410         tag->parent = freeTagList;
       
  2411         freeTagList = tag;
       
  2412         rawName = s + enc->minBytesPerChar*2;
       
  2413         len = XmlNameLength(enc, rawName);
       
  2414         if (len != tag->rawNameLength
       
  2415             || memcmp(tag->rawName, rawName, len) != 0) {
       
  2416           *eventPP = rawName;
       
  2417           return XML_ERROR_TAG_MISMATCH;
       
  2418         }
       
  2419         --tagLevel;
       
  2420         if (endElementHandler) {
       
  2421           const XML_Char *localPart;
       
  2422           const XML_Char *prefix;
       
  2423           XML_Char *uri;
       
  2424           localPart = tag->name.localPart;
       
  2425           if (ns && localPart) {
       
  2426             /* localPart and prefix may have been overwritten in
       
  2427                tag->name.str, since this points to the binding->uri
       
  2428                buffer which gets re-used; so we have to add them again
       
  2429             */
       
  2430             uri = (XML_Char *)tag->name.str + tag->name.uriLen;
       
  2431             /* don't need to check for space - already done in storeAtts() */
       
  2432             while (*localPart) *uri++ = *localPart++;
       
  2433             prefix = (XML_Char *)tag->name.prefix;
       
  2434             if (ns_triplets && prefix) {
       
  2435               *uri++ = namespaceSeparator;
       
  2436               while (*prefix) *uri++ = *prefix++;
       
  2437              }
       
  2438             *uri = XML_T('\0');
       
  2439           }
       
  2440           endElementHandler(handlerArg, tag->name.str);
       
  2441         }
       
  2442         else if (defaultHandler)
       
  2443           reportDefault(parser, enc, s, next);
       
  2444         while (tag->bindings) {
       
  2445           BINDING *b = tag->bindings;
       
  2446           if (endNamespaceDeclHandler)
       
  2447             endNamespaceDeclHandler(handlerArg, b->prefix->name);
       
  2448           tag->bindings = tag->bindings->nextTagBinding;
       
  2449           b->nextTagBinding = freeBindingList;
       
  2450           freeBindingList = b;
       
  2451           b->prefix->binding = b->prevPrefixBinding;
       
  2452         }
       
  2453         if (tagLevel == 0)
       
  2454           return epilogProcessor(parser, next, end, nextPtr);
       
  2455       }
       
  2456       break;
       
  2457     case XML_TOK_CHAR_REF:
       
  2458       {
       
  2459         int n = XmlCharRefNumber(enc, s);
       
  2460         if (n < 0)
       
  2461           return XML_ERROR_BAD_CHAR_REF;
       
  2462         if (characterDataHandler) {
       
  2463           XML_Char buf[XML_ENCODE_MAX];
       
  2464           characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
       
  2465         }
       
  2466         else if (defaultHandler)
       
  2467           reportDefault(parser, enc, s, next);
       
  2468       }
       
  2469       break;
       
  2470     case XML_TOK_XML_DECL:
       
  2471       return XML_ERROR_MISPLACED_XML_PI;
       
  2472     case XML_TOK_DATA_NEWLINE:
       
  2473       if (characterDataHandler) {
       
  2474         XML_Char c = 0xA;
       
  2475         characterDataHandler(handlerArg, &c, 1);
       
  2476       }
       
  2477       else if (defaultHandler)
       
  2478         reportDefault(parser, enc, s, next);
       
  2479       break;
       
  2480     case XML_TOK_CDATA_SECT_OPEN:
       
  2481       {
       
  2482         enum XML_Error result;
       
  2483         if (startCdataSectionHandler)
       
  2484           startCdataSectionHandler(handlerArg);
       
  2485 #if 0
       
  2486         /* Suppose you doing a transformation on a document that involves
       
  2487            changing only the character data.  You set up a defaultHandler
       
  2488            and a characterDataHandler.  The defaultHandler simply copies
       
  2489            characters through.  The characterDataHandler does the
       
  2490            transformation and writes the characters out escaping them as
       
  2491            necessary.  This case will fail to work if we leave out the
       
  2492            following two lines (because & and < inside CDATA sections will
       
  2493            be incorrectly escaped).
       
  2494 
       
  2495            However, now we have a start/endCdataSectionHandler, so it seems
       
  2496            easier to let the user deal with this.
       
  2497         */
       
  2498         else if (characterDataHandler)
       
  2499           characterDataHandler(handlerArg, dataBuf, 0);
       
  2500 #endif
       
  2501         else if (defaultHandler)
       
  2502           reportDefault(parser, enc, s, next);
       
  2503         result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
       
  2504         if (result != XML_ERROR_NONE)
       
  2505           return result;
       
  2506         else if (!next) {
       
  2507           processor = cdataSectionProcessor;
       
  2508           return result;
       
  2509         }
       
  2510       }
       
  2511       break;
       
  2512     case XML_TOK_TRAILING_RSQB:
       
  2513       if (haveMore) {
       
  2514         *nextPtr = s;
       
  2515         return XML_ERROR_NONE;
       
  2516       }
       
  2517       if (characterDataHandler) {
       
  2518         if (MUST_CONVERT(enc, s)) {
       
  2519           ICHAR *dataPtr = (ICHAR *)dataBuf;
       
  2520           XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
       
  2521           characterDataHandler(handlerArg, dataBuf,
       
  2522                                (int)(dataPtr - (ICHAR *)dataBuf));
       
  2523         }
       
  2524         else
       
  2525           characterDataHandler(handlerArg,
       
  2526                                (XML_Char *)s,
       
  2527                                (int)((XML_Char *)end - (XML_Char *)s));
       
  2528       }
       
  2529       else if (defaultHandler)
       
  2530         reportDefault(parser, enc, s, end);
       
  2531       /* We are at the end of the final buffer, should we check for 
       
  2532          XML_SUSPENDED, XML_FINISHED? 
       
  2533       */
       
  2534       if (startTagLevel == 0) {
       
  2535         *eventPP = end;
       
  2536         return XML_ERROR_NO_ELEMENTS;
       
  2537       }
       
  2538       if (tagLevel != startTagLevel) {
       
  2539         *eventPP = end;
       
  2540         return XML_ERROR_ASYNC_ENTITY;
       
  2541       }
       
  2542       *nextPtr = end;
       
  2543       return XML_ERROR_NONE;
       
  2544     case XML_TOK_DATA_CHARS:
       
  2545       if (characterDataHandler) {
       
  2546         if (MUST_CONVERT(enc, s)) {
       
  2547           for (;;) {
       
  2548             ICHAR *dataPtr = (ICHAR *)dataBuf;
       
  2549             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
       
  2550             *eventEndPP = s;
       
  2551             characterDataHandler(handlerArg, dataBuf,
       
  2552                                  (int)(dataPtr - (ICHAR *)dataBuf));
       
  2553             if (s == next)
       
  2554               break;
       
  2555             *eventPP = s;
       
  2556           }
       
  2557         }
       
  2558         else
       
  2559           characterDataHandler(handlerArg,
       
  2560                                (XML_Char *)s,
       
  2561                                (int)((XML_Char *)next - (XML_Char *)s));
       
  2562       }
       
  2563       else if (defaultHandler)
       
  2564         reportDefault(parser, enc, s, next);
       
  2565       break;
       
  2566     case XML_TOK_PI:
       
  2567       if (!reportProcessingInstruction(parser, enc, s, next))
       
  2568         return XML_ERROR_NO_MEMORY;
       
  2569       break;
       
  2570     case XML_TOK_COMMENT:
       
  2571       if (!reportComment(parser, enc, s, next))
       
  2572         return XML_ERROR_NO_MEMORY;
       
  2573       break;
       
  2574     default:
       
  2575       if (defaultHandler)
       
  2576         reportDefault(parser, enc, s, next);
       
  2577       break;
       
  2578     }
       
  2579     *eventPP = s = next;
       
  2580     switch (ps_parsing) {
       
  2581     case XML_SUSPENDED: 
       
  2582       *nextPtr = next;
       
  2583       return XML_ERROR_NONE;
       
  2584     case XML_FINISHED:
       
  2585       return XML_ERROR_ABORTED;
       
  2586     default: ;
       
  2587     }
       
  2588   }
       
  2589   /* not reached */
       
  2590 }
       
  2591 
       
  2592 /* Precondition: all arguments must be non-NULL;
       
  2593    Purpose:
       
  2594    - normalize attributes
       
  2595    - check attributes for well-formedness
       
  2596    - generate namespace aware attribute names (URI, prefix)
       
  2597    - build list of attributes for startElementHandler
       
  2598    - default attributes
       
  2599    - process namespace declarations (check and report them)
       
  2600    - generate namespace aware element name (URI, prefix)
       
  2601 */
       
  2602 static enum XML_Error
       
  2603 storeAtts(XML_Parser parser, const ENCODING *enc,
       
  2604           const char *attStr, TAG_NAME *tagNamePtr,
       
  2605           BINDING **bindingsPtr)
       
  2606 {
       
  2607   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  2608   ELEMENT_TYPE *elementType;
       
  2609   int nDefaultAtts;
       
  2610   const XML_Char **appAtts;   /* the attribute list for the application */
       
  2611   int attIndex = 0;
       
  2612   int prefixLen;
       
  2613   int i;
       
  2614   int n;
       
  2615   XML_Char *uri;
       
  2616   int nPrefixes = 0;
       
  2617   BINDING *binding;
       
  2618   const XML_Char *localPart;
       
  2619 
       
  2620   /* lookup the element type name */
       
  2621   elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
       
  2622   if (!elementType) {
       
  2623     const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
       
  2624     if (!name)
       
  2625       return XML_ERROR_NO_MEMORY;
       
  2626     elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
       
  2627                                          sizeof(ELEMENT_TYPE));
       
  2628     if (!elementType)
       
  2629       return XML_ERROR_NO_MEMORY;
       
  2630     if (ns && !setElementTypePrefix(parser, elementType))
       
  2631       return XML_ERROR_NO_MEMORY;
       
  2632   }
       
  2633   nDefaultAtts = elementType->nDefaultAtts;
       
  2634 
       
  2635   /* get the attributes from the tokenizer */
       
  2636   n = XmlGetAttributes(enc, attStr, attsSize, atts);
       
  2637   if (n + nDefaultAtts > attsSize) {
       
  2638     int oldAttsSize = attsSize;
       
  2639     ATTRIBUTE *temp;
       
  2640     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
       
  2641     temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
       
  2642     if (temp == NULL)
       
  2643       return XML_ERROR_NO_MEMORY;
       
  2644     atts = temp;
       
  2645     if (n > oldAttsSize)
       
  2646       XmlGetAttributes(enc, attStr, n, atts);
       
  2647   }
       
  2648 
       
  2649   appAtts = (const XML_Char **)atts;
       
  2650   for (i = 0; i < n; i++) {
       
  2651     /* add the name and value to the attribute list */
       
  2652     ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
       
  2653                                          atts[i].name
       
  2654                                          + XmlNameLength(enc, atts[i].name));
       
  2655     if (!attId)
       
  2656       return XML_ERROR_NO_MEMORY;
       
  2657     /* Detect duplicate attributes by their QNames. This does not work when
       
  2658        namespace processing is turned on and different prefixes for the same
       
  2659        namespace are used. For this case we have a check further down.
       
  2660     */
       
  2661     if ((attId->name)[-1]) {
       
  2662       if (enc == encoding)
       
  2663         eventPtr = atts[i].name;
       
  2664       return XML_ERROR_DUPLICATE_ATTRIBUTE;
       
  2665     }
       
  2666     (attId->name)[-1] = 1;
       
  2667     appAtts[attIndex++] = attId->name;
       
  2668     if (!atts[i].normalized) {
       
  2669       enum XML_Error result;
       
  2670       XML_Bool isCdata = XML_TRUE;
       
  2671 
       
  2672       /* figure out whether declared as other than CDATA */
       
  2673       if (attId->maybeTokenized) {
       
  2674         int j;
       
  2675         for (j = 0; j < nDefaultAtts; j++) {
       
  2676           if (attId == elementType->defaultAtts[j].id) {
       
  2677             isCdata = elementType->defaultAtts[j].isCdata;
       
  2678             break;
       
  2679           }
       
  2680         }
       
  2681       }
       
  2682 
       
  2683       /* normalize the attribute value */
       
  2684       result = storeAttributeValue(parser, enc, isCdata,
       
  2685                                    atts[i].valuePtr, atts[i].valueEnd,
       
  2686                                    &tempPool);
       
  2687       if (result)
       
  2688         return result;
       
  2689       appAtts[attIndex] = poolStart(&tempPool);
       
  2690       poolFinish(&tempPool);
       
  2691     }
       
  2692     else {
       
  2693       /* the value did not need normalizing */
       
  2694       appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
       
  2695                                           atts[i].valueEnd);
       
  2696       if (appAtts[attIndex] == 0)
       
  2697         return XML_ERROR_NO_MEMORY;
       
  2698       poolFinish(&tempPool);
       
  2699     }
       
  2700     /* handle prefixed attribute names */
       
  2701     if (attId->prefix) {
       
  2702       if (attId->xmlns) {
       
  2703         /* deal with namespace declarations here */
       
  2704         enum XML_Error result = addBinding(parser, attId->prefix, attId,
       
  2705                                            appAtts[attIndex], bindingsPtr);
       
  2706         if (result)
       
  2707           return result;
       
  2708         --attIndex;
       
  2709       }
       
  2710       else {
       
  2711         /* deal with other prefixed names later */
       
  2712         attIndex++;
       
  2713         nPrefixes++;
       
  2714         (attId->name)[-1] = 2;
       
  2715       }
       
  2716     }
       
  2717     else
       
  2718       attIndex++;
       
  2719   }
       
  2720 
       
  2721   /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
       
  2722   nSpecifiedAtts = attIndex;
       
  2723   if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
       
  2724     for (i = 0; i < attIndex; i += 2)
       
  2725       if (appAtts[i] == elementType->idAtt->name) {
       
  2726         idAttIndex = i;
       
  2727         break;
       
  2728       }
       
  2729   }
       
  2730   else
       
  2731     idAttIndex = -1;
       
  2732 
       
  2733   /* do attribute defaulting */
       
  2734   for (i = 0; i < nDefaultAtts; i++) {
       
  2735     const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
       
  2736     if (!(da->id->name)[-1] && da->value) {
       
  2737       if (da->id->prefix) {
       
  2738         if (da->id->xmlns) {
       
  2739           enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
       
  2740                                              da->value, bindingsPtr);
       
  2741           if (result)
       
  2742             return result;
       
  2743         }
       
  2744         else {
       
  2745           (da->id->name)[-1] = 2;
       
  2746           nPrefixes++;
       
  2747           appAtts[attIndex++] = da->id->name;
       
  2748           appAtts[attIndex++] = da->value;
       
  2749         }
       
  2750       }
       
  2751       else {
       
  2752         (da->id->name)[-1] = 1;
       
  2753         appAtts[attIndex++] = da->id->name;
       
  2754         appAtts[attIndex++] = da->value;
       
  2755       }
       
  2756     }
       
  2757   }
       
  2758   appAtts[attIndex] = 0;
       
  2759 
       
  2760   /* expand prefixed attribute names, check for duplicates,
       
  2761      and clear flags that say whether attributes were specified */
       
  2762   i = 0;
       
  2763   if (nPrefixes) {
       
  2764     int j;  /* hash table index */
       
  2765     unsigned long version = nsAttsVersion;
       
  2766     int nsAttsSize = (int)1 << nsAttsPower;
       
  2767     /* size of hash table must be at least 2 * (# of prefixed attributes) */
       
  2768     if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
       
  2769       NS_ATT *temp;
       
  2770       /* hash table size must also be a power of 2 and >= 8 */
       
  2771       while (nPrefixes >> nsAttsPower++);
       
  2772       if (nsAttsPower < 3)
       
  2773         nsAttsPower = 3;
       
  2774       nsAttsSize = (int)1 << nsAttsPower;
       
  2775       temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
       
  2776       if (!temp)
       
  2777         return XML_ERROR_NO_MEMORY;
       
  2778       nsAtts = temp;
       
  2779       version = 0;  /* force re-initialization of nsAtts hash table */
       
  2780     }
       
  2781     /* using a version flag saves us from initializing nsAtts every time */
       
  2782     if (!version) {  /* initialize version flags when version wraps around */
       
  2783       version = INIT_ATTS_VERSION;
       
  2784       for (j = nsAttsSize; j != 0; )
       
  2785         nsAtts[--j].version = version;
       
  2786     }
       
  2787     nsAttsVersion = --version;
       
  2788 
       
  2789     /* expand prefixed names and check for duplicates */
       
  2790     for (; i < attIndex; i += 2) {
       
  2791       const XML_Char *s = appAtts[i];
       
  2792       if (s[-1] == 2) {  /* prefixed */
       
  2793         ATTRIBUTE_ID *id;
       
  2794         const BINDING *b;
       
  2795         unsigned long uriHash = 0;
       
  2796         ((XML_Char *)s)[-1] = 0;  /* clear flag */
       
  2797         id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
       
  2798         if (!id)
       
  2799           return XML_ERROR_NO_MEMORY;
       
  2800         b = id->prefix->binding;
       
  2801         if (!b)
       
  2802           return XML_ERROR_UNBOUND_PREFIX;
       
  2803 
       
  2804         /* as we expand the name we also calculate its hash value */
       
  2805         for (j = 0; j < b->uriLen; j++) {
       
  2806           const XML_Char c = b->uri[j];
       
  2807           if (!poolAppendChar(&tempPool, c))
       
  2808             return XML_ERROR_NO_MEMORY;
       
  2809           uriHash = CHAR_HASH(uriHash, c);
       
  2810         }
       
  2811         while (*s++ != XML_T(':'))
       
  2812           ;
       
  2813         do {  /* copies null terminator */
       
  2814           const XML_Char c = *s;
       
  2815           if (!poolAppendChar(&tempPool, *s))
       
  2816             return XML_ERROR_NO_MEMORY;
       
  2817           uriHash = CHAR_HASH(uriHash, c);
       
  2818         } while (*s++);
       
  2819 
       
  2820         { /* Check hash table for duplicate of expanded name (uriName).
       
  2821              Derived from code in lookup(HASH_TABLE *table, ...).
       
  2822           */
       
  2823           unsigned char step = 0;
       
  2824           unsigned long mask = nsAttsSize - 1;
       
  2825           j = uriHash & mask;  /* index into hash table */
       
  2826           while (nsAtts[j].version == version) {
       
  2827             /* for speed we compare stored hash values first */
       
  2828             if (uriHash == nsAtts[j].hash) {
       
  2829               const XML_Char *s1 = poolStart(&tempPool);
       
  2830               const XML_Char *s2 = nsAtts[j].uriName;
       
  2831               /* s1 is null terminated, but not s2 */
       
  2832               for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
       
  2833               if (*s1 == 0)
       
  2834                 return XML_ERROR_DUPLICATE_ATTRIBUTE;
       
  2835             }
       
  2836             if (!step)
       
  2837               step = PROBE_STEP(uriHash, mask, nsAttsPower);
       
  2838             j < step ? (j += nsAttsSize - step) : (j -= step);
       
  2839           }
       
  2840         }
       
  2841 
       
  2842         if (ns_triplets) {  /* append namespace separator and prefix */
       
  2843           tempPool.ptr[-1] = namespaceSeparator;
       
  2844           s = b->prefix->name;
       
  2845           do {
       
  2846             if (!poolAppendChar(&tempPool, *s))
       
  2847               return XML_ERROR_NO_MEMORY;
       
  2848           } while (*s++);
       
  2849         }
       
  2850 
       
  2851         /* store expanded name in attribute list */
       
  2852         s = poolStart(&tempPool);
       
  2853         poolFinish(&tempPool);
       
  2854         appAtts[i] = s;
       
  2855 
       
  2856         /* fill empty slot with new version, uriName and hash value */
       
  2857         nsAtts[j].version = version;
       
  2858         nsAtts[j].hash = uriHash;
       
  2859         nsAtts[j].uriName = s;
       
  2860 
       
  2861         if (!--nPrefixes) {
       
  2862           i += 2;
       
  2863           break;
       
  2864         }
       
  2865       }
       
  2866       else  /* not prefixed */
       
  2867         ((XML_Char *)s)[-1] = 0;  /* clear flag */
       
  2868     }
       
  2869   }
       
  2870   /* clear flags for the remaining attributes */
       
  2871   for (; i < attIndex; i += 2)
       
  2872     ((XML_Char *)(appAtts[i]))[-1] = 0;
       
  2873   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
       
  2874     binding->attId->name[-1] = 0;
       
  2875 
       
  2876   if (!ns)
       
  2877     return XML_ERROR_NONE;
       
  2878 
       
  2879   /* expand the element type name */
       
  2880   if (elementType->prefix) {
       
  2881     binding = elementType->prefix->binding;
       
  2882     if (!binding)
       
  2883       return XML_ERROR_UNBOUND_PREFIX;
       
  2884     localPart = tagNamePtr->str;
       
  2885     while (*localPart++ != XML_T(':'))
       
  2886       ;
       
  2887   }
       
  2888   else if (dtd->defaultPrefix.binding) {
       
  2889     binding = dtd->defaultPrefix.binding;
       
  2890     localPart = tagNamePtr->str;
       
  2891   }
       
  2892   else
       
  2893     return XML_ERROR_NONE;
       
  2894   prefixLen = 0;
       
  2895   if (ns_triplets && binding->prefix->name) {
       
  2896     for (; binding->prefix->name[prefixLen++];)
       
  2897       ;  /* prefixLen includes null terminator */
       
  2898   }
       
  2899   tagNamePtr->localPart = localPart;
       
  2900   tagNamePtr->uriLen = binding->uriLen;
       
  2901   tagNamePtr->prefix = binding->prefix->name;
       
  2902   tagNamePtr->prefixLen = prefixLen;
       
  2903   for (i = 0; localPart[i++];)
       
  2904     ;  /* i includes null terminator */
       
  2905   n = i + binding->uriLen + prefixLen;
       
  2906   if (n > binding->uriAlloc) {
       
  2907     TAG *p;
       
  2908     uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
       
  2909     if (!uri)
       
  2910       return XML_ERROR_NO_MEMORY;
       
  2911     binding->uriAlloc = n + EXPAND_SPARE;
       
  2912     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
       
  2913     for (p = tagStack; p; p = p->parent)
       
  2914       if (p->name.str == binding->uri)
       
  2915         p->name.str = uri;
       
  2916     FREE(binding->uri);
       
  2917     binding->uri = uri;
       
  2918   }
       
  2919   /* if namespaceSeparator != '\0' then uri includes it already */
       
  2920   uri = binding->uri + binding->uriLen;
       
  2921   memcpy(uri, localPart, i * sizeof(XML_Char));
       
  2922   /* we always have a namespace separator between localPart and prefix */
       
  2923   if (prefixLen) {
       
  2924     uri += i - 1;
       
  2925     *uri = namespaceSeparator;  /* replace null terminator */
       
  2926     memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
       
  2927   }
       
  2928   tagNamePtr->str = binding->uri;
       
  2929   return XML_ERROR_NONE;
       
  2930 }
       
  2931 
       
  2932 /* addBinding() overwrites the value of prefix->binding without checking.
       
  2933    Therefore one must keep track of the old value outside of addBinding().
       
  2934 */
       
  2935 static enum XML_Error
       
  2936 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
       
  2937            const XML_Char *uri, BINDING **bindingsPtr)
       
  2938 {
       
  2939   static const XML_Char xmlNamespace[] = {
       
  2940     'h', 't', 't', 'p', ':', '/', '/',
       
  2941     'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
       
  2942     'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
       
  2943     'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
       
  2944   };
       
  2945   static const int xmlLen = 
       
  2946     (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
       
  2947   static const XML_Char xmlnsNamespace[] = {
       
  2948     'h', 't', 't', 'p', ':', '/', '/',
       
  2949     'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
       
  2950     '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
       
  2951   };
       
  2952   static const int xmlnsLen = 
       
  2953     (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
       
  2954 
       
  2955   XML_Bool mustBeXML = XML_FALSE;
       
  2956   XML_Bool isXML = XML_TRUE;
       
  2957   XML_Bool isXMLNS = XML_TRUE;
       
  2958   
       
  2959   BINDING *b;
       
  2960   int len;
       
  2961 
       
  2962   /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
       
  2963   if (*uri == XML_T('\0') && prefix->name)
       
  2964     return XML_ERROR_UNDECLARING_PREFIX;
       
  2965 
       
  2966   if (prefix->name
       
  2967       && prefix->name[0] == XML_T('x')
       
  2968       && prefix->name[1] == XML_T('m')
       
  2969       && prefix->name[2] == XML_T('l')) {
       
  2970 
       
  2971     /* Not allowed to bind xmlns */
       
  2972     if (prefix->name[3] == XML_T('n')
       
  2973         && prefix->name[4] == XML_T('s')
       
  2974         && prefix->name[5] == XML_T('\0'))
       
  2975       return XML_ERROR_RESERVED_PREFIX_XMLNS;
       
  2976 
       
  2977     if (prefix->name[3] == XML_T('\0'))
       
  2978       mustBeXML = XML_TRUE;
       
  2979   }
       
  2980 
       
  2981   for (len = 0; uri[len]; len++) {
       
  2982     if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
       
  2983       isXML = XML_FALSE;
       
  2984 
       
  2985     if (!mustBeXML && isXMLNS 
       
  2986         && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
       
  2987       isXMLNS = XML_FALSE;
       
  2988   }
       
  2989   isXML = isXML && len == xmlLen;
       
  2990   isXMLNS = isXMLNS && len == xmlnsLen;
       
  2991 
       
  2992   if (mustBeXML != isXML)
       
  2993     return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
       
  2994                      : XML_ERROR_RESERVED_NAMESPACE_URI;
       
  2995 
       
  2996   if (isXMLNS)
       
  2997     return XML_ERROR_RESERVED_NAMESPACE_URI;
       
  2998 
       
  2999   if (namespaceSeparator)
       
  3000     len++;
       
  3001   if (freeBindingList) {
       
  3002     b = freeBindingList;
       
  3003     if (len > b->uriAlloc) {
       
  3004       XML_Char *temp = (XML_Char *)REALLOC(b->uri,
       
  3005                           sizeof(XML_Char) * (len + EXPAND_SPARE));
       
  3006       if (temp == NULL)
       
  3007         return XML_ERROR_NO_MEMORY;
       
  3008       b->uri = temp;
       
  3009       b->uriAlloc = len + EXPAND_SPARE;
       
  3010     }
       
  3011     freeBindingList = b->nextTagBinding;
       
  3012   }
       
  3013   else {
       
  3014     b = (BINDING *)MALLOC(sizeof(BINDING));
       
  3015     if (!b)
       
  3016       return XML_ERROR_NO_MEMORY;
       
  3017     b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
       
  3018     if (!b->uri) {
       
  3019       FREE(b);
       
  3020       return XML_ERROR_NO_MEMORY;
       
  3021     }
       
  3022     b->uriAlloc = len + EXPAND_SPARE;
       
  3023   }
       
  3024   b->uriLen = len;
       
  3025   memcpy(b->uri, uri, len * sizeof(XML_Char));
       
  3026   if (namespaceSeparator)
       
  3027     b->uri[len - 1] = namespaceSeparator;
       
  3028   b->prefix = prefix;
       
  3029   b->attId = attId;
       
  3030   b->prevPrefixBinding = prefix->binding;
       
  3031   /* NULL binding when default namespace undeclared */
       
  3032   if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
       
  3033     prefix->binding = NULL;
       
  3034   else
       
  3035     prefix->binding = b;
       
  3036   b->nextTagBinding = *bindingsPtr;
       
  3037   *bindingsPtr = b;
       
  3038   /* if attId == NULL then we are not starting a namespace scope */
       
  3039   if (attId && startNamespaceDeclHandler)
       
  3040     startNamespaceDeclHandler(handlerArg, prefix->name,
       
  3041                               prefix->binding ? uri : 0);
       
  3042   return XML_ERROR_NONE;
       
  3043 }
       
  3044 
       
  3045 /* The idea here is to avoid using stack for each CDATA section when
       
  3046    the whole file is parsed with one call.
       
  3047 */
       
  3048 static enum XML_Error PTRCALL
       
  3049 cdataSectionProcessor(XML_Parser parser,
       
  3050                       const char *start,
       
  3051                       const char *end,
       
  3052                       const char **endPtr)
       
  3053 {
       
  3054   enum XML_Error result = doCdataSection(parser, encoding, &start, end,
       
  3055                                          endPtr, (XML_Bool)!ps_finalBuffer);
       
  3056   if (result != XML_ERROR_NONE)
       
  3057     return result;
       
  3058   if (start) {
       
  3059     if (parentParser) {  /* we are parsing an external entity */
       
  3060       processor = externalEntityContentProcessor;
       
  3061       return externalEntityContentProcessor(parser, start, end, endPtr);
       
  3062     }
       
  3063     else {
       
  3064       processor = contentProcessor;
       
  3065       return contentProcessor(parser, start, end, endPtr);
       
  3066     }
       
  3067   }
       
  3068   return result;
       
  3069 }
       
  3070 
       
  3071 /* startPtr gets set to non-null if the section is closed, and to null if
       
  3072    the section is not yet closed.
       
  3073 */
       
  3074 static enum XML_Error
       
  3075 doCdataSection(XML_Parser parser,
       
  3076                const ENCODING *enc,
       
  3077                const char **startPtr,
       
  3078                const char *end,
       
  3079                const char **nextPtr,
       
  3080                XML_Bool haveMore)
       
  3081 {
       
  3082   const char *s = *startPtr;
       
  3083   const char **eventPP;
       
  3084   const char **eventEndPP;
       
  3085   if (enc == encoding) {
       
  3086     eventPP = &eventPtr;
       
  3087     *eventPP = s;
       
  3088     eventEndPP = &eventEndPtr;
       
  3089   }
       
  3090   else {
       
  3091     eventPP = &(openInternalEntities->internalEventPtr);
       
  3092     eventEndPP = &(openInternalEntities->internalEventEndPtr);
       
  3093   }
       
  3094   *eventPP = s;
       
  3095   *startPtr = NULL;
       
  3096 
       
  3097   for (;;) {
       
  3098     const char *next;
       
  3099     int tok = XmlCdataSectionTok(enc, s, end, &next);
       
  3100     *eventEndPP = next;
       
  3101     switch (tok) {
       
  3102     case XML_TOK_CDATA_SECT_CLOSE:
       
  3103       if (endCdataSectionHandler)
       
  3104         endCdataSectionHandler(handlerArg);
       
  3105 #if 0
       
  3106       /* see comment under XML_TOK_CDATA_SECT_OPEN */
       
  3107       else if (characterDataHandler)
       
  3108         characterDataHandler(handlerArg, dataBuf, 0);
       
  3109 #endif
       
  3110       else if (defaultHandler)
       
  3111         reportDefault(parser, enc, s, next);
       
  3112       *startPtr = next;
       
  3113       *nextPtr = next;
       
  3114       if (ps_parsing == XML_FINISHED)
       
  3115         return XML_ERROR_ABORTED;
       
  3116       else
       
  3117         return XML_ERROR_NONE;
       
  3118     case XML_TOK_DATA_NEWLINE:
       
  3119       if (characterDataHandler) {
       
  3120         XML_Char c = 0xA;
       
  3121         characterDataHandler(handlerArg, &c, 1);
       
  3122       }
       
  3123       else if (defaultHandler)
       
  3124         reportDefault(parser, enc, s, next);
       
  3125       break;
       
  3126     case XML_TOK_DATA_CHARS:
       
  3127       if (characterDataHandler) {
       
  3128         if (MUST_CONVERT(enc, s)) {
       
  3129           for (;;) {
       
  3130             ICHAR *dataPtr = (ICHAR *)dataBuf;
       
  3131             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
       
  3132             *eventEndPP = next;
       
  3133             characterDataHandler(handlerArg, dataBuf,
       
  3134                                  (int)(dataPtr - (ICHAR *)dataBuf));
       
  3135             if (s == next)
       
  3136               break;
       
  3137             *eventPP = s;
       
  3138           }
       
  3139         }
       
  3140         else
       
  3141           characterDataHandler(handlerArg,
       
  3142                                (XML_Char *)s,
       
  3143                                (int)((XML_Char *)next - (XML_Char *)s));
       
  3144       }
       
  3145       else if (defaultHandler)
       
  3146         reportDefault(parser, enc, s, next);
       
  3147       break;
       
  3148     case XML_TOK_INVALID:
       
  3149       *eventPP = next;
       
  3150       return XML_ERROR_INVALID_TOKEN;
       
  3151     case XML_TOK_PARTIAL_CHAR:
       
  3152       if (haveMore) {
       
  3153         *nextPtr = s;
       
  3154         return XML_ERROR_NONE;
       
  3155       }
       
  3156       return XML_ERROR_PARTIAL_CHAR;
       
  3157     case XML_TOK_PARTIAL:
       
  3158     case XML_TOK_NONE:
       
  3159       if (haveMore) {
       
  3160         *nextPtr = s;
       
  3161         return XML_ERROR_NONE;
       
  3162       }
       
  3163       return XML_ERROR_UNCLOSED_CDATA_SECTION;
       
  3164     default:
       
  3165       *eventPP = next;
       
  3166       return XML_ERROR_UNEXPECTED_STATE;
       
  3167     }
       
  3168 
       
  3169     *eventPP = s = next;
       
  3170     switch (ps_parsing) {
       
  3171     case XML_SUSPENDED:
       
  3172       *nextPtr = next;
       
  3173       return XML_ERROR_NONE;
       
  3174     case XML_FINISHED:
       
  3175       return XML_ERROR_ABORTED;
       
  3176     default: ;
       
  3177     }
       
  3178   }
       
  3179   /* not reached */
       
  3180 }
       
  3181 
       
  3182 #ifdef XML_DTD
       
  3183 
       
  3184 /* The idea here is to avoid using stack for each IGNORE section when
       
  3185    the whole file is parsed with one call.
       
  3186 */
       
  3187 static enum XML_Error PTRCALL
       
  3188 ignoreSectionProcessor(XML_Parser parser,
       
  3189                        const char *start,
       
  3190                        const char *end,
       
  3191                        const char **endPtr)
       
  3192 {
       
  3193   enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 
       
  3194                                           endPtr, (XML_Bool)!ps_finalBuffer);
       
  3195   if (result != XML_ERROR_NONE)
       
  3196     return result;
       
  3197   if (start) {
       
  3198     processor = prologProcessor;
       
  3199     return prologProcessor(parser, start, end, endPtr);
       
  3200   }
       
  3201   return result;
       
  3202 }
       
  3203 
       
  3204 /* startPtr gets set to non-null is the section is closed, and to null
       
  3205    if the section is not yet closed.
       
  3206 */
       
  3207 static enum XML_Error
       
  3208 doIgnoreSection(XML_Parser parser,
       
  3209                 const ENCODING *enc,
       
  3210                 const char **startPtr,
       
  3211                 const char *end,
       
  3212                 const char **nextPtr,
       
  3213                 XML_Bool haveMore)
       
  3214 {
       
  3215   const char *next;
       
  3216   int tok;
       
  3217   const char *s = *startPtr;
       
  3218   const char **eventPP;
       
  3219   const char **eventEndPP;
       
  3220   if (enc == encoding) {
       
  3221     eventPP = &eventPtr;
       
  3222     *eventPP = s;
       
  3223     eventEndPP = &eventEndPtr;
       
  3224   }
       
  3225   else {
       
  3226     eventPP = &(openInternalEntities->internalEventPtr);
       
  3227     eventEndPP = &(openInternalEntities->internalEventEndPtr);
       
  3228   }
       
  3229   *eventPP = s;
       
  3230   *startPtr = NULL;
       
  3231   tok = XmlIgnoreSectionTok(enc, s, end, &next);
       
  3232   *eventEndPP = next;
       
  3233   switch (tok) {
       
  3234   case XML_TOK_IGNORE_SECT:
       
  3235     if (defaultHandler)
       
  3236       reportDefault(parser, enc, s, next);
       
  3237     *startPtr = next;
       
  3238     *nextPtr = next;
       
  3239     if (ps_parsing == XML_FINISHED)
       
  3240       return XML_ERROR_ABORTED;
       
  3241     else
       
  3242       return XML_ERROR_NONE;
       
  3243   case XML_TOK_INVALID:
       
  3244     *eventPP = next;
       
  3245     return XML_ERROR_INVALID_TOKEN;
       
  3246   case XML_TOK_PARTIAL_CHAR:
       
  3247     if (haveMore) {
       
  3248       *nextPtr = s;
       
  3249       return XML_ERROR_NONE;
       
  3250     }
       
  3251     return XML_ERROR_PARTIAL_CHAR;
       
  3252   case XML_TOK_PARTIAL:
       
  3253   case XML_TOK_NONE:
       
  3254     if (haveMore) {
       
  3255       *nextPtr = s;
       
  3256       return XML_ERROR_NONE;
       
  3257     }
       
  3258     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
       
  3259   default:
       
  3260     *eventPP = next;
       
  3261     return XML_ERROR_UNEXPECTED_STATE;
       
  3262   }
       
  3263   /* not reached */
       
  3264 }
       
  3265 
       
  3266 #endif /* XML_DTD */
       
  3267 
       
  3268 static enum XML_Error
       
  3269 initializeEncoding(XML_Parser parser)
       
  3270 {
       
  3271   const char *s;
       
  3272 #ifdef XML_UNICODE
       
  3273   char encodingBuf[128];
       
  3274   if (!protocolEncodingName)
       
  3275     s = NULL;
       
  3276   else {
       
  3277     int i;
       
  3278     for (i = 0; protocolEncodingName[i]; i++) {
       
  3279       if (i == sizeof(encodingBuf) - 1
       
  3280           || (protocolEncodingName[i] & ~0x7f) != 0) {
       
  3281         encodingBuf[0] = '\0';
       
  3282         break;
       
  3283       }
       
  3284       encodingBuf[i] = (char)protocolEncodingName[i];
       
  3285     }
       
  3286     encodingBuf[i] = '\0';
       
  3287     s = encodingBuf;
       
  3288   }
       
  3289 #else
       
  3290   s = protocolEncodingName;
       
  3291 #endif
       
  3292   if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
       
  3293     return XML_ERROR_NONE;
       
  3294   return handleUnknownEncoding(parser, protocolEncodingName);
       
  3295 }
       
  3296 
       
  3297 static enum XML_Error
       
  3298 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
       
  3299                const char *s, const char *next)
       
  3300 {
       
  3301   const char *encodingName = NULL;
       
  3302   const XML_Char *storedEncName = NULL;
       
  3303   const ENCODING *newEncoding = NULL;
       
  3304   const char *version = NULL;
       
  3305   const char *versionend;
       
  3306   const XML_Char *storedversion = NULL;
       
  3307   int standalone = -1;
       
  3308   if (!(ns
       
  3309         ? XmlParseXmlDeclNS
       
  3310         : XmlParseXmlDecl)(isGeneralTextEntity,
       
  3311                            encoding,
       
  3312                            s,
       
  3313                            next,
       
  3314                            &eventPtr,
       
  3315                            &version,
       
  3316                            &versionend,
       
  3317                            &encodingName,
       
  3318                            &newEncoding,
       
  3319                            &standalone)) {
       
  3320     if (isGeneralTextEntity)
       
  3321       return XML_ERROR_TEXT_DECL;
       
  3322     else
       
  3323       return XML_ERROR_XML_DECL;
       
  3324   }
       
  3325   if (!isGeneralTextEntity && standalone == 1) {
       
  3326     _dtd->standalone = XML_TRUE;
       
  3327 #ifdef XML_DTD
       
  3328     if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
       
  3329       paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
       
  3330 #endif /* XML_DTD */
       
  3331   }
       
  3332   if (xmlDeclHandler) {
       
  3333     if (encodingName != NULL) {
       
  3334       storedEncName = poolStoreString(&temp2Pool,
       
  3335                                       encoding,
       
  3336                                       encodingName,
       
  3337                                       encodingName
       
  3338                                       + XmlNameLength(encoding, encodingName));
       
  3339       if (!storedEncName)
       
  3340               return XML_ERROR_NO_MEMORY;
       
  3341       poolFinish(&temp2Pool);
       
  3342     }
       
  3343     if (version) {
       
  3344       storedversion = poolStoreString(&temp2Pool,
       
  3345                                       encoding,
       
  3346                                       version,
       
  3347                                       versionend - encoding->minBytesPerChar);
       
  3348       if (!storedversion)
       
  3349         return XML_ERROR_NO_MEMORY;
       
  3350     }
       
  3351     xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
       
  3352   }
       
  3353   else if (defaultHandler)
       
  3354     reportDefault(parser, encoding, s, next);
       
  3355   if (protocolEncodingName == NULL) {
       
  3356     if (newEncoding) {
       
  3357       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
       
  3358         eventPtr = encodingName;
       
  3359         return XML_ERROR_INCORRECT_ENCODING;
       
  3360       }
       
  3361       encoding = newEncoding;
       
  3362     }
       
  3363     else if (encodingName) {
       
  3364       enum XML_Error result;
       
  3365       if (!storedEncName) {
       
  3366         storedEncName = poolStoreString(
       
  3367           &temp2Pool, encoding, encodingName,
       
  3368           encodingName + XmlNameLength(encoding, encodingName));
       
  3369         if (!storedEncName)
       
  3370           return XML_ERROR_NO_MEMORY;
       
  3371       }
       
  3372       result = handleUnknownEncoding(parser, storedEncName);
       
  3373       poolClear(&temp2Pool);
       
  3374       if (result == XML_ERROR_UNKNOWN_ENCODING)
       
  3375         eventPtr = encodingName;
       
  3376       return result;
       
  3377     }
       
  3378   }
       
  3379 
       
  3380   if (storedEncName || storedversion)
       
  3381     poolClear(&temp2Pool);
       
  3382 
       
  3383   return XML_ERROR_NONE;
       
  3384 }
       
  3385 
       
  3386 static enum XML_Error
       
  3387 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
       
  3388 {
       
  3389   if (unknownEncodingHandler) {
       
  3390     XML_Encoding info;
       
  3391     int i;
       
  3392     for (i = 0; i < 256; i++)
       
  3393       info.map[i] = -1;
       
  3394     info.convert = NULL;
       
  3395     info.data = NULL;
       
  3396     info.release = NULL;
       
  3397     if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
       
  3398                                &info)) {
       
  3399       ENCODING *enc;
       
  3400       unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
       
  3401       if (!unknownEncodingMem) {
       
  3402         if (info.release)
       
  3403           info.release(info.data);
       
  3404         return XML_ERROR_NO_MEMORY;
       
  3405       }
       
  3406       enc = (ns
       
  3407              ? XmlInitUnknownEncodingNS
       
  3408              : XmlInitUnknownEncoding)(unknownEncodingMem,
       
  3409                                        info.map,
       
  3410                                        info.convert,
       
  3411                                        info.data);
       
  3412       if (enc) {
       
  3413         unknownEncodingData = info.data;
       
  3414         unknownEncodingRelease = info.release;
       
  3415         encoding = enc;
       
  3416         return XML_ERROR_NONE;
       
  3417       }
       
  3418     }
       
  3419     if (info.release != NULL)
       
  3420       info.release(info.data);
       
  3421   }
       
  3422   return XML_ERROR_UNKNOWN_ENCODING;
       
  3423 }
       
  3424 
       
  3425 static enum XML_Error PTRCALL
       
  3426 prologInitProcessor(XML_Parser parser,
       
  3427                     const char *s,
       
  3428                     const char *end,
       
  3429                     const char **nextPtr)
       
  3430 {
       
  3431   enum XML_Error result = initializeEncoding(parser);
       
  3432   if (result != XML_ERROR_NONE)
       
  3433     return result;
       
  3434   processor = prologProcessor;
       
  3435   return prologProcessor(parser, s, end, nextPtr);
       
  3436 }
       
  3437 
       
  3438 #ifdef XML_DTD
       
  3439 
       
  3440 static enum XML_Error PTRCALL
       
  3441 externalParEntInitProcessor(XML_Parser parser,
       
  3442                             const char *s,
       
  3443                             const char *end,
       
  3444                             const char **nextPtr)
       
  3445 {
       
  3446   enum XML_Error result = initializeEncoding(parser);
       
  3447   if (result != XML_ERROR_NONE)
       
  3448     return result;
       
  3449 
       
  3450   /* we know now that XML_Parse(Buffer) has been called,
       
  3451      so we consider the external parameter entity read */
       
  3452   _dtd->paramEntityRead = XML_TRUE;
       
  3453 
       
  3454   if (prologState.inEntityValue) {
       
  3455     processor = entityValueInitProcessor;
       
  3456     return entityValueInitProcessor(parser, s, end, nextPtr);
       
  3457   }
       
  3458   else {
       
  3459     processor = externalParEntProcessor;
       
  3460     return externalParEntProcessor(parser, s, end, nextPtr);
       
  3461   }
       
  3462 }
       
  3463 
       
  3464 static enum XML_Error PTRCALL
       
  3465 entityValueInitProcessor(XML_Parser parser,
       
  3466                          const char *s,
       
  3467                          const char *end,
       
  3468                          const char **nextPtr)
       
  3469 {
       
  3470   int tok;
       
  3471   const char *start = s;
       
  3472   const char *next = start;
       
  3473   eventPtr = start;
       
  3474 
       
  3475   for (;;) {  
       
  3476     tok = XmlPrologTok(encoding, start, end, &next);
       
  3477     eventEndPtr = next;
       
  3478     if (tok <= 0) {
       
  3479       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
       
  3480         *nextPtr = s;
       
  3481         return XML_ERROR_NONE;
       
  3482       }
       
  3483       switch (tok) {
       
  3484       case XML_TOK_INVALID:
       
  3485         return XML_ERROR_INVALID_TOKEN;
       
  3486       case XML_TOK_PARTIAL:
       
  3487         return XML_ERROR_UNCLOSED_TOKEN;
       
  3488       case XML_TOK_PARTIAL_CHAR:
       
  3489         return XML_ERROR_PARTIAL_CHAR;
       
  3490       case XML_TOK_NONE:   /* start == end */
       
  3491       default:
       
  3492         break;
       
  3493       }
       
  3494       /* found end of entity value - can store it now */
       
  3495       return storeEntityValue(parser, encoding, s, end);
       
  3496     }
       
  3497     else if (tok == XML_TOK_XML_DECL) {
       
  3498       enum XML_Error result;
       
  3499       result = processXmlDecl(parser, 0, start, next);
       
  3500       if (result != XML_ERROR_NONE)
       
  3501         return result;
       
  3502       switch (ps_parsing) {
       
  3503       case XML_SUSPENDED: 
       
  3504         *nextPtr = next;
       
  3505         return XML_ERROR_NONE;
       
  3506       case XML_FINISHED:
       
  3507         return XML_ERROR_ABORTED;
       
  3508       default:
       
  3509         *nextPtr = next;
       
  3510       }
       
  3511       /* stop scanning for text declaration - we found one */
       
  3512       processor = entityValueProcessor;
       
  3513       return entityValueProcessor(parser, next, end, nextPtr);
       
  3514     }
       
  3515     /* If we are at the end of the buffer, this would cause XmlPrologTok to
       
  3516        return XML_TOK_NONE on the next call, which would then cause the
       
  3517        function to exit with *nextPtr set to s - that is what we want for other
       
  3518        tokens, but not for the BOM - we would rather like to skip it;
       
  3519        then, when this routine is entered the next time, XmlPrologTok will
       
  3520        return XML_TOK_INVALID, since the BOM is still in the buffer
       
  3521     */
       
  3522     else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
       
  3523       *nextPtr = next;
       
  3524       return XML_ERROR_NONE;
       
  3525     }
       
  3526     start = next;
       
  3527     eventPtr = start;
       
  3528   }
       
  3529 }
       
  3530 
       
  3531 static enum XML_Error PTRCALL
       
  3532 externalParEntProcessor(XML_Parser parser,
       
  3533                         const char *s,
       
  3534                         const char *end,
       
  3535                         const char **nextPtr)
       
  3536 {
       
  3537   const char *next = s;
       
  3538   int tok;
       
  3539 
       
  3540   tok = XmlPrologTok(encoding, s, end, &next);
       
  3541   if (tok <= 0) {
       
  3542     if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
       
  3543       *nextPtr = s;
       
  3544       return XML_ERROR_NONE;
       
  3545     }
       
  3546     switch (tok) {
       
  3547     case XML_TOK_INVALID:
       
  3548       return XML_ERROR_INVALID_TOKEN;
       
  3549     case XML_TOK_PARTIAL:
       
  3550       return XML_ERROR_UNCLOSED_TOKEN;
       
  3551     case XML_TOK_PARTIAL_CHAR:
       
  3552       return XML_ERROR_PARTIAL_CHAR;
       
  3553     case XML_TOK_NONE:   /* start == end */
       
  3554     default:
       
  3555       break;
       
  3556     }
       
  3557   }
       
  3558   /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
       
  3559      However, when parsing an external subset, doProlog will not accept a BOM
       
  3560      as valid, and report a syntax error, so we have to skip the BOM
       
  3561   */
       
  3562   else if (tok == XML_TOK_BOM) {
       
  3563     s = next;
       
  3564     tok = XmlPrologTok(encoding, s, end, &next);
       
  3565   }
       
  3566 
       
  3567   processor = prologProcessor;
       
  3568   return doProlog(parser, encoding, s, end, tok, next, 
       
  3569                   nextPtr, (XML_Bool)!ps_finalBuffer);
       
  3570 }
       
  3571 
       
  3572 static enum XML_Error PTRCALL
       
  3573 entityValueProcessor(XML_Parser parser,
       
  3574                      const char *s,
       
  3575                      const char *end,
       
  3576                      const char **nextPtr)
       
  3577 {
       
  3578   const char *start = s;
       
  3579   const char *next = s;
       
  3580   const ENCODING *enc = encoding;
       
  3581   int tok;
       
  3582 
       
  3583   for (;;) {
       
  3584     tok = XmlPrologTok(enc, start, end, &next);
       
  3585     if (tok <= 0) {
       
  3586       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
       
  3587         *nextPtr = s;
       
  3588         return XML_ERROR_NONE;
       
  3589       }
       
  3590       switch (tok) {
       
  3591       case XML_TOK_INVALID:
       
  3592         return XML_ERROR_INVALID_TOKEN;
       
  3593       case XML_TOK_PARTIAL:
       
  3594         return XML_ERROR_UNCLOSED_TOKEN;
       
  3595       case XML_TOK_PARTIAL_CHAR:
       
  3596         return XML_ERROR_PARTIAL_CHAR;
       
  3597       case XML_TOK_NONE:   /* start == end */
       
  3598       default:
       
  3599         break;
       
  3600       }
       
  3601       /* found end of entity value - can store it now */
       
  3602       return storeEntityValue(parser, enc, s, end);
       
  3603     }
       
  3604     start = next;
       
  3605   }
       
  3606 }
       
  3607 
       
  3608 #endif /* XML_DTD */
       
  3609 
       
  3610 static enum XML_Error PTRCALL
       
  3611 prologProcessor(XML_Parser parser,
       
  3612                 const char *s,
       
  3613                 const char *end,
       
  3614                 const char **nextPtr)
       
  3615 {
       
  3616   const char *next = s;
       
  3617   int tok = XmlPrologTok(encoding, s, end, &next);
       
  3618   return doProlog(parser, encoding, s, end, tok, next, 
       
  3619                   nextPtr, (XML_Bool)!ps_finalBuffer);
       
  3620 }
       
  3621 
       
  3622 static enum XML_Error
       
  3623 doProlog(XML_Parser parser,
       
  3624          const ENCODING *enc,
       
  3625          const char *s,
       
  3626          const char *end,
       
  3627          int tok,
       
  3628          const char *next,
       
  3629          const char **nextPtr,
       
  3630          XML_Bool haveMore)
       
  3631 {
       
  3632 #ifdef XML_DTD
       
  3633   static const XML_Char externalSubsetName[] = { '#' , '\0' };
       
  3634 #endif /* XML_DTD */
       
  3635   static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
       
  3636   static const XML_Char atypeID[] = { 'I', 'D', '\0' };
       
  3637   static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
       
  3638   static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
       
  3639   static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
       
  3640   static const XML_Char atypeENTITIES[] =
       
  3641       { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
       
  3642   static const XML_Char atypeNMTOKEN[] = {
       
  3643       'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
       
  3644   static const XML_Char atypeNMTOKENS[] = {
       
  3645       'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
       
  3646   static const XML_Char notationPrefix[] = {
       
  3647       'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
       
  3648   static const XML_Char enumValueSep[] = { '|', '\0' };
       
  3649   static const XML_Char enumValueStart[] = { '(', '\0' };
       
  3650 
       
  3651   /* save one level of indirection */
       
  3652   DTD * const dtd = _dtd; 
       
  3653 
       
  3654   const char **eventPP;
       
  3655   const char **eventEndPP;
       
  3656   enum XML_Content_Quant quant;
       
  3657 
       
  3658   if (enc == encoding) {
       
  3659     eventPP = &eventPtr;
       
  3660     eventEndPP = &eventEndPtr;
       
  3661   }
       
  3662   else {
       
  3663     eventPP = &(openInternalEntities->internalEventPtr);
       
  3664     eventEndPP = &(openInternalEntities->internalEventEndPtr);
       
  3665   }
       
  3666 
       
  3667   for (;;) {
       
  3668     int role;
       
  3669     XML_Bool handleDefault = XML_TRUE;
       
  3670     *eventPP = s;
       
  3671     *eventEndPP = next;
       
  3672     if (tok <= 0) {
       
  3673       if (haveMore && tok != XML_TOK_INVALID) {
       
  3674         *nextPtr = s;
       
  3675         return XML_ERROR_NONE;
       
  3676       }
       
  3677       switch (tok) {
       
  3678       case XML_TOK_INVALID:
       
  3679         *eventPP = next;
       
  3680         return XML_ERROR_INVALID_TOKEN;
       
  3681       case XML_TOK_PARTIAL:
       
  3682         return XML_ERROR_UNCLOSED_TOKEN;
       
  3683       case XML_TOK_PARTIAL_CHAR:
       
  3684         return XML_ERROR_PARTIAL_CHAR;
       
  3685       case XML_TOK_NONE:
       
  3686 #ifdef XML_DTD
       
  3687         /* for internal PE NOT referenced between declarations */
       
  3688         if (enc != encoding && !openInternalEntities->betweenDecl) {
       
  3689           *nextPtr = s;
       
  3690           return XML_ERROR_NONE;
       
  3691         }
       
  3692         /* WFC: PE Between Declarations - must check that PE contains
       
  3693            complete markup, not only for external PEs, but also for
       
  3694            internal PEs if the reference occurs between declarations.
       
  3695         */
       
  3696         if (isParamEntity || enc != encoding) {
       
  3697           if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
       
  3698               == XML_ROLE_ERROR)
       
  3699             return XML_ERROR_INCOMPLETE_PE;
       
  3700           *nextPtr = s;
       
  3701           return XML_ERROR_NONE;
       
  3702         }
       
  3703 #endif /* XML_DTD */
       
  3704         return XML_ERROR_NO_ELEMENTS;
       
  3705       default:
       
  3706         tok = -tok;
       
  3707         next = end;
       
  3708         break;
       
  3709       }
       
  3710     }
       
  3711     role = XmlTokenRole(&prologState, tok, s, next, enc);
       
  3712     switch (role) {
       
  3713     case XML_ROLE_XML_DECL:
       
  3714       {
       
  3715         enum XML_Error result = processXmlDecl(parser, 0, s, next);
       
  3716         if (result != XML_ERROR_NONE)
       
  3717           return result;
       
  3718         enc = encoding;
       
  3719         handleDefault = XML_FALSE;
       
  3720       }
       
  3721       break;
       
  3722     case XML_ROLE_DOCTYPE_NAME:
       
  3723       if (startDoctypeDeclHandler) {
       
  3724         doctypeName = poolStoreString(&tempPool, enc, s, next);
       
  3725         if (!doctypeName)
       
  3726           return XML_ERROR_NO_MEMORY;
       
  3727         poolFinish(&tempPool);
       
  3728         doctypePubid = NULL;
       
  3729         handleDefault = XML_FALSE;
       
  3730       }
       
  3731       doctypeSysid = NULL; /* always initialize to NULL */
       
  3732       break;
       
  3733     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
       
  3734       if (startDoctypeDeclHandler) {
       
  3735         startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
       
  3736                                 doctypePubid, 1);
       
  3737         doctypeName = NULL;
       
  3738         poolClear(&tempPool);
       
  3739         handleDefault = XML_FALSE;
       
  3740       }
       
  3741       break;
       
  3742 #ifdef XML_DTD
       
  3743     case XML_ROLE_TEXT_DECL:
       
  3744       {
       
  3745         enum XML_Error result = processXmlDecl(parser, 1, s, next);
       
  3746         if (result != XML_ERROR_NONE)
       
  3747           return result;
       
  3748         enc = encoding;
       
  3749         handleDefault = XML_FALSE;
       
  3750       }
       
  3751       break;
       
  3752 #endif /* XML_DTD */
       
  3753     case XML_ROLE_DOCTYPE_PUBLIC_ID:
       
  3754 #ifdef XML_DTD
       
  3755       useForeignDTD = XML_FALSE;
       
  3756       declEntity = (ENTITY *)lookup(&dtd->paramEntities,
       
  3757                                     externalSubsetName,
       
  3758                                     sizeof(ENTITY));
       
  3759       if (!declEntity)
       
  3760         return XML_ERROR_NO_MEMORY;
       
  3761 #endif /* XML_DTD */
       
  3762       dtd->hasParamEntityRefs = XML_TRUE;
       
  3763       if (startDoctypeDeclHandler) {
       
  3764         if (!XmlIsPublicId(enc, s, next, eventPP))
       
  3765           return XML_ERROR_PUBLICID;
       
  3766         doctypePubid = poolStoreString(&tempPool, enc,
       
  3767                                        s + enc->minBytesPerChar,
       
  3768                                        next - enc->minBytesPerChar);
       
  3769         if (!doctypePubid)
       
  3770           return XML_ERROR_NO_MEMORY;
       
  3771         normalizePublicId((XML_Char *)doctypePubid);
       
  3772         poolFinish(&tempPool);
       
  3773         handleDefault = XML_FALSE;
       
  3774         goto alreadyChecked;
       
  3775       }
       
  3776       /* fall through */
       
  3777     case XML_ROLE_ENTITY_PUBLIC_ID:
       
  3778       if (!XmlIsPublicId(enc, s, next, eventPP))
       
  3779         return XML_ERROR_PUBLICID;
       
  3780     alreadyChecked:
       
  3781       if (dtd->keepProcessing && declEntity) {
       
  3782         XML_Char *tem = poolStoreString(&dtd->pool,
       
  3783                                         enc,
       
  3784                                         s + enc->minBytesPerChar,
       
  3785                                         next - enc->minBytesPerChar);
       
  3786         if (!tem)
       
  3787           return XML_ERROR_NO_MEMORY;
       
  3788         normalizePublicId(tem);
       
  3789         declEntity->publicId = tem;
       
  3790         poolFinish(&dtd->pool);
       
  3791         if (entityDeclHandler)
       
  3792           handleDefault = XML_FALSE;
       
  3793       }
       
  3794       break;
       
  3795     case XML_ROLE_DOCTYPE_CLOSE:
       
  3796       if (doctypeName) {
       
  3797         startDoctypeDeclHandler(handlerArg, doctypeName,
       
  3798                                 doctypeSysid, doctypePubid, 0);
       
  3799         poolClear(&tempPool);
       
  3800         handleDefault = XML_FALSE;
       
  3801       }
       
  3802       /* doctypeSysid will be non-NULL in the case of a previous
       
  3803          XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
       
  3804          was not set, indicating an external subset
       
  3805       */
       
  3806 #ifdef XML_DTD
       
  3807       if (doctypeSysid || useForeignDTD) {
       
  3808         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
       
  3809         dtd->hasParamEntityRefs = XML_TRUE;
       
  3810         if (paramEntityParsing && externalEntityRefHandler) {
       
  3811           ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
       
  3812                                             externalSubsetName,
       
  3813                                             sizeof(ENTITY));
       
  3814           if (!entity)
       
  3815             return XML_ERROR_NO_MEMORY;
       
  3816           if (useForeignDTD)
       
  3817             entity->base = curBase;
       
  3818           dtd->paramEntityRead = XML_FALSE;
       
  3819           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
       
  3820                                         0,
       
  3821                                         entity->base,
       
  3822                                         entity->systemId,
       
  3823                                         entity->publicId))
       
  3824             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
       
  3825           if (dtd->paramEntityRead) {
       
  3826             if (!dtd->standalone && 
       
  3827                 notStandaloneHandler && 
       
  3828                 !notStandaloneHandler(handlerArg))
       
  3829               return XML_ERROR_NOT_STANDALONE;
       
  3830           }
       
  3831           /* if we didn't read the foreign DTD then this means that there
       
  3832              is no external subset and we must reset dtd->hasParamEntityRefs
       
  3833           */
       
  3834           else if (!doctypeSysid)
       
  3835             dtd->hasParamEntityRefs = hadParamEntityRefs;
       
  3836           /* end of DTD - no need to update dtd->keepProcessing */
       
  3837         }
       
  3838         useForeignDTD = XML_FALSE;
       
  3839       }
       
  3840 #endif /* XML_DTD */
       
  3841       if (endDoctypeDeclHandler) {
       
  3842         endDoctypeDeclHandler(handlerArg);
       
  3843         handleDefault = XML_FALSE;
       
  3844       }
       
  3845       break;
       
  3846     case XML_ROLE_INSTANCE_START:
       
  3847 #ifdef XML_DTD
       
  3848       /* if there is no DOCTYPE declaration then now is the
       
  3849          last chance to read the foreign DTD
       
  3850       */
       
  3851       if (useForeignDTD) {
       
  3852         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
       
  3853         dtd->hasParamEntityRefs = XML_TRUE;
       
  3854         if (paramEntityParsing && externalEntityRefHandler) {
       
  3855           ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
       
  3856                                             externalSubsetName,
       
  3857                                             sizeof(ENTITY));
       
  3858           if (!entity)
       
  3859             return XML_ERROR_NO_MEMORY;
       
  3860           entity->base = curBase;
       
  3861           dtd->paramEntityRead = XML_FALSE;
       
  3862           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
       
  3863                                         0,
       
  3864                                         entity->base,
       
  3865                                         entity->systemId,
       
  3866                                         entity->publicId))
       
  3867             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
       
  3868           if (dtd->paramEntityRead) {
       
  3869             if (!dtd->standalone &&
       
  3870                 notStandaloneHandler &&
       
  3871                 !notStandaloneHandler(handlerArg))
       
  3872               return XML_ERROR_NOT_STANDALONE;
       
  3873           }
       
  3874           /* if we didn't read the foreign DTD then this means that there
       
  3875              is no external subset and we must reset dtd->hasParamEntityRefs
       
  3876           */
       
  3877           else
       
  3878             dtd->hasParamEntityRefs = hadParamEntityRefs;
       
  3879           /* end of DTD - no need to update dtd->keepProcessing */
       
  3880         }
       
  3881       }
       
  3882 #endif /* XML_DTD */
       
  3883       processor = contentProcessor;
       
  3884       return contentProcessor(parser, s, end, nextPtr);
       
  3885     case XML_ROLE_ATTLIST_ELEMENT_NAME:
       
  3886       declElementType = getElementType(parser, enc, s, next);
       
  3887       if (!declElementType)
       
  3888         return XML_ERROR_NO_MEMORY;
       
  3889       goto checkAttListDeclHandler;
       
  3890     case XML_ROLE_ATTRIBUTE_NAME:
       
  3891       declAttributeId = getAttributeId(parser, enc, s, next);
       
  3892       if (!declAttributeId)
       
  3893         return XML_ERROR_NO_MEMORY;
       
  3894       declAttributeIsCdata = XML_FALSE;
       
  3895       declAttributeType = NULL;
       
  3896       declAttributeIsId = XML_FALSE;
       
  3897       goto checkAttListDeclHandler;
       
  3898     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
       
  3899       declAttributeIsCdata = XML_TRUE;
       
  3900       declAttributeType = atypeCDATA;
       
  3901       goto checkAttListDeclHandler;
       
  3902     case XML_ROLE_ATTRIBUTE_TYPE_ID:
       
  3903       declAttributeIsId = XML_TRUE;
       
  3904       declAttributeType = atypeID;
       
  3905       goto checkAttListDeclHandler;
       
  3906     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
       
  3907       declAttributeType = atypeIDREF;
       
  3908       goto checkAttListDeclHandler;
       
  3909     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
       
  3910       declAttributeType = atypeIDREFS;
       
  3911       goto checkAttListDeclHandler;
       
  3912     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
       
  3913       declAttributeType = atypeENTITY;
       
  3914       goto checkAttListDeclHandler;
       
  3915     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
       
  3916       declAttributeType = atypeENTITIES;
       
  3917       goto checkAttListDeclHandler;
       
  3918     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
       
  3919       declAttributeType = atypeNMTOKEN;
       
  3920       goto checkAttListDeclHandler;
       
  3921     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
       
  3922       declAttributeType = atypeNMTOKENS;
       
  3923     checkAttListDeclHandler:
       
  3924       if (dtd->keepProcessing && attlistDeclHandler)
       
  3925         handleDefault = XML_FALSE;
       
  3926       break;
       
  3927     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
       
  3928     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
       
  3929       if (dtd->keepProcessing && attlistDeclHandler) {
       
  3930         const XML_Char *prefix;
       
  3931         if (declAttributeType) {
       
  3932           prefix = enumValueSep;
       
  3933         }
       
  3934         else {
       
  3935           prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
       
  3936                     ? notationPrefix
       
  3937                     : enumValueStart);
       
  3938         }
       
  3939         if (!poolAppendString(&tempPool, prefix))
       
  3940           return XML_ERROR_NO_MEMORY;
       
  3941         if (!poolAppend(&tempPool, enc, s, next))
       
  3942           return XML_ERROR_NO_MEMORY;
       
  3943         declAttributeType = tempPool.start;
       
  3944         handleDefault = XML_FALSE;
       
  3945       }
       
  3946       break;
       
  3947     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
       
  3948     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
       
  3949       if (dtd->keepProcessing) {
       
  3950         if (!defineAttribute(declElementType, declAttributeId,
       
  3951                              declAttributeIsCdata, declAttributeIsId,
       
  3952                              0, parser))
       
  3953           return XML_ERROR_NO_MEMORY;
       
  3954         if (attlistDeclHandler && declAttributeType) {
       
  3955           if (*declAttributeType == XML_T('(')
       
  3956               || (*declAttributeType == XML_T('N')
       
  3957                   && declAttributeType[1] == XML_T('O'))) {
       
  3958             /* Enumerated or Notation type */
       
  3959             if (!poolAppendChar(&tempPool, XML_T(')'))
       
  3960                 || !poolAppendChar(&tempPool, XML_T('\0')))
       
  3961               return XML_ERROR_NO_MEMORY;
       
  3962             declAttributeType = tempPool.start;
       
  3963             poolFinish(&tempPool);
       
  3964           }
       
  3965           *eventEndPP = s;
       
  3966           attlistDeclHandler(handlerArg, declElementType->name,
       
  3967                              declAttributeId->name, declAttributeType,
       
  3968                              0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
       
  3969           poolClear(&tempPool);
       
  3970           handleDefault = XML_FALSE;
       
  3971         }
       
  3972       }
       
  3973       break;
       
  3974     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
       
  3975     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
       
  3976       if (dtd->keepProcessing) {
       
  3977         const XML_Char *attVal;
       
  3978         enum XML_Error result =
       
  3979           storeAttributeValue(parser, enc, declAttributeIsCdata,
       
  3980                               s + enc->minBytesPerChar,
       
  3981                               next - enc->minBytesPerChar,
       
  3982                               &dtd->pool);
       
  3983         if (result)
       
  3984           return result;
       
  3985         attVal = poolStart(&dtd->pool);
       
  3986         poolFinish(&dtd->pool);
       
  3987         /* ID attributes aren't allowed to have a default */
       
  3988         if (!defineAttribute(declElementType, declAttributeId,
       
  3989                              declAttributeIsCdata, XML_FALSE, attVal, parser))
       
  3990           return XML_ERROR_NO_MEMORY;
       
  3991         if (attlistDeclHandler && declAttributeType) {
       
  3992           if (*declAttributeType == XML_T('(')
       
  3993               || (*declAttributeType == XML_T('N')
       
  3994                   && declAttributeType[1] == XML_T('O'))) {
       
  3995             /* Enumerated or Notation type */
       
  3996             if (!poolAppendChar(&tempPool, XML_T(')'))
       
  3997                 || !poolAppendChar(&tempPool, XML_T('\0')))
       
  3998               return XML_ERROR_NO_MEMORY;
       
  3999             declAttributeType = tempPool.start;
       
  4000             poolFinish(&tempPool);
       
  4001           }
       
  4002           *eventEndPP = s;
       
  4003           attlistDeclHandler(handlerArg, declElementType->name,
       
  4004                              declAttributeId->name, declAttributeType,
       
  4005                              attVal,
       
  4006                              role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
       
  4007           poolClear(&tempPool);
       
  4008           handleDefault = XML_FALSE;
       
  4009         }
       
  4010       }
       
  4011       break;
       
  4012     case XML_ROLE_ENTITY_VALUE:
       
  4013       if (dtd->keepProcessing) {
       
  4014         enum XML_Error result = storeEntityValue(parser, enc,
       
  4015                                             s + enc->minBytesPerChar,
       
  4016                                             next - enc->minBytesPerChar);
       
  4017         if (declEntity) {
       
  4018           declEntity->textPtr = poolStart(&dtd->entityValuePool);
       
  4019           declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
       
  4020           poolFinish(&dtd->entityValuePool);
       
  4021           if (entityDeclHandler) {
       
  4022             *eventEndPP = s;
       
  4023             entityDeclHandler(handlerArg,
       
  4024                               declEntity->name,
       
  4025                               declEntity->is_param,
       
  4026                               declEntity->textPtr,
       
  4027                               declEntity->textLen,
       
  4028                               curBase, 0, 0, 0);
       
  4029             handleDefault = XML_FALSE;
       
  4030           }
       
  4031         }
       
  4032         else
       
  4033           poolDiscard(&dtd->entityValuePool);
       
  4034         if (result != XML_ERROR_NONE)
       
  4035           return result;
       
  4036       }
       
  4037       break;
       
  4038     case XML_ROLE_DOCTYPE_SYSTEM_ID:
       
  4039 #ifdef XML_DTD
       
  4040       useForeignDTD = XML_FALSE;
       
  4041 #endif /* XML_DTD */
       
  4042       dtd->hasParamEntityRefs = XML_TRUE;
       
  4043       if (startDoctypeDeclHandler) {
       
  4044         doctypeSysid = poolStoreString(&tempPool, enc,
       
  4045                                        s + enc->minBytesPerChar,
       
  4046                                        next - enc->minBytesPerChar);
       
  4047         if (doctypeSysid == NULL)
       
  4048           return XML_ERROR_NO_MEMORY;
       
  4049         poolFinish(&tempPool);
       
  4050         handleDefault = XML_FALSE;
       
  4051       }
       
  4052 #ifdef XML_DTD
       
  4053       else
       
  4054         /* use externalSubsetName to make doctypeSysid non-NULL
       
  4055            for the case where no startDoctypeDeclHandler is set */
       
  4056         doctypeSysid = externalSubsetName;
       
  4057 #endif /* XML_DTD */
       
  4058       if (!dtd->standalone
       
  4059 #ifdef XML_DTD
       
  4060           && !paramEntityParsing
       
  4061 #endif /* XML_DTD */
       
  4062           && notStandaloneHandler
       
  4063           && !notStandaloneHandler(handlerArg))
       
  4064         return XML_ERROR_NOT_STANDALONE;
       
  4065 #ifndef XML_DTD
       
  4066       break;
       
  4067 #else /* XML_DTD */
       
  4068       if (!declEntity) {
       
  4069         declEntity = (ENTITY *)lookup(&dtd->paramEntities,
       
  4070                                       externalSubsetName,
       
  4071                                       sizeof(ENTITY));
       
  4072         if (!declEntity)
       
  4073           return XML_ERROR_NO_MEMORY;
       
  4074         declEntity->publicId = NULL;
       
  4075       }
       
  4076       /* fall through */
       
  4077 #endif /* XML_DTD */
       
  4078     case XML_ROLE_ENTITY_SYSTEM_ID:
       
  4079       if (dtd->keepProcessing && declEntity) {
       
  4080         declEntity->systemId = poolStoreString(&dtd->pool, enc,
       
  4081                                                s + enc->minBytesPerChar,
       
  4082                                                next - enc->minBytesPerChar);
       
  4083         if (!declEntity->systemId)
       
  4084           return XML_ERROR_NO_MEMORY;
       
  4085         declEntity->base = curBase;
       
  4086         poolFinish(&dtd->pool);
       
  4087         if (entityDeclHandler)
       
  4088           handleDefault = XML_FALSE;
       
  4089       }
       
  4090       break;
       
  4091     case XML_ROLE_ENTITY_COMPLETE:
       
  4092       if (dtd->keepProcessing && declEntity && entityDeclHandler) {
       
  4093         *eventEndPP = s;
       
  4094         entityDeclHandler(handlerArg,
       
  4095                           declEntity->name,
       
  4096                           declEntity->is_param,
       
  4097                           0,0,
       
  4098                           declEntity->base,
       
  4099                           declEntity->systemId,
       
  4100                           declEntity->publicId,
       
  4101                           0);
       
  4102         handleDefault = XML_FALSE;
       
  4103       }
       
  4104       break;
       
  4105     case XML_ROLE_ENTITY_NOTATION_NAME:
       
  4106       if (dtd->keepProcessing && declEntity) {
       
  4107         declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
       
  4108         if (!declEntity->notation)
       
  4109           return XML_ERROR_NO_MEMORY;
       
  4110         poolFinish(&dtd->pool);
       
  4111         if (unparsedEntityDeclHandler) {
       
  4112           *eventEndPP = s;
       
  4113           unparsedEntityDeclHandler(handlerArg,
       
  4114                                     declEntity->name,
       
  4115                                     declEntity->base,
       
  4116                                     declEntity->systemId,
       
  4117                                     declEntity->publicId,
       
  4118                                     declEntity->notation);
       
  4119           handleDefault = XML_FALSE;
       
  4120         }
       
  4121         else if (entityDeclHandler) {
       
  4122           *eventEndPP = s;
       
  4123           entityDeclHandler(handlerArg,
       
  4124                             declEntity->name,
       
  4125                             0,0,0,
       
  4126                             declEntity->base,
       
  4127                             declEntity->systemId,
       
  4128                             declEntity->publicId,
       
  4129                             declEntity->notation);
       
  4130           handleDefault = XML_FALSE;
       
  4131         }
       
  4132       }
       
  4133       break;
       
  4134     case XML_ROLE_GENERAL_ENTITY_NAME:
       
  4135       {
       
  4136         if (XmlPredefinedEntityName(enc, s, next)) {
       
  4137           declEntity = NULL;
       
  4138           break;
       
  4139         }
       
  4140         if (dtd->keepProcessing) {
       
  4141           const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
       
  4142           if (!name)
       
  4143             return XML_ERROR_NO_MEMORY;
       
  4144           declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
       
  4145                                         sizeof(ENTITY));
       
  4146           if (!declEntity)
       
  4147             return XML_ERROR_NO_MEMORY;
       
  4148           if (declEntity->name != name) {
       
  4149             poolDiscard(&dtd->pool);
       
  4150             declEntity = NULL;
       
  4151           }
       
  4152           else {
       
  4153             poolFinish(&dtd->pool);
       
  4154             declEntity->publicId = NULL;
       
  4155             declEntity->is_param = XML_FALSE;
       
  4156             /* if we have a parent parser or are reading an internal parameter
       
  4157                entity, then the entity declaration is not considered "internal"
       
  4158             */
       
  4159             declEntity->is_internal = !(parentParser || openInternalEntities);
       
  4160             if (entityDeclHandler)
       
  4161               handleDefault = XML_FALSE;
       
  4162           }
       
  4163         }
       
  4164         else {
       
  4165           poolDiscard(&dtd->pool);
       
  4166           declEntity = NULL;
       
  4167         }
       
  4168       }
       
  4169       break;
       
  4170     case XML_ROLE_PARAM_ENTITY_NAME:
       
  4171 #ifdef XML_DTD
       
  4172       if (dtd->keepProcessing) {
       
  4173         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
       
  4174         if (!name)
       
  4175           return XML_ERROR_NO_MEMORY;
       
  4176         declEntity = (ENTITY *)lookup(&dtd->paramEntities,
       
  4177                                            name, sizeof(ENTITY));
       
  4178         if (!declEntity)
       
  4179           return XML_ERROR_NO_MEMORY;
       
  4180         if (declEntity->name != name) {
       
  4181           poolDiscard(&dtd->pool);
       
  4182           declEntity = NULL;
       
  4183         }
       
  4184         else {
       
  4185           poolFinish(&dtd->pool);
       
  4186           declEntity->publicId = NULL;
       
  4187           declEntity->is_param = XML_TRUE;
       
  4188           /* if we have a parent parser or are reading an internal parameter
       
  4189              entity, then the entity declaration is not considered "internal"
       
  4190           */
       
  4191           declEntity->is_internal = !(parentParser || openInternalEntities);
       
  4192           if (entityDeclHandler)
       
  4193             handleDefault = XML_FALSE;
       
  4194         }
       
  4195       }
       
  4196       else {
       
  4197         poolDiscard(&dtd->pool);
       
  4198         declEntity = NULL;
       
  4199       }
       
  4200 #else /* not XML_DTD */
       
  4201       declEntity = NULL;
       
  4202 #endif /* XML_DTD */
       
  4203       break;
       
  4204     case XML_ROLE_NOTATION_NAME:
       
  4205       declNotationPublicId = NULL;
       
  4206       declNotationName = NULL;
       
  4207       if (notationDeclHandler) {
       
  4208         declNotationName = poolStoreString(&tempPool, enc, s, next);
       
  4209         if (!declNotationName)
       
  4210           return XML_ERROR_NO_MEMORY;
       
  4211         poolFinish(&tempPool);
       
  4212         handleDefault = XML_FALSE;
       
  4213       }
       
  4214       break;
       
  4215     case XML_ROLE_NOTATION_PUBLIC_ID:
       
  4216       if (!XmlIsPublicId(enc, s, next, eventPP))
       
  4217         return XML_ERROR_PUBLICID;
       
  4218       if (declNotationName) {  /* means notationDeclHandler != NULL */
       
  4219         XML_Char *tem = poolStoreString(&tempPool,
       
  4220                                         enc,
       
  4221                                         s + enc->minBytesPerChar,
       
  4222                                         next - enc->minBytesPerChar);
       
  4223         if (!tem)
       
  4224           return XML_ERROR_NO_MEMORY;
       
  4225         normalizePublicId(tem);
       
  4226         declNotationPublicId = tem;
       
  4227         poolFinish(&tempPool);
       
  4228         handleDefault = XML_FALSE;
       
  4229       }
       
  4230       break;
       
  4231     case XML_ROLE_NOTATION_SYSTEM_ID:
       
  4232       if (declNotationName && notationDeclHandler) {
       
  4233         const XML_Char *systemId
       
  4234           = poolStoreString(&tempPool, enc,
       
  4235                             s + enc->minBytesPerChar,
       
  4236                             next - enc->minBytesPerChar);
       
  4237         if (!systemId)
       
  4238           return XML_ERROR_NO_MEMORY;
       
  4239         *eventEndPP = s;
       
  4240         notationDeclHandler(handlerArg,
       
  4241                             declNotationName,
       
  4242                             curBase,
       
  4243                             systemId,
       
  4244                             declNotationPublicId);
       
  4245         handleDefault = XML_FALSE;
       
  4246       }
       
  4247       poolClear(&tempPool);
       
  4248       break;
       
  4249     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
       
  4250       if (declNotationPublicId && notationDeclHandler) {
       
  4251         *eventEndPP = s;
       
  4252         notationDeclHandler(handlerArg,
       
  4253                             declNotationName,
       
  4254                             curBase,
       
  4255                             0,
       
  4256                             declNotationPublicId);
       
  4257         handleDefault = XML_FALSE;
       
  4258       }
       
  4259       poolClear(&tempPool);
       
  4260       break;
       
  4261     case XML_ROLE_ERROR:
       
  4262       switch (tok) {
       
  4263       case XML_TOK_PARAM_ENTITY_REF:
       
  4264         /* PE references in internal subset are
       
  4265            not allowed within declarations. */  
       
  4266         return XML_ERROR_PARAM_ENTITY_REF;
       
  4267       case XML_TOK_XML_DECL:
       
  4268         return XML_ERROR_MISPLACED_XML_PI;
       
  4269       default:
       
  4270         return XML_ERROR_SYNTAX;
       
  4271       }
       
  4272 #ifdef XML_DTD
       
  4273     case XML_ROLE_IGNORE_SECT:
       
  4274       {
       
  4275         enum XML_Error result;
       
  4276         if (defaultHandler)
       
  4277           reportDefault(parser, enc, s, next);
       
  4278         handleDefault = XML_FALSE;
       
  4279         result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
       
  4280         if (result != XML_ERROR_NONE)
       
  4281           return result;
       
  4282         else if (!next) {
       
  4283           processor = ignoreSectionProcessor;
       
  4284           return result;
       
  4285         }
       
  4286       }
       
  4287       break;
       
  4288 #endif /* XML_DTD */
       
  4289     case XML_ROLE_GROUP_OPEN:
       
  4290       if (prologState.level >= groupSize) {
       
  4291         if (groupSize) {
       
  4292           char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
       
  4293           if (temp == NULL)
       
  4294             return XML_ERROR_NO_MEMORY;
       
  4295           groupConnector = temp;
       
  4296           if (dtd->scaffIndex) {
       
  4297             int *temp = (int *)REALLOC(dtd->scaffIndex,
       
  4298                           groupSize * sizeof(int));
       
  4299             if (temp == NULL)
       
  4300               return XML_ERROR_NO_MEMORY;
       
  4301             dtd->scaffIndex = temp;
       
  4302           }
       
  4303         }
       
  4304         else {
       
  4305           groupConnector = (char *)MALLOC(groupSize = 32);
       
  4306           if (!groupConnector)
       
  4307             return XML_ERROR_NO_MEMORY;
       
  4308         }
       
  4309       }
       
  4310       groupConnector[prologState.level] = 0;
       
  4311       if (dtd->in_eldecl) {
       
  4312         int myindex = nextScaffoldPart(parser);
       
  4313         if (myindex < 0)
       
  4314           return XML_ERROR_NO_MEMORY;
       
  4315         dtd->scaffIndex[dtd->scaffLevel] = myindex;
       
  4316         dtd->scaffLevel++;
       
  4317         dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
       
  4318         if (elementDeclHandler)
       
  4319           handleDefault = XML_FALSE;
       
  4320       }
       
  4321       break;
       
  4322     case XML_ROLE_GROUP_SEQUENCE:
       
  4323       if (groupConnector[prologState.level] == '|')
       
  4324         return XML_ERROR_SYNTAX;
       
  4325       groupConnector[prologState.level] = ',';
       
  4326       if (dtd->in_eldecl && elementDeclHandler)
       
  4327         handleDefault = XML_FALSE;
       
  4328       break;
       
  4329     case XML_ROLE_GROUP_CHOICE:
       
  4330       if (groupConnector[prologState.level] == ',')
       
  4331         return XML_ERROR_SYNTAX;
       
  4332       if (dtd->in_eldecl
       
  4333           && !groupConnector[prologState.level]
       
  4334           && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
       
  4335               != XML_CTYPE_MIXED)
       
  4336           ) {
       
  4337         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
       
  4338             = XML_CTYPE_CHOICE;
       
  4339         if (elementDeclHandler)
       
  4340           handleDefault = XML_FALSE;
       
  4341       }
       
  4342       groupConnector[prologState.level] = '|';
       
  4343       break;
       
  4344     case XML_ROLE_PARAM_ENTITY_REF:
       
  4345 #ifdef XML_DTD
       
  4346     case XML_ROLE_INNER_PARAM_ENTITY_REF:
       
  4347       dtd->hasParamEntityRefs = XML_TRUE;
       
  4348       if (!paramEntityParsing)
       
  4349         dtd->keepProcessing = dtd->standalone;
       
  4350       else {
       
  4351         const XML_Char *name;
       
  4352         ENTITY *entity;
       
  4353         name = poolStoreString(&dtd->pool, enc,
       
  4354                                 s + enc->minBytesPerChar,
       
  4355                                 next - enc->minBytesPerChar);
       
  4356         if (!name)
       
  4357           return XML_ERROR_NO_MEMORY;
       
  4358         entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
       
  4359         poolDiscard(&dtd->pool);
       
  4360         /* first, determine if a check for an existing declaration is needed;
       
  4361            if yes, check that the entity exists, and that it is internal,
       
  4362            otherwise call the skipped entity handler
       
  4363         */
       
  4364         if (prologState.documentEntity &&
       
  4365             (dtd->standalone
       
  4366              ? !openInternalEntities
       
  4367              : !dtd->hasParamEntityRefs)) {
       
  4368           if (!entity)
       
  4369             return XML_ERROR_UNDEFINED_ENTITY;
       
  4370           else if (!entity->is_internal)
       
  4371             return XML_ERROR_ENTITY_DECLARED_IN_PE;
       
  4372         }
       
  4373         else if (!entity) {
       
  4374           dtd->keepProcessing = dtd->standalone;
       
  4375           /* cannot report skipped entities in declarations */
       
  4376           if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
       
  4377             skippedEntityHandler(handlerArg, name, 1);
       
  4378             handleDefault = XML_FALSE;
       
  4379           }
       
  4380           break;
       
  4381         }
       
  4382         if (entity->open)
       
  4383           return XML_ERROR_RECURSIVE_ENTITY_REF;
       
  4384         if (entity->textPtr) {
       
  4385           enum XML_Error result;
       
  4386           XML_Bool betweenDecl = 
       
  4387             (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
       
  4388           result = processInternalEntity(parser, entity, betweenDecl);
       
  4389           if (result != XML_ERROR_NONE)
       
  4390             return result;
       
  4391           handleDefault = XML_FALSE;
       
  4392           break;
       
  4393         }
       
  4394         if (externalEntityRefHandler) {
       
  4395           dtd->paramEntityRead = XML_FALSE;
       
  4396           entity->open = XML_TRUE;
       
  4397           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
       
  4398                                         0,
       
  4399                                         entity->base,
       
  4400                                         entity->systemId,
       
  4401                                         entity->publicId)) {
       
  4402             entity->open = XML_FALSE;
       
  4403             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
       
  4404           }
       
  4405           entity->open = XML_FALSE;
       
  4406           handleDefault = XML_FALSE;
       
  4407           if (!dtd->paramEntityRead) {
       
  4408             dtd->keepProcessing = dtd->standalone;
       
  4409             break;
       
  4410           }
       
  4411         }
       
  4412         else {
       
  4413           dtd->keepProcessing = dtd->standalone;
       
  4414           break;
       
  4415         }
       
  4416       }
       
  4417 #endif /* XML_DTD */
       
  4418       if (!dtd->standalone &&
       
  4419           notStandaloneHandler &&
       
  4420           !notStandaloneHandler(handlerArg))
       
  4421         return XML_ERROR_NOT_STANDALONE;
       
  4422       break;
       
  4423 
       
  4424     /* Element declaration stuff */
       
  4425 
       
  4426     case XML_ROLE_ELEMENT_NAME:
       
  4427       if (elementDeclHandler) {
       
  4428         declElementType = getElementType(parser, enc, s, next);
       
  4429         if (!declElementType)
       
  4430           return XML_ERROR_NO_MEMORY;
       
  4431         dtd->scaffLevel = 0;
       
  4432         dtd->scaffCount = 0;
       
  4433         dtd->in_eldecl = XML_TRUE;
       
  4434         handleDefault = XML_FALSE;
       
  4435       }
       
  4436       break;
       
  4437 
       
  4438     case XML_ROLE_CONTENT_ANY:
       
  4439     case XML_ROLE_CONTENT_EMPTY:
       
  4440       if (dtd->in_eldecl) {
       
  4441         if (elementDeclHandler) {
       
  4442           XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
       
  4443           if (!content)
       
  4444             return XML_ERROR_NO_MEMORY;
       
  4445           content->quant = XML_CQUANT_NONE;
       
  4446           content->name = NULL;
       
  4447           content->numchildren = 0;
       
  4448           content->children = NULL;
       
  4449           content->type = ((role == XML_ROLE_CONTENT_ANY) ?
       
  4450                            XML_CTYPE_ANY :
       
  4451                            XML_CTYPE_EMPTY);
       
  4452           *eventEndPP = s;
       
  4453           elementDeclHandler(handlerArg, declElementType->name, content);
       
  4454           handleDefault = XML_FALSE;
       
  4455         }
       
  4456         dtd->in_eldecl = XML_FALSE;
       
  4457       }
       
  4458       break;
       
  4459 
       
  4460     case XML_ROLE_CONTENT_PCDATA:
       
  4461       if (dtd->in_eldecl) {
       
  4462         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
       
  4463             = XML_CTYPE_MIXED;
       
  4464         if (elementDeclHandler)
       
  4465           handleDefault = XML_FALSE;
       
  4466       }
       
  4467       break;
       
  4468 
       
  4469     case XML_ROLE_CONTENT_ELEMENT:
       
  4470       quant = XML_CQUANT_NONE;
       
  4471       goto elementContent;
       
  4472     case XML_ROLE_CONTENT_ELEMENT_OPT:
       
  4473       quant = XML_CQUANT_OPT;
       
  4474       goto elementContent;
       
  4475     case XML_ROLE_CONTENT_ELEMENT_REP:
       
  4476       quant = XML_CQUANT_REP;
       
  4477       goto elementContent;
       
  4478     case XML_ROLE_CONTENT_ELEMENT_PLUS:
       
  4479       quant = XML_CQUANT_PLUS;
       
  4480     elementContent:
       
  4481       if (dtd->in_eldecl) {
       
  4482         ELEMENT_TYPE *el;
       
  4483         const XML_Char *name;
       
  4484         int nameLen;
       
  4485         const char *nxt = (quant == XML_CQUANT_NONE
       
  4486                            ? next
       
  4487                            : next - enc->minBytesPerChar);
       
  4488         int myindex = nextScaffoldPart(parser);
       
  4489         if (myindex < 0)
       
  4490           return XML_ERROR_NO_MEMORY;
       
  4491         dtd->scaffold[myindex].type = XML_CTYPE_NAME;
       
  4492         dtd->scaffold[myindex].quant = quant;
       
  4493         el = getElementType(parser, enc, s, nxt);
       
  4494         if (!el)
       
  4495           return XML_ERROR_NO_MEMORY;
       
  4496         name = el->name;
       
  4497         dtd->scaffold[myindex].name = name;
       
  4498         nameLen = 0;
       
  4499         for (; name[nameLen++]; );
       
  4500         dtd->contentStringLen +=  nameLen;
       
  4501         if (elementDeclHandler)
       
  4502           handleDefault = XML_FALSE;
       
  4503       }
       
  4504       break;
       
  4505 
       
  4506     case XML_ROLE_GROUP_CLOSE:
       
  4507       quant = XML_CQUANT_NONE;
       
  4508       goto closeGroup;
       
  4509     case XML_ROLE_GROUP_CLOSE_OPT:
       
  4510       quant = XML_CQUANT_OPT;
       
  4511       goto closeGroup;
       
  4512     case XML_ROLE_GROUP_CLOSE_REP:
       
  4513       quant = XML_CQUANT_REP;
       
  4514       goto closeGroup;
       
  4515     case XML_ROLE_GROUP_CLOSE_PLUS:
       
  4516       quant = XML_CQUANT_PLUS;
       
  4517     closeGroup:
       
  4518       if (dtd->in_eldecl) {
       
  4519         if (elementDeclHandler)
       
  4520           handleDefault = XML_FALSE;
       
  4521         dtd->scaffLevel--;
       
  4522         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
       
  4523         if (dtd->scaffLevel == 0) {
       
  4524           if (!handleDefault) {
       
  4525             XML_Content *model = build_model(parser);
       
  4526             if (!model)
       
  4527               return XML_ERROR_NO_MEMORY;
       
  4528             *eventEndPP = s;
       
  4529             elementDeclHandler(handlerArg, declElementType->name, model);
       
  4530           }
       
  4531           dtd->in_eldecl = XML_FALSE;
       
  4532           dtd->contentStringLen = 0;
       
  4533         }
       
  4534       }
       
  4535       break;
       
  4536       /* End element declaration stuff */
       
  4537 
       
  4538     case XML_ROLE_PI:
       
  4539       if (!reportProcessingInstruction(parser, enc, s, next))
       
  4540         return XML_ERROR_NO_MEMORY;
       
  4541       handleDefault = XML_FALSE;
       
  4542       break;
       
  4543     case XML_ROLE_COMMENT:
       
  4544       if (!reportComment(parser, enc, s, next))
       
  4545         return XML_ERROR_NO_MEMORY;
       
  4546       handleDefault = XML_FALSE;
       
  4547       break;
       
  4548     case XML_ROLE_NONE:
       
  4549       switch (tok) {
       
  4550       case XML_TOK_BOM:
       
  4551         handleDefault = XML_FALSE;
       
  4552         break;
       
  4553       }
       
  4554       break;
       
  4555     case XML_ROLE_DOCTYPE_NONE:
       
  4556       if (startDoctypeDeclHandler)
       
  4557         handleDefault = XML_FALSE;
       
  4558       break;
       
  4559     case XML_ROLE_ENTITY_NONE:
       
  4560       if (dtd->keepProcessing && entityDeclHandler)
       
  4561         handleDefault = XML_FALSE;
       
  4562       break;
       
  4563     case XML_ROLE_NOTATION_NONE:
       
  4564       if (notationDeclHandler)
       
  4565         handleDefault = XML_FALSE;
       
  4566       break;
       
  4567     case XML_ROLE_ATTLIST_NONE:
       
  4568       if (dtd->keepProcessing && attlistDeclHandler)
       
  4569         handleDefault = XML_FALSE;
       
  4570       break;
       
  4571     case XML_ROLE_ELEMENT_NONE:
       
  4572       if (elementDeclHandler)
       
  4573         handleDefault = XML_FALSE;
       
  4574       break;
       
  4575     } /* end of big switch */
       
  4576 
       
  4577     if (handleDefault && defaultHandler)
       
  4578       reportDefault(parser, enc, s, next);
       
  4579 
       
  4580     switch (ps_parsing) {
       
  4581     case XML_SUSPENDED: 
       
  4582       *nextPtr = next;
       
  4583       return XML_ERROR_NONE;
       
  4584     case XML_FINISHED:
       
  4585       return XML_ERROR_ABORTED;
       
  4586     default:
       
  4587       s = next;
       
  4588       tok = XmlPrologTok(enc, s, end, &next);
       
  4589     }
       
  4590   }
       
  4591   /* not reached */
       
  4592 }
       
  4593 
       
  4594 static enum XML_Error PTRCALL
       
  4595 epilogProcessor(XML_Parser parser,
       
  4596                 const char *s,
       
  4597                 const char *end,
       
  4598                 const char **nextPtr)
       
  4599 {
       
  4600   processor = epilogProcessor;
       
  4601   eventPtr = s;
       
  4602   for (;;) {
       
  4603     const char *next = NULL;
       
  4604     int tok = XmlPrologTok(encoding, s, end, &next);
       
  4605     eventEndPtr = next;
       
  4606     switch (tok) {
       
  4607     /* report partial linebreak - it might be the last token */
       
  4608     case -XML_TOK_PROLOG_S:
       
  4609       if (defaultHandler) {
       
  4610         reportDefault(parser, encoding, s, next);
       
  4611         if (ps_parsing == XML_FINISHED)
       
  4612           return XML_ERROR_ABORTED;
       
  4613       }
       
  4614       *nextPtr = next;
       
  4615       return XML_ERROR_NONE;
       
  4616     case XML_TOK_NONE:
       
  4617       *nextPtr = s;
       
  4618       return XML_ERROR_NONE;
       
  4619     case XML_TOK_PROLOG_S:
       
  4620       if (defaultHandler)
       
  4621         reportDefault(parser, encoding, s, next);
       
  4622       break;
       
  4623     case XML_TOK_PI:
       
  4624       if (!reportProcessingInstruction(parser, encoding, s, next))
       
  4625         return XML_ERROR_NO_MEMORY;
       
  4626       break;
       
  4627     case XML_TOK_COMMENT:
       
  4628       if (!reportComment(parser, encoding, s, next))
       
  4629         return XML_ERROR_NO_MEMORY;
       
  4630       break;
       
  4631     case XML_TOK_INVALID:
       
  4632       eventPtr = next;
       
  4633       return XML_ERROR_INVALID_TOKEN;
       
  4634     case XML_TOK_PARTIAL:
       
  4635       if (!ps_finalBuffer) {
       
  4636         *nextPtr = s;
       
  4637         return XML_ERROR_NONE;
       
  4638       }
       
  4639       return XML_ERROR_UNCLOSED_TOKEN;
       
  4640     case XML_TOK_PARTIAL_CHAR:
       
  4641       if (!ps_finalBuffer) {
       
  4642         *nextPtr = s;
       
  4643         return XML_ERROR_NONE;
       
  4644       }
       
  4645       return XML_ERROR_PARTIAL_CHAR;
       
  4646     default:
       
  4647       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
       
  4648     }
       
  4649     eventPtr = s = next;
       
  4650     switch (ps_parsing) {
       
  4651     case XML_SUSPENDED: 
       
  4652       *nextPtr = next;
       
  4653       return XML_ERROR_NONE;
       
  4654     case XML_FINISHED:
       
  4655       return XML_ERROR_ABORTED;
       
  4656     default: ;
       
  4657     }
       
  4658   }
       
  4659 }
       
  4660 
       
  4661 static enum XML_Error
       
  4662 processInternalEntity(XML_Parser parser, ENTITY *entity,
       
  4663                       XML_Bool betweenDecl)
       
  4664 {
       
  4665   const char *textStart, *textEnd;
       
  4666   const char *next;
       
  4667   enum XML_Error result;
       
  4668   OPEN_INTERNAL_ENTITY *openEntity;
       
  4669 
       
  4670   if (freeInternalEntities) {
       
  4671     openEntity = freeInternalEntities;
       
  4672     freeInternalEntities = openEntity->next;
       
  4673   }
       
  4674   else {
       
  4675     openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
       
  4676     if (!openEntity)
       
  4677       return XML_ERROR_NO_MEMORY;
       
  4678   }
       
  4679   entity->open = XML_TRUE;
       
  4680   entity->processed = 0;
       
  4681   openEntity->next = openInternalEntities;
       
  4682   openInternalEntities = openEntity;
       
  4683   openEntity->entity = entity;
       
  4684   openEntity->startTagLevel = tagLevel;
       
  4685   openEntity->betweenDecl = betweenDecl;
       
  4686   openEntity->internalEventPtr = NULL;
       
  4687   openEntity->internalEventEndPtr = NULL;
       
  4688   textStart = (char *)entity->textPtr;
       
  4689   textEnd = (char *)(entity->textPtr + entity->textLen);
       
  4690 
       
  4691 #ifdef XML_DTD
       
  4692   if (entity->is_param) {
       
  4693     int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
       
  4694     result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
       
  4695                       next, &next, XML_FALSE);
       
  4696   }
       
  4697   else 
       
  4698 #endif /* XML_DTD */
       
  4699     result = doContent(parser, tagLevel, internalEncoding, textStart, 
       
  4700                        textEnd, &next, XML_FALSE);
       
  4701 
       
  4702   if (result == XML_ERROR_NONE) {
       
  4703     if (textEnd != next && ps_parsing == XML_SUSPENDED) {
       
  4704       entity->processed = (int)(next - textStart);
       
  4705       processor = internalEntityProcessor;
       
  4706     }
       
  4707     else {
       
  4708       entity->open = XML_FALSE;
       
  4709       openInternalEntities = openEntity->next;
       
  4710       /* put openEntity back in list of free instances */
       
  4711       openEntity->next = freeInternalEntities;
       
  4712       freeInternalEntities = openEntity;
       
  4713     }
       
  4714   }
       
  4715   return result;
       
  4716 }
       
  4717 
       
  4718 static enum XML_Error PTRCALL
       
  4719 internalEntityProcessor(XML_Parser parser,
       
  4720                         const char *s,
       
  4721                         const char *end,
       
  4722                         const char **nextPtr)
       
  4723 {
       
  4724   ENTITY *entity;
       
  4725   const char *textStart, *textEnd;
       
  4726   const char *next;
       
  4727   enum XML_Error result;
       
  4728   OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
       
  4729   if (!openEntity)
       
  4730     return XML_ERROR_UNEXPECTED_STATE;
       
  4731 
       
  4732   entity = openEntity->entity;
       
  4733   textStart = ((char *)entity->textPtr) + entity->processed;
       
  4734   textEnd = (char *)(entity->textPtr + entity->textLen);
       
  4735 
       
  4736 #ifdef XML_DTD
       
  4737   if (entity->is_param) {
       
  4738     int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
       
  4739     result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
       
  4740                       next, &next, XML_FALSE);
       
  4741   }
       
  4742   else
       
  4743 #endif /* XML_DTD */
       
  4744     result = doContent(parser, openEntity->startTagLevel, internalEncoding, 
       
  4745                        textStart, textEnd, &next, XML_FALSE);  
       
  4746 
       
  4747   if (result != XML_ERROR_NONE)
       
  4748     return result;
       
  4749   else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
       
  4750     entity->processed = (int)(next - (char *)entity->textPtr);
       
  4751     return result;
       
  4752   }
       
  4753   else {
       
  4754     entity->open = XML_FALSE;
       
  4755     openInternalEntities = openEntity->next;
       
  4756     /* put openEntity back in list of free instances */
       
  4757     openEntity->next = freeInternalEntities;
       
  4758     freeInternalEntities = openEntity;
       
  4759   }
       
  4760 
       
  4761 #ifdef XML_DTD
       
  4762   if (entity->is_param) {
       
  4763     int tok;
       
  4764     processor = prologProcessor;
       
  4765     tok = XmlPrologTok(encoding, s, end, &next);
       
  4766     return doProlog(parser, encoding, s, end, tok, next, nextPtr, 
       
  4767                     (XML_Bool)!ps_finalBuffer);
       
  4768   }
       
  4769   else
       
  4770 #endif /* XML_DTD */
       
  4771   {
       
  4772     processor = contentProcessor;
       
  4773     /* see externalEntityContentProcessor vs contentProcessor */
       
  4774     return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
       
  4775                      nextPtr, (XML_Bool)!ps_finalBuffer); 
       
  4776   }  
       
  4777 }
       
  4778 
       
  4779 static enum XML_Error PTRCALL
       
  4780 errorProcessor(XML_Parser parser,
       
  4781                const char *s,
       
  4782                const char *end,
       
  4783                const char **nextPtr)
       
  4784 {
       
  4785   return errorCode;
       
  4786 }
       
  4787 
       
  4788 static enum XML_Error
       
  4789 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
       
  4790                     const char *ptr, const char *end,
       
  4791                     STRING_POOL *pool)
       
  4792 {
       
  4793   enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
       
  4794                                                end, pool);
       
  4795   if (result)
       
  4796     return result;
       
  4797   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
       
  4798     poolChop(pool);
       
  4799   if (!poolAppendChar(pool, XML_T('\0')))
       
  4800     return XML_ERROR_NO_MEMORY;
       
  4801   return XML_ERROR_NONE;
       
  4802 }
       
  4803 
       
  4804 static enum XML_Error
       
  4805 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
       
  4806                      const char *ptr, const char *end,
       
  4807                      STRING_POOL *pool)
       
  4808 {
       
  4809   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  4810   for (;;) {
       
  4811     const char *next;
       
  4812     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
       
  4813     switch (tok) {
       
  4814     case XML_TOK_NONE:
       
  4815       return XML_ERROR_NONE;
       
  4816     case XML_TOK_INVALID:
       
  4817       if (enc == encoding)
       
  4818         eventPtr = next;
       
  4819       return XML_ERROR_INVALID_TOKEN;
       
  4820     case XML_TOK_PARTIAL:
       
  4821       if (enc == encoding)
       
  4822         eventPtr = ptr;
       
  4823       return XML_ERROR_INVALID_TOKEN;
       
  4824     case XML_TOK_CHAR_REF:
       
  4825       {
       
  4826         XML_Char buf[XML_ENCODE_MAX];
       
  4827         int i;
       
  4828         int n = XmlCharRefNumber(enc, ptr);
       
  4829         if (n < 0) {
       
  4830           if (enc == encoding)
       
  4831             eventPtr = ptr;
       
  4832           return XML_ERROR_BAD_CHAR_REF;
       
  4833         }
       
  4834         if (!isCdata
       
  4835             && n == 0x20 /* space */
       
  4836             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
       
  4837           break;
       
  4838         n = XmlEncode(n, (ICHAR *)buf);
       
  4839         if (!n) {
       
  4840           if (enc == encoding)
       
  4841             eventPtr = ptr;
       
  4842           return XML_ERROR_BAD_CHAR_REF;
       
  4843         }
       
  4844         for (i = 0; i < n; i++) {
       
  4845           if (!poolAppendChar(pool, buf[i]))
       
  4846             return XML_ERROR_NO_MEMORY;
       
  4847         }
       
  4848       }
       
  4849       break;
       
  4850     case XML_TOK_DATA_CHARS:
       
  4851       if (!poolAppend(pool, enc, ptr, next))
       
  4852         return XML_ERROR_NO_MEMORY;
       
  4853       break;
       
  4854     case XML_TOK_TRAILING_CR:
       
  4855       next = ptr + enc->minBytesPerChar;
       
  4856       /* fall through */
       
  4857     case XML_TOK_ATTRIBUTE_VALUE_S:
       
  4858     case XML_TOK_DATA_NEWLINE:
       
  4859       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
       
  4860         break;
       
  4861       if (!poolAppendChar(pool, 0x20))
       
  4862         return XML_ERROR_NO_MEMORY;
       
  4863       break;
       
  4864     case XML_TOK_ENTITY_REF:
       
  4865       {
       
  4866         const XML_Char *name;
       
  4867         ENTITY *entity;
       
  4868         char checkEntityDecl;
       
  4869         XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
       
  4870                                               ptr + enc->minBytesPerChar,
       
  4871                                               next - enc->minBytesPerChar);
       
  4872         if (ch) {
       
  4873           if (!poolAppendChar(pool, ch))
       
  4874                 return XML_ERROR_NO_MEMORY;
       
  4875           break;
       
  4876         }
       
  4877         name = poolStoreString(&temp2Pool, enc,
       
  4878                                ptr + enc->minBytesPerChar,
       
  4879                                next - enc->minBytesPerChar);
       
  4880         if (!name)
       
  4881           return XML_ERROR_NO_MEMORY;
       
  4882         entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
       
  4883         poolDiscard(&temp2Pool);
       
  4884         /* First, determine if a check for an existing declaration is needed;
       
  4885            if yes, check that the entity exists, and that it is internal.
       
  4886         */
       
  4887         if (pool == &dtd->pool)  /* are we called from prolog? */
       
  4888           checkEntityDecl =
       
  4889 #ifdef XML_DTD
       
  4890               prologState.documentEntity &&
       
  4891 #endif /* XML_DTD */
       
  4892               (dtd->standalone
       
  4893                ? !openInternalEntities
       
  4894                : !dtd->hasParamEntityRefs);
       
  4895         else /* if (pool == &tempPool): we are called from content */
       
  4896           checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
       
  4897         if (checkEntityDecl) {
       
  4898           if (!entity)
       
  4899             return XML_ERROR_UNDEFINED_ENTITY;
       
  4900           else if (!entity->is_internal)
       
  4901             return XML_ERROR_ENTITY_DECLARED_IN_PE;
       
  4902         }
       
  4903         else if (!entity) {
       
  4904           /* Cannot report skipped entity here - see comments on
       
  4905              skippedEntityHandler.
       
  4906           if (skippedEntityHandler)
       
  4907             skippedEntityHandler(handlerArg, name, 0);
       
  4908           */
       
  4909           /* Cannot call the default handler because this would be
       
  4910              out of sync with the call to the startElementHandler.
       
  4911           if ((pool == &tempPool) && defaultHandler)
       
  4912             reportDefault(parser, enc, ptr, next);
       
  4913           */
       
  4914           break;
       
  4915         }
       
  4916         if (entity->open) {
       
  4917           if (enc == encoding)
       
  4918             eventPtr = ptr;
       
  4919           return XML_ERROR_RECURSIVE_ENTITY_REF;
       
  4920         }
       
  4921         if (entity->notation) {
       
  4922           if (enc == encoding)
       
  4923             eventPtr = ptr;
       
  4924           return XML_ERROR_BINARY_ENTITY_REF;
       
  4925         }
       
  4926         if (!entity->textPtr) {
       
  4927           if (enc == encoding)
       
  4928             eventPtr = ptr;
       
  4929               return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
       
  4930         }
       
  4931         else {
       
  4932           enum XML_Error result;
       
  4933           const XML_Char *textEnd = entity->textPtr + entity->textLen;
       
  4934           entity->open = XML_TRUE;
       
  4935           result = appendAttributeValue(parser, internalEncoding, isCdata,
       
  4936                                         (char *)entity->textPtr,
       
  4937                                         (char *)textEnd, pool);
       
  4938           entity->open = XML_FALSE;
       
  4939           if (result)
       
  4940             return result;
       
  4941         }
       
  4942       }
       
  4943       break;
       
  4944     default:
       
  4945       if (enc == encoding)
       
  4946         eventPtr = ptr;
       
  4947       return XML_ERROR_UNEXPECTED_STATE;
       
  4948     }
       
  4949     ptr = next;
       
  4950   }
       
  4951   /* not reached */
       
  4952 }
       
  4953 
       
  4954 static enum XML_Error
       
  4955 storeEntityValue(XML_Parser parser,
       
  4956                  const ENCODING *enc,
       
  4957                  const char *entityTextPtr,
       
  4958                  const char *entityTextEnd)
       
  4959 {
       
  4960   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  4961   STRING_POOL *pool = &(dtd->entityValuePool);
       
  4962   enum XML_Error result = XML_ERROR_NONE;
       
  4963 #ifdef XML_DTD
       
  4964   int oldInEntityValue = prologState.inEntityValue;
       
  4965   prologState.inEntityValue = 1;
       
  4966 #endif /* XML_DTD */
       
  4967   /* never return Null for the value argument in EntityDeclHandler,
       
  4968      since this would indicate an external entity; therefore we
       
  4969      have to make sure that entityValuePool.start is not null */
       
  4970   if (!pool->blocks) {
       
  4971     if (!poolGrow(pool))
       
  4972       return XML_ERROR_NO_MEMORY;
       
  4973   }
       
  4974 
       
  4975   for (;;) {
       
  4976     const char *next;
       
  4977     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
       
  4978     switch (tok) {
       
  4979     case XML_TOK_PARAM_ENTITY_REF:
       
  4980 #ifdef XML_DTD
       
  4981       if (isParamEntity || enc != encoding) {
       
  4982         const XML_Char *name;
       
  4983         ENTITY *entity;
       
  4984         name = poolStoreString(&tempPool, enc,
       
  4985                                entityTextPtr + enc->minBytesPerChar,
       
  4986                                next - enc->minBytesPerChar);
       
  4987         if (!name) {
       
  4988           result = XML_ERROR_NO_MEMORY;
       
  4989           goto endEntityValue;
       
  4990         }
       
  4991         entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
       
  4992         poolDiscard(&tempPool);
       
  4993         if (!entity) {
       
  4994           /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
       
  4995           /* cannot report skipped entity here - see comments on
       
  4996              skippedEntityHandler
       
  4997           if (skippedEntityHandler)
       
  4998             skippedEntityHandler(handlerArg, name, 0);
       
  4999           */
       
  5000           dtd->keepProcessing = dtd->standalone;
       
  5001           goto endEntityValue;
       
  5002         }
       
  5003         if (entity->open) {
       
  5004           if (enc == encoding)
       
  5005             eventPtr = entityTextPtr;
       
  5006           result = XML_ERROR_RECURSIVE_ENTITY_REF;
       
  5007           goto endEntityValue;
       
  5008         }
       
  5009         if (entity->systemId) {
       
  5010           if (externalEntityRefHandler) {
       
  5011             dtd->paramEntityRead = XML_FALSE;
       
  5012             entity->open = XML_TRUE;
       
  5013             if (!externalEntityRefHandler(externalEntityRefHandlerArg,
       
  5014                                           0,
       
  5015                                           entity->base,
       
  5016                                           entity->systemId,
       
  5017                                           entity->publicId)) {
       
  5018               entity->open = XML_FALSE;
       
  5019               result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
       
  5020               goto endEntityValue;
       
  5021             }
       
  5022             entity->open = XML_FALSE;
       
  5023             if (!dtd->paramEntityRead)
       
  5024               dtd->keepProcessing = dtd->standalone;
       
  5025           }
       
  5026           else
       
  5027             dtd->keepProcessing = dtd->standalone;
       
  5028         }
       
  5029         else {
       
  5030           entity->open = XML_TRUE;
       
  5031           result = storeEntityValue(parser,
       
  5032                                     internalEncoding,
       
  5033                                     (char *)entity->textPtr,
       
  5034                                     (char *)(entity->textPtr
       
  5035                                              + entity->textLen));
       
  5036           entity->open = XML_FALSE;
       
  5037           if (result)
       
  5038             goto endEntityValue;
       
  5039         }
       
  5040         break;
       
  5041       }
       
  5042 #endif /* XML_DTD */
       
  5043       /* In the internal subset, PE references are not legal
       
  5044          within markup declarations, e.g entity values in this case. */
       
  5045       eventPtr = entityTextPtr;
       
  5046       result = XML_ERROR_PARAM_ENTITY_REF;
       
  5047       goto endEntityValue;
       
  5048     case XML_TOK_NONE:
       
  5049       result = XML_ERROR_NONE;
       
  5050       goto endEntityValue;
       
  5051     case XML_TOK_ENTITY_REF:
       
  5052     case XML_TOK_DATA_CHARS:
       
  5053       if (!poolAppend(pool, enc, entityTextPtr, next)) {
       
  5054         result = XML_ERROR_NO_MEMORY;
       
  5055         goto endEntityValue;
       
  5056       }
       
  5057       break;
       
  5058     case XML_TOK_TRAILING_CR:
       
  5059       next = entityTextPtr + enc->minBytesPerChar;
       
  5060       /* fall through */
       
  5061     case XML_TOK_DATA_NEWLINE:
       
  5062       if (pool->end == pool->ptr && !poolGrow(pool)) {
       
  5063               result = XML_ERROR_NO_MEMORY;
       
  5064         goto endEntityValue;
       
  5065       }
       
  5066       *(pool->ptr)++ = 0xA;
       
  5067       break;
       
  5068     case XML_TOK_CHAR_REF:
       
  5069       {
       
  5070         XML_Char buf[XML_ENCODE_MAX];
       
  5071         int i;
       
  5072         int n = XmlCharRefNumber(enc, entityTextPtr);
       
  5073         if (n < 0) {
       
  5074           if (enc == encoding)
       
  5075             eventPtr = entityTextPtr;
       
  5076           result = XML_ERROR_BAD_CHAR_REF;
       
  5077           goto endEntityValue;
       
  5078         }
       
  5079         n = XmlEncode(n, (ICHAR *)buf);
       
  5080         if (!n) {
       
  5081           if (enc == encoding)
       
  5082             eventPtr = entityTextPtr;
       
  5083           result = XML_ERROR_BAD_CHAR_REF;
       
  5084           goto endEntityValue;
       
  5085         }
       
  5086         for (i = 0; i < n; i++) {
       
  5087           if (pool->end == pool->ptr && !poolGrow(pool)) {
       
  5088             result = XML_ERROR_NO_MEMORY;
       
  5089             goto endEntityValue;
       
  5090           }
       
  5091           *(pool->ptr)++ = buf[i];
       
  5092         }
       
  5093       }
       
  5094       break;
       
  5095     case XML_TOK_PARTIAL:
       
  5096       if (enc == encoding)
       
  5097         eventPtr = entityTextPtr;
       
  5098       result = XML_ERROR_INVALID_TOKEN;
       
  5099       goto endEntityValue;
       
  5100     case XML_TOK_INVALID:
       
  5101       if (enc == encoding)
       
  5102         eventPtr = next;
       
  5103       result = XML_ERROR_INVALID_TOKEN;
       
  5104       goto endEntityValue;
       
  5105     default:
       
  5106       if (enc == encoding)
       
  5107         eventPtr = entityTextPtr;
       
  5108       result = XML_ERROR_UNEXPECTED_STATE;
       
  5109       goto endEntityValue;
       
  5110     }
       
  5111     entityTextPtr = next;
       
  5112   }
       
  5113 endEntityValue:
       
  5114 #ifdef XML_DTD
       
  5115   prologState.inEntityValue = oldInEntityValue;
       
  5116 #endif /* XML_DTD */
       
  5117   return result;
       
  5118 }
       
  5119 
       
  5120 static void FASTCALL
       
  5121 normalizeLines(XML_Char *s)
       
  5122 {
       
  5123   XML_Char *p;
       
  5124   for (;; s++) {
       
  5125     if (*s == XML_T('\0'))
       
  5126       return;
       
  5127     if (*s == 0xD)
       
  5128       break;
       
  5129   }
       
  5130   p = s;
       
  5131   do {
       
  5132     if (*s == 0xD) {
       
  5133       *p++ = 0xA;
       
  5134       if (*++s == 0xA)
       
  5135         s++;
       
  5136     }
       
  5137     else
       
  5138       *p++ = *s++;
       
  5139   } while (*s);
       
  5140   *p = XML_T('\0');
       
  5141 }
       
  5142 
       
  5143 static int
       
  5144 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
       
  5145                             const char *start, const char *end)
       
  5146 {
       
  5147   const XML_Char *target;
       
  5148   XML_Char *data;
       
  5149   const char *tem;
       
  5150   if (!processingInstructionHandler) {
       
  5151     if (defaultHandler)
       
  5152       reportDefault(parser, enc, start, end);
       
  5153     return 1;
       
  5154   }
       
  5155   start += enc->minBytesPerChar * 2;
       
  5156   tem = start + XmlNameLength(enc, start);
       
  5157   target = poolStoreString(&tempPool, enc, start, tem);
       
  5158   if (!target)
       
  5159     return 0;
       
  5160   poolFinish(&tempPool);
       
  5161   data = poolStoreString(&tempPool, enc,
       
  5162                         XmlSkipS(enc, tem),
       
  5163                         end - enc->minBytesPerChar*2);
       
  5164   if (!data)
       
  5165     return 0;
       
  5166   normalizeLines(data);
       
  5167   processingInstructionHandler(handlerArg, target, data);
       
  5168   poolClear(&tempPool);
       
  5169   return 1;
       
  5170 }
       
  5171 
       
  5172 static int
       
  5173 reportComment(XML_Parser parser, const ENCODING *enc,
       
  5174               const char *start, const char *end)
       
  5175 {
       
  5176   XML_Char *data;
       
  5177   if (!commentHandler) {
       
  5178     if (defaultHandler)
       
  5179       reportDefault(parser, enc, start, end);
       
  5180     return 1;
       
  5181   }
       
  5182   data = poolStoreString(&tempPool,
       
  5183                          enc,
       
  5184                          start + enc->minBytesPerChar * 4,
       
  5185                          end - enc->minBytesPerChar * 3);
       
  5186   if (!data)
       
  5187     return 0;
       
  5188   normalizeLines(data);
       
  5189   commentHandler(handlerArg, data);
       
  5190   poolClear(&tempPool);
       
  5191   return 1;
       
  5192 }
       
  5193 
       
  5194 static void
       
  5195 reportDefault(XML_Parser parser, const ENCODING *enc,
       
  5196               const char *s, const char *end)
       
  5197 {
       
  5198   if (MUST_CONVERT(enc, s)) {
       
  5199     const char **eventPP;
       
  5200     const char **eventEndPP;
       
  5201     if (enc == encoding) {
       
  5202       eventPP = &eventPtr;
       
  5203       eventEndPP = &eventEndPtr;
       
  5204     }
       
  5205     else {
       
  5206       eventPP = &(openInternalEntities->internalEventPtr);
       
  5207       eventEndPP = &(openInternalEntities->internalEventEndPtr);
       
  5208     }
       
  5209     do {
       
  5210       ICHAR *dataPtr = (ICHAR *)dataBuf;
       
  5211       XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
       
  5212       *eventEndPP = s;
       
  5213       defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
       
  5214       *eventPP = s;
       
  5215     } while (s != end);
       
  5216   }
       
  5217   else
       
  5218     defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
       
  5219 }
       
  5220 
       
  5221 
       
  5222 static int
       
  5223 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
       
  5224                 XML_Bool isId, const XML_Char *value, XML_Parser parser)
       
  5225 {
       
  5226   DEFAULT_ATTRIBUTE *att;
       
  5227   if (value || isId) {
       
  5228     /* The handling of default attributes gets messed up if we have
       
  5229        a default which duplicates a non-default. */
       
  5230     int i;
       
  5231     for (i = 0; i < type->nDefaultAtts; i++)
       
  5232       if (attId == type->defaultAtts[i].id)
       
  5233         return 1;
       
  5234     if (isId && !type->idAtt && !attId->xmlns)
       
  5235       type->idAtt = attId;
       
  5236   }
       
  5237   if (type->nDefaultAtts == type->allocDefaultAtts) {
       
  5238     if (type->allocDefaultAtts == 0) {
       
  5239       type->allocDefaultAtts = 8;
       
  5240       type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
       
  5241                             * sizeof(DEFAULT_ATTRIBUTE));
       
  5242       if (!type->defaultAtts)
       
  5243         return 0;
       
  5244     }
       
  5245     else {
       
  5246       DEFAULT_ATTRIBUTE *temp;
       
  5247       int count = type->allocDefaultAtts * 2;
       
  5248       temp = (DEFAULT_ATTRIBUTE *)
       
  5249         REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
       
  5250       if (temp == NULL)
       
  5251         return 0;
       
  5252       type->allocDefaultAtts = count;
       
  5253       type->defaultAtts = temp;
       
  5254     }
       
  5255   }
       
  5256   att = type->defaultAtts + type->nDefaultAtts;
       
  5257   att->id = attId;
       
  5258   att->value = value;
       
  5259   att->isCdata = isCdata;
       
  5260   if (!isCdata)
       
  5261     attId->maybeTokenized = XML_TRUE;
       
  5262   type->nDefaultAtts += 1;
       
  5263   return 1;
       
  5264 }
       
  5265 
       
  5266 static int
       
  5267 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
       
  5268 {
       
  5269   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  5270   const XML_Char *name;
       
  5271   for (name = elementType->name; *name; name++) {
       
  5272     if (*name == XML_T(':')) {
       
  5273       PREFIX *prefix;
       
  5274       const XML_Char *s;
       
  5275       for (s = elementType->name; s != name; s++) {
       
  5276         if (!poolAppendChar(&dtd->pool, *s))
       
  5277           return 0;
       
  5278       }
       
  5279       if (!poolAppendChar(&dtd->pool, XML_T('\0')))
       
  5280         return 0;
       
  5281       prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
       
  5282                                 sizeof(PREFIX));
       
  5283       if (!prefix)
       
  5284         return 0;
       
  5285       if (prefix->name == poolStart(&dtd->pool))
       
  5286         poolFinish(&dtd->pool);
       
  5287       else
       
  5288         poolDiscard(&dtd->pool);
       
  5289       elementType->prefix = prefix;
       
  5290 
       
  5291     }
       
  5292   }
       
  5293   return 1;
       
  5294 }
       
  5295 
       
  5296 static ATTRIBUTE_ID *
       
  5297 getAttributeId(XML_Parser parser, const ENCODING *enc,
       
  5298                const char *start, const char *end)
       
  5299 {
       
  5300   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  5301   ATTRIBUTE_ID *id;
       
  5302   const XML_Char *name;
       
  5303   if (!poolAppendChar(&dtd->pool, XML_T('\0')))
       
  5304     return NULL;
       
  5305   name = poolStoreString(&dtd->pool, enc, start, end);
       
  5306   if (!name)
       
  5307     return NULL;
       
  5308   /* skip quotation mark - its storage will be re-used (like in name[-1]) */
       
  5309   ++name;
       
  5310   id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
       
  5311   if (!id)
       
  5312     return NULL;
       
  5313   if (id->name != name)
       
  5314     poolDiscard(&dtd->pool);
       
  5315   else {
       
  5316     poolFinish(&dtd->pool);
       
  5317     if (!ns)
       
  5318       ;
       
  5319     else if (name[0] == XML_T('x')
       
  5320         && name[1] == XML_T('m')
       
  5321         && name[2] == XML_T('l')
       
  5322         && name[3] == XML_T('n')
       
  5323         && name[4] == XML_T('s')
       
  5324         && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
       
  5325       if (name[5] == XML_T('\0'))
       
  5326         id->prefix = &dtd->defaultPrefix;
       
  5327       else
       
  5328         id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
       
  5329       id->xmlns = XML_TRUE;
       
  5330     }
       
  5331     else {
       
  5332       int i;
       
  5333       for (i = 0; name[i]; i++) {
       
  5334         /* attributes without prefix are *not* in the default namespace */
       
  5335         if (name[i] == XML_T(':')) {
       
  5336           int j;
       
  5337           for (j = 0; j < i; j++) {
       
  5338             if (!poolAppendChar(&dtd->pool, name[j]))
       
  5339               return NULL;
       
  5340           }
       
  5341           if (!poolAppendChar(&dtd->pool, XML_T('\0')))
       
  5342             return NULL;
       
  5343           id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
       
  5344                                         sizeof(PREFIX));
       
  5345           if (!id->prefix)
       
  5346             return NULL;
       
  5347           if (id->prefix->name == poolStart(&dtd->pool))
       
  5348             poolFinish(&dtd->pool);
       
  5349           else
       
  5350             poolDiscard(&dtd->pool);
       
  5351           break;
       
  5352         }
       
  5353       }
       
  5354     }
       
  5355   }
       
  5356   return id;
       
  5357 }
       
  5358 
       
  5359 #define CONTEXT_SEP XML_T('\f')
       
  5360 
       
  5361 static const XML_Char *
       
  5362 getContext(XML_Parser parser)
       
  5363 {
       
  5364   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  5365   HASH_TABLE_ITER iter;
       
  5366   XML_Bool needSep = XML_FALSE;
       
  5367 
       
  5368   if (dtd->defaultPrefix.binding) {
       
  5369     int i;
       
  5370     int len;
       
  5371     if (!poolAppendChar(&tempPool, XML_T('=')))
       
  5372       return NULL;
       
  5373     len = dtd->defaultPrefix.binding->uriLen;
       
  5374     if (namespaceSeparator)
       
  5375       len--;
       
  5376     for (i = 0; i < len; i++)
       
  5377       if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
       
  5378         return NULL;
       
  5379     needSep = XML_TRUE;
       
  5380   }
       
  5381 
       
  5382   hashTableIterInit(&iter, &(dtd->prefixes));
       
  5383   for (;;) {
       
  5384     int i;
       
  5385     int len;
       
  5386     const XML_Char *s;
       
  5387     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
       
  5388     if (!prefix)
       
  5389       break;
       
  5390     if (!prefix->binding)
       
  5391       continue;
       
  5392     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
       
  5393       return NULL;
       
  5394     for (s = prefix->name; *s; s++)
       
  5395       if (!poolAppendChar(&tempPool, *s))
       
  5396         return NULL;
       
  5397     if (!poolAppendChar(&tempPool, XML_T('=')))
       
  5398       return NULL;
       
  5399     len = prefix->binding->uriLen;
       
  5400     if (namespaceSeparator)
       
  5401       len--;
       
  5402     for (i = 0; i < len; i++)
       
  5403       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
       
  5404         return NULL;
       
  5405     needSep = XML_TRUE;
       
  5406   }
       
  5407 
       
  5408 
       
  5409   hashTableIterInit(&iter, &(dtd->generalEntities));
       
  5410   for (;;) {
       
  5411     const XML_Char *s;
       
  5412     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
       
  5413     if (!e)
       
  5414       break;
       
  5415     if (!e->open)
       
  5416       continue;
       
  5417     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
       
  5418       return NULL;
       
  5419     for (s = e->name; *s; s++)
       
  5420       if (!poolAppendChar(&tempPool, *s))
       
  5421         return 0;
       
  5422     needSep = XML_TRUE;
       
  5423   }
       
  5424 
       
  5425   if (!poolAppendChar(&tempPool, XML_T('\0')))
       
  5426     return NULL;
       
  5427   return tempPool.start;
       
  5428 }
       
  5429 
       
  5430 static XML_Bool
       
  5431 setContext(XML_Parser parser, const XML_Char *context)
       
  5432 {
       
  5433   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  5434   const XML_Char *s = context;
       
  5435 
       
  5436   while (*context != XML_T('\0')) {
       
  5437     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
       
  5438       ENTITY *e;
       
  5439       if (!poolAppendChar(&tempPool, XML_T('\0')))
       
  5440         return XML_FALSE;
       
  5441       e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
       
  5442       if (e)
       
  5443         e->open = XML_TRUE;
       
  5444       if (*s != XML_T('\0'))
       
  5445         s++;
       
  5446       context = s;
       
  5447       poolDiscard(&tempPool);
       
  5448     }
       
  5449     else if (*s == XML_T('=')) {
       
  5450       PREFIX *prefix;
       
  5451       if (poolLength(&tempPool) == 0)
       
  5452         prefix = &dtd->defaultPrefix;
       
  5453       else {
       
  5454         if (!poolAppendChar(&tempPool, XML_T('\0')))
       
  5455           return XML_FALSE;
       
  5456         prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
       
  5457                                   sizeof(PREFIX));
       
  5458         if (!prefix)
       
  5459           return XML_FALSE;
       
  5460         if (prefix->name == poolStart(&tempPool)) {
       
  5461           prefix->name = poolCopyString(&dtd->pool, prefix->name);
       
  5462           if (!prefix->name)
       
  5463             return XML_FALSE;
       
  5464         }
       
  5465         poolDiscard(&tempPool);
       
  5466       }
       
  5467       for (context = s + 1;
       
  5468            *context != CONTEXT_SEP && *context != XML_T('\0');
       
  5469            context++)
       
  5470         if (!poolAppendChar(&tempPool, *context))
       
  5471           return XML_FALSE;
       
  5472       if (!poolAppendChar(&tempPool, XML_T('\0')))
       
  5473         return XML_FALSE;
       
  5474       if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
       
  5475                      &inheritedBindings) != XML_ERROR_NONE)
       
  5476         return XML_FALSE;
       
  5477       poolDiscard(&tempPool);
       
  5478       if (*context != XML_T('\0'))
       
  5479         ++context;
       
  5480       s = context;
       
  5481     }
       
  5482     else {
       
  5483       if (!poolAppendChar(&tempPool, *s))
       
  5484         return XML_FALSE;
       
  5485       s++;
       
  5486     }
       
  5487   }
       
  5488   return XML_TRUE;
       
  5489 }
       
  5490 
       
  5491 static void FASTCALL
       
  5492 normalizePublicId(XML_Char *publicId)
       
  5493 {
       
  5494   XML_Char *p = publicId;
       
  5495   XML_Char *s;
       
  5496   for (s = publicId; *s; s++) {
       
  5497     switch (*s) {
       
  5498     case 0x20:
       
  5499     case 0xD:
       
  5500     case 0xA:
       
  5501       if (p != publicId && p[-1] != 0x20)
       
  5502         *p++ = 0x20;
       
  5503       break;
       
  5504     default:
       
  5505       *p++ = *s;
       
  5506     }
       
  5507   }
       
  5508   if (p != publicId && p[-1] == 0x20)
       
  5509     --p;
       
  5510   *p = XML_T('\0');
       
  5511 }
       
  5512 
       
  5513 static DTD *
       
  5514 dtdCreate(const XML_Memory_Handling_Suite *ms)
       
  5515 {
       
  5516   DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
       
  5517   if (p == NULL)
       
  5518     return p;
       
  5519   poolInit(&(p->pool), ms);
       
  5520   poolInit(&(p->entityValuePool), ms);
       
  5521   hashTableInit(&(p->generalEntities), ms);
       
  5522   hashTableInit(&(p->elementTypes), ms);
       
  5523   hashTableInit(&(p->attributeIds), ms);
       
  5524   hashTableInit(&(p->prefixes), ms);
       
  5525 #ifdef XML_DTD
       
  5526   p->paramEntityRead = XML_FALSE;
       
  5527   hashTableInit(&(p->paramEntities), ms);
       
  5528 #endif /* XML_DTD */
       
  5529   p->defaultPrefix.name = NULL;
       
  5530   p->defaultPrefix.binding = NULL;
       
  5531 
       
  5532   p->in_eldecl = XML_FALSE;
       
  5533   p->scaffIndex = NULL;
       
  5534   p->scaffold = NULL;
       
  5535   p->scaffLevel = 0;
       
  5536   p->scaffSize = 0;
       
  5537   p->scaffCount = 0;
       
  5538   p->contentStringLen = 0;
       
  5539 
       
  5540   p->keepProcessing = XML_TRUE;
       
  5541   p->hasParamEntityRefs = XML_FALSE;
       
  5542   p->standalone = XML_FALSE;
       
  5543   return p;
       
  5544 }
       
  5545 
       
  5546 static void
       
  5547 dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
       
  5548 {
       
  5549   HASH_TABLE_ITER iter;
       
  5550   hashTableIterInit(&iter, &(p->elementTypes));
       
  5551   for (;;) {
       
  5552     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
       
  5553     if (!e)
       
  5554       break;
       
  5555     if (e->allocDefaultAtts != 0)
       
  5556       ms->free_fcn(e->defaultAtts);
       
  5557   }
       
  5558   hashTableClear(&(p->generalEntities));
       
  5559 #ifdef XML_DTD
       
  5560   p->paramEntityRead = XML_FALSE;
       
  5561   hashTableClear(&(p->paramEntities));
       
  5562 #endif /* XML_DTD */
       
  5563   hashTableClear(&(p->elementTypes));
       
  5564   hashTableClear(&(p->attributeIds));
       
  5565   hashTableClear(&(p->prefixes));
       
  5566   poolClear(&(p->pool));
       
  5567   poolClear(&(p->entityValuePool));
       
  5568   p->defaultPrefix.name = NULL;
       
  5569   p->defaultPrefix.binding = NULL;
       
  5570 
       
  5571   p->in_eldecl = XML_FALSE;
       
  5572 
       
  5573   ms->free_fcn(p->scaffIndex);
       
  5574   p->scaffIndex = NULL;
       
  5575   ms->free_fcn(p->scaffold);
       
  5576   p->scaffold = NULL;
       
  5577 
       
  5578   p->scaffLevel = 0;
       
  5579   p->scaffSize = 0;
       
  5580   p->scaffCount = 0;
       
  5581   p->contentStringLen = 0;
       
  5582 
       
  5583   p->keepProcessing = XML_TRUE;
       
  5584   p->hasParamEntityRefs = XML_FALSE;
       
  5585   p->standalone = XML_FALSE;
       
  5586 }
       
  5587 
       
  5588 static void
       
  5589 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
       
  5590 {
       
  5591   HASH_TABLE_ITER iter;
       
  5592   hashTableIterInit(&iter, &(p->elementTypes));
       
  5593   for (;;) {
       
  5594     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
       
  5595     if (!e)
       
  5596       break;
       
  5597     if (e->allocDefaultAtts != 0)
       
  5598       ms->free_fcn(e->defaultAtts);
       
  5599   }
       
  5600   hashTableDestroy(&(p->generalEntities));
       
  5601 #ifdef XML_DTD
       
  5602   hashTableDestroy(&(p->paramEntities));
       
  5603 #endif /* XML_DTD */
       
  5604   hashTableDestroy(&(p->elementTypes));
       
  5605   hashTableDestroy(&(p->attributeIds));
       
  5606   hashTableDestroy(&(p->prefixes));
       
  5607   poolDestroy(&(p->pool));
       
  5608   poolDestroy(&(p->entityValuePool));
       
  5609   if (isDocEntity) {
       
  5610     ms->free_fcn(p->scaffIndex);
       
  5611     ms->free_fcn(p->scaffold);
       
  5612   }
       
  5613   ms->free_fcn(p);
       
  5614 }
       
  5615 
       
  5616 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
       
  5617    The new DTD has already been initialized.
       
  5618 */
       
  5619 static int
       
  5620 dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
       
  5621 {
       
  5622   HASH_TABLE_ITER iter;
       
  5623 
       
  5624   /* Copy the prefix table. */
       
  5625 
       
  5626   hashTableIterInit(&iter, &(oldDtd->prefixes));
       
  5627   for (;;) {
       
  5628     const XML_Char *name;
       
  5629     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
       
  5630     if (!oldP)
       
  5631       break;
       
  5632     name = poolCopyString(&(newDtd->pool), oldP->name);
       
  5633     if (!name)
       
  5634       return 0;
       
  5635     if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
       
  5636       return 0;
       
  5637   }
       
  5638 
       
  5639   hashTableIterInit(&iter, &(oldDtd->attributeIds));
       
  5640 
       
  5641   /* Copy the attribute id table. */
       
  5642 
       
  5643   for (;;) {
       
  5644     ATTRIBUTE_ID *newA;
       
  5645     const XML_Char *name;
       
  5646     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
       
  5647 
       
  5648     if (!oldA)
       
  5649       break;
       
  5650     /* Remember to allocate the scratch byte before the name. */
       
  5651     if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
       
  5652       return 0;
       
  5653     name = poolCopyString(&(newDtd->pool), oldA->name);
       
  5654     if (!name)
       
  5655       return 0;
       
  5656     ++name;
       
  5657     newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
       
  5658                                   sizeof(ATTRIBUTE_ID));
       
  5659     if (!newA)
       
  5660       return 0;
       
  5661     newA->maybeTokenized = oldA->maybeTokenized;
       
  5662     if (oldA->prefix) {
       
  5663       newA->xmlns = oldA->xmlns;
       
  5664       if (oldA->prefix == &oldDtd->defaultPrefix)
       
  5665         newA->prefix = &newDtd->defaultPrefix;
       
  5666       else
       
  5667         newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
       
  5668                                         oldA->prefix->name, 0);
       
  5669     }
       
  5670   }
       
  5671 
       
  5672   /* Copy the element type table. */
       
  5673 
       
  5674   hashTableIterInit(&iter, &(oldDtd->elementTypes));
       
  5675 
       
  5676   for (;;) {
       
  5677     int i;
       
  5678     ELEMENT_TYPE *newE;
       
  5679     const XML_Char *name;
       
  5680     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
       
  5681     if (!oldE)
       
  5682       break;
       
  5683     name = poolCopyString(&(newDtd->pool), oldE->name);
       
  5684     if (!name)
       
  5685       return 0;
       
  5686     newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
       
  5687                                   sizeof(ELEMENT_TYPE));
       
  5688     if (!newE)
       
  5689       return 0;
       
  5690     if (oldE->nDefaultAtts) {
       
  5691       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
       
  5692           ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
       
  5693       if (!newE->defaultAtts) {
       
  5694         ms->free_fcn(newE);
       
  5695         return 0;
       
  5696       }
       
  5697     }
       
  5698     if (oldE->idAtt)
       
  5699       newE->idAtt = (ATTRIBUTE_ID *)
       
  5700           lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
       
  5701     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
       
  5702     if (oldE->prefix)
       
  5703       newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
       
  5704                                       oldE->prefix->name, 0);
       
  5705     for (i = 0; i < newE->nDefaultAtts; i++) {
       
  5706       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
       
  5707           lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
       
  5708       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
       
  5709       if (oldE->defaultAtts[i].value) {
       
  5710         newE->defaultAtts[i].value
       
  5711             = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
       
  5712         if (!newE->defaultAtts[i].value)
       
  5713           return 0;
       
  5714       }
       
  5715       else
       
  5716         newE->defaultAtts[i].value = NULL;
       
  5717     }
       
  5718   }
       
  5719 
       
  5720   /* Copy the entity tables. */
       
  5721   if (!copyEntityTable(&(newDtd->generalEntities),
       
  5722                        &(newDtd->pool),
       
  5723                        &(oldDtd->generalEntities)))
       
  5724       return 0;
       
  5725 
       
  5726 #ifdef XML_DTD
       
  5727   if (!copyEntityTable(&(newDtd->paramEntities),
       
  5728                        &(newDtd->pool),
       
  5729                        &(oldDtd->paramEntities)))
       
  5730       return 0;
       
  5731   newDtd->paramEntityRead = oldDtd->paramEntityRead;
       
  5732 #endif /* XML_DTD */
       
  5733 
       
  5734   newDtd->keepProcessing = oldDtd->keepProcessing;
       
  5735   newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
       
  5736   newDtd->standalone = oldDtd->standalone;
       
  5737 
       
  5738   /* Don't want deep copying for scaffolding */
       
  5739   newDtd->in_eldecl = oldDtd->in_eldecl;
       
  5740   newDtd->scaffold = oldDtd->scaffold;
       
  5741   newDtd->contentStringLen = oldDtd->contentStringLen;
       
  5742   newDtd->scaffSize = oldDtd->scaffSize;
       
  5743   newDtd->scaffLevel = oldDtd->scaffLevel;
       
  5744   newDtd->scaffIndex = oldDtd->scaffIndex;
       
  5745 
       
  5746   return 1;
       
  5747 }  /* End dtdCopy */
       
  5748 
       
  5749 static int
       
  5750 copyEntityTable(HASH_TABLE *newTable,
       
  5751                 STRING_POOL *newPool,
       
  5752                 const HASH_TABLE *oldTable)
       
  5753 {
       
  5754   HASH_TABLE_ITER iter;
       
  5755   const XML_Char *cachedOldBase = NULL;
       
  5756   const XML_Char *cachedNewBase = NULL;
       
  5757 
       
  5758   hashTableIterInit(&iter, oldTable);
       
  5759 
       
  5760   for (;;) {
       
  5761     ENTITY *newE;
       
  5762     const XML_Char *name;
       
  5763     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
       
  5764     if (!oldE)
       
  5765       break;
       
  5766     name = poolCopyString(newPool, oldE->name);
       
  5767     if (!name)
       
  5768       return 0;
       
  5769     newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
       
  5770     if (!newE)
       
  5771       return 0;
       
  5772     if (oldE->systemId) {
       
  5773       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
       
  5774       if (!tem)
       
  5775         return 0;
       
  5776       newE->systemId = tem;
       
  5777       if (oldE->base) {
       
  5778         if (oldE->base == cachedOldBase)
       
  5779           newE->base = cachedNewBase;
       
  5780         else {
       
  5781           cachedOldBase = oldE->base;
       
  5782           tem = poolCopyString(newPool, cachedOldBase);
       
  5783           if (!tem)
       
  5784             return 0;
       
  5785           cachedNewBase = newE->base = tem;
       
  5786         }
       
  5787       }
       
  5788       if (oldE->publicId) {
       
  5789         tem = poolCopyString(newPool, oldE->publicId);
       
  5790         if (!tem)
       
  5791           return 0;
       
  5792         newE->publicId = tem;
       
  5793       }
       
  5794     }
       
  5795     else {
       
  5796       const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
       
  5797                                             oldE->textLen);
       
  5798       if (!tem)
       
  5799         return 0;
       
  5800       newE->textPtr = tem;
       
  5801       newE->textLen = oldE->textLen;
       
  5802     }
       
  5803     if (oldE->notation) {
       
  5804       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
       
  5805       if (!tem)
       
  5806         return 0;
       
  5807       newE->notation = tem;
       
  5808     }
       
  5809     newE->is_param = oldE->is_param;
       
  5810     newE->is_internal = oldE->is_internal;
       
  5811   }
       
  5812   return 1;
       
  5813 }
       
  5814 
       
  5815 #define INIT_POWER 6
       
  5816 
       
  5817 static XML_Bool FASTCALL
       
  5818 keyeq(KEY s1, KEY s2)
       
  5819 {
       
  5820   for (; *s1 == *s2; s1++, s2++)
       
  5821     if (*s1 == 0)
       
  5822       return XML_TRUE;
       
  5823   return XML_FALSE;
       
  5824 }
       
  5825 
       
  5826 static unsigned long FASTCALL
       
  5827 hash(KEY s)
       
  5828 {
       
  5829   unsigned long h = 0;
       
  5830   while (*s)
       
  5831     h = CHAR_HASH(h, *s++);
       
  5832   return h;
       
  5833 }
       
  5834 
       
  5835 static NAMED *
       
  5836 lookup(HASH_TABLE *table, KEY name, size_t createSize)
       
  5837 {
       
  5838   size_t i;
       
  5839   if (table->size == 0) {
       
  5840     size_t tsize;
       
  5841     if (!createSize)
       
  5842       return NULL;
       
  5843     table->power = INIT_POWER;
       
  5844     /* table->size is a power of 2 */
       
  5845     table->size = (size_t)1 << INIT_POWER;
       
  5846     tsize = table->size * sizeof(NAMED *);
       
  5847     table->v = (NAMED **)table->mem->malloc_fcn(tsize);
       
  5848     if (!table->v) {
       
  5849       table->size = 0;
       
  5850       return NULL;
       
  5851     }
       
  5852     memset(table->v, 0, tsize);
       
  5853     i = hash(name) & ((unsigned long)table->size - 1);
       
  5854   }
       
  5855   else {
       
  5856     unsigned long h = hash(name);
       
  5857     unsigned long mask = (unsigned long)table->size - 1;
       
  5858     unsigned char step = 0;
       
  5859     i = h & mask;
       
  5860     while (table->v[i]) {
       
  5861       if (keyeq(name, table->v[i]->name))
       
  5862         return table->v[i];
       
  5863       if (!step)
       
  5864         step = PROBE_STEP(h, mask, table->power);
       
  5865       i < step ? (i += table->size - step) : (i -= step);
       
  5866     }
       
  5867     if (!createSize)
       
  5868       return NULL;
       
  5869 
       
  5870     /* check for overflow (table is half full) */
       
  5871     if (table->used >> (table->power - 1)) {
       
  5872       unsigned char newPower = table->power + 1;
       
  5873       size_t newSize = (size_t)1 << newPower;
       
  5874       unsigned long newMask = (unsigned long)newSize - 1;
       
  5875       size_t tsize = newSize * sizeof(NAMED *);
       
  5876       NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
       
  5877       if (!newV)
       
  5878         return NULL;
       
  5879       memset(newV, 0, tsize);
       
  5880       for (i = 0; i < table->size; i++)
       
  5881         if (table->v[i]) {
       
  5882           unsigned long newHash = hash(table->v[i]->name);
       
  5883           size_t j = newHash & newMask;
       
  5884           step = 0;
       
  5885           while (newV[j]) {
       
  5886             if (!step)
       
  5887               step = PROBE_STEP(newHash, newMask, newPower);
       
  5888             j < step ? (j += newSize - step) : (j -= step);
       
  5889           }
       
  5890           newV[j] = table->v[i];
       
  5891         }
       
  5892       table->mem->free_fcn(table->v);
       
  5893       table->v = newV;
       
  5894       table->power = newPower;
       
  5895       table->size = newSize;
       
  5896       i = h & newMask;
       
  5897       step = 0;
       
  5898       while (table->v[i]) {
       
  5899         if (!step)
       
  5900           step = PROBE_STEP(h, newMask, newPower);
       
  5901         i < step ? (i += newSize - step) : (i -= step);
       
  5902       }
       
  5903     }
       
  5904   }
       
  5905   table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
       
  5906   if (!table->v[i])
       
  5907     return NULL;
       
  5908   memset(table->v[i], 0, createSize);
       
  5909   table->v[i]->name = name;
       
  5910   (table->used)++;
       
  5911   return table->v[i];
       
  5912 }
       
  5913 
       
  5914 static void FASTCALL
       
  5915 hashTableClear(HASH_TABLE *table)
       
  5916 {
       
  5917   size_t i;
       
  5918   for (i = 0; i < table->size; i++) {
       
  5919     table->mem->free_fcn(table->v[i]);
       
  5920     table->v[i] = NULL;
       
  5921   }
       
  5922   table->used = 0;
       
  5923 }
       
  5924 
       
  5925 static void FASTCALL
       
  5926 hashTableDestroy(HASH_TABLE *table)
       
  5927 {
       
  5928   size_t i;
       
  5929   for (i = 0; i < table->size; i++)
       
  5930     table->mem->free_fcn(table->v[i]);
       
  5931   table->mem->free_fcn(table->v);
       
  5932 }
       
  5933 
       
  5934 static void FASTCALL
       
  5935 hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
       
  5936 {
       
  5937   p->power = 0;
       
  5938   p->size = 0;
       
  5939   p->used = 0;
       
  5940   p->v = NULL;
       
  5941   p->mem = ms;
       
  5942 }
       
  5943 
       
  5944 static void FASTCALL
       
  5945 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
       
  5946 {
       
  5947   iter->p = table->v;
       
  5948   iter->end = iter->p + table->size;
       
  5949 }
       
  5950 
       
  5951 static NAMED * FASTCALL
       
  5952 hashTableIterNext(HASH_TABLE_ITER *iter)
       
  5953 {
       
  5954   while (iter->p != iter->end) {
       
  5955     NAMED *tem = *(iter->p)++;
       
  5956     if (tem)
       
  5957       return tem;
       
  5958   }
       
  5959   return NULL;
       
  5960 }
       
  5961 
       
  5962 static void FASTCALL
       
  5963 poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
       
  5964 {
       
  5965   pool->blocks = NULL;
       
  5966   pool->freeBlocks = NULL;
       
  5967   pool->start = NULL;
       
  5968   pool->ptr = NULL;
       
  5969   pool->end = NULL;
       
  5970   pool->mem = ms;
       
  5971 }
       
  5972 
       
  5973 static void FASTCALL
       
  5974 poolClear(STRING_POOL *pool)
       
  5975 {
       
  5976   if (!pool->freeBlocks)
       
  5977     pool->freeBlocks = pool->blocks;
       
  5978   else {
       
  5979     BLOCK *p = pool->blocks;
       
  5980     while (p) {
       
  5981       BLOCK *tem = p->next;
       
  5982       p->next = pool->freeBlocks;
       
  5983       pool->freeBlocks = p;
       
  5984       p = tem;
       
  5985     }
       
  5986   }
       
  5987   pool->blocks = NULL;
       
  5988   pool->start = NULL;
       
  5989   pool->ptr = NULL;
       
  5990   pool->end = NULL;
       
  5991 }
       
  5992 
       
  5993 static void FASTCALL
       
  5994 poolDestroy(STRING_POOL *pool)
       
  5995 {
       
  5996   BLOCK *p = pool->blocks;
       
  5997   while (p) {
       
  5998     BLOCK *tem = p->next;
       
  5999     pool->mem->free_fcn(p);
       
  6000     p = tem;
       
  6001   }
       
  6002   p = pool->freeBlocks;
       
  6003   while (p) {
       
  6004     BLOCK *tem = p->next;
       
  6005     pool->mem->free_fcn(p);
       
  6006     p = tem;
       
  6007   }
       
  6008 }
       
  6009 
       
  6010 static XML_Char *
       
  6011 poolAppend(STRING_POOL *pool, const ENCODING *enc,
       
  6012            const char *ptr, const char *end)
       
  6013 {
       
  6014   if (!pool->ptr && !poolGrow(pool))
       
  6015     return NULL;
       
  6016   for (;;) {
       
  6017     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
       
  6018     if (ptr == end)
       
  6019       break;
       
  6020     if (!poolGrow(pool))
       
  6021       return NULL;
       
  6022   }
       
  6023   return pool->start;
       
  6024 }
       
  6025 
       
  6026 static const XML_Char * FASTCALL
       
  6027 poolCopyString(STRING_POOL *pool, const XML_Char *s)
       
  6028 {
       
  6029   do {
       
  6030     if (!poolAppendChar(pool, *s))
       
  6031       return NULL;
       
  6032   } while (*s++);
       
  6033   s = pool->start;
       
  6034   poolFinish(pool);
       
  6035   return s;
       
  6036 }
       
  6037 
       
  6038 static const XML_Char *
       
  6039 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
       
  6040 {
       
  6041   if (!pool->ptr && !poolGrow(pool))
       
  6042     return NULL;
       
  6043   for (; n > 0; --n, s++) {
       
  6044     if (!poolAppendChar(pool, *s))
       
  6045       return NULL;
       
  6046   }
       
  6047   s = pool->start;
       
  6048   poolFinish(pool);
       
  6049   return s;
       
  6050 }
       
  6051 
       
  6052 static const XML_Char * FASTCALL
       
  6053 poolAppendString(STRING_POOL *pool, const XML_Char *s)
       
  6054 {
       
  6055   while (*s) {
       
  6056     if (!poolAppendChar(pool, *s))
       
  6057       return NULL;
       
  6058     s++;
       
  6059   }
       
  6060   return pool->start;
       
  6061 }
       
  6062 
       
  6063 static XML_Char *
       
  6064 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
       
  6065                 const char *ptr, const char *end)
       
  6066 {
       
  6067   if (!poolAppend(pool, enc, ptr, end))
       
  6068     return NULL;
       
  6069   if (pool->ptr == pool->end && !poolGrow(pool))
       
  6070     return NULL;
       
  6071   *(pool->ptr)++ = 0;
       
  6072   return pool->start;
       
  6073 }
       
  6074 
       
  6075 static XML_Bool FASTCALL
       
  6076 poolGrow(STRING_POOL *pool)
       
  6077 {
       
  6078   if (pool->freeBlocks) {
       
  6079     if (pool->start == 0) {
       
  6080       pool->blocks = pool->freeBlocks;
       
  6081       pool->freeBlocks = pool->freeBlocks->next;
       
  6082       pool->blocks->next = NULL;
       
  6083       pool->start = pool->blocks->s;
       
  6084       pool->end = pool->start + pool->blocks->size;
       
  6085       pool->ptr = pool->start;
       
  6086       return XML_TRUE;
       
  6087     }
       
  6088     if (pool->end - pool->start < pool->freeBlocks->size) {
       
  6089       BLOCK *tem = pool->freeBlocks->next;
       
  6090       pool->freeBlocks->next = pool->blocks;
       
  6091       pool->blocks = pool->freeBlocks;
       
  6092       pool->freeBlocks = tem;
       
  6093       memcpy(pool->blocks->s, pool->start,
       
  6094              (pool->end - pool->start) * sizeof(XML_Char));
       
  6095       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
       
  6096       pool->start = pool->blocks->s;
       
  6097       pool->end = pool->start + pool->blocks->size;
       
  6098       return XML_TRUE;
       
  6099     }
       
  6100   }
       
  6101   if (pool->blocks && pool->start == pool->blocks->s) {
       
  6102     int blockSize = (int)(pool->end - pool->start)*2;
       
  6103     pool->blocks = (BLOCK *)
       
  6104       pool->mem->realloc_fcn(pool->blocks,
       
  6105                              (offsetof(BLOCK, s)
       
  6106                               + blockSize * sizeof(XML_Char)));
       
  6107     if (pool->blocks == NULL)
       
  6108       return XML_FALSE;
       
  6109     pool->blocks->size = blockSize;
       
  6110     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
       
  6111     pool->start = pool->blocks->s;
       
  6112     pool->end = pool->start + blockSize;
       
  6113   }
       
  6114   else {
       
  6115     BLOCK *tem;
       
  6116     int blockSize = (int)(pool->end - pool->start);
       
  6117     if (blockSize < INIT_BLOCK_SIZE)
       
  6118       blockSize = INIT_BLOCK_SIZE;
       
  6119     else
       
  6120       blockSize *= 2;
       
  6121     tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
       
  6122                                         + blockSize * sizeof(XML_Char));
       
  6123     if (!tem)
       
  6124       return XML_FALSE;
       
  6125     tem->size = blockSize;
       
  6126     tem->next = pool->blocks;
       
  6127     pool->blocks = tem;
       
  6128     if (pool->ptr != pool->start)
       
  6129       memcpy(tem->s, pool->start,
       
  6130              (pool->ptr - pool->start) * sizeof(XML_Char));
       
  6131     pool->ptr = tem->s + (pool->ptr - pool->start);
       
  6132     pool->start = tem->s;
       
  6133     pool->end = tem->s + blockSize;
       
  6134   }
       
  6135   return XML_TRUE;
       
  6136 }
       
  6137 
       
  6138 static int FASTCALL
       
  6139 nextScaffoldPart(XML_Parser parser)
       
  6140 {
       
  6141   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  6142   CONTENT_SCAFFOLD * me;
       
  6143   int next;
       
  6144 
       
  6145   if (!dtd->scaffIndex) {
       
  6146     dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
       
  6147     if (!dtd->scaffIndex)
       
  6148       return -1;
       
  6149     dtd->scaffIndex[0] = 0;
       
  6150   }
       
  6151 
       
  6152   if (dtd->scaffCount >= dtd->scaffSize) {
       
  6153     CONTENT_SCAFFOLD *temp;
       
  6154     if (dtd->scaffold) {
       
  6155       temp = (CONTENT_SCAFFOLD *)
       
  6156         REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
       
  6157       if (temp == NULL)
       
  6158         return -1;
       
  6159       dtd->scaffSize *= 2;
       
  6160     }
       
  6161     else {
       
  6162       temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
       
  6163                                         * sizeof(CONTENT_SCAFFOLD));
       
  6164       if (temp == NULL)
       
  6165         return -1;
       
  6166       dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
       
  6167     }
       
  6168     dtd->scaffold = temp;
       
  6169   }
       
  6170   next = dtd->scaffCount++;
       
  6171   me = &dtd->scaffold[next];
       
  6172   if (dtd->scaffLevel) {
       
  6173     CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
       
  6174     if (parent->lastchild) {
       
  6175       dtd->scaffold[parent->lastchild].nextsib = next;
       
  6176     }
       
  6177     if (!parent->childcnt)
       
  6178       parent->firstchild = next;
       
  6179     parent->lastchild = next;
       
  6180     parent->childcnt++;
       
  6181   }
       
  6182   me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
       
  6183   return next;
       
  6184 }
       
  6185 
       
  6186 static void
       
  6187 build_node(XML_Parser parser,
       
  6188            int src_node,
       
  6189            XML_Content *dest,
       
  6190            XML_Content **contpos,
       
  6191            XML_Char **strpos)
       
  6192 {
       
  6193   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  6194   dest->type = dtd->scaffold[src_node].type;
       
  6195   dest->quant = dtd->scaffold[src_node].quant;
       
  6196   if (dest->type == XML_CTYPE_NAME) {
       
  6197     const XML_Char *src;
       
  6198     dest->name = *strpos;
       
  6199     src = dtd->scaffold[src_node].name;
       
  6200     for (;;) {
       
  6201       *(*strpos)++ = *src;
       
  6202       if (!*src)
       
  6203         break;
       
  6204       src++;
       
  6205     }
       
  6206     dest->numchildren = 0;
       
  6207     dest->children = NULL;
       
  6208   }
       
  6209   else {
       
  6210     unsigned int i;
       
  6211     int cn;
       
  6212     dest->numchildren = dtd->scaffold[src_node].childcnt;
       
  6213     dest->children = *contpos;
       
  6214     *contpos += dest->numchildren;
       
  6215     for (i = 0, cn = dtd->scaffold[src_node].firstchild;
       
  6216          i < dest->numchildren;
       
  6217          i++, cn = dtd->scaffold[cn].nextsib) {
       
  6218       build_node(parser, cn, &(dest->children[i]), contpos, strpos);
       
  6219     }
       
  6220     dest->name = NULL;
       
  6221   }
       
  6222 }
       
  6223 
       
  6224 static XML_Content *
       
  6225 build_model (XML_Parser parser)
       
  6226 {
       
  6227   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  6228   XML_Content *ret;
       
  6229   XML_Content *cpos;
       
  6230   XML_Char * str;
       
  6231   int allocsize = (dtd->scaffCount * sizeof(XML_Content)
       
  6232                    + (dtd->contentStringLen * sizeof(XML_Char)));
       
  6233 
       
  6234   ret = (XML_Content *)MALLOC(allocsize);
       
  6235   if (!ret)
       
  6236     return NULL;
       
  6237 
       
  6238   str =  (XML_Char *) (&ret[dtd->scaffCount]);
       
  6239   cpos = &ret[1];
       
  6240 
       
  6241   build_node(parser, 0, ret, &cpos, &str);
       
  6242   return ret;
       
  6243 }
       
  6244 
       
  6245 static ELEMENT_TYPE *
       
  6246 getElementType(XML_Parser parser,
       
  6247                const ENCODING *enc,
       
  6248                const char *ptr,
       
  6249                const char *end)
       
  6250 {
       
  6251   DTD * const dtd = _dtd;  /* save one level of indirection */
       
  6252   const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
       
  6253   ELEMENT_TYPE *ret;
       
  6254 
       
  6255   if (!name)
       
  6256     return NULL;
       
  6257   ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
       
  6258   if (!ret)
       
  6259     return NULL;
       
  6260   if (ret->name != name)
       
  6261     poolDiscard(&dtd->pool);
       
  6262   else {
       
  6263     poolFinish(&dtd->pool);
       
  6264     if (!setElementTypePrefix(parser, ret))
       
  6265       return NULL;
       
  6266   }
       
  6267   return ret;
       
  6268 }