/[MITgcm]/mitgcm.org/devel/buildweb/pkg/swish-e/src/expat/xmlparse/xmlparse.c
ViewVC logotype

Annotation of /mitgcm.org/devel/buildweb/pkg/swish-e/src/expat/xmlparse/xmlparse.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Fri Sep 20 19:47:30 2002 UTC (22 years, 10 months ago) by adcroft
Branch point for: Import, MAIN
File MIME type: text/plain
Initial revision

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

  ViewVC Help
Powered by ViewVC 1.1.22