TZIVI-254: IVI needs a newer version of cmake
[profile/ivi/cmake.git] / Utilities / cmexpat / xmlparse.c
1 /*
2 Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
3 See the file COPYING for copying permission.
4 */
5
6 #include <cmexpat/expatConfig.h>
7 #include <cmexpat/expat.h>
8
9 #include <stddef.h>
10 #include <string.h>
11
12 #ifdef XML_UNICODE
13 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
14 #define XmlConvert XmlUtf16Convert
15 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
16 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
17 #define XmlEncode XmlUtf16Encode
18 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
19 typedef unsigned short ICHAR;
20 #else
21 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
22 #define XmlConvert XmlUtf8Convert
23 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
24 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
25 #define XmlEncode XmlUtf8Encode
26 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
27 typedef char ICHAR;
28 #endif
29
30
31 #ifndef XML_NS
32
33 #define XmlInitEncodingNS XmlInitEncoding
34 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
35 #undef XmlGetInternalEncodingNS
36 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
37 #define XmlParseXmlDeclNS XmlParseXmlDecl
38
39 #endif
40
41 #ifdef XML_UNICODE_WCHAR_T
42 #define XML_T(x) L ## x
43 #else
44 #define XML_T(x) x
45 #endif
46
47 /* Round up n to be a multiple of sz, where sz is a power of 2. */
48 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
49
50 #include "xmltok.h"
51 #include "xmlrole.h"
52
53 typedef const XML_Char *KEY;
54
55 typedef struct {
56   KEY name;
57 } NAMED;
58
59 typedef struct {
60   NAMED **v;
61   size_t size;
62   size_t used;
63   size_t usedLim;
64   XML_Memory_Handling_Suite *mem;
65 } HASH_TABLE;
66
67 typedef struct {
68   NAMED **p;
69   NAMED **end;
70 } HASH_TABLE_ITER;
71
72 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
73 #define INIT_DATA_BUF_SIZE 1024
74 #define INIT_ATTS_SIZE 16
75 #define INIT_BLOCK_SIZE 1024
76 #define INIT_BUFFER_SIZE 1024
77
78 #define EXPAND_SPARE 24
79
80 typedef struct binding {
81   struct prefix *prefix;
82   struct binding *nextTagBinding;
83   struct binding *prevPrefixBinding;
84   const struct attribute_id *attId;
85   XML_Char *uri;
86   int uriLen;
87   int uriAlloc;
88 } BINDING;
89
90 typedef struct prefix {
91   const XML_Char *name;
92   BINDING *binding;
93 } PREFIX;
94
95 typedef struct {
96   const XML_Char *str;
97   const XML_Char *localPart;
98   int uriLen;
99 } TAG_NAME;
100
101 typedef struct tag {
102   struct tag *parent;
103   const char *rawName;
104   int rawNameLength;
105   TAG_NAME name;
106   char *buf;
107   char *bufEnd;
108   BINDING *bindings;
109 } TAG;
110
111 typedef struct {
112   const XML_Char *name;
113   const XML_Char *textPtr;
114   int textLen;
115   const XML_Char *systemId;
116   const XML_Char *base;
117   const XML_Char *publicId;
118   const XML_Char *notation;
119   char open;
120   char is_param;
121 } ENTITY;
122
123 typedef struct {
124   enum XML_Content_Type         type;
125   enum XML_Content_Quant        quant;
126   const XML_Char *              name;
127   int                           firstchild;
128   int                           lastchild;
129   int                           childcnt;
130   int                           nextsib;
131 } CONTENT_SCAFFOLD;
132
133 typedef struct block {
134   struct block *next;
135   int size;
136   XML_Char s[1];
137 } BLOCK;
138
139 typedef struct {
140   BLOCK *blocks;
141   BLOCK *freeBlocks;
142   const XML_Char *end;
143   XML_Char *ptr;
144   XML_Char *start;
145   XML_Memory_Handling_Suite *mem;
146 } STRING_POOL;
147
148 /* The XML_Char before the name is used to determine whether
149 an attribute has been specified. */
150 typedef struct attribute_id {
151   XML_Char *name;
152   PREFIX *prefix;
153   char maybeTokenized;
154   char xmlns;
155 } ATTRIBUTE_ID;
156
157 typedef struct {
158   const ATTRIBUTE_ID *id;
159   char isCdata;
160   const XML_Char *value;
161 } DEFAULT_ATTRIBUTE;
162
163 typedef struct {
164   const XML_Char *name;
165   PREFIX *prefix;
166   const ATTRIBUTE_ID *idAtt;
167   int nDefaultAtts;
168   int allocDefaultAtts;
169   DEFAULT_ATTRIBUTE *defaultAtts;
170 } ELEMENT_TYPE;
171
172 typedef struct {
173   HASH_TABLE generalEntities;
174   HASH_TABLE elementTypes;
175   HASH_TABLE attributeIds;
176   HASH_TABLE prefixes;
177   STRING_POOL pool;
178   int complete;
179   int standalone;
180 #ifdef XML_DTD
181   HASH_TABLE paramEntities;
182 #endif /* XML_DTD */
183   PREFIX defaultPrefix;
184   /* === scaffolding for building content model === */
185   int in_eldecl;
186   CONTENT_SCAFFOLD *scaffold;
187   unsigned contentStringLen;
188   unsigned scaffSize;
189   unsigned scaffCount;
190   int scaffLevel;
191   int *scaffIndex;
192 } DTD;
193
194 typedef struct open_internal_entity {
195   const char *internalEventPtr;
196   const char *internalEventEndPtr;
197   struct open_internal_entity *next;
198   ENTITY *entity;
199 } OPEN_INTERNAL_ENTITY;
200
201 typedef enum XML_Error Processor(XML_Parser parser,
202                                  const char *start,
203                                  const char *end,
204                                  const char **endPtr);
205
206 static Processor prologProcessor;
207 static Processor prologInitProcessor;
208 static Processor contentProcessor;
209 static Processor cdataSectionProcessor;
210 #ifdef XML_DTD
211 static Processor ignoreSectionProcessor;
212 #endif /* XML_DTD */
213 static Processor epilogProcessor;
214 static Processor errorProcessor;
215 static Processor externalEntityInitProcessor;
216 static Processor externalEntityInitProcessor2;
217 static Processor externalEntityInitProcessor3;
218 static Processor externalEntityContentProcessor;
219
220 static enum XML_Error
221 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
222 static enum XML_Error
223 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
224 static enum XML_Error
225 initializeEncoding(XML_Parser parser);
226 static enum XML_Error
227 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
228          const char *end, int tok, const char *next, const char **nextPtr);
229 static enum XML_Error
230 processInternalParamEntity(XML_Parser parser, ENTITY *entity);
231 static enum XML_Error
232 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
233           const char *start, const char *end, const char **endPtr);
234 static enum XML_Error
235 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
236 #ifdef XML_DTD
237 static enum XML_Error
238 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
239 #endif /* XML_DTD */
240 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
241                                 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
242 static
243 int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
244
245 static int
246 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
247                 int isCdata, int isId, const XML_Char *dfltValue,
248                 XML_Parser parser);
249
250 static enum XML_Error
251 storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
252                     STRING_POOL *);
253 static enum XML_Error
254 appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
255                     STRING_POOL *);
256 static ATTRIBUTE_ID *
257 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
258 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
259 static enum XML_Error
260 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
261 static int
262 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
263 static int
264 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
265 static void
266 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
267
268 static const XML_Char *getContext(XML_Parser parser);
269 static int setContext(XML_Parser parser, const XML_Char *context);
270 static void normalizePublicId(XML_Char *s);
271 static int dtdInit(DTD *, XML_Parser parser);
272
273 static void dtdDestroy(DTD *, XML_Parser parser);
274
275 static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
276
277 static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *,
278                            XML_Parser parser);
279
280 #ifdef XML_DTD
281 static void dtdSwap(DTD *, DTD *);
282 #endif /* XML_DTD */
283
284 static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
285
286 static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
287
288 static void hashTableDestroy(HASH_TABLE *);
289 static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
290 static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
291 static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
292 static void poolClear(STRING_POOL *);
293 static void poolDestroy(STRING_POOL *);
294 static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
295                             const char *ptr, const char *end);
296 static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
297                                   const char *ptr, const char *end);
298
299 static int poolGrow(STRING_POOL *pool);
300
301 static int nextScaffoldPart(XML_Parser parser);
302 static XML_Content *build_model(XML_Parser parser);
303
304 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
305 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
306 static const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s);
307 static ELEMENT_TYPE * getElementType(XML_Parser Paraser,
308                                      const ENCODING *enc,
309                                      const char *ptr,
310                                      const char *end);
311
312 #define poolStart(pool) ((pool)->start)
313 #define poolEnd(pool) ((pool)->ptr)
314 #define poolLength(pool) ((pool)->ptr - (pool)->start)
315 #define poolChop(pool) ((void)--(pool->ptr))
316 #define poolLastChar(pool) (((pool)->ptr)[-1])
317 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
318 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
319 #define poolAppendChar(pool, c) \
320   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
321    ? 0 \
322    : ((*((pool)->ptr)++ = c), 1))
323
324 typedef struct {
325   /* The first member must be userData so that the XML_GetUserData macro works. */
326   void *m_userData;
327   void *m_handlerArg;
328   char *m_buffer;
329   XML_Memory_Handling_Suite m_mem;
330   /* first character to be parsed */
331   const char *m_bufferPtr;
332   /* past last character to be parsed */
333   char *m_bufferEnd;
334   /* allocated end of buffer */
335   const char *m_bufferLim;
336   long m_parseEndByteIndex;
337   const char *m_parseEndPtr;
338   XML_Char *m_dataBuf;
339   XML_Char *m_dataBufEnd;
340   XML_StartElementHandler m_startElementHandler;
341   XML_EndElementHandler m_endElementHandler;
342   XML_CharacterDataHandler m_characterDataHandler;
343   XML_ProcessingInstructionHandler m_processingInstructionHandler;
344   XML_CommentHandler m_commentHandler;
345   XML_StartCdataSectionHandler m_startCdataSectionHandler;
346   XML_EndCdataSectionHandler m_endCdataSectionHandler;
347   XML_DefaultHandler m_defaultHandler;
348   XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
349   XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
350   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
351   XML_NotationDeclHandler m_notationDeclHandler;
352   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
353   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
354   XML_NotStandaloneHandler m_notStandaloneHandler;
355   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
356   void *m_externalEntityRefHandlerArg;
357   XML_UnknownEncodingHandler m_unknownEncodingHandler;
358   XML_ElementDeclHandler m_elementDeclHandler;
359   XML_AttlistDeclHandler m_attlistDeclHandler;
360   XML_EntityDeclHandler m_entityDeclHandler;
361   XML_XmlDeclHandler m_xmlDeclHandler;
362   const ENCODING *m_encoding;
363   INIT_ENCODING m_initEncoding;
364   const ENCODING *m_internalEncoding;
365   const XML_Char *m_protocolEncodingName;
366   int m_ns;
367   int m_ns_triplets;
368   void *m_unknownEncodingMem;
369   void *m_unknownEncodingData;
370   void *m_unknownEncodingHandlerData;
371   void (*m_unknownEncodingRelease)(void *);
372   PROLOG_STATE m_prologState;
373   Processor *m_processor;
374   enum XML_Error m_errorCode;
375   const char *m_eventPtr;
376   const char *m_eventEndPtr;
377   const char *m_positionPtr;
378   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
379   int m_defaultExpandInternalEntities;
380   int m_tagLevel;
381   ENTITY *m_declEntity;
382   const XML_Char *m_doctypeName;
383   const XML_Char *m_doctypeSysid;
384   const XML_Char *m_doctypePubid;
385   const XML_Char *m_declAttributeType;
386   const XML_Char *m_declNotationName;
387   const XML_Char *m_declNotationPublicId;
388   ELEMENT_TYPE *m_declElementType;
389   ATTRIBUTE_ID *m_declAttributeId;
390   char m_declAttributeIsCdata;
391   char m_declAttributeIsId;
392   DTD m_dtd;
393   const XML_Char *m_curBase;
394   TAG *m_tagStack;
395   TAG *m_freeTagList;
396   BINDING *m_inheritedBindings;
397   BINDING *m_freeBindingList;
398   int m_attsSize;
399   int m_nSpecifiedAtts;
400   int m_idAttIndex;
401   ATTRIBUTE *m_atts;
402   POSITION m_position;
403   STRING_POOL m_tempPool;
404   STRING_POOL m_temp2Pool;
405   char *m_groupConnector;
406   unsigned m_groupSize;
407   int m_hadExternalDoctype;
408   XML_Char m_namespaceSeparator;
409 #ifdef XML_DTD
410   enum XML_ParamEntityParsing m_paramEntityParsing;
411   XML_Parser m_parentParser;
412 #endif
413 } Parser;
414
415 #define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
416 #define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
417 #define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
418
419 #define userData (((Parser *)parser)->m_userData)
420 #define handlerArg (((Parser *)parser)->m_handlerArg)
421 #define startElementHandler (((Parser *)parser)->m_startElementHandler)
422 #define endElementHandler (((Parser *)parser)->m_endElementHandler)
423 #define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
424 #define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
425 #define commentHandler (((Parser *)parser)->m_commentHandler)
426 #define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
427 #define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
428 #define defaultHandler (((Parser *)parser)->m_defaultHandler)
429 #define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
430 #define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
431 #define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
432 #define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
433 #define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
434 #define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
435 #define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
436 #define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
437 #define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
438 #define internalEntityRefHandler (((Parser *)parser)->m_internalEntityRefHandler)
439 #define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
440 #define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
441 #define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
442 #define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
443 #define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
444 #define encoding (((Parser *)parser)->m_encoding)
445 #define initEncoding (((Parser *)parser)->m_initEncoding)
446 #define internalEncoding (((Parser *)parser)->m_internalEncoding)
447 #define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
448 #define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
449 #define unknownEncodingHandlerData \
450   (((Parser *)parser)->m_unknownEncodingHandlerData)
451 #define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
452 #define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
453 #define ns (((Parser *)parser)->m_ns)
454 #define ns_triplets (((Parser *)parser)->m_ns_triplets)
455 #define prologState (((Parser *)parser)->m_prologState)
456 #define processor (((Parser *)parser)->m_processor)
457 #define errorCode (((Parser *)parser)->m_errorCode)
458 #define eventPtr (((Parser *)parser)->m_eventPtr)
459 #define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
460 #define positionPtr (((Parser *)parser)->m_positionPtr)
461 #define position (((Parser *)parser)->m_position)
462 #define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
463 #define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
464 #define tagLevel (((Parser *)parser)->m_tagLevel)
465 #define buffer (((Parser *)parser)->m_buffer)
466 #define bufferPtr (((Parser *)parser)->m_bufferPtr)
467 #define bufferEnd (((Parser *)parser)->m_bufferEnd)
468 #define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
469 #define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
470 #define bufferLim (((Parser *)parser)->m_bufferLim)
471 #define dataBuf (((Parser *)parser)->m_dataBuf)
472 #define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
473 #define dtd (((Parser *)parser)->m_dtd)
474 #define curBase (((Parser *)parser)->m_curBase)
475 #define declEntity (((Parser *)parser)->m_declEntity)
476 #define doctypeName (((Parser *)parser)->m_doctypeName)
477 #define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
478 #define doctypePubid (((Parser *)parser)->m_doctypePubid)
479 #define declAttributeType (((Parser *)parser)->m_declAttributeType)
480 #define declNotationName (((Parser *)parser)->m_declNotationName)
481 #define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
482 #define declElementType (((Parser *)parser)->m_declElementType)
483 #define declAttributeId (((Parser *)parser)->m_declAttributeId)
484 #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
485 #define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
486 #define freeTagList (((Parser *)parser)->m_freeTagList)
487 #define freeBindingList (((Parser *)parser)->m_freeBindingList)
488 #define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
489 #define tagStack (((Parser *)parser)->m_tagStack)
490 #define atts (((Parser *)parser)->m_atts)
491 #define attsSize (((Parser *)parser)->m_attsSize)
492 #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
493 #define idAttIndex (((Parser *)parser)->m_idAttIndex)
494 #define tempPool (((Parser *)parser)->m_tempPool)
495 #define temp2Pool (((Parser *)parser)->m_temp2Pool)
496 #define groupConnector (((Parser *)parser)->m_groupConnector)
497 #define groupSize (((Parser *)parser)->m_groupSize)
498 #define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
499 #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
500 #ifdef XML_DTD
501 #define parentParser (((Parser *)parser)->m_parentParser)
502 #define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
503 #endif /* XML_DTD */
504
505 #ifdef COMPILED_FROM_DSP
506 BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p) {
507   return TRUE;
508 }
509 #endif /* def COMPILED_FROM_DSP */
510
511 #ifdef _MSC_VER
512 #ifdef _DEBUG
513 Parser *asParser(XML_Parser parser)
514 {
515   return parser;
516 }
517 #endif
518 #endif
519
520 XML_Parser XML_ParserCreate(const XML_Char *encodingName)
521 {
522   return XML_ParserCreate_MM(encodingName, NULL, NULL);
523 }
524
525 XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
526 {
527   XML_Char tmp[2];
528   *tmp = nsSep;
529   return XML_ParserCreate_MM(encodingName, NULL, tmp);
530 }
531
532 XML_Parser
533 XML_ParserCreate_MM(const XML_Char *encodingName,
534                     const XML_Memory_Handling_Suite *memsuite,
535                     const XML_Char *nameSep) {
536   
537   XML_Parser parser;
538   static
539   const XML_Char implicitContext[] = {
540     XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
541     XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
542     XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
543     XML_T('.'), XML_T('w'), XML_T('3'),
544     XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
545     XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
546     XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
547     XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
548     XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
549     XML_T('\0')
550   };
551
552
553   if (memsuite) {
554     XML_Memory_Handling_Suite *mtemp;
555     parser = memsuite->malloc_fcn(sizeof(Parser));
556     mtemp = &(((Parser *) parser)->m_mem);
557     mtemp->malloc_fcn = memsuite->malloc_fcn;
558     mtemp->realloc_fcn = memsuite->realloc_fcn;
559     mtemp->free_fcn = memsuite->free_fcn;
560   }
561   else {
562     XML_Memory_Handling_Suite *mtemp;
563     parser = malloc(sizeof(Parser));
564     mtemp = &(((Parser *) parser)->m_mem);
565     mtemp->malloc_fcn = malloc;
566     mtemp->realloc_fcn = realloc;
567     mtemp->free_fcn = free;
568   }
569
570   if (!parser)
571     return parser;
572   processor = prologInitProcessor;
573   XmlPrologStateInit(&prologState);
574   userData = 0;
575   handlerArg = 0;
576   startElementHandler = 0;
577   endElementHandler = 0;
578   characterDataHandler = 0;
579   processingInstructionHandler = 0;
580   commentHandler = 0;
581   startCdataSectionHandler = 0;
582   endCdataSectionHandler = 0;
583   defaultHandler = 0;
584   startDoctypeDeclHandler = 0;
585   endDoctypeDeclHandler = 0;
586   unparsedEntityDeclHandler = 0;
587   notationDeclHandler = 0;
588   startNamespaceDeclHandler = 0;
589   endNamespaceDeclHandler = 0;
590   notStandaloneHandler = 0;
591   externalEntityRefHandler = 0;
592   externalEntityRefHandlerArg = parser;
593   unknownEncodingHandler = 0;
594   elementDeclHandler = 0;
595   attlistDeclHandler = 0;
596   entityDeclHandler = 0;
597   xmlDeclHandler = 0;
598   buffer = 0;
599   bufferPtr = 0;
600   bufferEnd = 0;
601   parseEndByteIndex = 0;
602   parseEndPtr = 0;
603   bufferLim = 0;
604   declElementType = 0;
605   declAttributeId = 0;
606   declEntity = 0;
607   doctypeName = 0;
608   doctypeSysid = 0;
609   doctypePubid = 0;
610   declAttributeType = 0;
611   declNotationName = 0;
612   declNotationPublicId = 0;
613   memset(&position, 0, sizeof(POSITION));
614   errorCode = XML_ERROR_NONE;
615   eventPtr = 0;
616   eventEndPtr = 0;
617   positionPtr = 0;
618   openInternalEntities = 0;
619   tagLevel = 0;
620   tagStack = 0;
621   freeTagList = 0;
622   freeBindingList = 0;
623   inheritedBindings = 0;
624   attsSize = INIT_ATTS_SIZE;
625   atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
626   nSpecifiedAtts = 0;
627   dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
628   groupSize = 0;
629   groupConnector = 0;
630   hadExternalDoctype = 0;
631   unknownEncodingMem = 0;
632   unknownEncodingRelease = 0;
633   unknownEncodingData = 0;
634   unknownEncodingHandlerData = 0;
635   namespaceSeparator = '!';
636 #ifdef XML_DTD
637   parentParser = 0;
638   paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
639 #endif
640   ns = 0;
641   ns_triplets = 0;
642   poolInit(&tempPool, &(((Parser *) parser)->m_mem));
643   poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
644   protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
645   curBase = 0;
646   if (!dtdInit(&dtd, parser) || !atts || !dataBuf
647       || (encodingName && !protocolEncodingName)) {
648     XML_ParserFree(parser);
649     return 0;
650   }
651   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
652
653   if (nameSep) {
654     XmlInitEncodingNS(&initEncoding, &encoding, 0);
655     ns = 1;
656     internalEncoding = XmlGetInternalEncodingNS();
657     namespaceSeparator = *nameSep;
658
659     if (! setContext(parser, implicitContext)) {
660       XML_ParserFree(parser);
661       return 0;
662     }
663   }
664   else {
665     XmlInitEncoding(&initEncoding, &encoding, 0);
666     internalEncoding = XmlGetInternalEncoding();
667   }
668
669   return parser;
670 }  /* End XML_ParserCreate_MM */
671
672 int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
673 {
674   if (!encodingName)
675     protocolEncodingName = 0;
676   else {
677     protocolEncodingName = poolCopyString(&tempPool, encodingName);
678     if (!protocolEncodingName)
679       return 0;
680   }
681   return 1;
682 }
683
684 XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
685                                           const XML_Char *context,
686                                           const XML_Char *encodingName)
687 {
688   XML_Parser parser = oldParser;
689   DTD *oldDtd = &dtd;
690   XML_StartElementHandler oldStartElementHandler = startElementHandler;
691   XML_EndElementHandler oldEndElementHandler = endElementHandler;
692   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
693   XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
694   XML_CommentHandler oldCommentHandler = commentHandler;
695   XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
696   XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
697   XML_DefaultHandler oldDefaultHandler = defaultHandler;
698   XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
699   XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
700   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
701   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
702   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
703   XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
704   XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
705   XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
706   XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
707   XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
708   XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
709   ELEMENT_TYPE * oldDeclElementType = declElementType;
710
711   void *oldUserData = userData;
712   void *oldHandlerArg = handlerArg;
713   int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
714   void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
715 #ifdef XML_DTD
716   enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
717 #endif
718   int oldns_triplets = ns_triplets;
719
720   if (ns) {
721     XML_Char tmp[2];
722
723     *tmp = namespaceSeparator;
724     parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
725                                  tmp);
726   }
727   else {
728     parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
729                                  NULL);
730   }
731
732   if (!parser)
733     return 0;
734
735   startElementHandler = oldStartElementHandler;
736   endElementHandler = oldEndElementHandler;
737   characterDataHandler = oldCharacterDataHandler;
738   processingInstructionHandler = oldProcessingInstructionHandler;
739   commentHandler = oldCommentHandler;
740   startCdataSectionHandler = oldStartCdataSectionHandler;
741   endCdataSectionHandler = oldEndCdataSectionHandler;
742   defaultHandler = oldDefaultHandler;
743   unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
744   notationDeclHandler = oldNotationDeclHandler;
745   startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
746   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
747   notStandaloneHandler = oldNotStandaloneHandler;
748   externalEntityRefHandler = oldExternalEntityRefHandler;
749   unknownEncodingHandler = oldUnknownEncodingHandler;
750   elementDeclHandler = oldElementDeclHandler;
751   attlistDeclHandler = oldAttlistDeclHandler;
752   entityDeclHandler = oldEntityDeclHandler;
753   xmlDeclHandler = oldXmlDeclHandler;
754   declElementType = oldDeclElementType;
755   userData = oldUserData;
756   if (oldUserData == oldHandlerArg)
757     handlerArg = userData;
758   else
759     handlerArg = parser;
760   if (oldExternalEntityRefHandlerArg != oldParser)
761     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
762   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
763   ns_triplets = oldns_triplets;
764 #ifdef XML_DTD
765   paramEntityParsing = oldParamEntityParsing;
766   if (context) {
767 #endif /* XML_DTD */
768     if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
769       XML_ParserFree(parser);
770       return 0;
771     }
772     processor = externalEntityInitProcessor;
773 #ifdef XML_DTD
774   }
775   else {
776     dtdSwap(&dtd, oldDtd);
777     parentParser = oldParser;
778     XmlPrologStateInitExternalEntity(&prologState);
779     dtd.complete = 1;
780     hadExternalDoctype = 1;
781   }
782 #endif /* XML_DTD */
783   return parser;
784 }
785
786 static
787 void destroyBindings(BINDING *bindings, XML_Parser parser)
788 {
789   for (;;) {
790     BINDING *b = bindings;
791     if (!b)
792       break;
793     bindings = b->nextTagBinding;
794     FREE(b->uri);
795     FREE(b);
796   }
797 }
798
799 void XML_ParserFree(XML_Parser parser)
800 {
801   for (;;) {
802     TAG *p;
803     if (tagStack == 0) {
804       if (freeTagList == 0)
805         break;
806       tagStack = freeTagList;
807       freeTagList = 0;
808     }
809     p = tagStack;
810     tagStack = tagStack->parent;
811     FREE(p->buf);
812     destroyBindings(p->bindings, parser);
813     FREE(p);
814   }
815   destroyBindings(freeBindingList, parser);
816   destroyBindings(inheritedBindings, parser);
817   poolDestroy(&tempPool);
818   poolDestroy(&temp2Pool);
819 #ifdef XML_DTD
820   if (parentParser) {
821     if (hadExternalDoctype)
822       dtd.complete = 0;
823     dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
824   }
825 #endif /* XML_DTD */
826   dtdDestroy(&dtd, parser);
827   FREE((void *)atts);
828   if (groupConnector)
829     FREE(groupConnector);
830   if (buffer)
831     FREE(buffer);
832   FREE(dataBuf);
833   if (unknownEncodingMem)
834     FREE(unknownEncodingMem);
835   if (unknownEncodingRelease)
836     unknownEncodingRelease(unknownEncodingData);
837   FREE(parser);
838 }
839
840 void XML_UseParserAsHandlerArg(XML_Parser parser)
841 {
842   handlerArg = parser;
843 }
844
845 void
846 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
847   ns_triplets = do_nst;
848 }
849
850 void XML_SetUserData(XML_Parser parser, void *p)
851 {
852   if (handlerArg == userData)
853     handlerArg = userData = p;
854   else
855     userData = p;
856 }
857
858 int XML_SetBase(XML_Parser parser, const XML_Char *p)
859 {
860   if (p) {
861     p = poolCopyString(&dtd.pool, p);
862     if (!p)
863       return 0;
864     curBase = p;
865   }
866   else
867     curBase = 0;
868   return 1;
869 }
870
871 const XML_Char *XML_GetBase(XML_Parser parser)
872 {
873   return curBase;
874 }
875
876 int XML_GetSpecifiedAttributeCount(XML_Parser parser)
877 {
878   return nSpecifiedAtts;
879 }
880
881 int XML_GetIdAttributeIndex(XML_Parser parser)
882 {
883   return idAttIndex;
884 }
885
886 void XML_SetElementHandler(XML_Parser parser,
887                            XML_StartElementHandler start,
888                            XML_EndElementHandler end)
889 {
890   startElementHandler = start;
891   endElementHandler = end;
892 }
893
894 void XML_SetStartElementHandler(XML_Parser parser,
895                                 XML_StartElementHandler start) {
896   startElementHandler = start;
897 }
898
899 void XML_SetEndElementHandler(XML_Parser parser,
900                               XML_EndElementHandler end) {
901   endElementHandler = end;
902 }
903
904 void XML_SetCharacterDataHandler(XML_Parser parser,
905                                  XML_CharacterDataHandler handler)
906 {
907   characterDataHandler = handler;
908 }
909
910 void XML_SetProcessingInstructionHandler(XML_Parser parser,
911                                          XML_ProcessingInstructionHandler handler)
912 {
913   processingInstructionHandler = handler;
914 }
915
916 void XML_SetCommentHandler(XML_Parser parser,
917                            XML_CommentHandler handler)
918 {
919   commentHandler = handler;
920 }
921
922 void XML_SetCdataSectionHandler(XML_Parser parser,
923                                 XML_StartCdataSectionHandler start,
924                                 XML_EndCdataSectionHandler end)
925 {
926   startCdataSectionHandler = start;
927   endCdataSectionHandler = end;
928 }
929
930 void XML_SetStartCdataSectionHandler(XML_Parser parser,
931                                      XML_StartCdataSectionHandler start) {
932   startCdataSectionHandler = start;
933 }
934
935 void XML_SetEndCdataSectionHandler(XML_Parser parser,
936                                    XML_EndCdataSectionHandler end) {
937   endCdataSectionHandler = end;
938 }
939
940 void XML_SetDefaultHandler(XML_Parser parser,
941                            XML_DefaultHandler handler)
942 {
943   defaultHandler = handler;
944   defaultExpandInternalEntities = 0;
945 }
946
947 void XML_SetDefaultHandlerExpand(XML_Parser parser,
948                                  XML_DefaultHandler handler)
949 {
950   defaultHandler = handler;
951   defaultExpandInternalEntities = 1;
952 }
953
954 void XML_SetDoctypeDeclHandler(XML_Parser parser,
955                                XML_StartDoctypeDeclHandler start,
956                                XML_EndDoctypeDeclHandler end)
957 {
958   startDoctypeDeclHandler = start;
959   endDoctypeDeclHandler = end;
960 }
961
962 void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
963                                     XML_StartDoctypeDeclHandler start) {
964   startDoctypeDeclHandler = start;
965 }
966
967 void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
968                                   XML_EndDoctypeDeclHandler end) {
969   endDoctypeDeclHandler = end;
970 }
971
972 void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
973                                       XML_UnparsedEntityDeclHandler handler)
974 {
975   unparsedEntityDeclHandler = handler;
976 }
977
978 void XML_SetNotationDeclHandler(XML_Parser parser,
979                                 XML_NotationDeclHandler handler)
980 {
981   notationDeclHandler = handler;
982 }
983
984 void XML_SetNamespaceDeclHandler(XML_Parser parser,
985                                  XML_StartNamespaceDeclHandler start,
986                                  XML_EndNamespaceDeclHandler end)
987 {
988   startNamespaceDeclHandler = start;
989   endNamespaceDeclHandler = end;
990 }
991
992 void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
993                                       XML_StartNamespaceDeclHandler start) {
994   startNamespaceDeclHandler = start;
995 }
996
997 void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
998                                     XML_EndNamespaceDeclHandler end) {
999   endNamespaceDeclHandler = end;
1000 }
1001
1002
1003 void XML_SetNotStandaloneHandler(XML_Parser parser,
1004                                  XML_NotStandaloneHandler handler)
1005 {
1006   notStandaloneHandler = handler;
1007 }
1008
1009 void XML_SetExternalEntityRefHandler(XML_Parser parser,
1010                                      XML_ExternalEntityRefHandler handler)
1011 {
1012   externalEntityRefHandler = handler;
1013 }
1014
1015 void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1016 {
1017   if (arg)
1018     externalEntityRefHandlerArg = arg;
1019   else
1020     externalEntityRefHandlerArg = parser;
1021 }
1022
1023 void XML_SetUnknownEncodingHandler(XML_Parser parser,
1024                                    XML_UnknownEncodingHandler handler,
1025                                    void *data)
1026 {
1027   unknownEncodingHandler = handler;
1028   unknownEncodingHandlerData = data;
1029 }
1030
1031 void XML_SetElementDeclHandler(XML_Parser parser,
1032                                XML_ElementDeclHandler eldecl)
1033 {
1034   elementDeclHandler = eldecl;
1035 }
1036
1037 void XML_SetAttlistDeclHandler(XML_Parser parser,
1038                                XML_AttlistDeclHandler attdecl)
1039 {
1040   attlistDeclHandler = attdecl;
1041 }
1042
1043 void XML_SetEntityDeclHandler(XML_Parser parser,
1044                               XML_EntityDeclHandler handler)
1045 {
1046   entityDeclHandler = handler;
1047 }
1048
1049 void XML_SetXmlDeclHandler(XML_Parser parser,
1050                            XML_XmlDeclHandler handler) {
1051   xmlDeclHandler = handler;
1052 }
1053
1054 int XML_SetParamEntityParsing(XML_Parser parser,
1055                               enum XML_ParamEntityParsing parsing)
1056 {
1057 #ifdef XML_DTD
1058   paramEntityParsing = parsing;
1059   return 1;
1060 #else
1061   return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
1062 #endif
1063 }
1064
1065 int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1066 {
1067   if (len == 0) {
1068     if (!isFinal)
1069       return 1;
1070     positionPtr = bufferPtr;
1071     errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
1072     if (errorCode == XML_ERROR_NONE)
1073       return 1;
1074     eventEndPtr = eventPtr;
1075     processor = errorProcessor;
1076     return 0;
1077   }
1078 #ifndef XML_CONTEXT_BYTES
1079   else if (bufferPtr == bufferEnd) {
1080     const char *end;
1081     int nLeftOver;
1082     parseEndByteIndex += len;
1083     positionPtr = s;
1084     if (isFinal) {
1085       errorCode = processor(parser, s, parseEndPtr = s + len, 0);
1086       if (errorCode == XML_ERROR_NONE)
1087         return 1;
1088       eventEndPtr = eventPtr;
1089       processor = errorProcessor;
1090       return 0;
1091     }
1092     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1093     if (errorCode != XML_ERROR_NONE) {
1094       eventEndPtr = eventPtr;
1095       processor = errorProcessor;
1096       return 0;
1097     }
1098     XmlUpdatePosition(encoding, positionPtr, end, &position);
1099     nLeftOver = s + len - end;
1100     if (nLeftOver) {
1101       if (buffer == 0 || nLeftOver > bufferLim - buffer) {
1102         /* FIXME avoid integer overflow */
1103         buffer = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
1104         /* FIXME storage leak if realloc fails */
1105         if (!buffer) {
1106           errorCode = XML_ERROR_NO_MEMORY;
1107           eventPtr = eventEndPtr = 0;
1108           processor = errorProcessor;
1109           return 0;
1110         }
1111         bufferLim = buffer + len * 2;
1112       }
1113       memcpy(buffer, end, nLeftOver);
1114       bufferPtr = buffer;
1115       bufferEnd = buffer + nLeftOver;
1116     }
1117     return 1;
1118   }
1119 #endif  /* not defined XML_CONTEXT_BYTES */
1120   else {
1121     memcpy(XML_GetBuffer(parser, len), s, len);
1122     return XML_ParseBuffer(parser, len, isFinal);
1123   }
1124 }
1125
1126 int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1127 {
1128   const char *start = bufferPtr;
1129   positionPtr = start;
1130   bufferEnd += len;
1131   parseEndByteIndex += len;
1132   errorCode = processor(parser, start, parseEndPtr = bufferEnd,
1133                         isFinal ? (const char **)0 : &bufferPtr);
1134   if (errorCode == XML_ERROR_NONE) {
1135     if (!isFinal)
1136       XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1137     return 1;
1138   }
1139   else {
1140     eventEndPtr = eventPtr;
1141     processor = errorProcessor;
1142     return 0;
1143   }
1144 }
1145
1146 void *XML_GetBuffer(XML_Parser parser, int len)
1147 {
1148   if (len > bufferLim - bufferEnd) {
1149     /* FIXME avoid integer overflow */
1150     int neededSize = len + (bufferEnd - bufferPtr);
1151 #ifdef XML_CONTEXT_BYTES
1152     int keep = bufferPtr - buffer;
1153
1154     if (keep > XML_CONTEXT_BYTES)
1155       keep = XML_CONTEXT_BYTES;
1156     neededSize += keep;
1157 #endif  /* defined XML_CONTEXT_BYTES */
1158     if (neededSize  <= bufferLim - buffer) {
1159 #ifdef XML_CONTEXT_BYTES
1160       if (keep < bufferPtr - buffer) {
1161         int offset = (bufferPtr - buffer) - keep;
1162         memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1163         bufferEnd -= offset;
1164         bufferPtr -= offset;
1165       }
1166 #else
1167       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1168       bufferEnd = buffer + (bufferEnd - bufferPtr);
1169       bufferPtr = buffer;
1170 #endif  /* not defined XML_CONTEXT_BYTES */
1171     }
1172     else {
1173       char *newBuf;
1174       int bufferSize = bufferLim - bufferPtr;
1175       if (bufferSize == 0)
1176         bufferSize = INIT_BUFFER_SIZE;
1177       do {
1178         bufferSize *= 2;
1179       } while (bufferSize < neededSize);
1180       newBuf = MALLOC(bufferSize);
1181       if (newBuf == 0) {
1182         errorCode = XML_ERROR_NO_MEMORY;
1183         return 0;
1184       }
1185       bufferLim = newBuf + bufferSize;
1186 #ifdef XML_CONTEXT_BYTES
1187       if (bufferPtr) {
1188         int xmKeep = bufferPtr - buffer;
1189         if (xmKeep > XML_CONTEXT_BYTES)
1190           xmKeep = XML_CONTEXT_BYTES;
1191         memcpy(newBuf, &bufferPtr[-xmKeep], bufferEnd - bufferPtr + xmKeep);
1192         FREE(buffer);
1193         buffer = newBuf;
1194         bufferEnd = buffer + (bufferEnd - bufferPtr) + xmKeep;
1195         bufferPtr = buffer + xmKeep;
1196       }
1197       else {
1198         bufferEnd = newBuf + (bufferEnd - bufferPtr);
1199         bufferPtr = buffer = newBuf;
1200       }
1201 #else
1202       if (bufferPtr) {
1203         memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1204         FREE(buffer);
1205       }
1206       bufferEnd = newBuf + (bufferEnd - bufferPtr);
1207       bufferPtr = buffer = newBuf;
1208 #endif  /* not defined XML_CONTEXT_BYTES */
1209     }
1210   }
1211   return bufferEnd;
1212 }
1213
1214 enum XML_Error XML_GetErrorCode(XML_Parser parser)
1215 {
1216   return errorCode;
1217 }
1218
1219 long XML_GetCurrentByteIndex(XML_Parser parser)
1220 {
1221   if (eventPtr)
1222     return parseEndByteIndex - (parseEndPtr - eventPtr);
1223   return -1;
1224 }
1225
1226 int XML_GetCurrentByteCount(XML_Parser parser)
1227 {
1228   if (eventEndPtr && eventPtr)
1229     return eventEndPtr - eventPtr;
1230   return 0;
1231 }
1232
1233 const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1234 {
1235 #ifdef XML_CONTEXT_BYTES
1236   if (eventPtr && buffer) {
1237     *offset = eventPtr - buffer;
1238     *size   = bufferEnd - buffer;
1239     return buffer;
1240   }
1241 #endif /* defined XML_CONTEXT_BYTES */
1242   return (char *) 0;
1243 }
1244
1245 int XML_GetCurrentLineNumber(XML_Parser parser)
1246 {
1247   if (eventPtr) {
1248     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1249     positionPtr = eventPtr;
1250   }
1251   return position.lineNumber + 1;
1252 }
1253
1254 int XML_GetCurrentColumnNumber(XML_Parser parser)
1255 {
1256   if (eventPtr) {
1257     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1258     positionPtr = eventPtr;
1259   }
1260   return position.columnNumber;
1261 }
1262
1263 void XML_DefaultCurrent(XML_Parser parser)
1264 {
1265   if (defaultHandler) {
1266     if (openInternalEntities)
1267       reportDefault(parser,
1268                     internalEncoding,
1269                     openInternalEntities->internalEventPtr,
1270                     openInternalEntities->internalEventEndPtr);
1271     else
1272       reportDefault(parser, encoding, eventPtr, eventEndPtr);
1273   }
1274 }
1275
1276 const XML_LChar *XML_ErrorString(int code)
1277 {
1278   static const XML_LChar *message[] = {
1279     0,
1280     XML_T("out of memory"),
1281     XML_T("syntax error"),
1282     XML_T("no element found"),
1283     XML_T("not well-formed (invalid token)"),
1284     XML_T("unclosed token"),
1285     XML_T("unclosed token"),
1286     XML_T("mismatched tag"),
1287     XML_T("duplicate attribute"),
1288     XML_T("junk after document element"),
1289     XML_T("illegal parameter entity reference"),
1290     XML_T("undefined entity"),
1291     XML_T("recursive entity reference"),
1292     XML_T("asynchronous entity"),
1293     XML_T("reference to invalid character number"),
1294     XML_T("reference to binary entity"),
1295     XML_T("reference to external entity in attribute"),
1296     XML_T("xml processing instruction not at start of external entity"),
1297     XML_T("unknown encoding"),
1298     XML_T("encoding specified in XML declaration is incorrect"),
1299     XML_T("unclosed CDATA section"),
1300     XML_T("error in processing external entity reference"),
1301     XML_T("document is not standalone"),
1302     XML_T("unexpected parser state - please send a bug report")
1303   };
1304   if (code > 0 && code < (int)(sizeof(message)/sizeof(message[0])))
1305     return message[code];
1306   return 0;
1307 }
1308
1309 const XML_LChar *
1310 XML_ExpatVersion(void) {
1311   return VERSION;
1312 }
1313
1314 XML_Expat_Version
1315 XML_ExpatVersionInfo(void) {
1316   XML_Expat_Version version;
1317
1318   version.major = XML_MAJOR_VERSION;
1319   version.minor = XML_MINOR_VERSION;
1320   version.micro = XML_MICRO_VERSION;
1321
1322   return version;
1323 }
1324
1325 static
1326 enum XML_Error contentProcessor(XML_Parser parser,
1327                                 const char *start,
1328                                 const char *end,
1329                                 const char **endPtr)
1330 {
1331   return doContent(parser, 0, encoding, start, end, endPtr);
1332 }
1333
1334 static
1335 enum XML_Error externalEntityInitProcessor(XML_Parser parser,
1336                                            const char *start,
1337                                            const char *end,
1338                                            const char **endPtr)
1339 {
1340   enum XML_Error result = initializeEncoding(parser);
1341   if (result != XML_ERROR_NONE)
1342     return result;
1343   processor = externalEntityInitProcessor2;
1344   return externalEntityInitProcessor2(parser, start, end, endPtr);
1345 }
1346
1347 static
1348 enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
1349                                             const char *start,
1350                                             const char *end,
1351                                             const char **endPtr)
1352 {
1353   const char *next;
1354   int tok = XmlContentTok(encoding, start, end, &next);
1355   switch (tok) {
1356   case XML_TOK_BOM:
1357     start = next;
1358     break;
1359   case XML_TOK_PARTIAL:
1360     if (endPtr) {
1361       *endPtr = start;
1362       return XML_ERROR_NONE;
1363     }
1364     eventPtr = start;
1365     return XML_ERROR_UNCLOSED_TOKEN;
1366   case XML_TOK_PARTIAL_CHAR:
1367     if (endPtr) {
1368       *endPtr = start;
1369       return XML_ERROR_NONE;
1370     }
1371     eventPtr = start;
1372     return XML_ERROR_PARTIAL_CHAR;
1373   }
1374   processor = externalEntityInitProcessor3;
1375   return externalEntityInitProcessor3(parser, start, end, endPtr);
1376 }
1377
1378 static
1379 enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
1380                                             const char *start,
1381                                             const char *end,
1382                                             const char **endPtr)
1383 {
1384   const char *next;
1385   int tok = XmlContentTok(encoding, start, end, &next);
1386   switch (tok) {
1387   case XML_TOK_XML_DECL:
1388     {
1389       enum XML_Error result = processXmlDecl(parser, 1, start, next);
1390       if (result != XML_ERROR_NONE)
1391         return result;
1392       start = next;
1393     }
1394     break;
1395   case XML_TOK_PARTIAL:
1396     if (endPtr) {
1397       *endPtr = start;
1398       return XML_ERROR_NONE;
1399     }
1400     eventPtr = start;
1401     return XML_ERROR_UNCLOSED_TOKEN;
1402   case XML_TOK_PARTIAL_CHAR:
1403     if (endPtr) {
1404       *endPtr = start;
1405       return XML_ERROR_NONE;
1406     }
1407     eventPtr = start;
1408     return XML_ERROR_PARTIAL_CHAR;
1409   }
1410   processor = externalEntityContentProcessor;
1411   tagLevel = 1;
1412   return doContent(parser, 1, encoding, start, end, endPtr);
1413 }
1414
1415 static
1416 enum XML_Error externalEntityContentProcessor(XML_Parser parser,
1417                                               const char *start,
1418                                               const char *end,
1419                                               const char **endPtr)
1420 {
1421   return doContent(parser, 1, encoding, start, end, endPtr);
1422 }
1423
1424 static enum XML_Error
1425 doContent(XML_Parser parser,
1426           int startTagLevel,
1427           const ENCODING *enc,
1428           const char *s,
1429           const char *end,
1430           const char **nextPtr)
1431 {
1432   const char **eventPP;
1433   const char **eventEndPP;
1434   if (enc == encoding) {
1435     eventPP = &eventPtr;
1436     eventEndPP = &eventEndPtr;
1437   }
1438   else {
1439     eventPP = &(openInternalEntities->internalEventPtr);
1440     eventEndPP = &(openInternalEntities->internalEventEndPtr);
1441   }
1442   *eventPP = s;
1443   for (;;) {
1444     const char *next = s; /* XmlContentTok doesn't always set the last arg */
1445     int tok = XmlContentTok(enc, s, end, &next);
1446     *eventEndPP = next;
1447     switch (tok) {
1448     case XML_TOK_TRAILING_CR:
1449       if (nextPtr) {
1450         *nextPtr = s;
1451         return XML_ERROR_NONE;
1452       }
1453       *eventEndPP = end;
1454       if (characterDataHandler) {
1455         XML_Char c = 0xA;
1456         characterDataHandler(handlerArg, &c, 1);
1457       }
1458       else if (defaultHandler)
1459         reportDefault(parser, enc, s, end);
1460       if (startTagLevel == 0)
1461         return XML_ERROR_NO_ELEMENTS;
1462       if (tagLevel != startTagLevel)
1463         return XML_ERROR_ASYNC_ENTITY;
1464       return XML_ERROR_NONE;
1465     case XML_TOK_NONE:
1466       if (nextPtr) {
1467         *nextPtr = s;
1468         return XML_ERROR_NONE;
1469       }
1470       if (startTagLevel > 0) {
1471         if (tagLevel != startTagLevel)
1472           return XML_ERROR_ASYNC_ENTITY;
1473         return XML_ERROR_NONE;
1474       }
1475       return XML_ERROR_NO_ELEMENTS;
1476     case XML_TOK_INVALID:
1477       *eventPP = next;
1478       return XML_ERROR_INVALID_TOKEN;
1479     case XML_TOK_PARTIAL:
1480       if (nextPtr) {
1481         *nextPtr = s;
1482         return XML_ERROR_NONE;
1483       }
1484       return XML_ERROR_UNCLOSED_TOKEN;
1485     case XML_TOK_PARTIAL_CHAR:
1486       if (nextPtr) {
1487         *nextPtr = s;
1488         return XML_ERROR_NONE;
1489       }
1490       return XML_ERROR_PARTIAL_CHAR;
1491     case XML_TOK_ENTITY_REF:
1492       {
1493         const XML_Char *name;
1494         ENTITY *entity;
1495         XML_Char ch = XmlPredefinedEntityName(enc,
1496                                               s + enc->minBytesPerChar,
1497                                               next - enc->minBytesPerChar);
1498         if (ch) {
1499           if (characterDataHandler)
1500             characterDataHandler(handlerArg, &ch, 1);
1501           else if (defaultHandler)
1502             reportDefault(parser, enc, s, next);
1503           break;
1504         }
1505         name = poolStoreString(&dtd.pool, enc,
1506                                 s + enc->minBytesPerChar,
1507                                 next - enc->minBytesPerChar);
1508         if (!name)
1509           return XML_ERROR_NO_MEMORY;
1510         entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
1511         poolDiscard(&dtd.pool);
1512         if (!entity) {
1513           if (dtd.complete || dtd.standalone)
1514             return XML_ERROR_UNDEFINED_ENTITY;
1515           if (defaultHandler)
1516             reportDefault(parser, enc, s, next);
1517           break;
1518         }
1519         if (entity->open)
1520           return XML_ERROR_RECURSIVE_ENTITY_REF;
1521         if (entity->notation)
1522           return XML_ERROR_BINARY_ENTITY_REF;
1523         if (entity) {
1524           if (entity->textPtr) {
1525             enum XML_Error result;
1526             OPEN_INTERNAL_ENTITY openEntity;
1527             if (defaultHandler && !defaultExpandInternalEntities) {
1528               reportDefault(parser, enc, s, next);
1529               break;
1530             }
1531             entity->open = 1;
1532             openEntity.next = openInternalEntities;
1533             openInternalEntities = &openEntity;
1534             openEntity.entity = entity;
1535             openEntity.internalEventPtr = 0;
1536             openEntity.internalEventEndPtr = 0;
1537             result = doContent(parser,
1538                                tagLevel,
1539                                internalEncoding,
1540                                (char *)entity->textPtr,
1541                                (char *)(entity->textPtr + entity->textLen),
1542                                0);
1543             entity->open = 0;
1544             openInternalEntities = openEntity.next;
1545             if (result)
1546               return result;
1547           }
1548           else if (externalEntityRefHandler) {
1549             const XML_Char *context;
1550             entity->open = 1;
1551             context = getContext(parser);
1552             entity->open = 0;
1553             if (!context)
1554               return XML_ERROR_NO_MEMORY;
1555             if (!externalEntityRefHandler(externalEntityRefHandlerArg,
1556                                           context,
1557                                           entity->base,
1558                                           entity->systemId,
1559                                           entity->publicId))
1560               return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
1561             poolDiscard(&tempPool);
1562           }
1563           else if (defaultHandler)
1564             reportDefault(parser, enc, s, next);
1565         }
1566         break;
1567       }
1568     case XML_TOK_START_TAG_WITH_ATTS:
1569       if (!startElementHandler) {
1570         enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
1571         if (result)
1572           return result;
1573       }
1574       /* fall through */
1575     case XML_TOK_START_TAG_NO_ATTS:
1576       {
1577         TAG *tag;
1578         if (freeTagList) {
1579           tag = freeTagList;
1580           freeTagList = freeTagList->parent;
1581         }
1582         else {
1583           tag = MALLOC(sizeof(TAG));
1584           if (!tag)
1585             return XML_ERROR_NO_MEMORY;
1586           tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
1587           if (!tag->buf)
1588             return XML_ERROR_NO_MEMORY;
1589           tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
1590         }
1591         tag->bindings = 0;
1592         tag->parent = tagStack;
1593         tagStack = tag;
1594         tag->name.localPart = 0;
1595         tag->rawName = s + enc->minBytesPerChar;
1596         tag->rawNameLength = XmlNameLength(enc, tag->rawName);
1597         if (nextPtr) {
1598           /* Need to guarantee that:
1599              tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
1600           if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
1601             int bufSize = tag->rawNameLength * 4;
1602             bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
1603             tag->buf = REALLOC(tag->buf, bufSize);
1604             if (!tag->buf)
1605               return XML_ERROR_NO_MEMORY;
1606             tag->bufEnd = tag->buf + bufSize;
1607           }
1608           memcpy(tag->buf, tag->rawName, tag->rawNameLength);
1609           tag->rawName = tag->buf;
1610         }
1611         ++tagLevel;
1612         if (startElementHandler) {
1613           enum XML_Error result;
1614           XML_Char *toPtr;
1615           for (;;) {
1616             const char *rawNameEnd = tag->rawName + tag->rawNameLength;
1617             const char *fromPtr = tag->rawName;
1618             int bufSize;
1619             if (nextPtr)
1620               toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
1621             else
1622               toPtr = (XML_Char *)tag->buf;
1623             tag->name.str = toPtr;
1624             XmlConvert(enc,
1625                        &fromPtr, rawNameEnd,
1626                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
1627             if (fromPtr == rawNameEnd)
1628               break;
1629             bufSize = (tag->bufEnd - tag->buf) << 1;
1630             tag->buf = REALLOC(tag->buf, bufSize);
1631             if (!tag->buf)
1632               return XML_ERROR_NO_MEMORY;
1633             tag->bufEnd = tag->buf + bufSize;
1634             if (nextPtr)
1635               tag->rawName = tag->buf;
1636           }
1637           *toPtr = XML_T('\0');
1638           result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
1639           if (result)
1640             return result;
1641           startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
1642           poolClear(&tempPool);
1643         }
1644         else {
1645           tag->name.str = 0;
1646           if (defaultHandler)
1647             reportDefault(parser, enc, s, next);
1648         }
1649         break;
1650       }
1651     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
1652       if (!startElementHandler) {
1653         enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
1654         if (result)
1655           return result;
1656       }
1657       /* fall through */
1658     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
1659       if (startElementHandler || endElementHandler) {
1660         const char *rawName = s + enc->minBytesPerChar;
1661         enum XML_Error result;
1662         BINDING *bindings = 0;
1663         TAG_NAME name;
1664         name.str = poolStoreString(&tempPool, enc, rawName,
1665                                    rawName + XmlNameLength(enc, rawName));
1666         if (!name.str)
1667           return XML_ERROR_NO_MEMORY;
1668         poolFinish(&tempPool);
1669         result = storeAtts(parser, enc, s, &name, &bindings);
1670         if (result)
1671           return result;
1672         poolFinish(&tempPool);
1673         if (startElementHandler)
1674           startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
1675         if (endElementHandler) {
1676           if (startElementHandler)
1677             *eventPP = *eventEndPP;
1678           endElementHandler(handlerArg, name.str);
1679         }
1680         poolClear(&tempPool);
1681         while (bindings) {
1682           BINDING *b = bindings;
1683           if (endNamespaceDeclHandler)
1684             endNamespaceDeclHandler(handlerArg, b->prefix->name);
1685           bindings = bindings->nextTagBinding;
1686           b->nextTagBinding = freeBindingList;
1687           freeBindingList = b;
1688           b->prefix->binding = b->prevPrefixBinding;
1689         }
1690       }
1691       else if (defaultHandler)
1692         reportDefault(parser, enc, s, next);
1693       if (tagLevel == 0)
1694         return epilogProcessor(parser, next, end, nextPtr);
1695       break;
1696     case XML_TOK_END_TAG:
1697       if (tagLevel == startTagLevel)
1698         return XML_ERROR_ASYNC_ENTITY;
1699       else {
1700         int len;
1701         const char *rawName;
1702         TAG *tag = tagStack;
1703         tagStack = tag->parent;
1704         tag->parent = freeTagList;
1705         freeTagList = tag;
1706         rawName = s + enc->minBytesPerChar*2;
1707         len = XmlNameLength(enc, rawName);
1708         if (len != tag->rawNameLength
1709             || memcmp(tag->rawName, rawName, len) != 0) {
1710           *eventPP = rawName;
1711           return XML_ERROR_TAG_MISMATCH;
1712         }
1713         --tagLevel;
1714         if (endElementHandler && tag->name.str) {
1715           if (tag->name.localPart) {
1716             XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
1717             const XML_Char *from = tag->name.localPart;
1718             while ((*to++ = *from++) != 0)
1719               ;
1720           }
1721           endElementHandler(handlerArg, tag->name.str);
1722         }
1723         else if (defaultHandler)
1724           reportDefault(parser, enc, s, next);
1725         while (tag->bindings) {
1726           BINDING *b = tag->bindings;
1727           if (endNamespaceDeclHandler)
1728             endNamespaceDeclHandler(handlerArg, b->prefix->name);
1729           tag->bindings = tag->bindings->nextTagBinding;
1730           b->nextTagBinding = freeBindingList;
1731           freeBindingList = b;
1732           b->prefix->binding = b->prevPrefixBinding;
1733         }
1734         if (tagLevel == 0)
1735           return epilogProcessor(parser, next, end, nextPtr);
1736       }
1737       break;
1738     case XML_TOK_CHAR_REF:
1739       {
1740         int n = XmlCharRefNumber(enc, s);
1741         if (n < 0)
1742           return XML_ERROR_BAD_CHAR_REF;
1743         if (characterDataHandler) {
1744           XML_Char buf[XML_ENCODE_MAX];
1745           characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
1746         }
1747         else if (defaultHandler)
1748           reportDefault(parser, enc, s, next);
1749       }
1750       break;
1751     case XML_TOK_XML_DECL:
1752       return XML_ERROR_MISPLACED_XML_PI;
1753     case XML_TOK_DATA_NEWLINE:
1754       if (characterDataHandler) {
1755         XML_Char c = 0xA;
1756         characterDataHandler(handlerArg, &c, 1);
1757       }
1758       else if (defaultHandler)
1759         reportDefault(parser, enc, s, next);
1760       break;
1761     case XML_TOK_CDATA_SECT_OPEN:
1762       {
1763         enum XML_Error result;
1764         if (startCdataSectionHandler)
1765           startCdataSectionHandler(handlerArg);
1766 #if 0
1767         /* Suppose you doing a transformation on a document that involves
1768            changing only the character data.  You set up a defaultHandler
1769            and a characterDataHandler.  The defaultHandler simply copies
1770            characters through.  The characterDataHandler does the transformation
1771            and writes the characters out escaping them as necessary.  This case
1772            will fail to work if we leave out the following two lines (because &
1773            and < inside CDATA sections will be incorrectly escaped).
1774
1775            However, now we have a start/endCdataSectionHandler, so it seems
1776            easier to let the user deal with this. */
1777
1778         else if (characterDataHandler)
1779           characterDataHandler(handlerArg, dataBuf, 0);
1780 #endif
1781         else if (defaultHandler)
1782           reportDefault(parser, enc, s, next);
1783         result = doCdataSection(parser, enc, &next, end, nextPtr);
1784         if (!next) {
1785           processor = cdataSectionProcessor;
1786           return result;
1787         }
1788       }
1789       break;
1790     case XML_TOK_TRAILING_RSQB:
1791       if (nextPtr) {
1792         *nextPtr = s;
1793         return XML_ERROR_NONE;
1794       }
1795       if (characterDataHandler) {
1796         if (MUST_CONVERT(enc, s)) {
1797           ICHAR *dataPtr = (ICHAR *)dataBuf;
1798           XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
1799           characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1800         }
1801         else
1802           characterDataHandler(handlerArg,
1803                                (XML_Char *)s,
1804                                (XML_Char *)end - (XML_Char *)s);
1805       }
1806       else if (defaultHandler)
1807         reportDefault(parser, enc, s, end);
1808       if (startTagLevel == 0) {
1809         *eventPP = end;
1810         return XML_ERROR_NO_ELEMENTS;
1811       }
1812       if (tagLevel != startTagLevel) {
1813         *eventPP = end;
1814         return XML_ERROR_ASYNC_ENTITY;
1815       }
1816       return XML_ERROR_NONE;
1817     case XML_TOK_DATA_CHARS:
1818       if (characterDataHandler) {
1819         if (MUST_CONVERT(enc, s)) {
1820           for (;;) {
1821             ICHAR *dataPtr = (ICHAR *)dataBuf;
1822             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
1823             *eventEndPP = s;
1824             characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1825             if (s == next)
1826               break;
1827             *eventPP = s;
1828           }
1829         }
1830         else
1831           characterDataHandler(handlerArg,
1832                                (XML_Char *)s,
1833                                (XML_Char *)next - (XML_Char *)s);
1834       }
1835       else if (defaultHandler)
1836         reportDefault(parser, enc, s, next);
1837       break;
1838     case XML_TOK_PI:
1839       if (!reportProcessingInstruction(parser, enc, s, next))
1840         return XML_ERROR_NO_MEMORY;
1841       break;
1842     case XML_TOK_COMMENT:
1843       if (!reportComment(parser, enc, s, next))
1844         return XML_ERROR_NO_MEMORY;
1845       break;
1846     default:
1847       if (defaultHandler)
1848         reportDefault(parser, enc, s, next);
1849       break;
1850     }
1851     *eventPP = s = next;
1852   }
1853   /* not reached */
1854 }
1855
1856 /* If tagNamePtr is non-null, build a real list of attributes,
1857 otherwise just check the attributes for well-formedness. */
1858
1859 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
1860                                 const char *attStr, TAG_NAME *tagNamePtr,
1861                                 BINDING **bindingsPtr)
1862 {
1863   ELEMENT_TYPE *elementType = 0;
1864   int nDefaultAtts = 0;
1865   const XML_Char **appAtts;   /* the attribute list to pass to the application */
1866   int attIndex = 0;
1867   int i;
1868   int n;
1869   int nPrefixes = 0;
1870   BINDING *binding;
1871   const XML_Char *localPart;
1872
1873   /* lookup the element type name */
1874   if (tagNamePtr) {
1875     elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
1876     if (!elementType) {
1877       tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
1878       if (!tagNamePtr->str)
1879         return XML_ERROR_NO_MEMORY;
1880       elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
1881       if (!elementType)
1882         return XML_ERROR_NO_MEMORY;
1883       if (ns && !setElementTypePrefix(parser, elementType))
1884         return XML_ERROR_NO_MEMORY;
1885     }
1886     nDefaultAtts = elementType->nDefaultAtts;
1887   }
1888   /* get the attributes from the tokenizer */
1889   n = XmlGetAttributes(enc, attStr, attsSize, atts);
1890   if (n + nDefaultAtts > attsSize) {
1891     int oldAttsSize = attsSize;
1892     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
1893     atts = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
1894     if (!atts)
1895       return XML_ERROR_NO_MEMORY;
1896     if (n > oldAttsSize)
1897       XmlGetAttributes(enc, attStr, n, atts);
1898   }
1899   appAtts = (const XML_Char **)atts;
1900   for (i = 0; i < n; i++) {
1901     /* add the name and value to the attribute list */
1902     ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
1903                                          atts[i].name
1904                                          + XmlNameLength(enc, atts[i].name));
1905     if (!attId)
1906       return XML_ERROR_NO_MEMORY;
1907     /* detect duplicate attributes */
1908     if ((attId->name)[-1]) {
1909       if (enc == encoding)
1910         eventPtr = atts[i].name;
1911       return XML_ERROR_DUPLICATE_ATTRIBUTE;
1912     }
1913     (attId->name)[-1] = 1;
1914     appAtts[attIndex++] = attId->name;
1915     if (!atts[i].normalized) {
1916       enum XML_Error result;
1917       int isCdata = 1;
1918
1919       /* figure out whether declared as other than CDATA */
1920       if (attId->maybeTokenized) {
1921         int j;
1922         for (j = 0; j < nDefaultAtts; j++) {
1923           if (attId == elementType->defaultAtts[j].id) {
1924             isCdata = elementType->defaultAtts[j].isCdata;
1925             break;
1926           }
1927         }
1928       }
1929
1930       /* normalize the attribute value */
1931       result = storeAttributeValue(parser, enc, isCdata,
1932                                    atts[i].valuePtr, atts[i].valueEnd,
1933                                    &tempPool);
1934       if (result)
1935         return result;
1936       if (tagNamePtr) {
1937         appAtts[attIndex] = poolStart(&tempPool);
1938         poolFinish(&tempPool);
1939       }
1940       else
1941         poolDiscard(&tempPool);
1942     }
1943     else if (tagNamePtr) {
1944       /* the value did not need normalizing */
1945       appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
1946       if (appAtts[attIndex] == 0)
1947         return XML_ERROR_NO_MEMORY;
1948       poolFinish(&tempPool);
1949     }
1950     /* handle prefixed attribute names */
1951     if (attId->prefix && tagNamePtr) {
1952       if (attId->xmlns) {
1953         /* deal with namespace declarations here */
1954         if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
1955           return XML_ERROR_NO_MEMORY;
1956         --attIndex;
1957       }
1958       else {
1959         /* deal with other prefixed names later */
1960         attIndex++;
1961         nPrefixes++;
1962         (attId->name)[-1] = 2;
1963       }
1964     }
1965     else
1966       attIndex++;
1967   }
1968   if (tagNamePtr) {
1969     int j;
1970     nSpecifiedAtts = attIndex;
1971     if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
1972       for (i = 0; i < attIndex; i += 2)
1973         if (appAtts[i] == elementType->idAtt->name) {
1974           idAttIndex = i;
1975           break;
1976         }
1977     }
1978     else
1979       idAttIndex = -1;
1980     /* do attribute defaulting */
1981     for (j = 0; j < nDefaultAtts; j++) {
1982       const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
1983       if (!(da->id->name)[-1] && da->value) {
1984         if (da->id->prefix) {
1985           if (da->id->xmlns) {
1986             if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
1987               return XML_ERROR_NO_MEMORY;
1988           }
1989           else {
1990             (da->id->name)[-1] = 2;
1991             nPrefixes++;
1992             appAtts[attIndex++] = da->id->name;
1993             appAtts[attIndex++] = da->value;
1994           }
1995         }
1996         else {
1997           (da->id->name)[-1] = 1;
1998           appAtts[attIndex++] = da->id->name;
1999           appAtts[attIndex++] = da->value;
2000         }
2001       }
2002     }
2003     appAtts[attIndex] = 0;
2004   }
2005   i = 0;
2006   if (nPrefixes) {
2007     /* expand prefixed attribute names */
2008     for (; i < attIndex; i += 2) {
2009       if (appAtts[i][-1] == 2) {
2010         ATTRIBUTE_ID *id;
2011         ((XML_Char *)(appAtts[i]))[-1] = 0;
2012         id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
2013         if (id->prefix->binding) {
2014           int j;
2015           const BINDING *b = id->prefix->binding;
2016           const XML_Char *s = appAtts[i];
2017           for (j = 0; j < b->uriLen; j++) {
2018             if (!poolAppendChar(&tempPool, b->uri[j]))
2019               return XML_ERROR_NO_MEMORY;
2020           }
2021           while (*s++ != ':')
2022             ;
2023           do {
2024             if (!poolAppendChar(&tempPool, *s))
2025               return XML_ERROR_NO_MEMORY;
2026           } while (*s++);
2027           if (ns_triplets) {
2028             tempPool.ptr[-1] = namespaceSeparator;
2029             s = b->prefix->name;
2030             do {
2031               if (!poolAppendChar(&tempPool, *s))
2032                 return XML_ERROR_NO_MEMORY;
2033             } while (*s++);
2034           }
2035
2036           appAtts[i] = poolStart(&tempPool);
2037           poolFinish(&tempPool);
2038         }
2039         if (!--nPrefixes)
2040           break;
2041       }
2042       else
2043         ((XML_Char *)(appAtts[i]))[-1] = 0;
2044     }
2045   }
2046   /* clear the flags that say whether attributes were specified */
2047   for (; i < attIndex; i += 2)
2048     ((XML_Char *)(appAtts[i]))[-1] = 0;
2049   if (!tagNamePtr)
2050     return XML_ERROR_NONE;
2051   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2052     binding->attId->name[-1] = 0;
2053   /* expand the element type name */
2054   if (elementType->prefix) {
2055     binding = elementType->prefix->binding;
2056     if (!binding)
2057       return XML_ERROR_NONE;
2058     localPart = tagNamePtr->str;
2059     while (*localPart++ != XML_T(':'))
2060       ;
2061   }
2062   else if (dtd.defaultPrefix.binding) {
2063     binding = dtd.defaultPrefix.binding;
2064     localPart = tagNamePtr->str;
2065   }
2066   else
2067     return XML_ERROR_NONE;
2068   tagNamePtr->localPart = localPart;
2069   tagNamePtr->uriLen = binding->uriLen;
2070   for (i = 0; localPart[i++];)
2071     ;
2072   n = i + binding->uriLen;
2073   if (n > binding->uriAlloc) {
2074     TAG *p;
2075     XML_Char *uri = MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
2076     if (!uri)
2077       return XML_ERROR_NO_MEMORY;
2078     binding->uriAlloc = n + EXPAND_SPARE;
2079     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2080     for (p = tagStack; p; p = p->parent)
2081       if (p->name.str == binding->uri)
2082         p->name.str = uri;
2083     FREE(binding->uri);
2084     binding->uri = uri;
2085   }
2086   memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
2087   tagNamePtr->str = binding->uri;
2088   return XML_ERROR_NONE;
2089 }
2090
2091 static
2092 int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
2093 {
2094   BINDING *b;
2095   int len;
2096   for (len = 0; uri[len]; len++)
2097     ;
2098   if (namespaceSeparator)
2099     len++;
2100   if (freeBindingList) {
2101     b = freeBindingList;
2102     if (len > b->uriAlloc) {
2103       b->uri = REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
2104       if (!b->uri)
2105         return 0;
2106       b->uriAlloc = len + EXPAND_SPARE;
2107     }
2108     freeBindingList = b->nextTagBinding;
2109   }
2110   else {
2111     b = MALLOC(sizeof(BINDING));
2112     if (!b)
2113       return 0;
2114     b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
2115     if (!b->uri) {
2116       FREE(b);
2117       return 0;
2118     }
2119     b->uriAlloc = len + EXPAND_SPARE;
2120   }
2121   b->uriLen = len;
2122   memcpy(b->uri, uri, len * sizeof(XML_Char));
2123   if (namespaceSeparator)
2124     b->uri[len - 1] = namespaceSeparator;
2125   b->prefix = prefix;
2126   b->attId = attId;
2127   b->prevPrefixBinding = prefix->binding;
2128   if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
2129     prefix->binding = 0;
2130   else
2131     prefix->binding = b;
2132   b->nextTagBinding = *bindingsPtr;
2133   *bindingsPtr = b;
2134   if (startNamespaceDeclHandler)
2135     startNamespaceDeclHandler(handlerArg, prefix->name,
2136                               prefix->binding ? uri : 0);
2137   return 1;
2138 }
2139
2140 /* The idea here is to avoid using stack for each CDATA section when
2141 the whole file is parsed with one call. */
2142
2143 static
2144 enum XML_Error cdataSectionProcessor(XML_Parser parser,
2145                                      const char *start,
2146                                      const char *end,
2147                                      const char **endPtr)
2148 {
2149   enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
2150   if (start) {
2151     processor = contentProcessor;
2152     return contentProcessor(parser, start, end, endPtr);
2153   }
2154   return result;
2155 }
2156
2157 /* startPtr gets set to non-null is the section is closed, and to null if
2158 the section is not yet closed. */
2159
2160 static
2161 enum XML_Error doCdataSection(XML_Parser parser,
2162                               const ENCODING *enc,
2163                               const char **startPtr,
2164                               const char *end,
2165                               const char **nextPtr)
2166 {
2167   const char *s = *startPtr;
2168   const char **eventPP;
2169   const char **eventEndPP;
2170   if (enc == encoding) {
2171     eventPP = &eventPtr;
2172     *eventPP = s;
2173     eventEndPP = &eventEndPtr;
2174   }
2175   else {
2176     eventPP = &(openInternalEntities->internalEventPtr);
2177     eventEndPP = &(openInternalEntities->internalEventEndPtr);
2178   }
2179   *eventPP = s;
2180   *startPtr = 0;
2181   for (;;) {
2182     const char *next;
2183     int tok = XmlCdataSectionTok(enc, s, end, &next);
2184     *eventEndPP = next;
2185     switch (tok) {
2186     case XML_TOK_CDATA_SECT_CLOSE:
2187       if (endCdataSectionHandler)
2188         endCdataSectionHandler(handlerArg);
2189 #if 0
2190       /* see comment under XML_TOK_CDATA_SECT_OPEN */
2191       else if (characterDataHandler)
2192         characterDataHandler(handlerArg, dataBuf, 0);
2193 #endif
2194       else if (defaultHandler)
2195         reportDefault(parser, enc, s, next);
2196       *startPtr = next;
2197       return XML_ERROR_NONE;
2198     case XML_TOK_DATA_NEWLINE:
2199       if (characterDataHandler) {
2200         XML_Char c = 0xA;
2201         characterDataHandler(handlerArg, &c, 1);
2202       }
2203       else if (defaultHandler)
2204         reportDefault(parser, enc, s, next);
2205       break;
2206     case XML_TOK_DATA_CHARS:
2207       if (characterDataHandler) {
2208         if (MUST_CONVERT(enc, s)) {
2209           for (;;) {
2210             ICHAR *dataPtr = (ICHAR *)dataBuf;
2211             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2212             *eventEndPP = next;
2213             characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
2214             if (s == next)
2215               break;
2216             *eventPP = s;
2217           }
2218         }
2219         else
2220           characterDataHandler(handlerArg,
2221                                (XML_Char *)s,
2222                                (XML_Char *)next - (XML_Char *)s);
2223       }
2224       else if (defaultHandler)
2225         reportDefault(parser, enc, s, next);
2226       break;
2227     case XML_TOK_INVALID:
2228       *eventPP = next;
2229       return XML_ERROR_INVALID_TOKEN;
2230     case XML_TOK_PARTIAL_CHAR:
2231       if (nextPtr) {
2232         *nextPtr = s;
2233         return XML_ERROR_NONE;
2234       }
2235       return XML_ERROR_PARTIAL_CHAR;
2236     case XML_TOK_PARTIAL:
2237     case XML_TOK_NONE:
2238       if (nextPtr) {
2239         *nextPtr = s;
2240         return XML_ERROR_NONE;
2241       }
2242       return XML_ERROR_UNCLOSED_CDATA_SECTION;
2243     default:
2244       *eventPP = next;
2245       return XML_ERROR_UNEXPECTED_STATE;
2246     }
2247     *eventPP = s = next;
2248   }
2249   /* not reached */
2250 }
2251
2252 #ifdef XML_DTD
2253
2254 /* The idea here is to avoid using stack for each IGNORE section when
2255 the whole file is parsed with one call. */
2256
2257 static
2258 enum XML_Error ignoreSectionProcessor(XML_Parser parser,
2259                                       const char *start,
2260                                       const char *end,
2261                                       const char **endPtr)
2262 {
2263   enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
2264   if (start) {
2265     processor = prologProcessor;
2266     return prologProcessor(parser, start, end, endPtr);
2267   }
2268   return result;
2269 }
2270
2271 /* startPtr gets set to non-null is the section is closed, and to null if
2272 the section is not yet closed. */
2273
2274 static
2275 enum XML_Error doIgnoreSection(XML_Parser parser,
2276                                const ENCODING *enc,
2277                                const char **startPtr,
2278                                const char *end,
2279                                const char **nextPtr)
2280 {
2281   const char *next;
2282   int tok;
2283   const char *s = *startPtr;
2284   const char **eventPP;
2285   const char **eventEndPP;
2286   if (enc == encoding) {
2287     eventPP = &eventPtr;
2288     *eventPP = s;
2289     eventEndPP = &eventEndPtr;
2290   }
2291   else {
2292     eventPP = &(openInternalEntities->internalEventPtr);
2293     eventEndPP = &(openInternalEntities->internalEventEndPtr);
2294   }
2295   *eventPP = s;
2296   *startPtr = 0;
2297   tok = XmlIgnoreSectionTok(enc, s, end, &next);
2298   *eventEndPP = next;
2299   switch (tok) {
2300   case XML_TOK_IGNORE_SECT:
2301     if (defaultHandler)
2302       reportDefault(parser, enc, s, next);
2303     *startPtr = next;
2304     return XML_ERROR_NONE;
2305   case XML_TOK_INVALID:
2306     *eventPP = next;
2307     return XML_ERROR_INVALID_TOKEN;
2308   case XML_TOK_PARTIAL_CHAR:
2309     if (nextPtr) {
2310       *nextPtr = s;
2311       return XML_ERROR_NONE;
2312     }
2313     return XML_ERROR_PARTIAL_CHAR;
2314   case XML_TOK_PARTIAL:
2315   case XML_TOK_NONE:
2316     if (nextPtr) {
2317       *nextPtr = s;
2318       return XML_ERROR_NONE;
2319     }
2320     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2321   default:
2322     *eventPP = next;
2323     return XML_ERROR_UNEXPECTED_STATE;
2324   }
2325   /* not reached */
2326 }
2327
2328 #endif /* XML_DTD */
2329
2330 static enum XML_Error
2331 initializeEncoding(XML_Parser parser)
2332 {
2333   const char *s;
2334 #ifdef XML_UNICODE
2335   char encodingBuf[128];
2336   if (!protocolEncodingName)
2337     s = 0;
2338   else {
2339     int i;
2340     for (i = 0; protocolEncodingName[i]; i++) {
2341       if (i == sizeof(encodingBuf) - 1
2342           || (protocolEncodingName[i] & ~0x7f) != 0) {
2343         encodingBuf[0] = '\0';
2344         break;
2345       }
2346       encodingBuf[i] = (char)protocolEncodingName[i];
2347     }
2348     encodingBuf[i] = '\0';
2349     s = encodingBuf;
2350   }
2351 #else
2352   s = protocolEncodingName;
2353 #endif
2354   if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
2355     return XML_ERROR_NONE;
2356   return handleUnknownEncoding(parser, protocolEncodingName);
2357 }
2358
2359 static enum XML_Error
2360 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
2361                const char *s, const char *next)
2362 {
2363   const char *encodingName = 0;
2364   const char *storedEncName = 0;
2365   const ENCODING *newEncoding = 0;
2366   const char *version = 0;
2367   const char *versionend;
2368   const char *storedversion = 0;
2369   int standalone = -1;
2370   if (!(ns
2371         ? XmlParseXmlDeclNS
2372         : XmlParseXmlDecl)(isGeneralTextEntity,
2373                            encoding,
2374                            s,
2375                            next,
2376                            &eventPtr,
2377                            &version,
2378                            &versionend,
2379                            &encodingName,
2380                            &newEncoding,
2381                            &standalone))
2382     return XML_ERROR_SYNTAX;
2383   if (!isGeneralTextEntity && standalone == 1) {
2384     dtd.standalone = 1;
2385 #ifdef XML_DTD
2386     if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
2387       paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
2388 #endif /* XML_DTD */
2389   }
2390   if (xmlDeclHandler) {
2391     if (encodingName) {
2392       storedEncName = poolStoreString(&temp2Pool,
2393                                       encoding,
2394                                       encodingName,
2395                                       encodingName
2396                                       + XmlNameLength(encoding, encodingName));
2397       if (! storedEncName)
2398         return XML_ERROR_NO_MEMORY;
2399       poolFinish(&temp2Pool);
2400     }
2401     if (version) {
2402       storedversion = poolStoreString(&temp2Pool,
2403                                       encoding,
2404                                       version,
2405                                       versionend - encoding->minBytesPerChar);
2406       if (! storedversion)
2407         return XML_ERROR_NO_MEMORY;
2408     }
2409     xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
2410   }
2411   else if (defaultHandler)
2412     reportDefault(parser, encoding, s, next);
2413   if (!protocolEncodingName) {
2414     if (newEncoding) {
2415       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
2416         eventPtr = encodingName;
2417         return XML_ERROR_INCORRECT_ENCODING;
2418       }
2419       encoding = newEncoding;
2420     }
2421     else if (encodingName) {
2422       enum XML_Error result;
2423       if (! storedEncName) {
2424         storedEncName = poolStoreString(&temp2Pool,
2425                                         encoding,
2426                                         encodingName,
2427                                         encodingName
2428                                         + XmlNameLength(encoding, encodingName));
2429         if (! storedEncName)
2430           return XML_ERROR_NO_MEMORY;
2431       }
2432       result = handleUnknownEncoding(parser, storedEncName);
2433       poolClear(&tempPool);
2434       if (result == XML_ERROR_UNKNOWN_ENCODING)
2435         eventPtr = encodingName;
2436       return result;
2437     }
2438   }
2439
2440   if (storedEncName || storedversion)
2441     poolClear(&temp2Pool);
2442
2443   return XML_ERROR_NONE;
2444 }
2445
2446 static enum XML_Error
2447 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
2448 {
2449   if (unknownEncodingHandler) {
2450     XML_Encoding info;
2451     int i;
2452     for (i = 0; i < 256; i++)
2453       info.map[i] = -1;
2454     info.convert = 0;
2455     info.data = 0;
2456     info.release = 0;
2457     if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
2458       ENCODING *enc;
2459       unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
2460       if (!unknownEncodingMem) {
2461         if (info.release)
2462           info.release(info.data);
2463         return XML_ERROR_NO_MEMORY;
2464       }
2465       enc = (ns
2466              ? XmlInitUnknownEncodingNS
2467              : XmlInitUnknownEncoding)(unknownEncodingMem,
2468                                        info.map,
2469                                        info.convert,
2470                                        info.data);
2471       if (enc) {
2472         unknownEncodingData = info.data;
2473         unknownEncodingRelease = info.release;
2474         encoding = enc;
2475         return XML_ERROR_NONE;
2476       }
2477     }
2478     if (info.release)
2479       info.release(info.data);
2480   }
2481   return XML_ERROR_UNKNOWN_ENCODING;
2482 }
2483
2484 static enum XML_Error
2485 prologInitProcessor(XML_Parser parser,
2486                     const char *s,
2487                     const char *end,
2488                     const char **nextPtr)
2489 {
2490   enum XML_Error result = initializeEncoding(parser);
2491   if (result != XML_ERROR_NONE)
2492     return result;
2493   processor = prologProcessor;
2494   return prologProcessor(parser, s, end, nextPtr);
2495 }
2496
2497 static enum XML_Error
2498 prologProcessor(XML_Parser parser,
2499                 const char *s,
2500                 const char *end,
2501                 const char **nextPtr)
2502 {
2503   const char *next;
2504   int tok = XmlPrologTok(encoding, s, end, &next);
2505   return doProlog(parser, encoding, s, end, tok, next, nextPtr);
2506 }
2507
2508 static enum XML_Error
2509 doProlog(XML_Parser parser,
2510          const ENCODING *enc,
2511          const char *s,
2512          const char *end,
2513          int tok,
2514          const char *next,
2515          const char **nextPtr)
2516 {
2517 #ifdef XML_DTD
2518   static const XML_Char externalSubsetName[] = { '#' , '\0' };
2519 #endif /* XML_DTD */
2520
2521   const char **eventPP;
2522   const char **eventEndPP;
2523   enum XML_Content_Quant quant;
2524
2525   if (enc == encoding) {
2526     eventPP = &eventPtr;
2527     eventEndPP = &eventEndPtr;
2528   }
2529   else {
2530     eventPP = &(openInternalEntities->internalEventPtr);
2531     eventEndPP = &(openInternalEntities->internalEventEndPtr);
2532   }
2533   for (;;) {
2534     int role;
2535     *eventPP = s;
2536     *eventEndPP = next;
2537     if (tok <= 0) {
2538       if (nextPtr != 0 && tok != XML_TOK_INVALID) {
2539         *nextPtr = s;
2540         return XML_ERROR_NONE;
2541       }
2542       switch (tok) {
2543       case XML_TOK_INVALID:
2544         *eventPP = next;
2545         return XML_ERROR_INVALID_TOKEN;
2546       case XML_TOK_PARTIAL:
2547         return XML_ERROR_UNCLOSED_TOKEN;
2548       case XML_TOK_PARTIAL_CHAR:
2549         return XML_ERROR_PARTIAL_CHAR;
2550       case XML_TOK_NONE:
2551 #ifdef XML_DTD
2552         if (enc != encoding)
2553           return XML_ERROR_NONE;
2554         if (parentParser) {
2555           if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
2556               == XML_ROLE_ERROR)
2557             return XML_ERROR_SYNTAX;
2558           hadExternalDoctype = 0;
2559           return XML_ERROR_NONE;
2560         }
2561 #endif /* XML_DTD */
2562         return XML_ERROR_NO_ELEMENTS;
2563       default:
2564         tok = -tok;
2565         next = end;
2566         break;
2567       }
2568     }
2569     role = XmlTokenRole(&prologState, tok, s, next, enc);
2570     switch (role) {
2571     case XML_ROLE_XML_DECL:
2572       {
2573         enum XML_Error result = processXmlDecl(parser, 0, s, next);
2574         if (result != XML_ERROR_NONE)
2575           return result;
2576         enc = encoding;
2577       }
2578       break;
2579     case XML_ROLE_DOCTYPE_NAME:
2580       if (startDoctypeDeclHandler) {
2581         doctypeName = poolStoreString(&tempPool, enc, s, next);
2582         if (! doctypeName)
2583           return XML_ERROR_NO_MEMORY;
2584         poolFinish(&tempPool);
2585         doctypeSysid = 0;
2586         doctypePubid = 0;
2587       }
2588       break;
2589     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
2590       if (startDoctypeDeclHandler) {
2591         startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
2592                                 doctypePubid, 1);
2593         doctypeName = 0;
2594         poolClear(&tempPool);
2595       }
2596       break;
2597 #ifdef XML_DTD
2598     case XML_ROLE_TEXT_DECL:
2599       {
2600         enum XML_Error result = processXmlDecl(parser, 1, s, next);
2601         if (result != XML_ERROR_NONE)
2602           return result;
2603         enc = encoding;
2604       }
2605       break;
2606 #endif /* XML_DTD */
2607     case XML_ROLE_DOCTYPE_PUBLIC_ID:
2608       if (startDoctypeDeclHandler) {
2609         doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1);
2610         if (! doctypePubid)
2611           return XML_ERROR_NO_MEMORY;
2612         poolFinish(&tempPool);
2613       }
2614 #ifdef XML_DTD
2615       declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2616                                     externalSubsetName,
2617                                     sizeof(ENTITY));
2618       if (!declEntity)
2619         return XML_ERROR_NO_MEMORY;
2620 #endif /* XML_DTD */
2621       /* fall through */
2622     case XML_ROLE_ENTITY_PUBLIC_ID:
2623       if (!XmlIsPublicId(enc, s, next, eventPP))
2624         return XML_ERROR_SYNTAX;
2625       if (declEntity) {
2626         XML_Char *tem = poolStoreString(&dtd.pool,
2627                                         enc,
2628                                         s + enc->minBytesPerChar,
2629                                         next - enc->minBytesPerChar);
2630         if (!tem)
2631           return XML_ERROR_NO_MEMORY;
2632         normalizePublicId(tem);
2633         declEntity->publicId = tem;
2634         poolFinish(&dtd.pool);
2635       }
2636       break;
2637     case XML_ROLE_DOCTYPE_CLOSE:
2638       if (doctypeName) {
2639         startDoctypeDeclHandler(handlerArg, doctypeName,
2640                                 doctypeSysid, doctypePubid, 0);
2641         poolClear(&tempPool);
2642       }
2643       if (dtd.complete && hadExternalDoctype) {
2644         dtd.complete = 0;
2645 #ifdef XML_DTD
2646         if (paramEntityParsing && externalEntityRefHandler) {
2647           ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
2648                                             externalSubsetName,
2649                                             0);
2650           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2651                                         0,
2652                                         entity->base,
2653                                         entity->systemId,
2654                                         entity->publicId))
2655            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2656         }
2657 #endif /* XML_DTD */
2658         if (!dtd.complete
2659             && !dtd.standalone
2660             && notStandaloneHandler
2661             && !notStandaloneHandler(handlerArg))
2662           return XML_ERROR_NOT_STANDALONE;
2663       }
2664       if (endDoctypeDeclHandler)
2665         endDoctypeDeclHandler(handlerArg);
2666       break;
2667     case XML_ROLE_INSTANCE_START:
2668       processor = contentProcessor;
2669       return contentProcessor(parser, s, end, nextPtr);
2670     case XML_ROLE_ATTLIST_ELEMENT_NAME:
2671       declElementType = getElementType(parser, enc, s, next);
2672       if (!declElementType)
2673         return XML_ERROR_NO_MEMORY;
2674       break;
2675     case XML_ROLE_ATTRIBUTE_NAME:
2676       declAttributeId = getAttributeId(parser, enc, s, next);
2677       if (!declAttributeId)
2678         return XML_ERROR_NO_MEMORY;
2679       declAttributeIsCdata = 0;
2680       declAttributeType = 0;
2681       declAttributeIsId = 0;
2682       break;
2683     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
2684       declAttributeIsCdata = 1;
2685       declAttributeType = "CDATA";
2686       break;
2687     case XML_ROLE_ATTRIBUTE_TYPE_ID:
2688       declAttributeIsId = 1;
2689       declAttributeType = "ID";
2690       break;
2691     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
2692       declAttributeType = "IDREF";
2693       break;
2694     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
2695       declAttributeType = "IDREFS";
2696       break;
2697     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
2698       declAttributeType = "ENTITY";
2699       break;
2700     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
2701       declAttributeType = "ENTITIES";
2702       break;
2703     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
2704       declAttributeType = "NMTOKEN";
2705       break;
2706     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
2707       declAttributeType = "NMTOKENS";
2708       break;
2709
2710     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
2711     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
2712       if (attlistDeclHandler)
2713       {
2714         char *prefix;
2715         if (declAttributeType) {
2716           prefix = "|";
2717         }
2718         else {
2719           prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
2720                     ? "NOTATION("
2721                     : "(");
2722         }
2723         if (! poolAppendString(&tempPool, prefix))
2724           return XML_ERROR_NO_MEMORY;
2725         if (! poolAppend(&tempPool, enc, s, next))
2726           return XML_ERROR_NO_MEMORY;
2727         declAttributeType = tempPool.start;
2728       }
2729       break;
2730     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
2731     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
2732       if (dtd.complete
2733           && !defineAttribute(declElementType, declAttributeId,
2734                               declAttributeIsCdata, declAttributeIsId, 0,
2735                               parser))
2736         return XML_ERROR_NO_MEMORY;
2737       if (attlistDeclHandler && declAttributeType) {
2738         if (*declAttributeType == '('
2739             || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
2740           /* Enumerated or Notation type */
2741           if (! poolAppendChar(&tempPool, ')')
2742               || ! poolAppendChar(&tempPool, '\0'))
2743             return XML_ERROR_NO_MEMORY;
2744           declAttributeType = tempPool.start;
2745           poolFinish(&tempPool);
2746         }
2747         *eventEndPP = s;
2748         attlistDeclHandler(handlerArg, declElementType->name,
2749                            declAttributeId->name, declAttributeType,
2750                            0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
2751         poolClear(&tempPool);
2752       }
2753       break;
2754     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
2755     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
2756       {
2757         const XML_Char *attVal;
2758         enum XML_Error result
2759           = storeAttributeValue(parser, enc, declAttributeIsCdata,
2760                                 s + enc->minBytesPerChar,
2761                                 next - enc->minBytesPerChar,
2762                                 &dtd.pool);
2763         if (result)
2764           return result;
2765         attVal = poolStart(&dtd.pool);
2766         poolFinish(&dtd.pool);
2767         if (dtd.complete
2768             /* ID attributes aren't allowed to have a default */
2769             && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
2770           return XML_ERROR_NO_MEMORY;
2771         if (attlistDeclHandler && declAttributeType) {
2772           if (*declAttributeType == '('
2773               || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
2774             /* Enumerated or Notation type */
2775             if (! poolAppendChar(&tempPool, ')')
2776                 || ! poolAppendChar(&tempPool, '\0'))
2777               return XML_ERROR_NO_MEMORY;
2778             declAttributeType = tempPool.start;
2779             poolFinish(&tempPool);
2780           }
2781           *eventEndPP = s;
2782           attlistDeclHandler(handlerArg, declElementType->name,
2783                              declAttributeId->name, declAttributeType,
2784                              attVal,
2785                              role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
2786           poolClear(&tempPool);
2787         }
2788         break;
2789       }
2790     case XML_ROLE_ENTITY_VALUE:
2791       {
2792         enum XML_Error result = storeEntityValue(parser, enc,
2793                                                  s + enc->minBytesPerChar,
2794                                                  next - enc->minBytesPerChar);
2795         if (declEntity) {
2796           declEntity->textPtr = poolStart(&dtd.pool);
2797           declEntity->textLen = poolLength(&dtd.pool);
2798           poolFinish(&dtd.pool);
2799           if (entityDeclHandler) {
2800             *eventEndPP = s;
2801             entityDeclHandler(handlerArg,
2802                               declEntity->name,
2803                               declEntity->is_param,
2804                               declEntity->textPtr,
2805                               declEntity->textLen,
2806                               curBase, 0, 0, 0);
2807           }
2808         }
2809         else
2810           poolDiscard(&dtd.pool);
2811         if (result != XML_ERROR_NONE)
2812           return result;
2813       }
2814       break;
2815     case XML_ROLE_DOCTYPE_SYSTEM_ID:
2816       if (startDoctypeDeclHandler) {
2817         doctypeSysid = poolStoreString(&tempPool, enc, s + 1, next - 1);
2818         if (! doctypeSysid)
2819           return XML_ERROR_NO_MEMORY;
2820         poolFinish(&tempPool);
2821       }
2822       if (!dtd.standalone
2823 #ifdef XML_DTD
2824           && !paramEntityParsing
2825 #endif /* XML_DTD */
2826           && notStandaloneHandler
2827           && !notStandaloneHandler(handlerArg))
2828         return XML_ERROR_NOT_STANDALONE;
2829       hadExternalDoctype = 1;
2830 #ifndef XML_DTD
2831       break;
2832 #else /* XML_DTD */
2833       if (!declEntity) {
2834         declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2835                                       externalSubsetName,
2836                                       sizeof(ENTITY));
2837         declEntity->publicId = 0;
2838         if (!declEntity)
2839           return XML_ERROR_NO_MEMORY;
2840       }
2841       /* fall through */
2842 #endif /* XML_DTD */
2843     case XML_ROLE_ENTITY_SYSTEM_ID:
2844       if (declEntity) {
2845         declEntity->systemId = poolStoreString(&dtd.pool, enc,
2846                                                s + enc->minBytesPerChar,
2847                                                next - enc->minBytesPerChar);
2848         if (!declEntity->systemId)
2849           return XML_ERROR_NO_MEMORY;
2850         declEntity->base = curBase;
2851         poolFinish(&dtd.pool);
2852       }
2853       break;
2854     case XML_ROLE_ENTITY_COMPLETE:
2855       if (declEntity && entityDeclHandler) {
2856         *eventEndPP = s;
2857         entityDeclHandler(handlerArg,
2858                           declEntity->name,
2859                           0,0,0,
2860                           declEntity->base,
2861                           declEntity->systemId,
2862                           declEntity->publicId,
2863                           0);
2864       }
2865       break;
2866     case XML_ROLE_ENTITY_NOTATION_NAME:
2867       if (declEntity) {
2868         declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
2869         if (!declEntity->notation)
2870           return XML_ERROR_NO_MEMORY;
2871         poolFinish(&dtd.pool);
2872         if (unparsedEntityDeclHandler) {
2873           *eventEndPP = s;
2874           unparsedEntityDeclHandler(handlerArg,
2875                                     declEntity->name,
2876                                     declEntity->base,
2877                                     declEntity->systemId,
2878                                     declEntity->publicId,
2879                                     declEntity->notation);
2880         }
2881         else if (entityDeclHandler) {
2882           *eventEndPP = s;
2883           entityDeclHandler(handlerArg,
2884                             declEntity->name,
2885                             0,0,0,
2886                             declEntity->base,
2887                             declEntity->systemId,
2888                             declEntity->publicId,
2889                             declEntity->notation);
2890         }
2891       }
2892       break;
2893     case XML_ROLE_GENERAL_ENTITY_NAME:
2894       {
2895         const XML_Char *name;
2896         if (XmlPredefinedEntityName(enc, s, next)) {
2897           declEntity = 0;
2898           break;
2899         }
2900         name = poolStoreString(&dtd.pool, enc, s, next);
2901         if (!name)
2902           return XML_ERROR_NO_MEMORY;
2903         if (dtd.complete) {
2904           declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
2905           if (!declEntity)
2906             return XML_ERROR_NO_MEMORY;
2907           if (declEntity->name != name) {
2908             poolDiscard(&dtd.pool);
2909             declEntity = 0;
2910           }
2911           else {
2912             poolFinish(&dtd.pool);
2913             declEntity->publicId = 0;
2914             declEntity->is_param = 0;
2915           }
2916         }
2917         else {
2918           poolDiscard(&dtd.pool);
2919           declEntity = 0;
2920         }
2921       }
2922       break;
2923     case XML_ROLE_PARAM_ENTITY_NAME:
2924 #ifdef XML_DTD
2925       if (dtd.complete) {
2926         const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
2927         if (!name)
2928           return XML_ERROR_NO_MEMORY;
2929         declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2930                                       name, sizeof(ENTITY));
2931         if (!declEntity)
2932           return XML_ERROR_NO_MEMORY;
2933         if (declEntity->name != name) {
2934           poolDiscard(&dtd.pool);
2935           declEntity = 0;
2936         }
2937         else {
2938           poolFinish(&dtd.pool);
2939           declEntity->publicId = 0;
2940           declEntity->is_param = 1;
2941         }
2942       }
2943 #else /* not XML_DTD */
2944       declEntity = 0;
2945 #endif /* not XML_DTD */
2946       break;
2947     case XML_ROLE_NOTATION_NAME:
2948       declNotationPublicId = 0;
2949       declNotationName = 0;
2950       if (notationDeclHandler) {
2951         declNotationName = poolStoreString(&tempPool, enc, s, next);
2952         if (!declNotationName)
2953           return XML_ERROR_NO_MEMORY;
2954         poolFinish(&tempPool);
2955       }
2956       break;
2957     case XML_ROLE_NOTATION_PUBLIC_ID:
2958       if (!XmlIsPublicId(enc, s, next, eventPP))
2959         return XML_ERROR_SYNTAX;
2960       if (declNotationName) {
2961         XML_Char *tem = poolStoreString(&tempPool,
2962                                         enc,
2963                                         s + enc->minBytesPerChar,
2964                                         next - enc->minBytesPerChar);
2965         if (!tem)
2966           return XML_ERROR_NO_MEMORY;
2967         normalizePublicId(tem);
2968         declNotationPublicId = tem;
2969         poolFinish(&tempPool);
2970       }
2971       break;
2972     case XML_ROLE_NOTATION_SYSTEM_ID:
2973       if (declNotationName && notationDeclHandler) {
2974         const XML_Char *systemId
2975           = poolStoreString(&tempPool, enc,
2976                             s + enc->minBytesPerChar,
2977                             next - enc->minBytesPerChar);
2978         if (!systemId)
2979           return XML_ERROR_NO_MEMORY;
2980         *eventEndPP = s;
2981         notationDeclHandler(handlerArg,
2982                             declNotationName,
2983                             curBase,
2984                             systemId,
2985                             declNotationPublicId);
2986       }
2987       poolClear(&tempPool);
2988       break;
2989     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
2990       if (declNotationPublicId && notationDeclHandler) {
2991         *eventEndPP = s;
2992         notationDeclHandler(handlerArg,
2993                             declNotationName,
2994                             curBase,
2995                             0,
2996                             declNotationPublicId);
2997       }
2998       poolClear(&tempPool);
2999       break;
3000     case XML_ROLE_ERROR:
3001       switch (tok) {
3002       case XML_TOK_PARAM_ENTITY_REF:
3003         return XML_ERROR_PARAM_ENTITY_REF;
3004       case XML_TOK_XML_DECL:
3005         return XML_ERROR_MISPLACED_XML_PI;
3006       default:
3007         return XML_ERROR_SYNTAX;
3008       }
3009 #ifdef XML_DTD
3010     case XML_ROLE_IGNORE_SECT:
3011       {
3012         enum XML_Error result;
3013         if (defaultHandler)
3014           reportDefault(parser, enc, s, next);
3015         result = doIgnoreSection(parser, enc, &next, end, nextPtr);
3016         if (!next) {
3017           processor = ignoreSectionProcessor;
3018           return result;
3019         }
3020       }
3021       break;
3022 #endif /* XML_DTD */
3023     case XML_ROLE_GROUP_OPEN:
3024       if (prologState.level >= groupSize) {
3025         if (groupSize) {
3026           groupConnector = REALLOC(groupConnector, groupSize *= 2);
3027           if (dtd.scaffIndex)
3028             dtd.scaffIndex = REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
3029         }
3030         else
3031           groupConnector = MALLOC(groupSize = 32);
3032         if (!groupConnector)
3033           return XML_ERROR_NO_MEMORY;
3034       }
3035       groupConnector[prologState.level] = 0;
3036       if (dtd.in_eldecl) {
3037         int myindex = nextScaffoldPart(parser);
3038         if (myindex < 0)
3039           return XML_ERROR_NO_MEMORY;
3040         dtd.scaffIndex[dtd.scaffLevel] = myindex;
3041         dtd.scaffLevel++;
3042         dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
3043       }
3044       break;
3045     case XML_ROLE_GROUP_SEQUENCE:
3046       if (groupConnector[prologState.level] == '|')
3047         return XML_ERROR_SYNTAX;
3048       groupConnector[prologState.level] = ',';
3049       break;
3050     case XML_ROLE_GROUP_CHOICE:
3051       if (groupConnector[prologState.level] == ',')
3052         return XML_ERROR_SYNTAX;
3053       if (dtd.in_eldecl
3054           && ! groupConnector[prologState.level]
3055           && dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type != XML_CTYPE_MIXED
3056           ) {
3057         dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_CHOICE;
3058       }
3059       groupConnector[prologState.level] = '|';
3060       break;
3061     case XML_ROLE_PARAM_ENTITY_REF:
3062 #ifdef XML_DTD
3063     case XML_ROLE_INNER_PARAM_ENTITY_REF:
3064       if (paramEntityParsing
3065           && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
3066         const XML_Char *name;
3067         ENTITY *entity;
3068         name = poolStoreString(&dtd.pool, enc,
3069                                 s + enc->minBytesPerChar,
3070                                 next - enc->minBytesPerChar);
3071         if (!name)
3072           return XML_ERROR_NO_MEMORY;
3073         entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
3074         poolDiscard(&dtd.pool);
3075         if (!entity) {
3076           /* FIXME what to do if !dtd.complete? */
3077           return XML_ERROR_UNDEFINED_ENTITY;
3078         }
3079         if (entity->open)
3080           return XML_ERROR_RECURSIVE_ENTITY_REF;
3081         if (entity->textPtr) {
3082           enum XML_Error result;
3083           result = processInternalParamEntity(parser, entity);
3084           if (result != XML_ERROR_NONE)
3085             return result;
3086           break;
3087         }
3088         if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
3089           return XML_ERROR_PARAM_ENTITY_REF;
3090         if (externalEntityRefHandler) {
3091           dtd.complete = 0;
3092           entity->open = 1;
3093           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3094                                         0,
3095                                         entity->base,
3096                                         entity->systemId,
3097                                         entity->publicId)) {
3098             entity->open = 0;
3099             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3100           }
3101           entity->open = 0;
3102           if (dtd.complete)
3103             break;
3104         }
3105       }
3106 #endif /* XML_DTD */
3107       if (!dtd.standalone
3108           && notStandaloneHandler
3109           && !notStandaloneHandler(handlerArg))
3110         return XML_ERROR_NOT_STANDALONE;
3111       dtd.complete = 0;
3112       if (defaultHandler)
3113         reportDefault(parser, enc, s, next);
3114       break;
3115
3116       /* Element declaration stuff */
3117
3118     case XML_ROLE_ELEMENT_NAME:
3119       if (elementDeclHandler) {
3120         declElementType = getElementType(parser, enc, s, next);
3121         if (! declElementType)
3122           return XML_ERROR_NO_MEMORY;
3123         dtd.scaffLevel = 0;
3124         dtd.scaffCount = 0;
3125         dtd.in_eldecl = 1;
3126       }
3127       break;
3128
3129     case XML_ROLE_CONTENT_ANY:
3130     case XML_ROLE_CONTENT_EMPTY:
3131       if (dtd.in_eldecl) {
3132         if (elementDeclHandler) {
3133           XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
3134           if (! content)
3135             return XML_ERROR_NO_MEMORY;
3136           content->quant = XML_CQUANT_NONE;
3137           content->name = 0;
3138           content->numchildren = 0;
3139           content->children = 0;
3140           content->type = ((role == XML_ROLE_CONTENT_ANY) ?
3141                            XML_CTYPE_ANY :
3142                            XML_CTYPE_EMPTY);
3143           *eventEndPP = s;
3144           elementDeclHandler(handlerArg, declElementType->name, content);
3145         }
3146         dtd.in_eldecl = 0;
3147       }
3148       break;
3149       
3150     case XML_ROLE_CONTENT_PCDATA:
3151       if (dtd.in_eldecl) {
3152         dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_MIXED;
3153       }
3154       break;
3155
3156     case XML_ROLE_CONTENT_ELEMENT:
3157       quant = XML_CQUANT_NONE;
3158       goto elementContent;
3159     case XML_ROLE_CONTENT_ELEMENT_OPT:
3160       quant = XML_CQUANT_OPT;
3161       goto elementContent;
3162     case XML_ROLE_CONTENT_ELEMENT_REP:
3163       quant = XML_CQUANT_REP;
3164       goto elementContent;
3165     case XML_ROLE_CONTENT_ELEMENT_PLUS:
3166       quant = XML_CQUANT_PLUS;
3167     elementContent:
3168       if (dtd.in_eldecl)
3169         {
3170           ELEMENT_TYPE *el;
3171           const char *nxt = quant == XML_CQUANT_NONE ? next : next - 1;
3172           int myindex = nextScaffoldPart(parser);
3173           if (myindex < 0)
3174             return XML_ERROR_NO_MEMORY;
3175           dtd.scaffold[myindex].type = XML_CTYPE_NAME;
3176           dtd.scaffold[myindex].quant = quant;
3177           el = getElementType(parser, enc, s, nxt);
3178           if (! el)
3179             return XML_ERROR_NO_MEMORY;
3180           dtd.scaffold[myindex].name = el->name;
3181           dtd.contentStringLen +=  nxt - s + 1;
3182         }
3183       break;
3184
3185     case XML_ROLE_GROUP_CLOSE:
3186       quant = XML_CQUANT_NONE;
3187       goto closeGroup;
3188     case XML_ROLE_GROUP_CLOSE_OPT:
3189       quant = XML_CQUANT_OPT;
3190       goto closeGroup;
3191     case XML_ROLE_GROUP_CLOSE_REP:
3192       quant = XML_CQUANT_REP;
3193       goto closeGroup;
3194     case XML_ROLE_GROUP_CLOSE_PLUS:
3195       quant = XML_CQUANT_PLUS;
3196     closeGroup:
3197       if (dtd.in_eldecl) {
3198         dtd.scaffLevel--;
3199         dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
3200         if (dtd.scaffLevel == 0) {
3201           if (elementDeclHandler) {
3202             XML_Content *model = build_model(parser);
3203             if (! model)
3204               return XML_ERROR_NO_MEMORY;
3205             *eventEndPP = s;
3206             elementDeclHandler(handlerArg, declElementType->name, model);
3207           }
3208           dtd.in_eldecl = 0;
3209           dtd.contentStringLen = 0;
3210         }
3211       }
3212       break;
3213       /* End element declaration stuff */
3214
3215     case XML_ROLE_NONE:
3216       switch (tok) {
3217       case XML_TOK_PI:
3218         if (!reportProcessingInstruction(parser, enc, s, next))
3219           return XML_ERROR_NO_MEMORY;
3220         break;
3221       case XML_TOK_COMMENT:
3222         if (!reportComment(parser, enc, s, next))
3223           return XML_ERROR_NO_MEMORY;
3224         break;
3225       }
3226       break;
3227     }
3228     if (defaultHandler) {
3229       switch (tok) {
3230       case XML_TOK_PI:
3231       case XML_TOK_COMMENT:
3232       case XML_TOK_BOM:
3233       case XML_TOK_XML_DECL:
3234 #ifdef XML_DTD
3235       case XML_TOK_IGNORE_SECT:
3236 #endif /* XML_DTD */
3237       case XML_TOK_PARAM_ENTITY_REF:
3238         break;
3239       default:
3240 #ifdef XML_DTD
3241         if (role != XML_ROLE_IGNORE_SECT)
3242 #endif /* XML_DTD */
3243           reportDefault(parser, enc, s, next);
3244       }
3245     }
3246     s = next;
3247     tok = XmlPrologTok(enc, s, end, &next);
3248   }
3249   /* not reached */
3250 }
3251
3252 static
3253 enum XML_Error epilogProcessor(XML_Parser parser,
3254                                const char *s,
3255                                const char *end,
3256                                const char **nextPtr)
3257 {
3258   processor = epilogProcessor;
3259   eventPtr = s;
3260   for (;;) {
3261     const char *next;
3262     int tok = XmlPrologTok(encoding, s, end, &next);
3263     eventEndPtr = next;
3264     switch (tok) {
3265     case -XML_TOK_PROLOG_S:
3266       if (defaultHandler) {
3267         eventEndPtr = end;
3268         reportDefault(parser, encoding, s, end);
3269       }
3270       /* fall through */
3271     case XML_TOK_NONE:
3272       if (nextPtr)
3273         *nextPtr = end;
3274       return XML_ERROR_NONE;
3275     case XML_TOK_PROLOG_S:
3276       if (defaultHandler)
3277         reportDefault(parser, encoding, s, next);
3278       break;
3279     case XML_TOK_PI:
3280       if (!reportProcessingInstruction(parser, encoding, s, next))
3281         return XML_ERROR_NO_MEMORY;
3282       break;
3283     case XML_TOK_COMMENT:
3284       if (!reportComment(parser, encoding, s, next))
3285         return XML_ERROR_NO_MEMORY;
3286       break;
3287     case XML_TOK_INVALID:
3288       eventPtr = next;
3289       return XML_ERROR_INVALID_TOKEN;
3290     case XML_TOK_PARTIAL:
3291       if (nextPtr) {
3292         *nextPtr = s;
3293         return XML_ERROR_NONE;
3294       }
3295       return XML_ERROR_UNCLOSED_TOKEN;
3296     case XML_TOK_PARTIAL_CHAR:
3297       if (nextPtr) {
3298         *nextPtr = s;
3299         return XML_ERROR_NONE;
3300       }
3301       return XML_ERROR_PARTIAL_CHAR;
3302     default:
3303       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
3304     }
3305     eventPtr = s = next;
3306   }
3307 }
3308
3309 #ifdef XML_DTD
3310
3311 static enum XML_Error
3312 processInternalParamEntity(XML_Parser parser, ENTITY *entity)
3313 {
3314   const char *s, *end, *next;
3315   int tok;
3316   enum XML_Error result;
3317   OPEN_INTERNAL_ENTITY openEntity;
3318   entity->open = 1;
3319   openEntity.next = openInternalEntities;
3320   openInternalEntities = &openEntity;
3321   openEntity.entity = entity;
3322   openEntity.internalEventPtr = 0;
3323   openEntity.internalEventEndPtr = 0;
3324   s = (char *)entity->textPtr;
3325   end = (char *)(entity->textPtr + entity->textLen);
3326   tok = XmlPrologTok(internalEncoding, s, end, &next);
3327   result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
3328   entity->open = 0;
3329   openInternalEntities = openEntity.next;
3330   return result;
3331 }
3332
3333 #endif /* XML_DTD */
3334
3335 static
3336 enum XML_Error errorProcessor(XML_Parser parser,
3337                               const char *s,
3338                               const char *end,
3339                               const char **nextPtr)
3340 {
3341   cmExpatUnused(s);
3342   cmExpatUnused(end);
3343   cmExpatUnused(nextPtr);
3344   return errorCode;
3345 }
3346
3347 static enum XML_Error
3348 storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
3349                     const char *ptr, const char *end,
3350                     STRING_POOL *pool)
3351 {
3352   enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
3353   if (result)
3354     return result;
3355   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
3356     poolChop(pool);
3357   if (!poolAppendChar(pool, XML_T('\0')))
3358     return XML_ERROR_NO_MEMORY;
3359   return XML_ERROR_NONE;
3360 }
3361
3362 static enum XML_Error
3363 appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
3364                      const char *ptr, const char *end,
3365                      STRING_POOL *pool)
3366 {
3367   for (;;) {
3368     const char *next;
3369     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
3370     switch (tok) {
3371     case XML_TOK_NONE:
3372       return XML_ERROR_NONE;
3373     case XML_TOK_INVALID:
3374       if (enc == encoding)
3375         eventPtr = next;
3376       return XML_ERROR_INVALID_TOKEN;
3377     case XML_TOK_PARTIAL:
3378       if (enc == encoding)
3379         eventPtr = ptr;
3380       return XML_ERROR_INVALID_TOKEN;
3381     case XML_TOK_CHAR_REF:
3382       {
3383         XML_Char buf[XML_ENCODE_MAX];
3384         int i;
3385         int n = XmlCharRefNumber(enc, ptr);
3386         if (n < 0) {
3387           if (enc == encoding)
3388             eventPtr = ptr;
3389           return XML_ERROR_BAD_CHAR_REF;
3390         }
3391         if (!isCdata
3392             && n == 0x20 /* space */
3393             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
3394           break;
3395         n = XmlEncode(n, (ICHAR *)buf);
3396         if (!n) {
3397           if (enc == encoding)
3398             eventPtr = ptr;
3399           return XML_ERROR_BAD_CHAR_REF;
3400         }
3401         for (i = 0; i < n; i++) {
3402           if (!poolAppendChar(pool, buf[i]))
3403             return XML_ERROR_NO_MEMORY;
3404         }
3405       }
3406       break;
3407     case XML_TOK_DATA_CHARS:
3408       if (!poolAppend(pool, enc, ptr, next))
3409         return XML_ERROR_NO_MEMORY;
3410       break;
3411     case XML_TOK_TRAILING_CR:
3412       next = ptr + enc->minBytesPerChar;
3413       /* fall through */
3414     case XML_TOK_ATTRIBUTE_VALUE_S:
3415     case XML_TOK_DATA_NEWLINE:
3416       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
3417         break;
3418       if (!poolAppendChar(pool, 0x20))
3419         return XML_ERROR_NO_MEMORY;
3420       break;
3421     case XML_TOK_ENTITY_REF:
3422       {
3423         const XML_Char *name;
3424         ENTITY *entity;
3425         XML_Char ch = XmlPredefinedEntityName(enc,
3426                                               ptr + enc->minBytesPerChar,
3427                                               next - enc->minBytesPerChar);
3428         if (ch) {
3429           if (!poolAppendChar(pool, ch))
3430             return XML_ERROR_NO_MEMORY;
3431           break;
3432         }
3433         name = poolStoreString(&temp2Pool, enc,
3434                                ptr + enc->minBytesPerChar,
3435                                next - enc->minBytesPerChar);
3436         if (!name)
3437           return XML_ERROR_NO_MEMORY;
3438         entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
3439         poolDiscard(&temp2Pool);
3440         if (!entity) {
3441           if (dtd.complete) {
3442             if (enc == encoding)
3443               eventPtr = ptr;
3444             return XML_ERROR_UNDEFINED_ENTITY;
3445           }
3446         }
3447         else if (entity->open) {
3448           if (enc == encoding)
3449             eventPtr = ptr;
3450           return XML_ERROR_RECURSIVE_ENTITY_REF;
3451         }
3452         else if (entity->notation) {
3453           if (enc == encoding)
3454             eventPtr = ptr;
3455           return XML_ERROR_BINARY_ENTITY_REF;
3456         }
3457         else if (!entity->textPtr) {
3458           if (enc == encoding)
3459             eventPtr = ptr;
3460           return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
3461         }
3462         else {
3463           enum XML_Error result;
3464           const XML_Char *textEnd = entity->textPtr + entity->textLen;
3465           entity->open = 1;
3466           result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
3467           entity->open = 0;
3468           if (result)
3469             return result;
3470         }
3471       }
3472       break;
3473     default:
3474       if (enc == encoding)
3475         eventPtr = ptr;
3476       return XML_ERROR_UNEXPECTED_STATE;
3477     }
3478     ptr = next;
3479   }
3480   /* not reached */
3481 }
3482
3483 static
3484 enum XML_Error storeEntityValue(XML_Parser parser,
3485                                 const ENCODING *enc,
3486                                 const char *entityTextPtr,
3487                                 const char *entityTextEnd)
3488 {
3489   STRING_POOL *pool = &(dtd.pool);
3490   for (;;) {
3491     const char *next;
3492     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
3493     switch (tok) {
3494     case XML_TOK_PARAM_ENTITY_REF:
3495 #ifdef XML_DTD
3496       if (parentParser || enc != encoding) {
3497         enum XML_Error result;
3498         const XML_Char *name;
3499         ENTITY *entity;
3500         name = poolStoreString(&tempPool, enc,
3501                                entityTextPtr + enc->minBytesPerChar,
3502                                next - enc->minBytesPerChar);
3503         if (!name)
3504           return XML_ERROR_NO_MEMORY;
3505         entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
3506         poolDiscard(&tempPool);
3507         if (!entity) {
3508           if (enc == encoding)
3509             eventPtr = entityTextPtr;
3510           return XML_ERROR_UNDEFINED_ENTITY;
3511         }
3512         if (entity->open) {
3513           if (enc == encoding)
3514             eventPtr = entityTextPtr;
3515           return XML_ERROR_RECURSIVE_ENTITY_REF;
3516         }
3517         if (entity->systemId) {
3518           if (enc == encoding)
3519             eventPtr = entityTextPtr;
3520           return XML_ERROR_PARAM_ENTITY_REF;
3521         }
3522         entity->open = 1;
3523         result = storeEntityValue(parser,
3524                                   internalEncoding,
3525                                   (char *)entity->textPtr,
3526                                   (char *)(entity->textPtr + entity->textLen));
3527         entity->open = 0;
3528         if (result)
3529           return result;
3530         break;
3531       }
3532 #endif /* XML_DTD */
3533       eventPtr = entityTextPtr;
3534       return XML_ERROR_SYNTAX;
3535     case XML_TOK_NONE:
3536       return XML_ERROR_NONE;
3537     case XML_TOK_ENTITY_REF:
3538     case XML_TOK_DATA_CHARS:
3539       if (!poolAppend(pool, enc, entityTextPtr, next))
3540         return XML_ERROR_NO_MEMORY;
3541       break;
3542     case XML_TOK_TRAILING_CR:
3543       next = entityTextPtr + enc->minBytesPerChar;
3544       /* fall through */
3545     case XML_TOK_DATA_NEWLINE:
3546       if (pool->end == pool->ptr && !poolGrow(pool))
3547         return XML_ERROR_NO_MEMORY;
3548       *(pool->ptr)++ = 0xA;
3549       break;
3550     case XML_TOK_CHAR_REF:
3551       {
3552         XML_Char buf[XML_ENCODE_MAX];
3553         int i;
3554         int n = XmlCharRefNumber(enc, entityTextPtr);
3555         if (n < 0) {
3556           if (enc == encoding)
3557             eventPtr = entityTextPtr;
3558           return XML_ERROR_BAD_CHAR_REF;
3559         }
3560         n = XmlEncode(n, (ICHAR *)buf);
3561         if (!n) {
3562           if (enc == encoding)
3563             eventPtr = entityTextPtr;
3564           return XML_ERROR_BAD_CHAR_REF;
3565         }
3566         for (i = 0; i < n; i++) {
3567           if (pool->end == pool->ptr && !poolGrow(pool))
3568             return XML_ERROR_NO_MEMORY;
3569           *(pool->ptr)++ = buf[i];
3570         }
3571       }
3572       break;
3573     case XML_TOK_PARTIAL:
3574       if (enc == encoding)
3575         eventPtr = entityTextPtr;
3576       return XML_ERROR_INVALID_TOKEN;
3577     case XML_TOK_INVALID:
3578       if (enc == encoding)
3579         eventPtr = next;
3580       return XML_ERROR_INVALID_TOKEN;
3581     default:
3582       if (enc == encoding)
3583         eventPtr = entityTextPtr;
3584       return XML_ERROR_UNEXPECTED_STATE;
3585     }
3586     entityTextPtr = next;
3587   }
3588   /* not reached */
3589 }
3590
3591 static void
3592 normalizeLines(XML_Char *s)
3593 {
3594   XML_Char *p;
3595   for (;; s++) {
3596     if (*s == XML_T('\0'))
3597       return;
3598     if (*s == 0xD)
3599       break;
3600   }
3601   p = s;
3602   do {
3603     if (*s == 0xD) {
3604       *p++ = 0xA;
3605       if (*++s == 0xA)
3606         s++;
3607     }
3608     else
3609       *p++ = *s++;
3610   } while (*s);
3611   *p = XML_T('\0');
3612 }
3613
3614 static int
3615 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3616 {
3617   const XML_Char *target;
3618   XML_Char *data;
3619   const char *tem;
3620   if (!processingInstructionHandler) {
3621     if (defaultHandler)
3622       reportDefault(parser, enc, start, end);
3623     return 1;
3624   }
3625   start += enc->minBytesPerChar * 2;
3626   tem = start + XmlNameLength(enc, start);
3627   target = poolStoreString(&tempPool, enc, start, tem);
3628   if (!target)
3629     return 0;
3630   poolFinish(&tempPool);
3631   data = poolStoreString(&tempPool, enc,
3632                         XmlSkipS(enc, tem),
3633                         end - enc->minBytesPerChar*2);
3634   if (!data)
3635     return 0;
3636   normalizeLines(data);
3637   processingInstructionHandler(handlerArg, target, data);
3638   poolClear(&tempPool);
3639   return 1;
3640 }
3641
3642 static int
3643 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3644 {
3645   XML_Char *data;
3646   if (!commentHandler) {
3647     if (defaultHandler)
3648       reportDefault(parser, enc, start, end);
3649     return 1;
3650   }
3651   data = poolStoreString(&tempPool,
3652                          enc,
3653                          start + enc->minBytesPerChar * 4, 
3654                          end - enc->minBytesPerChar * 3);
3655   if (!data)
3656     return 0;
3657   normalizeLines(data);
3658   commentHandler(handlerArg, data);
3659   poolClear(&tempPool);
3660   return 1;
3661 }
3662
3663 static void
3664 reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
3665 {
3666   if (MUST_CONVERT(enc, s)) {
3667     const char **eventPP;
3668     const char **eventEndPP;
3669     if (enc == encoding) {
3670       eventPP = &eventPtr;
3671       eventEndPP = &eventEndPtr;
3672     }
3673     else {
3674       eventPP = &(openInternalEntities->internalEventPtr);
3675       eventEndPP = &(openInternalEntities->internalEventEndPtr);
3676     }
3677     do {
3678       ICHAR *dataPtr = (ICHAR *)dataBuf;
3679       XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
3680       *eventEndPP = s;
3681       defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
3682       *eventPP = s;
3683     } while (s != end);
3684   }
3685   else
3686     defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
3687 }
3688
3689
3690 static int
3691 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata,
3692                 int isId, const XML_Char *value, XML_Parser parser)
3693 {
3694   DEFAULT_ATTRIBUTE *att;
3695   if (value || isId) {
3696     /* The handling of default attributes gets messed up if we have
3697        a default which duplicates a non-default. */
3698     int i;
3699     for (i = 0; i < type->nDefaultAtts; i++)
3700       if (attId == type->defaultAtts[i].id)
3701         return 1;
3702     if (isId && !type->idAtt && !attId->xmlns)
3703       type->idAtt = attId;
3704   }
3705   if (type->nDefaultAtts == type->allocDefaultAtts) {
3706     if (type->allocDefaultAtts == 0) {
3707       type->allocDefaultAtts = 8;
3708       type->defaultAtts = MALLOC(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
3709     }
3710     else {
3711       type->allocDefaultAtts *= 2;
3712       type->defaultAtts = REALLOC(type->defaultAtts,
3713                                   type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
3714     }
3715     if (!type->defaultAtts)
3716       return 0;
3717   }
3718   att = type->defaultAtts + type->nDefaultAtts;
3719   att->id = attId;
3720   att->value = value;
3721   att->isCdata = isCdata;
3722   if (!isCdata)
3723     attId->maybeTokenized = 1;
3724   type->nDefaultAtts += 1;
3725   return 1;
3726 }
3727
3728 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
3729 {
3730   const XML_Char *name;
3731   for (name = elementType->name; *name; name++) {
3732     if (*name == XML_T(':')) {
3733       PREFIX *prefix;
3734       const XML_Char *s;
3735       for (s = elementType->name; s != name; s++) {
3736         if (!poolAppendChar(&dtd.pool, *s))
3737           return 0;
3738       }
3739       if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3740         return 0;
3741       prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
3742       if (!prefix)
3743         return 0;
3744       if (prefix->name == poolStart(&dtd.pool))
3745         poolFinish(&dtd.pool);
3746       else
3747         poolDiscard(&dtd.pool);
3748       elementType->prefix = prefix;
3749
3750     }
3751   }
3752   return 1;
3753 }
3754
3755 static ATTRIBUTE_ID *
3756 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3757 {
3758   ATTRIBUTE_ID *id;
3759   const XML_Char *name;
3760   if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3761     return 0;
3762   name = poolStoreString(&dtd.pool, enc, start, end);
3763   if (!name)
3764     return 0;
3765   ++name;
3766   id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
3767   if (!id)
3768     return 0;
3769   if (id->name != name)
3770     poolDiscard(&dtd.pool);
3771   else {
3772     poolFinish(&dtd.pool);
3773     if (!ns)
3774       ;
3775     else if (name[0] == 'x'
3776         && name[1] == 'm'
3777         && name[2] == 'l'
3778         && name[3] == 'n'
3779         && name[4] == 's'
3780         && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
3781       if (name[5] == '\0')
3782         id->prefix = &dtd.defaultPrefix;
3783       else
3784         id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
3785       id->xmlns = 1;
3786     }
3787     else {
3788       int i;
3789       for (i = 0; name[i]; i++) {
3790         if (name[i] == XML_T(':')) {
3791           int j;
3792           for (j = 0; j < i; j++) {
3793             if (!poolAppendChar(&dtd.pool, name[j]))
3794               return 0;
3795           }
3796           if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3797             return 0;
3798           id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
3799           if (id->prefix->name == poolStart(&dtd.pool))
3800             poolFinish(&dtd.pool);
3801           else
3802             poolDiscard(&dtd.pool);
3803           break;
3804         }
3805       }
3806     }
3807   }
3808   return id;
3809 }
3810
3811 #define CONTEXT_SEP XML_T('\f')
3812
3813 static
3814 const XML_Char *getContext(XML_Parser parser)
3815 {
3816   HASH_TABLE_ITER iter;
3817   int needSep = 0;
3818
3819   if (dtd.defaultPrefix.binding) {
3820     int i;
3821     int len;
3822     if (!poolAppendChar(&tempPool, XML_T('=')))
3823       return 0;
3824     len = dtd.defaultPrefix.binding->uriLen;
3825     if (namespaceSeparator != XML_T('\0'))
3826       len--;
3827     for (i = 0; i < len; i++)
3828       if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
3829         return 0;
3830     needSep = 1;
3831   }
3832
3833   hashTableIterInit(&iter, &(dtd.prefixes));
3834   for (;;) {
3835     int i;
3836     int len;
3837     const XML_Char *s;
3838     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
3839     if (!prefix)
3840       break;
3841     if (!prefix->binding)
3842       continue;
3843     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
3844       return 0;
3845     for (s = prefix->name; *s; s++)
3846       if (!poolAppendChar(&tempPool, *s))
3847         return 0;
3848     if (!poolAppendChar(&tempPool, XML_T('=')))
3849       return 0;
3850     len = prefix->binding->uriLen;
3851     if (namespaceSeparator != XML_T('\0'))
3852       len--;
3853     for (i = 0; i < len; i++)
3854       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
3855         return 0;
3856     needSep = 1;
3857   }
3858
3859
3860   hashTableIterInit(&iter, &(dtd.generalEntities));
3861   for (;;) {
3862     const XML_Char *s;
3863     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
3864     if (!e)
3865       break;
3866     if (!e->open)
3867       continue;
3868     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
3869       return 0;
3870     for (s = e->name; *s; s++)
3871       if (!poolAppendChar(&tempPool, *s))
3872         return 0;
3873     needSep = 1;
3874   }
3875
3876   if (!poolAppendChar(&tempPool, XML_T('\0')))
3877     return 0;
3878   return tempPool.start;
3879 }
3880
3881 static
3882 int setContext(XML_Parser parser, const XML_Char *context)
3883 {
3884   const XML_Char *s = context;
3885
3886   while (*context != XML_T('\0')) {
3887     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
3888       ENTITY *e;
3889       if (!poolAppendChar(&tempPool, XML_T('\0')))
3890         return 0;
3891       e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
3892       if (e)
3893         e->open = 1;
3894       if (*s != XML_T('\0'))
3895         s++;
3896       context = s;
3897       poolDiscard(&tempPool);
3898     }
3899     else if (*s == '=') {
3900       PREFIX *prefix;
3901       if (poolLength(&tempPool) == 0)
3902         prefix = &dtd.defaultPrefix;
3903       else {
3904         if (!poolAppendChar(&tempPool, XML_T('\0')))
3905           return 0;
3906         prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
3907         if (!prefix)
3908           return 0;
3909         if (prefix->name == poolStart(&tempPool)) {
3910           prefix->name = poolCopyString(&dtd.pool, prefix->name);
3911           if (!prefix->name)
3912             return 0;
3913         }
3914         poolDiscard(&tempPool);
3915       }
3916       for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
3917         if (!poolAppendChar(&tempPool, *context))
3918           return 0;
3919       if (!poolAppendChar(&tempPool, XML_T('\0')))
3920         return 0;
3921       if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
3922         return 0;
3923       poolDiscard(&tempPool);
3924       if (*context != XML_T('\0'))
3925         ++context;
3926       s = context;
3927     }
3928     else {
3929       if (!poolAppendChar(&tempPool, *s))
3930         return 0;
3931       s++;
3932     }
3933   }
3934   return 1;
3935 }
3936
3937
3938 static
3939 void normalizePublicId(XML_Char *publicId)
3940 {
3941   XML_Char *p = publicId;
3942   XML_Char *s;
3943   for (s = publicId; *s; s++) {
3944     switch (*s) {
3945     case 0x20:
3946     case 0xD:
3947     case 0xA:
3948       if (p != publicId && p[-1] != 0x20)
3949         *p++ = 0x20;
3950       break;
3951     default:
3952       *p++ = *s;
3953     }
3954   }
3955   if (p != publicId && p[-1] == 0x20)
3956     --p;
3957   *p = XML_T('\0');
3958 }
3959
3960 static int dtdInit(DTD *p, XML_Parser parser)
3961 {
3962   XML_Memory_Handling_Suite *ms = &((Parser *) parser)->m_mem; 
3963   poolInit(&(p->pool), ms);
3964   hashTableInit(&(p->generalEntities), ms);
3965   hashTableInit(&(p->elementTypes), ms);
3966   hashTableInit(&(p->attributeIds), ms);
3967   hashTableInit(&(p->prefixes), ms);
3968   p->complete = 1;
3969   p->standalone = 0;
3970 #ifdef XML_DTD
3971   hashTableInit(&(p->paramEntities), ms);
3972 #endif /* XML_DTD */
3973   p->defaultPrefix.name = 0;
3974   p->defaultPrefix.binding = 0;
3975
3976   p->in_eldecl = 0;
3977   p->scaffIndex = 0;
3978   p->scaffLevel = 0;
3979   p->scaffold = 0;
3980   p->contentStringLen = 0;
3981   p->scaffSize = 0;
3982   p->scaffCount = 0;
3983
3984   return 1;
3985 }
3986
3987 #ifdef XML_DTD
3988
3989 static void dtdSwap(DTD *p1, DTD *p2)
3990 {
3991   DTD tem;
3992   memcpy(&tem, p1, sizeof(DTD));
3993   memcpy(p1, p2, sizeof(DTD));
3994   memcpy(p2, &tem, sizeof(DTD));
3995 }
3996
3997 #endif /* XML_DTD */
3998
3999 static void dtdDestroy(DTD *p, XML_Parser parser)
4000 {
4001   HASH_TABLE_ITER iter;
4002   hashTableIterInit(&iter, &(p->elementTypes));
4003   for (;;) {
4004     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4005     if (!e)
4006       break;
4007     if (e->allocDefaultAtts != 0)
4008       FREE(e->defaultAtts);
4009   }
4010   hashTableDestroy(&(p->generalEntities));
4011 #ifdef XML_DTD
4012   hashTableDestroy(&(p->paramEntities));
4013 #endif /* XML_DTD */
4014   hashTableDestroy(&(p->elementTypes));
4015   hashTableDestroy(&(p->attributeIds));
4016   hashTableDestroy(&(p->prefixes));
4017   poolDestroy(&(p->pool));
4018   if (p->scaffIndex)
4019     FREE(p->scaffIndex);
4020   if (p->scaffold)
4021     FREE(p->scaffold);
4022 }
4023
4024 /* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
4025 The new DTD has already been initialized. */
4026
4027 static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser)
4028 {
4029   HASH_TABLE_ITER iter;
4030
4031   /* Copy the prefix table. */
4032
4033   hashTableIterInit(&iter, &(oldDtd->prefixes));
4034   for (;;) {
4035     const XML_Char *name;
4036     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
4037     if (!oldP)
4038       break;
4039     name = poolCopyString(&(newDtd->pool), oldP->name);
4040     if (!name)
4041       return 0;
4042     if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
4043       return 0;
4044   }
4045
4046   hashTableIterInit(&iter, &(oldDtd->attributeIds));
4047
4048   /* Copy the attribute id table. */
4049
4050   for (;;) {
4051     ATTRIBUTE_ID *newA;
4052     const XML_Char *name;
4053     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
4054
4055     if (!oldA)
4056       break;
4057     /* Remember to allocate the scratch byte before the name. */
4058     if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
4059       return 0;
4060     name = poolCopyString(&(newDtd->pool), oldA->name);
4061     if (!name)
4062       return 0;
4063     ++name;
4064     newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
4065     if (!newA)
4066       return 0;
4067     newA->maybeTokenized = oldA->maybeTokenized;
4068     if (oldA->prefix) {
4069       newA->xmlns = oldA->xmlns;
4070       if (oldA->prefix == &oldDtd->defaultPrefix)
4071         newA->prefix = &newDtd->defaultPrefix;
4072       else
4073         newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
4074     }
4075   }
4076
4077   /* Copy the element type table. */
4078
4079   hashTableIterInit(&iter, &(oldDtd->elementTypes));
4080
4081   for (;;) {
4082     int i;
4083     ELEMENT_TYPE *newE;
4084     const XML_Char *name;
4085     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4086     if (!oldE)
4087       break;
4088     name = poolCopyString(&(newDtd->pool), oldE->name);
4089     if (!name)
4090       return 0;
4091     newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
4092     if (!newE)
4093       return 0;
4094     if (oldE->nDefaultAtts) {
4095       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
4096       if (!newE->defaultAtts)
4097         return 0;
4098     }
4099     if (oldE->idAtt)
4100       newE->idAtt = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
4101     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
4102     if (oldE->prefix)
4103       newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
4104     for (i = 0; i < newE->nDefaultAtts; i++) {
4105       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
4106       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
4107       if (oldE->defaultAtts[i].value) {
4108         newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
4109         if (!newE->defaultAtts[i].value)
4110           return 0;
4111       }
4112       else
4113         newE->defaultAtts[i].value = 0;
4114     }
4115   }
4116
4117   /* Copy the entity tables. */
4118   if (!copyEntityTable(&(newDtd->generalEntities),
4119                        &(newDtd->pool),
4120                        &(oldDtd->generalEntities), parser))
4121       return 0;
4122
4123 #ifdef XML_DTD
4124   if (!copyEntityTable(&(newDtd->paramEntities),
4125                        &(newDtd->pool),
4126                        &(oldDtd->paramEntities), parser))
4127       return 0;
4128 #endif /* XML_DTD */
4129
4130   newDtd->complete = oldDtd->complete;
4131   newDtd->standalone = oldDtd->standalone;
4132
4133   /* Don't want deep copying for scaffolding */
4134   newDtd->in_eldecl = oldDtd->in_eldecl;
4135   newDtd->scaffold = oldDtd->scaffold;
4136   newDtd->contentStringLen = oldDtd->contentStringLen;
4137   newDtd->scaffSize = oldDtd->scaffSize;
4138   newDtd->scaffLevel = oldDtd->scaffLevel;
4139   newDtd->scaffIndex = oldDtd->scaffIndex;
4140
4141   return 1;
4142 }  /* End dtdCopy */
4143
4144 static int copyEntityTable(HASH_TABLE *newTable,
4145                            STRING_POOL *newPool,
4146                            const HASH_TABLE *oldTable,
4147                            XML_Parser parser)
4148 {
4149   HASH_TABLE_ITER iter;
4150   const XML_Char *cachedOldBase = 0;
4151   const XML_Char *cachedNewBase = 0;
4152   cmExpatUnused(parser);
4153
4154   hashTableIterInit(&iter, oldTable);
4155
4156   for (;;) {
4157     ENTITY *newE;
4158     const XML_Char *name;
4159     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
4160     if (!oldE)
4161       break;
4162     name = poolCopyString(newPool, oldE->name);
4163     if (!name)
4164       return 0;
4165     newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
4166     if (!newE)
4167       return 0;
4168     if (oldE->systemId) {
4169       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
4170       if (!tem)
4171         return 0;
4172       newE->systemId = tem;
4173       if (oldE->base) {
4174         if (oldE->base == cachedOldBase)
4175           newE->base = cachedNewBase;
4176         else {
4177           cachedOldBase = oldE->base;
4178           tem = poolCopyString(newPool, cachedOldBase);
4179           if (!tem)
4180             return 0;
4181           cachedNewBase = newE->base = tem;
4182         }
4183       }
4184     }
4185     else {
4186       const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
4187       if (!tem)
4188         return 0;
4189       newE->textPtr = tem;
4190       newE->textLen = oldE->textLen;
4191     }
4192     if (oldE->notation) {
4193       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
4194       if (!tem)
4195         return 0;
4196       newE->notation = tem;
4197     }
4198   }
4199   return 1;
4200 }
4201
4202 #define INIT_SIZE 64
4203
4204 static
4205 int keyeq(KEY s1, KEY s2)
4206 {
4207   for (; *s1 == *s2; s1++, s2++)
4208     if (*s1 == 0)
4209       return 1;
4210   return 0;
4211 }
4212
4213 static
4214 unsigned long hash(KEY s)
4215 {
4216   unsigned long h = 0;
4217   while (*s)
4218     h = (h << 5) + h + (unsigned char)*s++;
4219   return h;
4220 }
4221
4222 static
4223 NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
4224 {
4225   size_t i;
4226   if (table->size == 0) {
4227     size_t tsize;
4228
4229     if (!createSize)
4230       return 0;
4231     tsize = INIT_SIZE * sizeof(NAMED *);
4232     table->v = table->mem->malloc_fcn(tsize);
4233     if (!table->v)
4234       return 0;
4235     memset(table->v, 0, tsize);
4236     table->size = INIT_SIZE;
4237     table->usedLim = INIT_SIZE / 2;
4238     i = hash(name) & (table->size - 1);
4239   }
4240   else {
4241     unsigned long h = hash(name);
4242     for (i = h & (table->size - 1);
4243          table->v[i];
4244          i == 0 ? i = table->size - 1 : --i) {
4245       if (keyeq(name, table->v[i]->name))
4246         return table->v[i];
4247     }
4248     if (!createSize)
4249       return 0;
4250     if (table->used == table->usedLim) {
4251       /* check for overflow */
4252       size_t newSize = table->size * 2;
4253       size_t tsize = newSize * sizeof(NAMED *);
4254       NAMED **newV = table->mem->malloc_fcn(tsize);
4255       if (!newV)
4256         return 0;
4257       memset(newV, 0, tsize);
4258       for (i = 0; i < table->size; i++)
4259         if (table->v[i]) {
4260           size_t j;
4261           for (j = hash(table->v[i]->name) & (newSize - 1);
4262                newV[j];
4263                j == 0 ? j = newSize - 1 : --j)
4264             ;
4265           newV[j] = table->v[i];
4266         }
4267       table->mem->free_fcn(table->v);
4268       table->v = newV;
4269       table->size = newSize;
4270       table->usedLim = newSize/2;
4271       for (i = h & (table->size - 1);
4272            table->v[i];
4273            i == 0 ? i = table->size - 1 : --i)
4274         ;
4275     }
4276   }
4277   table->v[i] = table->mem->malloc_fcn(createSize);
4278   if (!table->v[i])
4279     return 0;
4280   memset(table->v[i], 0, createSize);
4281   table->v[i]->name = name;
4282   (table->used)++;
4283   return table->v[i];
4284 }
4285
4286 static
4287 void hashTableDestroy(HASH_TABLE *table)
4288 {
4289   size_t i;
4290   for (i = 0; i < table->size; i++) {
4291     NAMED *p = table->v[i];
4292     if (p)
4293       table->mem->free_fcn(p);
4294   }
4295   if (table->v)
4296     table->mem->free_fcn(table->v);
4297 }
4298
4299 static
4300 void hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms)
4301 {
4302   p->size = 0;
4303   p->usedLim = 0;
4304   p->used = 0;
4305   p->v = 0;
4306   p->mem = ms;
4307 }
4308
4309 static
4310 void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
4311 {
4312   iter->p = table->v;
4313   iter->end = iter->p + table->size;
4314 }
4315
4316 static
4317 NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
4318 {
4319   while (iter->p != iter->end) {
4320     NAMED *tem = *(iter->p)++;
4321     if (tem)
4322       return tem;
4323   }
4324   return 0;
4325 }
4326
4327
4328 static
4329 void poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms)
4330 {
4331   pool->blocks = 0;
4332   pool->freeBlocks = 0;
4333   pool->start = 0;
4334   pool->ptr = 0;
4335   pool->end = 0;
4336   pool->mem = ms;
4337 }
4338
4339 static
4340 void poolClear(STRING_POOL *pool)
4341 {
4342   if (!pool->freeBlocks)
4343     pool->freeBlocks = pool->blocks;
4344   else {
4345     BLOCK *p = pool->blocks;
4346     while (p) {
4347       BLOCK *tem = p->next;
4348       p->next = pool->freeBlocks;
4349       pool->freeBlocks = p;
4350       p = tem;
4351     }
4352   }
4353   pool->blocks = 0;
4354   pool->start = 0;
4355   pool->ptr = 0;
4356   pool->end = 0;
4357 }
4358
4359 static
4360 void poolDestroy(STRING_POOL *pool)
4361 {
4362   BLOCK *p = pool->blocks;
4363   while (p) {
4364     BLOCK *tem = p->next;
4365     pool->mem->free_fcn(p);
4366     p = tem;
4367   }
4368   pool->blocks = 0;
4369   p = pool->freeBlocks;
4370   while (p) {
4371     BLOCK *tem = p->next;
4372     pool->mem->free_fcn(p);
4373     p = tem;
4374   }
4375   pool->freeBlocks = 0;
4376   pool->ptr = 0;
4377   pool->start = 0;
4378   pool->end = 0;
4379 }
4380
4381 static
4382 XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
4383                      const char *ptr, const char *end)
4384 {
4385   if (!pool->ptr && !poolGrow(pool))
4386     return 0;
4387   for (;;) {
4388     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
4389     if (ptr == end)
4390       break;
4391     if (!poolGrow(pool))
4392       return 0;
4393   }
4394   return pool->start;
4395 }
4396
4397 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
4398 {
4399   do {
4400     if (!poolAppendChar(pool, *s))
4401       return 0;
4402   } while (*s++);
4403   s = pool->start;
4404   poolFinish(pool);
4405   return s;
4406 }
4407
4408 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
4409 {
4410   if (!pool->ptr && !poolGrow(pool))
4411     return 0;
4412   for (; n > 0; --n, s++) {
4413     if (!poolAppendChar(pool, *s))
4414       return 0;
4415
4416   }
4417   s = pool->start;
4418   poolFinish(pool);
4419   return s;
4420 }
4421
4422 static
4423 const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s)
4424 {
4425   while (*s) {
4426     if (!poolAppendChar(pool, *s))
4427       return 0;
4428     s++;
4429   } 
4430   return pool->start;
4431 }  /* End poolAppendString */
4432
4433 static
4434 XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
4435                           const char *ptr, const char *end)
4436 {
4437   if (!poolAppend(pool, enc, ptr, end))
4438     return 0;
4439   if (pool->ptr == pool->end && !poolGrow(pool))
4440     return 0;
4441   *(pool->ptr)++ = 0;
4442   return pool->start;
4443 }
4444
4445 static
4446 int poolGrow(STRING_POOL *pool)
4447 {
4448   if (pool->freeBlocks) {
4449     if (pool->start == 0) {
4450       pool->blocks = pool->freeBlocks;
4451       pool->freeBlocks = pool->freeBlocks->next;
4452       pool->blocks->next = 0;
4453       pool->start = pool->blocks->s;
4454       pool->end = pool->start + pool->blocks->size;
4455       pool->ptr = pool->start;
4456       return 1;
4457     }
4458     if (pool->end - pool->start < pool->freeBlocks->size) {
4459       BLOCK *tem = pool->freeBlocks->next;
4460       pool->freeBlocks->next = pool->blocks;
4461       pool->blocks = pool->freeBlocks;
4462       pool->freeBlocks = tem;
4463       memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
4464       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
4465       pool->start = pool->blocks->s;
4466       pool->end = pool->start + pool->blocks->size;
4467       return 1;
4468     }
4469   }
4470   if (pool->blocks && pool->start == pool->blocks->s) {
4471     int blockSize = (pool->end - pool->start)*2;
4472     pool->blocks = pool->mem->realloc_fcn(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
4473     if (!pool->blocks)
4474       return 0;
4475     pool->blocks->size = blockSize;
4476     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
4477     pool->start = pool->blocks->s;
4478     pool->end = pool->start + blockSize;
4479   }
4480   else {
4481     BLOCK *tem;
4482     int blockSize = pool->end - pool->start;
4483     if (blockSize < INIT_BLOCK_SIZE)
4484       blockSize = INIT_BLOCK_SIZE;
4485     else
4486       blockSize *= 2;
4487     tem = pool->mem->malloc_fcn(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
4488     if (!tem)
4489       return 0;
4490     tem->size = blockSize;
4491     tem->next = pool->blocks;
4492     pool->blocks = tem;
4493     if (pool->ptr != pool->start)
4494       memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
4495     pool->ptr = tem->s + (pool->ptr - pool->start);
4496     pool->start = tem->s;
4497     pool->end = tem->s + blockSize;
4498   }
4499   return 1;
4500 }
4501
4502 static int
4503 nextScaffoldPart(XML_Parser parser)
4504 {
4505   CONTENT_SCAFFOLD * me;
4506   int next;
4507
4508   if (! dtd.scaffIndex) {
4509     dtd.scaffIndex = MALLOC(groupSize * sizeof(int));
4510     if (! dtd.scaffIndex)
4511       return -1;
4512     dtd.scaffIndex[0] = 0;
4513   }
4514
4515   if (dtd.scaffCount >= dtd.scaffSize) {
4516     if (dtd.scaffold) {
4517       dtd.scaffSize *= 2;
4518       dtd.scaffold = (CONTENT_SCAFFOLD *) REALLOC(dtd.scaffold,
4519                                               dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
4520     }
4521     else {
4522       dtd.scaffSize = 32;
4523       dtd.scaffold = (CONTENT_SCAFFOLD *) MALLOC(dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
4524     }
4525     if (! dtd.scaffold)
4526       return -1;
4527   }
4528   next = dtd.scaffCount++;
4529   me = &dtd.scaffold[next];
4530   if (dtd.scaffLevel) { 
4531     CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]];
4532     if (parent->lastchild) {
4533       dtd.scaffold[parent->lastchild].nextsib = next;
4534     }
4535     if (! parent->childcnt)
4536       parent->firstchild = next;
4537     parent->lastchild = next;
4538     parent->childcnt++;
4539   }
4540   me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
4541   return next;
4542 }  /* End nextScaffoldPart */
4543
4544 static void
4545 build_node (XML_Parser parser,
4546             int src_node,
4547             XML_Content *dest,
4548             XML_Content **contpos,
4549             char **strpos)
4550 {
4551   dest->type = dtd.scaffold[src_node].type;
4552   dest->quant = dtd.scaffold[src_node].quant;
4553   if (dest->type == XML_CTYPE_NAME) {
4554     const char *src;
4555     dest->name = *strpos;
4556     src = dtd.scaffold[src_node].name;
4557     for (;;) {
4558       *(*strpos)++ = *src;
4559       if (! *src)
4560         break;
4561       src++;
4562     }
4563     dest->numchildren = 0;
4564     dest->children = 0;
4565   }
4566   else {
4567     unsigned int i;
4568     int cn;
4569     dest->numchildren = dtd.scaffold[src_node].childcnt;
4570     dest->children = *contpos;
4571     *contpos += dest->numchildren;
4572     for (i = 0, cn = dtd.scaffold[src_node].firstchild;
4573          i < dest->numchildren;
4574          i++, cn = dtd.scaffold[cn].nextsib) {
4575       build_node(parser, cn, &(dest->children[i]), contpos, strpos);
4576     }
4577     dest->name = 0;
4578   }
4579 }  /* End build_node */
4580
4581 static XML_Content *
4582 build_model (XML_Parser parser)
4583 {
4584   XML_Content *ret;
4585   XML_Content *cpos;
4586   char * str;
4587   int allocsize = dtd.scaffCount * sizeof(XML_Content) + dtd.contentStringLen;
4588   
4589   ret = MALLOC(allocsize);
4590   if (! ret)
4591     return 0;
4592
4593   str =  (char *) (&ret[dtd.scaffCount]);
4594   cpos = &ret[1];
4595
4596   build_node(parser, 0, ret, &cpos, &str);
4597   return ret;
4598 }  /* End build_model */
4599
4600 static ELEMENT_TYPE *
4601 getElementType(XML_Parser parser,
4602                const ENCODING *enc,
4603                const char *ptr,
4604                const char *end)
4605 {
4606   const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
4607   ELEMENT_TYPE *ret;
4608
4609   if (! name)
4610     return 0;
4611   ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
4612   if (! ret)
4613     return 0;
4614   if (ret->name != name)
4615     poolDiscard(&dtd.pool);
4616   else {
4617     poolFinish(&dtd.pool);
4618     if (!setElementTypePrefix(parser, ret))
4619       return 0;
4620   }
4621   return ret;
4622 }  /* End getElementType */