OSDN Git Service

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