source: trunk/third/jwgc/lib/libxode/xmlparse.c @ 22406

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