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