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