1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
6 #include <string.h> /* memset(), memcpy() */
8 #ifdef COMPILED_FROM_DSP
10 #include "winconfig.h"
11 #define XMLPARSEAPI(type) type __cdecl
15 #elif defined(MACOS_CLASSIC)
17 #include "macconfig.h"
22 #include <expat_config.h>
25 #define XMLPARSEAPI(type) type __cdecl
33 #endif /* ndef COMPILED_FROM_DSP */
36 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
37 #define XmlConvert XmlUtf16Convert
38 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
39 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
40 #define XmlEncode XmlUtf16Encode
41 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
42 typedef unsigned short ICHAR;
44 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
45 #define XmlConvert XmlUtf8Convert
46 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
47 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
48 #define XmlEncode XmlUtf8Encode
49 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
56 #define XmlInitEncodingNS XmlInitEncoding
57 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
58 #undef XmlGetInternalEncodingNS
59 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
60 #define XmlParseXmlDeclNS XmlParseXmlDecl
66 #ifdef XML_UNICODE_WCHAR_T
67 #define XML_T(x) (const wchar_t)x
68 #define XML_L(x) L ## x
70 #define XML_T(x) (const unsigned short)x
81 /* Round up n to be a multiple of sz, where sz is a power of 2. */
82 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
84 /* Handle the case where memmove() doesn't exist. */
87 #define memmove(d,s,l) bcopy((s),(d),(l))
89 #error memmove does not exist on this platform, nor is a substitute available
90 #endif /* HAVE_BCOPY */
91 #endif /* HAVE_MEMMOVE */
97 typedef const XML_Char *KEY;
108 const XML_Memory_Handling_Suite *mem;
116 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
117 #define INIT_DATA_BUF_SIZE 1024
118 #define INIT_ATTS_SIZE 16
119 #define INIT_BLOCK_SIZE 1024
120 #define INIT_BUFFER_SIZE 1024
122 #define EXPAND_SPARE 24
124 typedef struct binding {
125 struct prefix *prefix;
126 struct binding *nextTagBinding;
127 struct binding *prevPrefixBinding;
128 const struct attribute_id *attId;
134 typedef struct prefix {
135 const XML_Char *name;
141 const XML_Char *localPart;
142 const XML_Char *prefix;
148 /* TAG represents an open element.
149 The name of the element is stored in both the document and API
150 encodings. The memory buffer 'buf' is a separately-allocated
151 memory area which stores the name. During the XML_Parse()/
152 XMLParseBuffer() when the element is open, the memory for the 'raw'
153 version of the name (in the document encoding) is shared with the
154 document buffer. If the element is open across calls to
155 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
156 contain the 'raw' name as well.
158 A parser re-uses these structures, maintaining a list of allocated
159 TAG objects in a free list.
162 struct tag *parent; /* parent of this element */
163 const char *rawName; /* tagName in the original encoding */
165 TAG_NAME name; /* tagName in the API encoding */
166 char *buf; /* buffer for name components */
167 char *bufEnd; /* end of the buffer */
172 const XML_Char *name;
173 const XML_Char *textPtr;
175 const XML_Char *systemId;
176 const XML_Char *base;
177 const XML_Char *publicId;
178 const XML_Char *notation;
181 XML_Bool is_internal; /* true if declared in internal subset outside PE */
185 enum XML_Content_Type type;
186 enum XML_Content_Quant quant;
187 const XML_Char * name;
194 #define INIT_SCAFFOLD_ELEMENTS 32
196 typedef struct block {
208 const XML_Memory_Handling_Suite *mem;
211 /* The XML_Char before the name is used to determine whether
212 an attribute has been specified. */
213 typedef struct attribute_id {
216 XML_Bool maybeTokenized;
221 const ATTRIBUTE_ID *id;
223 const XML_Char *value;
228 const XML_Char *uriName;
232 const XML_Char *name;
234 const ATTRIBUTE_ID *idAtt;
236 int allocDefaultAtts;
237 DEFAULT_ATTRIBUTE *defaultAtts;
241 HASH_TABLE generalEntities;
242 HASH_TABLE elementTypes;
243 HASH_TABLE attributeIds;
246 STRING_POOL entityValuePool;
247 /* false once a parameter entity reference has been skipped */
248 XML_Bool keepProcessing;
249 /* true once an internal or external PE reference has been encountered;
250 this includes the reference to an external subset */
251 XML_Bool hasParamEntityRefs;
254 /* indicates if external PE has been read */
255 XML_Bool paramEntityRead;
256 HASH_TABLE paramEntities;
258 PREFIX defaultPrefix;
259 /* === scaffolding for building content model === */
261 CONTENT_SCAFFOLD *scaffold;
262 unsigned contentStringLen;
269 typedef struct open_internal_entity {
270 const char *internalEventPtr;
271 const char *internalEventEndPtr;
272 struct open_internal_entity *next;
274 } OPEN_INTERNAL_ENTITY;
276 typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
279 const char **endPtr);
281 static Processor prologProcessor;
282 static Processor prologInitProcessor;
283 static Processor contentProcessor;
284 static Processor cdataSectionProcessor;
286 static Processor ignoreSectionProcessor;
287 static Processor externalParEntProcessor;
288 static Processor externalParEntInitProcessor;
289 static Processor entityValueProcessor;
290 static Processor entityValueInitProcessor;
292 static Processor epilogProcessor;
293 static Processor errorProcessor;
294 static Processor externalEntityInitProcessor;
295 static Processor externalEntityInitProcessor2;
296 static Processor externalEntityInitProcessor3;
297 static Processor externalEntityContentProcessor;
299 static enum XML_Error
300 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
301 static enum XML_Error
302 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
303 const char *, const char *);
304 static enum XML_Error
305 initializeEncoding(XML_Parser parser);
306 static enum XML_Error
307 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
308 const char *end, int tok, const char *next, const char **nextPtr);
309 static enum XML_Error
310 processInternalParamEntity(XML_Parser parser, ENTITY *entity);
311 static enum XML_Error
312 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
313 const char *start, const char *end, const char **endPtr);
314 static enum XML_Error
315 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
316 const char *end, const char **nextPtr);
318 static enum XML_Error
319 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
320 const char *end, const char **nextPtr);
323 static enum XML_Error
324 storeAtts(XML_Parser parser, const ENCODING *, const char *s,
325 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
326 static enum XML_Error
327 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
328 const XML_Char *uri, BINDING **bindingsPtr);
330 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
331 XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue,
333 static enum XML_Error
334 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
335 const char *, const char *, STRING_POOL *);
336 static enum XML_Error
337 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
338 const char *, const char *, STRING_POOL *);
339 static ATTRIBUTE_ID *
340 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
343 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
344 static enum XML_Error
345 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
348 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
349 const char *start, const char *end);
351 reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
354 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
357 static const XML_Char * getContext(XML_Parser parser);
359 setContext(XML_Parser parser, const XML_Char *context);
361 static void FASTCALL normalizePublicId(XML_Char *s);
363 static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
364 /* do not call if parentParser != NULL */
365 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
367 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
369 dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
371 copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
374 lookup(HASH_TABLE *table, KEY name, size_t createSize);
376 hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
377 static void FASTCALL hashTableClear(HASH_TABLE *);
378 static void FASTCALL hashTableDestroy(HASH_TABLE *);
380 hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
381 static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
384 poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
385 static void FASTCALL poolClear(STRING_POOL *);
386 static void FASTCALL poolDestroy(STRING_POOL *);
388 poolAppend(STRING_POOL *pool, const ENCODING *enc,
389 const char *ptr, const char *end);
391 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
392 const char *ptr, const char *end);
393 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
394 static const XML_Char * FASTCALL
395 poolCopyString(STRING_POOL *pool, const XML_Char *s);
396 static const XML_Char *
397 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
398 static const XML_Char * FASTCALL
399 poolAppendString(STRING_POOL *pool, const XML_Char *s);
401 static int FASTCALL nextScaffoldPart(XML_Parser parser);
402 static XML_Content * build_model(XML_Parser parser);
403 static ELEMENT_TYPE *
404 getElementType(XML_Parser parser, const ENCODING *enc,
405 const char *ptr, const char *end);
408 parserCreate(const XML_Char *encodingName,
409 const XML_Memory_Handling_Suite *memsuite,
410 const XML_Char *nameSep,
413 parserInit(XML_Parser parser, const XML_Char *encodingName);
415 #define poolStart(pool) ((pool)->start)
416 #define poolEnd(pool) ((pool)->ptr)
417 #define poolLength(pool) ((pool)->ptr - (pool)->start)
418 #define poolChop(pool) ((void)--(pool->ptr))
419 #define poolLastChar(pool) (((pool)->ptr)[-1])
420 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
421 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
422 #define poolAppendChar(pool, c) \
423 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
425 : ((*((pool)->ptr)++ = c), 1))
427 struct XML_ParserStruct {
428 /* The first member must be userData so that the XML_GetUserData
433 const XML_Memory_Handling_Suite m_mem;
434 /* first character to be parsed */
435 const char *m_bufferPtr;
436 /* past last character to be parsed */
438 /* allocated end of buffer */
439 const char *m_bufferLim;
440 long m_parseEndByteIndex;
441 const char *m_parseEndPtr;
443 XML_Char *m_dataBufEnd;
444 XML_StartElementHandler m_startElementHandler;
445 XML_EndElementHandler m_endElementHandler;
446 XML_CharacterDataHandler m_characterDataHandler;
447 XML_ProcessingInstructionHandler m_processingInstructionHandler;
448 XML_CommentHandler m_commentHandler;
449 XML_StartCdataSectionHandler m_startCdataSectionHandler;
450 XML_EndCdataSectionHandler m_endCdataSectionHandler;
451 XML_DefaultHandler m_defaultHandler;
452 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
453 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
454 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
455 XML_NotationDeclHandler m_notationDeclHandler;
456 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
457 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
458 XML_NotStandaloneHandler m_notStandaloneHandler;
459 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
460 XML_Parser m_externalEntityRefHandlerArg;
461 XML_SkippedEntityHandler m_skippedEntityHandler;
462 XML_UnknownEncodingHandler m_unknownEncodingHandler;
463 XML_ElementDeclHandler m_elementDeclHandler;
464 XML_AttlistDeclHandler m_attlistDeclHandler;
465 XML_EntityDeclHandler m_entityDeclHandler;
466 XML_XmlDeclHandler m_xmlDeclHandler;
467 const ENCODING *m_encoding;
468 INIT_ENCODING m_initEncoding;
469 const ENCODING *m_internalEncoding;
470 const XML_Char *m_protocolEncodingName;
472 XML_Bool m_ns_triplets;
473 void *m_unknownEncodingMem;
474 void *m_unknownEncodingData;
475 void *m_unknownEncodingHandlerData;
476 void (*m_unknownEncodingRelease)(void *);
477 PROLOG_STATE m_prologState;
478 Processor *m_processor;
479 enum XML_Error m_errorCode;
480 const char *m_eventPtr;
481 const char *m_eventEndPtr;
482 const char *m_positionPtr;
483 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
484 XML_Bool m_defaultExpandInternalEntities;
486 ENTITY *m_declEntity;
487 const XML_Char *m_doctypeName;
488 const XML_Char *m_doctypeSysid;
489 const XML_Char *m_doctypePubid;
490 const XML_Char *m_declAttributeType;
491 const XML_Char *m_declNotationName;
492 const XML_Char *m_declNotationPublicId;
493 ELEMENT_TYPE *m_declElementType;
494 ATTRIBUTE_ID *m_declAttributeId;
495 XML_Bool m_declAttributeIsCdata;
496 XML_Bool m_declAttributeIsId;
498 const XML_Char *m_curBase;
501 BINDING *m_inheritedBindings;
502 BINDING *m_freeBindingList;
504 int m_nSpecifiedAtts;
510 STRING_POOL m_tempPool;
511 STRING_POOL m_temp2Pool;
512 char *m_groupConnector;
513 unsigned m_groupSize;
514 XML_Char m_namespaceSeparator;
515 XML_Parser m_parentParser;
517 XML_Bool m_isParamEntity;
518 XML_Bool m_useForeignDTD;
519 enum XML_ParamEntityParsing m_paramEntityParsing;
523 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
524 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
525 #define FREE(p) (parser->m_mem.free_fcn((p)))
527 #define userData (parser->m_userData)
528 #define handlerArg (parser->m_handlerArg)
529 #define startElementHandler (parser->m_startElementHandler)
530 #define endElementHandler (parser->m_endElementHandler)
531 #define characterDataHandler (parser->m_characterDataHandler)
532 #define processingInstructionHandler \
533 (parser->m_processingInstructionHandler)
534 #define commentHandler (parser->m_commentHandler)
535 #define startCdataSectionHandler \
536 (parser->m_startCdataSectionHandler)
537 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
538 #define defaultHandler (parser->m_defaultHandler)
539 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
540 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
541 #define unparsedEntityDeclHandler \
542 (parser->m_unparsedEntityDeclHandler)
543 #define notationDeclHandler (parser->m_notationDeclHandler)
544 #define startNamespaceDeclHandler \
545 (parser->m_startNamespaceDeclHandler)
546 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
547 #define notStandaloneHandler (parser->m_notStandaloneHandler)
548 #define externalEntityRefHandler \
549 (parser->m_externalEntityRefHandler)
550 #define externalEntityRefHandlerArg \
551 (parser->m_externalEntityRefHandlerArg)
552 #define internalEntityRefHandler \
553 (parser->m_internalEntityRefHandler)
554 #define skippedEntityHandler (parser->m_skippedEntityHandler)
555 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
556 #define elementDeclHandler (parser->m_elementDeclHandler)
557 #define attlistDeclHandler (parser->m_attlistDeclHandler)
558 #define entityDeclHandler (parser->m_entityDeclHandler)
559 #define xmlDeclHandler (parser->m_xmlDeclHandler)
560 #define encoding (parser->m_encoding)
561 #define initEncoding (parser->m_initEncoding)
562 #define internalEncoding (parser->m_internalEncoding)
563 #define unknownEncodingMem (parser->m_unknownEncodingMem)
564 #define unknownEncodingData (parser->m_unknownEncodingData)
565 #define unknownEncodingHandlerData \
566 (parser->m_unknownEncodingHandlerData)
567 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
568 #define protocolEncodingName (parser->m_protocolEncodingName)
569 #define ns (parser->m_ns)
570 #define ns_triplets (parser->m_ns_triplets)
571 #define prologState (parser->m_prologState)
572 #define processor (parser->m_processor)
573 #define errorCode (parser->m_errorCode)
574 #define eventPtr (parser->m_eventPtr)
575 #define eventEndPtr (parser->m_eventEndPtr)
576 #define positionPtr (parser->m_positionPtr)
577 #define position (parser->m_position)
578 #define openInternalEntities (parser->m_openInternalEntities)
579 #define defaultExpandInternalEntities \
580 (parser->m_defaultExpandInternalEntities)
581 #define tagLevel (parser->m_tagLevel)
582 #define buffer (parser->m_buffer)
583 #define bufferPtr (parser->m_bufferPtr)
584 #define bufferEnd (parser->m_bufferEnd)
585 #define parseEndByteIndex (parser->m_parseEndByteIndex)
586 #define parseEndPtr (parser->m_parseEndPtr)
587 #define bufferLim (parser->m_bufferLim)
588 #define dataBuf (parser->m_dataBuf)
589 #define dataBufEnd (parser->m_dataBufEnd)
590 #define _dtd (parser->m_dtd)
591 #define curBase (parser->m_curBase)
592 #define declEntity (parser->m_declEntity)
593 #define doctypeName (parser->m_doctypeName)
594 #define doctypeSysid (parser->m_doctypeSysid)
595 #define doctypePubid (parser->m_doctypePubid)
596 #define declAttributeType (parser->m_declAttributeType)
597 #define declNotationName (parser->m_declNotationName)
598 #define declNotationPublicId (parser->m_declNotationPublicId)
599 #define declElementType (parser->m_declElementType)
600 #define declAttributeId (parser->m_declAttributeId)
601 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
602 #define declAttributeIsId (parser->m_declAttributeIsId)
603 #define freeTagList (parser->m_freeTagList)
604 #define freeBindingList (parser->m_freeBindingList)
605 #define inheritedBindings (parser->m_inheritedBindings)
606 #define tagStack (parser->m_tagStack)
607 #define atts (parser->m_atts)
608 #define attsSize (parser->m_attsSize)
609 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
610 #define idAttIndex (parser->m_idAttIndex)
611 #define nsAtts (parser->m_nsAtts)
612 #define nsAttsSize (parser->m_nsAttsSize)
613 #define tempPool (parser->m_tempPool)
614 #define temp2Pool (parser->m_temp2Pool)
615 #define groupConnector (parser->m_groupConnector)
616 #define groupSize (parser->m_groupSize)
617 #define namespaceSeparator (parser->m_namespaceSeparator)
618 #define parentParser (parser->m_parentParser)
620 #define isParamEntity (parser->m_isParamEntity)
621 #define useForeignDTD (parser->m_useForeignDTD)
622 #define paramEntityParsing (parser->m_paramEntityParsing)
631 (processor != externalParEntInitProcessor) \
633 (processor != externalEntityInitProcessor)) \
635 (processor != prologInitProcessor))
640 (processor != externalEntityInitProcessor) \
642 (processor != prologInitProcessor))
646 XML_ParserCreate(const XML_Char *encodingName)
648 return XML_ParserCreate_MM(encodingName, NULL, NULL);
652 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
656 return XML_ParserCreate_MM(encodingName, NULL, tmp);
659 static const XML_Char implicitContext[] = {
660 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
661 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
662 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
663 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
667 XML_ParserCreate_MM(const XML_Char *encodingName,
668 const XML_Memory_Handling_Suite *memsuite,
669 const XML_Char *nameSep)
671 XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
672 if (parser != NULL && ns) {
673 /* implicit context only set for root parser, since child
674 parsers (i.e. external entity parsers) will inherit it
676 if (!setContext(parser, implicitContext)) {
677 XML_ParserFree(parser);
685 parserCreate(const XML_Char *encodingName,
686 const XML_Memory_Handling_Suite *memsuite,
687 const XML_Char *nameSep,
693 XML_Memory_Handling_Suite *mtemp;
694 parser = (XML_Parser)
695 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
696 if (parser != NULL) {
697 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
698 mtemp->malloc_fcn = memsuite->malloc_fcn;
699 mtemp->realloc_fcn = memsuite->realloc_fcn;
700 mtemp->free_fcn = memsuite->free_fcn;
704 XML_Memory_Handling_Suite *mtemp;
705 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
706 if (parser != NULL) {
707 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
708 mtemp->malloc_fcn = malloc;
709 mtemp->realloc_fcn = realloc;
710 mtemp->free_fcn = free;
720 attsSize = INIT_ATTS_SIZE;
721 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
726 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
727 if (dataBuf == NULL) {
732 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
737 _dtd = dtdCreate(&parser->m_mem);
746 freeBindingList = NULL;
750 groupConnector = NULL;
752 unknownEncodingHandler = NULL;
753 unknownEncodingHandlerData = NULL;
755 namespaceSeparator = '!';
757 ns_triplets = XML_FALSE;
762 poolInit(&tempPool, &(parser->m_mem));
763 poolInit(&temp2Pool, &(parser->m_mem));
764 parserInit(parser, encodingName);
766 if (encodingName && !protocolEncodingName) {
767 XML_ParserFree(parser);
773 internalEncoding = XmlGetInternalEncodingNS();
774 namespaceSeparator = *nameSep;
777 internalEncoding = XmlGetInternalEncoding();
784 parserInit(XML_Parser parser, const XML_Char *encodingName)
786 processor = prologInitProcessor;
787 XmlPrologStateInit(&prologState);
788 protocolEncodingName = (encodingName != NULL
789 ? poolCopyString(&tempPool, encodingName)
792 XmlInitEncoding(&initEncoding, &encoding, 0);
795 startElementHandler = NULL;
796 endElementHandler = NULL;
797 characterDataHandler = NULL;
798 processingInstructionHandler = NULL;
799 commentHandler = NULL;
800 startCdataSectionHandler = NULL;
801 endCdataSectionHandler = NULL;
802 defaultHandler = NULL;
803 startDoctypeDeclHandler = NULL;
804 endDoctypeDeclHandler = NULL;
805 unparsedEntityDeclHandler = NULL;
806 notationDeclHandler = NULL;
807 startNamespaceDeclHandler = NULL;
808 endNamespaceDeclHandler = NULL;
809 notStandaloneHandler = NULL;
810 externalEntityRefHandler = NULL;
811 externalEntityRefHandlerArg = parser;
812 skippedEntityHandler = NULL;
813 elementDeclHandler = NULL;
814 attlistDeclHandler = NULL;
815 entityDeclHandler = NULL;
816 xmlDeclHandler = NULL;
819 parseEndByteIndex = 0;
821 declElementType = NULL;
822 declAttributeId = NULL;
827 declAttributeType = NULL;
828 declNotationName = NULL;
829 declNotationPublicId = NULL;
830 declAttributeIsCdata = XML_FALSE;
831 declAttributeIsId = XML_FALSE;
832 memset(&position, 0, sizeof(POSITION));
833 errorCode = XML_ERROR_NONE;
837 openInternalEntities = 0;
838 defaultExpandInternalEntities = XML_TRUE;
841 inheritedBindings = NULL;
843 unknownEncodingMem = NULL;
844 unknownEncodingRelease = NULL;
845 unknownEncodingData = NULL;
848 isParamEntity = XML_FALSE;
849 useForeignDTD = XML_FALSE;
850 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
854 /* moves list of bindings to freeBindingList */
856 moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
859 BINDING *b = bindings;
860 bindings = bindings->nextTagBinding;
861 b->nextTagBinding = freeBindingList;
867 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
872 /* move tagStack to freeTagList */
877 tag->parent = freeTagList;
878 moveToFreeBindingList(parser, tag->bindings);
879 tag->bindings = NULL;
882 moveToFreeBindingList(parser, inheritedBindings);
883 FREE(unknownEncodingMem);
884 if (unknownEncodingRelease)
885 unknownEncodingRelease(unknownEncodingData);
886 poolClear(&tempPool);
887 poolClear(&temp2Pool);
888 parserInit(parser, encodingName);
889 dtdReset(_dtd, &parser->m_mem);
890 return setContext(parser, implicitContext);
894 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
896 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
897 XXX There's no way for the caller to determine which of the
898 XXX possible error cases caused the XML_STATUS_ERROR return.
901 return XML_STATUS_ERROR;
902 if (encodingName == NULL)
903 protocolEncodingName = NULL;
905 protocolEncodingName = poolCopyString(&tempPool, encodingName);
906 if (!protocolEncodingName)
907 return XML_STATUS_ERROR;
909 return XML_STATUS_OK;
913 XML_ExternalEntityParserCreate(XML_Parser oldParser,
914 const XML_Char *context,
915 const XML_Char *encodingName)
917 XML_Parser parser = oldParser;
920 XML_StartElementHandler oldStartElementHandler = startElementHandler;
921 XML_EndElementHandler oldEndElementHandler = endElementHandler;
922 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
923 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
924 = processingInstructionHandler;
925 XML_CommentHandler oldCommentHandler = commentHandler;
926 XML_StartCdataSectionHandler oldStartCdataSectionHandler
927 = startCdataSectionHandler;
928 XML_EndCdataSectionHandler oldEndCdataSectionHandler
929 = endCdataSectionHandler;
930 XML_DefaultHandler oldDefaultHandler = defaultHandler;
931 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
932 = unparsedEntityDeclHandler;
933 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
934 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
935 = startNamespaceDeclHandler;
936 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
937 = endNamespaceDeclHandler;
938 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
939 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
940 = externalEntityRefHandler;
941 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
942 XML_UnknownEncodingHandler oldUnknownEncodingHandler
943 = unknownEncodingHandler;
944 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
945 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
946 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
947 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
948 ELEMENT_TYPE * oldDeclElementType = declElementType;
950 void *oldUserData = userData;
951 void *oldHandlerArg = handlerArg;
952 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
953 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
955 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
956 int oldInEntityValue = prologState.inEntityValue;
958 XML_Bool oldns_triplets = ns_triplets;
965 /* Note that the magical uses of the pre-processor to make field
966 access look more like C++ require that `parser' be overwritten
967 here. This makes this function more painful to follow than it
972 *tmp = namespaceSeparator;
973 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
976 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
982 startElementHandler = oldStartElementHandler;
983 endElementHandler = oldEndElementHandler;
984 characterDataHandler = oldCharacterDataHandler;
985 processingInstructionHandler = oldProcessingInstructionHandler;
986 commentHandler = oldCommentHandler;
987 startCdataSectionHandler = oldStartCdataSectionHandler;
988 endCdataSectionHandler = oldEndCdataSectionHandler;
989 defaultHandler = oldDefaultHandler;
990 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
991 notationDeclHandler = oldNotationDeclHandler;
992 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
993 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
994 notStandaloneHandler = oldNotStandaloneHandler;
995 externalEntityRefHandler = oldExternalEntityRefHandler;
996 skippedEntityHandler = oldSkippedEntityHandler;
997 unknownEncodingHandler = oldUnknownEncodingHandler;
998 elementDeclHandler = oldElementDeclHandler;
999 attlistDeclHandler = oldAttlistDeclHandler;
1000 entityDeclHandler = oldEntityDeclHandler;
1001 xmlDeclHandler = oldXmlDeclHandler;
1002 declElementType = oldDeclElementType;
1003 userData = oldUserData;
1004 if (oldUserData == oldHandlerArg)
1005 handlerArg = userData;
1007 handlerArg = parser;
1008 if (oldExternalEntityRefHandlerArg != oldParser)
1009 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1010 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1011 ns_triplets = oldns_triplets;
1012 parentParser = oldParser;
1014 paramEntityParsing = oldParamEntityParsing;
1015 prologState.inEntityValue = oldInEntityValue;
1017 #endif /* XML_DTD */
1018 if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
1019 || !setContext(parser, context)) {
1020 XML_ParserFree(parser);
1023 processor = externalEntityInitProcessor;
1027 /* The DTD instance referenced by _dtd is shared between the document's
1028 root parser and external PE parsers, therefore one does not need to
1029 call setContext. In addition, one also *must* not call setContext,
1030 because this would overwrite existing prefix->binding pointers in
1031 _dtd with ones that get destroyed with the external PE parser.
1032 This would leave those prefixes with dangling pointers.
1034 isParamEntity = XML_TRUE;
1035 XmlPrologStateInitExternalEntity(&prologState);
1036 processor = externalParEntInitProcessor;
1038 #endif /* XML_DTD */
1042 static void FASTCALL
1043 destroyBindings(BINDING *bindings, XML_Parser parser)
1046 BINDING *b = bindings;
1049 bindings = b->nextTagBinding;
1056 XML_ParserFree(XML_Parser parser)
1060 if (tagStack == NULL) {
1061 if (freeTagList == NULL)
1063 tagStack = freeTagList;
1067 tagStack = tagStack->parent;
1069 destroyBindings(p->bindings, parser);
1072 destroyBindings(freeBindingList, parser);
1073 destroyBindings(inheritedBindings, parser);
1074 poolDestroy(&tempPool);
1075 poolDestroy(&temp2Pool);
1077 /* external parameter entity parsers share the DTD structure
1078 parser->m_dtd with the root parser, so we must not destroy it
1080 if (!isParamEntity && _dtd)
1083 #endif /* XML_DTD */
1084 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
1086 FREE(groupConnector);
1090 FREE(unknownEncodingMem);
1091 if (unknownEncodingRelease)
1092 unknownEncodingRelease(unknownEncodingData);
1097 XML_UseParserAsHandlerArg(XML_Parser parser)
1099 handlerArg = parser;
1103 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1106 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1108 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1109 useForeignDTD = useDTD;
1110 return XML_ERROR_NONE;
1112 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1117 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1119 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1122 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1126 XML_SetUserData(XML_Parser parser, void *p)
1128 if (handlerArg == userData)
1129 handlerArg = userData = p;
1135 XML_SetBase(XML_Parser parser, const XML_Char *p)
1138 p = poolCopyString(&_dtd->pool, p);
1140 return XML_STATUS_ERROR;
1145 return XML_STATUS_OK;
1149 XML_GetBase(XML_Parser parser)
1155 XML_GetSpecifiedAttributeCount(XML_Parser parser)
1157 return nSpecifiedAtts;
1161 XML_GetIdAttributeIndex(XML_Parser parser)
1167 XML_SetElementHandler(XML_Parser parser,
1168 XML_StartElementHandler start,
1169 XML_EndElementHandler end)
1171 startElementHandler = start;
1172 endElementHandler = end;
1176 XML_SetStartElementHandler(XML_Parser parser,
1177 XML_StartElementHandler start) {
1178 startElementHandler = start;
1182 XML_SetEndElementHandler(XML_Parser parser,
1183 XML_EndElementHandler end) {
1184 endElementHandler = end;
1188 XML_SetCharacterDataHandler(XML_Parser parser,
1189 XML_CharacterDataHandler handler)
1191 characterDataHandler = handler;
1195 XML_SetProcessingInstructionHandler(XML_Parser parser,
1196 XML_ProcessingInstructionHandler handler)
1198 processingInstructionHandler = handler;
1202 XML_SetCommentHandler(XML_Parser parser,
1203 XML_CommentHandler handler)
1205 commentHandler = handler;
1209 XML_SetCdataSectionHandler(XML_Parser parser,
1210 XML_StartCdataSectionHandler start,
1211 XML_EndCdataSectionHandler end)
1213 startCdataSectionHandler = start;
1214 endCdataSectionHandler = end;
1218 XML_SetStartCdataSectionHandler(XML_Parser parser,
1219 XML_StartCdataSectionHandler start) {
1220 startCdataSectionHandler = start;
1224 XML_SetEndCdataSectionHandler(XML_Parser parser,
1225 XML_EndCdataSectionHandler end) {
1226 endCdataSectionHandler = end;
1230 XML_SetDefaultHandler(XML_Parser parser,
1231 XML_DefaultHandler handler)
1233 defaultHandler = handler;
1234 defaultExpandInternalEntities = XML_FALSE;
1238 XML_SetDefaultHandlerExpand(XML_Parser parser,
1239 XML_DefaultHandler handler)
1241 defaultHandler = handler;
1242 defaultExpandInternalEntities = XML_TRUE;
1246 XML_SetDoctypeDeclHandler(XML_Parser parser,
1247 XML_StartDoctypeDeclHandler start,
1248 XML_EndDoctypeDeclHandler end)
1250 startDoctypeDeclHandler = start;
1251 endDoctypeDeclHandler = end;
1255 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1256 XML_StartDoctypeDeclHandler start) {
1257 startDoctypeDeclHandler = start;
1261 XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1262 XML_EndDoctypeDeclHandler end) {
1263 endDoctypeDeclHandler = end;
1267 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1268 XML_UnparsedEntityDeclHandler handler)
1270 unparsedEntityDeclHandler = handler;
1274 XML_SetNotationDeclHandler(XML_Parser parser,
1275 XML_NotationDeclHandler handler)
1277 notationDeclHandler = handler;
1281 XML_SetNamespaceDeclHandler(XML_Parser parser,
1282 XML_StartNamespaceDeclHandler start,
1283 XML_EndNamespaceDeclHandler end)
1285 startNamespaceDeclHandler = start;
1286 endNamespaceDeclHandler = end;
1290 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1291 XML_StartNamespaceDeclHandler start) {
1292 startNamespaceDeclHandler = start;
1296 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1297 XML_EndNamespaceDeclHandler end) {
1298 endNamespaceDeclHandler = end;
1302 XML_SetNotStandaloneHandler(XML_Parser parser,
1303 XML_NotStandaloneHandler handler)
1305 notStandaloneHandler = handler;
1309 XML_SetExternalEntityRefHandler(XML_Parser parser,
1310 XML_ExternalEntityRefHandler handler)
1312 externalEntityRefHandler = handler;
1316 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1319 externalEntityRefHandlerArg = (XML_Parser)arg;
1321 externalEntityRefHandlerArg = parser;
1325 XML_SetSkippedEntityHandler(XML_Parser parser,
1326 XML_SkippedEntityHandler handler)
1328 skippedEntityHandler = handler;
1332 XML_SetUnknownEncodingHandler(XML_Parser parser,
1333 XML_UnknownEncodingHandler handler,
1336 unknownEncodingHandler = handler;
1337 unknownEncodingHandlerData = data;
1341 XML_SetElementDeclHandler(XML_Parser parser,
1342 XML_ElementDeclHandler eldecl)
1344 elementDeclHandler = eldecl;
1348 XML_SetAttlistDeclHandler(XML_Parser parser,
1349 XML_AttlistDeclHandler attdecl)
1351 attlistDeclHandler = attdecl;
1355 XML_SetEntityDeclHandler(XML_Parser parser,
1356 XML_EntityDeclHandler handler)
1358 entityDeclHandler = handler;
1362 XML_SetXmlDeclHandler(XML_Parser parser,
1363 XML_XmlDeclHandler handler) {
1364 xmlDeclHandler = handler;
1368 XML_SetParamEntityParsing(XML_Parser parser,
1369 enum XML_ParamEntityParsing peParsing)
1371 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1375 paramEntityParsing = peParsing;
1378 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1383 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1387 return XML_STATUS_OK;
1388 positionPtr = bufferPtr;
1389 errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
1390 if (errorCode == XML_ERROR_NONE)
1391 return XML_STATUS_OK;
1392 eventEndPtr = eventPtr;
1393 processor = errorProcessor;
1394 return XML_STATUS_ERROR;
1396 #ifndef XML_CONTEXT_BYTES
1397 else if (bufferPtr == bufferEnd) {
1400 parseEndByteIndex += len;
1403 errorCode = processor(parser, s, parseEndPtr = s + len, 0);
1404 if (errorCode == XML_ERROR_NONE)
1405 return XML_STATUS_OK;
1406 eventEndPtr = eventPtr;
1407 processor = errorProcessor;
1408 return XML_STATUS_ERROR;
1410 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1411 if (errorCode != XML_ERROR_NONE) {
1412 eventEndPtr = eventPtr;
1413 processor = errorProcessor;
1414 return XML_STATUS_ERROR;
1416 XmlUpdatePosition(encoding, positionPtr, end, &position);
1418 nLeftOver = s + len - end;
1420 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1421 /* FIXME avoid integer overflow */
1423 temp = (buffer == NULL
1424 ? (char *)MALLOC(len * 2)
1425 : (char *)REALLOC(buffer, len * 2));
1427 errorCode = XML_ERROR_NO_MEMORY;
1428 return XML_STATUS_ERROR;
1432 errorCode = XML_ERROR_NO_MEMORY;
1433 eventPtr = eventEndPtr = NULL;
1434 processor = errorProcessor;
1435 return XML_STATUS_ERROR;
1437 bufferLim = buffer + len * 2;
1439 memcpy(buffer, end, nLeftOver);
1441 bufferEnd = buffer + nLeftOver;
1443 return XML_STATUS_OK;
1445 #endif /* not defined XML_CONTEXT_BYTES */
1447 void *buff = XML_GetBuffer(parser, len);
1449 return XML_STATUS_ERROR;
1451 memcpy(buff, s, len);
1452 return XML_ParseBuffer(parser, len, isFinal);
1458 XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1460 const char *start = bufferPtr;
1461 positionPtr = start;
1463 parseEndByteIndex += len;
1464 errorCode = processor(parser, start, parseEndPtr = bufferEnd,
1465 isFinal ? (const char **)NULL : &bufferPtr);
1466 if (errorCode == XML_ERROR_NONE) {
1468 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1469 positionPtr = bufferPtr;
1471 return XML_STATUS_OK;
1474 eventEndPtr = eventPtr;
1475 processor = errorProcessor;
1476 return XML_STATUS_ERROR;
1481 XML_GetBuffer(XML_Parser parser, int len)
1483 if (len > bufferLim - bufferEnd) {
1484 /* FIXME avoid integer overflow */
1485 int neededSize = len + (bufferEnd - bufferPtr);
1486 #ifdef XML_CONTEXT_BYTES
1487 int keep = bufferPtr - buffer;
1489 if (keep > XML_CONTEXT_BYTES)
1490 keep = XML_CONTEXT_BYTES;
1492 #endif /* defined XML_CONTEXT_BYTES */
1493 if (neededSize <= bufferLim - buffer) {
1494 #ifdef XML_CONTEXT_BYTES
1495 if (keep < bufferPtr - buffer) {
1496 int offset = (bufferPtr - buffer) - keep;
1497 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1498 bufferEnd -= offset;
1499 bufferPtr -= offset;
1502 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1503 bufferEnd = buffer + (bufferEnd - bufferPtr);
1505 #endif /* not defined XML_CONTEXT_BYTES */
1509 int bufferSize = bufferLim - bufferPtr;
1510 if (bufferSize == 0)
1511 bufferSize = INIT_BUFFER_SIZE;
1514 } while (bufferSize < neededSize);
1515 newBuf = (char *)MALLOC(bufferSize);
1517 errorCode = XML_ERROR_NO_MEMORY;
1520 bufferLim = newBuf + bufferSize;
1521 #ifdef XML_CONTEXT_BYTES
1523 int keep = bufferPtr - buffer;
1524 if (keep > XML_CONTEXT_BYTES)
1525 keep = XML_CONTEXT_BYTES;
1526 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1529 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1530 bufferPtr = buffer + keep;
1533 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1534 bufferPtr = buffer = newBuf;
1538 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1541 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1542 bufferPtr = buffer = newBuf;
1543 #endif /* not defined XML_CONTEXT_BYTES */
1550 XML_GetErrorCode(XML_Parser parser)
1556 XML_GetCurrentByteIndex(XML_Parser parser)
1559 return parseEndByteIndex - (parseEndPtr - eventPtr);
1564 XML_GetCurrentByteCount(XML_Parser parser)
1566 if (eventEndPtr && eventPtr)
1567 return eventEndPtr - eventPtr;
1572 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1574 #ifdef XML_CONTEXT_BYTES
1575 if (eventPtr && buffer) {
1576 *offset = eventPtr - buffer;
1577 *size = bufferEnd - buffer;
1580 #endif /* defined XML_CONTEXT_BYTES */
1585 XML_GetCurrentLineNumber(XML_Parser parser)
1588 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1589 positionPtr = eventPtr;
1591 return position.lineNumber + 1;
1595 XML_GetCurrentColumnNumber(XML_Parser parser)
1598 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1599 positionPtr = eventPtr;
1601 return position.columnNumber;
1605 XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1611 XML_MemMalloc(XML_Parser parser, size_t size)
1613 return MALLOC(size);
1617 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1619 return REALLOC(ptr, size);
1623 XML_MemFree(XML_Parser parser, void *ptr)
1629 XML_DefaultCurrent(XML_Parser parser)
1631 if (defaultHandler) {
1632 if (openInternalEntities)
1633 reportDefault(parser,
1635 openInternalEntities->internalEventPtr,
1636 openInternalEntities->internalEventEndPtr);
1638 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1643 XML_ErrorString(enum XML_Error code)
1645 static const XML_LChar *message[] = {
1647 XML_L("out of memory"),
1648 XML_L("syntax error"),
1649 XML_L("no element found"),
1650 XML_L("not well-formed (invalid token)"),
1651 XML_L("unclosed token"),
1652 XML_L("partial character"),
1653 XML_L("mismatched tag"),
1654 XML_L("duplicate attribute"),
1655 XML_L("junk after document element"),
1656 XML_L("illegal parameter entity reference"),
1657 XML_L("undefined entity"),
1658 XML_L("recursive entity reference"),
1659 XML_L("asynchronous entity"),
1660 XML_L("reference to invalid character number"),
1661 XML_L("reference to binary entity"),
1662 XML_L("reference to external entity in attribute"),
1663 XML_L("xml declaration not at start of external entity"),
1664 XML_L("unknown encoding"),
1665 XML_L("encoding specified in XML declaration is incorrect"),
1666 XML_L("unclosed CDATA section"),
1667 XML_L("error in processing external entity reference"),
1668 XML_L("document is not standalone"),
1669 XML_L("unexpected parser state - please send a bug report"),
1670 XML_L("entity declared in parameter entity"),
1671 XML_L("requested feature requires XML_DTD support in Expat"),
1672 XML_L("cannot change setting once parsing has begun"),
1673 XML_L("unbound prefix")
1675 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1676 return message[code];
1681 XML_ExpatVersion(void) {
1683 /* V1 is used to string-ize the version number. However, it would
1684 string-ize the actual version macro *names* unless we get them
1685 substituted before being passed to V1. CPP is defined to expand
1686 a macro, then rescan for more expansions. Thus, we use V2 to expand
1687 the version macros, then CPP will expand the resulting V1() macro
1688 with the correct numerals. */
1689 /* ### I'm assuming cpp is portable in this respect... */
1691 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1692 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1694 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1701 XML_ExpatVersionInfo(void)
1703 XML_Expat_Version version;
1705 version.major = XML_MAJOR_VERSION;
1706 version.minor = XML_MINOR_VERSION;
1707 version.micro = XML_MICRO_VERSION;
1713 XML_GetFeatureList(void)
1715 static XML_Feature features[] = {
1716 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)")},
1717 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)")},
1719 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE")},
1721 #ifdef XML_UNICODE_WCHAR_T
1722 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T")},
1725 {XML_FEATURE_DTD, XML_L("XML_DTD")},
1727 #ifdef XML_CONTEXT_BYTES
1728 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
1732 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE")},
1734 {XML_FEATURE_END, NULL}
1737 features[0].value = sizeof(XML_Char);
1738 features[1].value = sizeof(XML_LChar);
1742 /* Initially tag->rawName always points into the parse buffer;
1743 for those TAG instances opened while the current parse buffer was
1744 processed, and not yet closed, we need to store tag->rawName in a more
1745 permanent location, since the parse buffer is about to be discarded.
1748 storeRawNames(XML_Parser parser)
1750 TAG *tag = tagStack;
1753 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
1754 char *rawNameBuf = tag->buf + nameLen;
1755 /* Stop if already stored. Since tagStack is a stack, we can stop
1756 at the first entry that has already been copied; everything
1757 below it in the stack is already been accounted for in a
1758 previous call to this function.
1760 if (tag->rawName == rawNameBuf)
1762 /* For re-use purposes we need to ensure that the
1763 size of tag->buf is a multiple of sizeof(XML_Char).
1765 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
1766 if (bufSize > tag->bufEnd - tag->buf) {
1767 char *temp = (char *)REALLOC(tag->buf, bufSize);
1770 /* if tag->name.str points to tag->buf (only when namespace
1771 processing is off) then we have to update it
1773 if (tag->name.str == (XML_Char *)tag->buf)
1774 tag->name.str = (XML_Char *)temp;
1775 /* if tag->name.localPart is set (when namespace processing is on)
1776 then update it as well, since it will always point into tag->buf
1778 if (tag->name.localPart)
1779 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
1780 (XML_Char *)tag->buf);
1782 tag->bufEnd = temp + bufSize;
1783 rawNameBuf = temp + nameLen;
1785 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
1786 tag->rawName = rawNameBuf;
1792 static enum XML_Error PTRCALL
1793 contentProcessor(XML_Parser parser,
1796 const char **endPtr)
1798 enum XML_Error result =
1799 doContent(parser, 0, encoding, start, end, endPtr);
1800 if (result != XML_ERROR_NONE)
1802 if (!storeRawNames(parser))
1803 return XML_ERROR_NO_MEMORY;
1807 static enum XML_Error PTRCALL
1808 externalEntityInitProcessor(XML_Parser parser,
1811 const char **endPtr)
1813 enum XML_Error result = initializeEncoding(parser);
1814 if (result != XML_ERROR_NONE)
1816 processor = externalEntityInitProcessor2;
1817 return externalEntityInitProcessor2(parser, start, end, endPtr);
1820 static enum XML_Error PTRCALL
1821 externalEntityInitProcessor2(XML_Parser parser,
1824 const char **endPtr)
1826 const char *next = start; /* XmlContentTok doesn't always set the last arg */
1827 int tok = XmlContentTok(encoding, start, end, &next);
1830 /* If we are at the end of the buffer, this would cause the next stage,
1831 i.e. externalEntityInitProcessor3, to pass control directly to
1832 doContent (by detecting XML_TOK_NONE) without processing any xml text
1833 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1835 if (next == end && endPtr) {
1837 return XML_ERROR_NONE;
1841 case XML_TOK_PARTIAL:
1844 return XML_ERROR_NONE;
1847 return XML_ERROR_UNCLOSED_TOKEN;
1848 case XML_TOK_PARTIAL_CHAR:
1851 return XML_ERROR_NONE;
1854 return XML_ERROR_PARTIAL_CHAR;
1856 processor = externalEntityInitProcessor3;
1857 return externalEntityInitProcessor3(parser, start, end, endPtr);
1860 static enum XML_Error PTRCALL
1861 externalEntityInitProcessor3(XML_Parser parser,
1864 const char **endPtr)
1866 const char *next = start; /* XmlContentTok doesn't always set the last arg */
1867 int tok = XmlContentTok(encoding, start, end, &next);
1869 case XML_TOK_XML_DECL:
1871 enum XML_Error result = processXmlDecl(parser, 1, start, next);
1872 if (result != XML_ERROR_NONE)
1877 case XML_TOK_PARTIAL:
1880 return XML_ERROR_NONE;
1883 return XML_ERROR_UNCLOSED_TOKEN;
1884 case XML_TOK_PARTIAL_CHAR:
1887 return XML_ERROR_NONE;
1890 return XML_ERROR_PARTIAL_CHAR;
1892 processor = externalEntityContentProcessor;
1894 return externalEntityContentProcessor(parser, start, end, endPtr);
1897 static enum XML_Error PTRCALL
1898 externalEntityContentProcessor(XML_Parser parser,
1901 const char **endPtr)
1903 enum XML_Error result =
1904 doContent(parser, 1, encoding, start, end, endPtr);
1905 if (result != XML_ERROR_NONE)
1907 if (!storeRawNames(parser))
1908 return XML_ERROR_NO_MEMORY;
1912 static enum XML_Error
1913 doContent(XML_Parser parser,
1915 const ENCODING *enc,
1918 const char **nextPtr)
1920 DTD * const dtd = _dtd; /* save one level of indirection */
1921 const char **eventPP;
1922 const char **eventEndPP;
1923 if (enc == encoding) {
1924 eventPP = &eventPtr;
1925 eventEndPP = &eventEndPtr;
1928 eventPP = &(openInternalEntities->internalEventPtr);
1929 eventEndPP = &(openInternalEntities->internalEventEndPtr);
1933 const char *next = s; /* XmlContentTok doesn't always set the last arg */
1934 int tok = XmlContentTok(enc, s, end, &next);
1937 case XML_TOK_TRAILING_CR:
1940 return XML_ERROR_NONE;
1943 if (characterDataHandler) {
1945 characterDataHandler(handlerArg, &c, 1);
1947 else if (defaultHandler)
1948 reportDefault(parser, enc, s, end);
1949 if (startTagLevel == 0)
1950 return XML_ERROR_NO_ELEMENTS;
1951 if (tagLevel != startTagLevel)
1952 return XML_ERROR_ASYNC_ENTITY;
1953 return XML_ERROR_NONE;
1957 return XML_ERROR_NONE;
1959 if (startTagLevel > 0) {
1960 if (tagLevel != startTagLevel)
1961 return XML_ERROR_ASYNC_ENTITY;
1962 return XML_ERROR_NONE;
1964 return XML_ERROR_NO_ELEMENTS;
1965 case XML_TOK_INVALID:
1967 return XML_ERROR_INVALID_TOKEN;
1968 case XML_TOK_PARTIAL:
1971 return XML_ERROR_NONE;
1973 return XML_ERROR_UNCLOSED_TOKEN;
1974 case XML_TOK_PARTIAL_CHAR:
1977 return XML_ERROR_NONE;
1979 return XML_ERROR_PARTIAL_CHAR;
1980 case XML_TOK_ENTITY_REF:
1982 const XML_Char *name;
1984 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
1985 s + enc->minBytesPerChar,
1986 next - enc->minBytesPerChar);
1988 if (characterDataHandler)
1989 characterDataHandler(handlerArg, &ch, 1);
1990 else if (defaultHandler)
1991 reportDefault(parser, enc, s, next);
1994 name = poolStoreString(&dtd->pool, enc,
1995 s + enc->minBytesPerChar,
1996 next - enc->minBytesPerChar);
1998 return XML_ERROR_NO_MEMORY;
1999 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
2000 poolDiscard(&dtd->pool);
2001 /* First, determine if a check for an existing declaration is needed;
2002 if yes, check that the entity exists, and that it is internal,
2003 otherwise call the skipped entity or default handler.
2005 if (!dtd->hasParamEntityRefs || dtd->standalone) {
2007 return XML_ERROR_UNDEFINED_ENTITY;
2008 else if (!entity->is_internal)
2009 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2012 if (skippedEntityHandler)
2013 skippedEntityHandler(handlerArg, name, 0);
2014 else if (defaultHandler)
2015 reportDefault(parser, enc, s, next);
2019 return XML_ERROR_RECURSIVE_ENTITY_REF;
2020 if (entity->notation)
2021 return XML_ERROR_BINARY_ENTITY_REF;
2022 if (entity->textPtr) {
2023 enum XML_Error result;
2024 OPEN_INTERNAL_ENTITY openEntity;
2025 if (!defaultExpandInternalEntities) {
2026 if (skippedEntityHandler)
2027 skippedEntityHandler(handlerArg, entity->name, 0);
2028 else if (defaultHandler)
2029 reportDefault(parser, enc, s, next);
2032 entity->open = XML_TRUE;
2033 openEntity.next = openInternalEntities;
2034 openInternalEntities = &openEntity;
2035 openEntity.entity = entity;
2036 openEntity.internalEventPtr = NULL;
2037 openEntity.internalEventEndPtr = NULL;
2038 result = doContent(parser,
2041 (char *)entity->textPtr,
2042 (char *)(entity->textPtr + entity->textLen),
2044 entity->open = XML_FALSE;
2045 openInternalEntities = openEntity.next;
2049 else if (externalEntityRefHandler) {
2050 const XML_Char *context;
2051 entity->open = XML_TRUE;
2052 context = getContext(parser);
2053 entity->open = XML_FALSE;
2055 return XML_ERROR_NO_MEMORY;
2056 if (!externalEntityRefHandler((XML_Parser)externalEntityRefHandlerArg,
2061 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2062 poolDiscard(&tempPool);
2064 else if (defaultHandler)
2065 reportDefault(parser, enc, s, next);
2068 case XML_TOK_START_TAG_NO_ATTS:
2070 case XML_TOK_START_TAG_WITH_ATTS:
2073 enum XML_Error result;
2077 freeTagList = freeTagList->parent;
2080 tag = (TAG *)MALLOC(sizeof(TAG));
2082 return XML_ERROR_NO_MEMORY;
2083 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2086 return XML_ERROR_NO_MEMORY;
2088 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2090 tag->bindings = NULL;
2091 tag->parent = tagStack;
2093 tag->name.localPart = NULL;
2094 tag->name.prefix = NULL;
2095 tag->rawName = s + enc->minBytesPerChar;
2096 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2099 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2100 const char *fromPtr = tag->rawName;
2101 toPtr = (XML_Char *)tag->buf;
2106 &fromPtr, rawNameEnd,
2107 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2108 convLen = toPtr - (XML_Char *)tag->buf;
2109 if (fromPtr == rawNameEnd) {
2110 tag->name.strLen = convLen;
2113 bufSize = (tag->bufEnd - tag->buf) << 1;
2115 char *temp = (char *)REALLOC(tag->buf, bufSize);
2117 return XML_ERROR_NO_MEMORY;
2119 tag->bufEnd = temp + bufSize;
2120 toPtr = (XML_Char *)temp + convLen;
2124 tag->name.str = (XML_Char *)tag->buf;
2125 *toPtr = XML_T('\0');
2126 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2129 if (startElementHandler)
2130 startElementHandler(handlerArg, tag->name.str,
2131 (const XML_Char **)atts);
2132 else if (defaultHandler)
2133 reportDefault(parser, enc, s, next);
2134 poolClear(&tempPool);
2137 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2139 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2141 const char *rawName = s + enc->minBytesPerChar;
2142 enum XML_Error result;
2143 BINDING *bindings = NULL;
2144 XML_Bool noElmHandlers = XML_TRUE;
2146 name.str = poolStoreString(&tempPool, enc, rawName,
2147 rawName + XmlNameLength(enc, rawName));
2149 return XML_ERROR_NO_MEMORY;
2150 poolFinish(&tempPool);
2151 result = storeAtts(parser, enc, s, &name, &bindings);
2154 poolFinish(&tempPool);
2155 if (startElementHandler) {
2156 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2157 noElmHandlers = XML_FALSE;
2159 if (endElementHandler) {
2160 if (startElementHandler)
2161 *eventPP = *eventEndPP;
2162 endElementHandler(handlerArg, name.str);
2163 noElmHandlers = XML_FALSE;
2165 if (noElmHandlers && defaultHandler)
2166 reportDefault(parser, enc, s, next);
2167 poolClear(&tempPool);
2169 BINDING *b = bindings;
2170 if (endNamespaceDeclHandler)
2171 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2172 bindings = bindings->nextTagBinding;
2173 b->nextTagBinding = freeBindingList;
2174 freeBindingList = b;
2175 b->prefix->binding = b->prevPrefixBinding;
2179 return epilogProcessor(parser, next, end, nextPtr);
2181 case XML_TOK_END_TAG:
2182 if (tagLevel == startTagLevel)
2183 return XML_ERROR_ASYNC_ENTITY;
2186 const char *rawName;
2187 TAG *tag = tagStack;
2188 tagStack = tag->parent;
2189 tag->parent = freeTagList;
2191 rawName = s + enc->minBytesPerChar*2;
2192 len = XmlNameLength(enc, rawName);
2193 if (len != tag->rawNameLength
2194 || memcmp(tag->rawName, rawName, len) != 0) {
2196 return XML_ERROR_TAG_MISMATCH;
2199 if (endElementHandler) {
2200 const XML_Char *localPart;
2201 const XML_Char *prefix;
2203 localPart = tag->name.localPart;
2204 if (ns && localPart) {
2205 /* localPart and prefix may have been overwritten in
2206 tag->name.str, since this points to the binding->uri
2207 buffer which gets re-used; so we have to add them again
2209 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2210 /* don't need to check for space - already done in storeAtts() */
2211 while (*localPart) *uri++ = *localPart++;
2212 prefix = (XML_Char *)tag->name.prefix;
2213 if (ns_triplets && prefix) {
2214 *uri++ = namespaceSeparator;
2215 while (*prefix) *uri++ = *prefix++;
2219 endElementHandler(handlerArg, tag->name.str);
2221 else if (defaultHandler)
2222 reportDefault(parser, enc, s, next);
2223 while (tag->bindings) {
2224 BINDING *b = tag->bindings;
2225 if (endNamespaceDeclHandler)
2226 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2227 tag->bindings = tag->bindings->nextTagBinding;
2228 b->nextTagBinding = freeBindingList;
2229 freeBindingList = b;
2230 b->prefix->binding = b->prevPrefixBinding;
2233 return epilogProcessor(parser, next, end, nextPtr);
2236 case XML_TOK_CHAR_REF:
2238 int n = XmlCharRefNumber(enc, s);
2240 return XML_ERROR_BAD_CHAR_REF;
2241 if (characterDataHandler) {
2242 XML_Char buf[XML_ENCODE_MAX];
2243 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2245 else if (defaultHandler)
2246 reportDefault(parser, enc, s, next);
2249 case XML_TOK_XML_DECL:
2250 return XML_ERROR_MISPLACED_XML_PI;
2251 case XML_TOK_DATA_NEWLINE:
2252 if (characterDataHandler) {
2254 characterDataHandler(handlerArg, &c, 1);
2256 else if (defaultHandler)
2257 reportDefault(parser, enc, s, next);
2259 case XML_TOK_CDATA_SECT_OPEN:
2261 enum XML_Error result;
2262 if (startCdataSectionHandler)
2263 startCdataSectionHandler(handlerArg);
2265 /* Suppose you doing a transformation on a document that involves
2266 changing only the character data. You set up a defaultHandler
2267 and a characterDataHandler. The defaultHandler simply copies
2268 characters through. The characterDataHandler does the
2269 transformation and writes the characters out escaping them as
2270 necessary. This case will fail to work if we leave out the
2271 following two lines (because & and < inside CDATA sections will
2272 be incorrectly escaped).
2274 However, now we have a start/endCdataSectionHandler, so it seems
2275 easier to let the user deal with this.
2277 else if (characterDataHandler)
2278 characterDataHandler(handlerArg, dataBuf, 0);
2280 else if (defaultHandler)
2281 reportDefault(parser, enc, s, next);
2282 result = doCdataSection(parser, enc, &next, end, nextPtr);
2284 processor = cdataSectionProcessor;
2289 case XML_TOK_TRAILING_RSQB:
2292 return XML_ERROR_NONE;
2294 if (characterDataHandler) {
2295 if (MUST_CONVERT(enc, s)) {
2296 ICHAR *dataPtr = (ICHAR *)dataBuf;
2297 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2298 characterDataHandler(handlerArg, dataBuf,
2299 dataPtr - (ICHAR *)dataBuf);
2302 characterDataHandler(handlerArg,
2304 (XML_Char *)end - (XML_Char *)s);
2306 else if (defaultHandler)
2307 reportDefault(parser, enc, s, end);
2308 if (startTagLevel == 0) {
2310 return XML_ERROR_NO_ELEMENTS;
2312 if (tagLevel != startTagLevel) {
2314 return XML_ERROR_ASYNC_ENTITY;
2316 return XML_ERROR_NONE;
2317 case XML_TOK_DATA_CHARS:
2318 if (characterDataHandler) {
2319 if (MUST_CONVERT(enc, s)) {
2321 ICHAR *dataPtr = (ICHAR *)dataBuf;
2322 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2324 characterDataHandler(handlerArg, dataBuf,
2325 dataPtr - (ICHAR *)dataBuf);
2332 characterDataHandler(handlerArg,
2334 (XML_Char *)next - (XML_Char *)s);
2336 else if (defaultHandler)
2337 reportDefault(parser, enc, s, next);
2340 if (!reportProcessingInstruction(parser, enc, s, next))
2341 return XML_ERROR_NO_MEMORY;
2343 case XML_TOK_COMMENT:
2344 if (!reportComment(parser, enc, s, next))
2345 return XML_ERROR_NO_MEMORY;
2349 reportDefault(parser, enc, s, next);
2352 *eventPP = s = next;
2357 /* Precondition: all arguments must be non-NULL;
2359 - normalize attributes
2360 - check attributes for well-formedness
2361 - generate namespace aware attribute names (URI, prefix)
2362 - build list of attributes for startElementHandler
2363 - default attributes
2364 - process namespace declarations (check and report them)
2365 - generate namespace aware element name (URI, prefix)
2367 static enum XML_Error
2368 storeAtts(XML_Parser parser, const ENCODING *enc,
2369 const char *attStr, TAG_NAME *tagNamePtr,
2370 BINDING **bindingsPtr)
2372 DTD * const dtd = _dtd; /* save one level of indirection */
2373 ELEMENT_TYPE *elementType = NULL;
2374 int nDefaultAtts = 0;
2375 const XML_Char **appAtts; /* the attribute list for the application */
2383 const XML_Char *localPart;
2385 /* lookup the element type name */
2386 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
2388 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2390 return XML_ERROR_NO_MEMORY;
2391 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
2392 sizeof(ELEMENT_TYPE));
2394 return XML_ERROR_NO_MEMORY;
2395 if (ns && !setElementTypePrefix(parser, elementType))
2396 return XML_ERROR_NO_MEMORY;
2398 nDefaultAtts = elementType->nDefaultAtts;
2400 /* get the attributes from the tokenizer */
2401 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2402 if (n + nDefaultAtts > attsSize) {
2403 int oldAttsSize = attsSize;
2405 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2406 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2408 return XML_ERROR_NO_MEMORY;
2410 if (n > oldAttsSize)
2411 XmlGetAttributes(enc, attStr, n, atts);
2414 appAtts = (const XML_Char **)atts;
2415 for (i = 0; i < n; i++) {
2416 /* add the name and value to the attribute list */
2417 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
2419 + XmlNameLength(enc, atts[i].name));
2421 return XML_ERROR_NO_MEMORY;
2422 /* detect duplicate attributes by their QNames */
2423 if ((attId->name)[-1]) {
2424 if (enc == encoding)
2425 eventPtr = atts[i].name;
2426 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2428 (attId->name)[-1] = 1;
2429 appAtts[attIndex++] = attId->name;
2430 if (!atts[i].normalized) {
2431 enum XML_Error result;
2432 XML_Bool isCdata = XML_TRUE;
2434 /* figure out whether declared as other than CDATA */
2435 if (attId->maybeTokenized) {
2437 for (j = 0; j < nDefaultAtts; j++) {
2438 if (attId == elementType->defaultAtts[j].id) {
2439 isCdata = elementType->defaultAtts[j].isCdata;
2445 /* normalize the attribute value */
2446 result = storeAttributeValue(parser, enc, isCdata,
2447 atts[i].valuePtr, atts[i].valueEnd,
2451 appAtts[attIndex] = poolStart(&tempPool);
2452 poolFinish(&tempPool);
2455 /* the value did not need normalizing */
2456 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2458 if (appAtts[attIndex] == 0)
2459 return XML_ERROR_NO_MEMORY;
2460 poolFinish(&tempPool);
2462 /* handle prefixed attribute names */
2463 if (attId->prefix) {
2465 /* deal with namespace declarations here */
2466 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2467 appAtts[attIndex], bindingsPtr);
2473 /* deal with other prefixed names later */
2476 (attId->name)[-1] = 2;
2483 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2484 nSpecifiedAtts = attIndex;
2485 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2486 for (i = 0; i < attIndex; i += 2)
2487 if (appAtts[i] == elementType->idAtt->name) {
2495 /* do attribute defaulting */
2496 for (i = 0; i < nDefaultAtts; i++) {
2497 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2498 if (!(da->id->name)[-1] && da->value) {
2499 if (da->id->prefix) {
2500 if (da->id->xmlns) {
2501 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2502 da->value, bindingsPtr);
2507 (da->id->name)[-1] = 2;
2509 appAtts[attIndex++] = da->id->name;
2510 appAtts[attIndex++] = da->value;
2514 (da->id->name)[-1] = 1;
2515 appAtts[attIndex++] = da->id->name;
2516 appAtts[attIndex++] = da->value;
2520 appAtts[attIndex] = 0;
2522 /* expand prefixed attribute names and
2523 clear flags that say whether attributes were specified */
2527 if ((nPrefixes * 2) > nsAttsSize) {
2528 NS_ATT *temp = (NS_ATT *)REALLOC(nsAtts, nPrefixes * 2 * sizeof(NS_ATT));
2530 return XML_ERROR_NO_MEMORY;
2532 nsAttsSize = nPrefixes * 2;
2534 /* clear nsAtts hash table */
2535 for (j = 0; j < nsAttsSize; j++)
2536 nsAtts[j].uriName = NULL;
2538 for (; i < attIndex; i += 2) {
2539 const XML_Char *s = appAtts[i];
2543 unsigned long uriHash = 0;
2544 ((XML_Char *)s)[-1] = 0;
2545 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
2546 b = id->prefix->binding;
2548 return XML_ERROR_UNBOUND_PREFIX;
2550 /* b->uri includes namespace separator */
2551 for (j = 0; j < b->uriLen; j++) {
2552 const XML_Char c = b->uri[j];
2553 if (!poolAppendChar(&tempPool, c))
2554 return XML_ERROR_NO_MEMORY;
2555 uriHash = (uriHash << 5) + uriHash + (unsigned char)c;
2557 while (*s++ != XML_T(':'))
2560 const XML_Char c = *s;
2561 if (!poolAppendChar(&tempPool, *s))
2562 return XML_ERROR_NO_MEMORY;
2563 uriHash = (uriHash << 5) + uriHash + (unsigned char)c;
2566 /* detect duplicate attributes based on uriName = uri + local name */
2567 for (j = uriHash & (nsAttsSize - 1);
2569 j == 0 ? j = nsAttsSize - 1 : --j) {
2570 if (uriHash == nsAtts[j].hash) {
2571 const XML_Char *s1 = poolStart(&tempPool); /* null-terminated */
2572 const XML_Char *s2 = nsAtts[j].uriName;
2573 for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2575 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2580 tempPool.ptr[-1] = namespaceSeparator;
2581 s = b->prefix->name;
2583 if (!poolAppendChar(&tempPool, *s))
2584 return XML_ERROR_NO_MEMORY;
2588 s = poolStart(&tempPool);
2590 poolFinish(&tempPool);
2592 /* fill empty slot with new attribute */
2593 nsAtts[j].hash = uriHash;
2594 nsAtts[j].uriName = s;
2600 ((XML_Char *)s)[-1] = 0;
2603 /* clear flags for the remaining attributes */
2604 for (; i < attIndex; i += 2)
2605 ((XML_Char *)(appAtts[i]))[-1] = 0;
2606 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2607 binding->attId->name[-1] = 0;
2609 /* expand the element type name */
2610 if (elementType->prefix) {
2611 binding = elementType->prefix->binding;
2613 return XML_ERROR_UNBOUND_PREFIX;
2614 localPart = tagNamePtr->str;
2615 while (*localPart++ != XML_T(':'))
2618 else if (dtd->defaultPrefix.binding) {
2619 binding = dtd->defaultPrefix.binding;
2620 localPart = tagNamePtr->str;
2623 return XML_ERROR_NONE;
2625 if (ns && ns_triplets && binding->prefix->name) {
2626 for (; binding->prefix->name[prefixLen++];)
2629 tagNamePtr->localPart = localPart;
2630 tagNamePtr->uriLen = binding->uriLen;
2631 tagNamePtr->prefix = binding->prefix->name;
2632 tagNamePtr->prefixLen = prefixLen;
2633 for (i = 0; localPart[i++];)
2635 n = i + binding->uriLen + prefixLen;
2636 if (n > binding->uriAlloc) {
2638 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
2640 return XML_ERROR_NO_MEMORY;
2641 binding->uriAlloc = n + EXPAND_SPARE;
2642 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2643 for (p = tagStack; p; p = p->parent)
2644 if (p->name.str == binding->uri)
2649 uri = binding->uri + binding->uriLen;
2650 memcpy(uri, localPart, i * sizeof(XML_Char));
2652 uri = uri + (i - 1);
2653 if (namespaceSeparator)
2654 *uri = namespaceSeparator;
2655 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2657 tagNamePtr->str = binding->uri;
2658 return XML_ERROR_NONE;
2661 /* addBinding() overwrites the value of prefix->binding without checking.
2662 Therefore one must keep track of the old value outside of addBinding().
2664 static enum XML_Error
2665 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2666 const XML_Char *uri, BINDING **bindingsPtr)
2671 /* empty string is only valid when there is no prefix per XML NS 1.0 */
2672 if (*uri == XML_T('\0') && prefix->name)
2673 return XML_ERROR_SYNTAX;
2675 for (len = 0; uri[len]; len++)
2677 if (namespaceSeparator)
2679 if (freeBindingList) {
2680 b = freeBindingList;
2681 if (len > b->uriAlloc) {
2682 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
2683 sizeof(XML_Char) * (len + EXPAND_SPARE));
2685 return XML_ERROR_NO_MEMORY;
2687 b->uriAlloc = len + EXPAND_SPARE;
2689 freeBindingList = b->nextTagBinding;
2692 b = (BINDING *)MALLOC(sizeof(BINDING));
2694 return XML_ERROR_NO_MEMORY;
2695 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
2698 return XML_ERROR_NO_MEMORY;
2700 b->uriAlloc = len + EXPAND_SPARE;
2703 memcpy(b->uri, uri, len * sizeof(XML_Char));
2704 if (namespaceSeparator)
2705 b->uri[len - 1] = namespaceSeparator;
2708 b->prevPrefixBinding = prefix->binding;
2709 /* NULL binding when default namespace undeclared */
2710 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
2711 prefix->binding = NULL;
2713 prefix->binding = b;
2714 b->nextTagBinding = *bindingsPtr;
2716 if (startNamespaceDeclHandler)
2717 startNamespaceDeclHandler(handlerArg, prefix->name,
2718 prefix->binding ? uri : 0);
2719 return XML_ERROR_NONE;
2722 /* The idea here is to avoid using stack for each CDATA section when
2723 the whole file is parsed with one call.
2725 static enum XML_Error PTRCALL
2726 cdataSectionProcessor(XML_Parser parser,
2729 const char **endPtr)
2731 enum XML_Error result = doCdataSection(parser, encoding, &start,
2734 if (parentParser) { /* we are parsing an external entity */
2735 processor = externalEntityContentProcessor;
2736 return externalEntityContentProcessor(parser, start, end, endPtr);
2739 processor = contentProcessor;
2740 return contentProcessor(parser, start, end, endPtr);
2746 /* startPtr gets set to non-null is the section is closed, and to null if
2747 the section is not yet closed.
2749 static enum XML_Error
2750 doCdataSection(XML_Parser parser,
2751 const ENCODING *enc,
2752 const char **startPtr,
2754 const char **nextPtr)
2756 const char *s = *startPtr;
2757 const char **eventPP;
2758 const char **eventEndPP;
2759 if (enc == encoding) {
2760 eventPP = &eventPtr;
2762 eventEndPP = &eventEndPtr;
2765 eventPP = &(openInternalEntities->internalEventPtr);
2766 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2772 int tok = XmlCdataSectionTok(enc, s, end, &next);
2775 case XML_TOK_CDATA_SECT_CLOSE:
2776 if (endCdataSectionHandler)
2777 endCdataSectionHandler(handlerArg);
2779 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2780 else if (characterDataHandler)
2781 characterDataHandler(handlerArg, dataBuf, 0);
2783 else if (defaultHandler)
2784 reportDefault(parser, enc, s, next);
2786 return XML_ERROR_NONE;
2787 case XML_TOK_DATA_NEWLINE:
2788 if (characterDataHandler) {
2790 characterDataHandler(handlerArg, &c, 1);
2792 else if (defaultHandler)
2793 reportDefault(parser, enc, s, next);
2795 case XML_TOK_DATA_CHARS:
2796 if (characterDataHandler) {
2797 if (MUST_CONVERT(enc, s)) {
2799 ICHAR *dataPtr = (ICHAR *)dataBuf;
2800 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2802 characterDataHandler(handlerArg, dataBuf,
2803 dataPtr - (ICHAR *)dataBuf);
2810 characterDataHandler(handlerArg,
2812 (XML_Char *)next - (XML_Char *)s);
2814 else if (defaultHandler)
2815 reportDefault(parser, enc, s, next);
2817 case XML_TOK_INVALID:
2819 return XML_ERROR_INVALID_TOKEN;
2820 case XML_TOK_PARTIAL_CHAR:
2823 return XML_ERROR_NONE;
2825 return XML_ERROR_PARTIAL_CHAR;
2826 case XML_TOK_PARTIAL:
2830 return XML_ERROR_NONE;
2832 return XML_ERROR_UNCLOSED_CDATA_SECTION;
2835 return XML_ERROR_UNEXPECTED_STATE;
2837 *eventPP = s = next;
2844 /* The idea here is to avoid using stack for each IGNORE section when
2845 the whole file is parsed with one call.
2847 static enum XML_Error PTRCALL
2848 ignoreSectionProcessor(XML_Parser parser,
2851 const char **endPtr)
2853 enum XML_Error result = doIgnoreSection(parser, encoding, &start,
2856 processor = prologProcessor;
2857 return prologProcessor(parser, start, end, endPtr);
2862 /* startPtr gets set to non-null is the section is closed, and to null
2863 if the section is not yet closed.
2865 static enum XML_Error
2866 doIgnoreSection(XML_Parser parser,
2867 const ENCODING *enc,
2868 const char **startPtr,
2870 const char **nextPtr)
2874 const char *s = *startPtr;
2875 const char **eventPP;
2876 const char **eventEndPP;
2877 if (enc == encoding) {
2878 eventPP = &eventPtr;
2880 eventEndPP = &eventEndPtr;
2883 eventPP = &(openInternalEntities->internalEventPtr);
2884 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2888 tok = XmlIgnoreSectionTok(enc, s, end, &next);
2891 case XML_TOK_IGNORE_SECT:
2893 reportDefault(parser, enc, s, next);
2895 return XML_ERROR_NONE;
2896 case XML_TOK_INVALID:
2898 return XML_ERROR_INVALID_TOKEN;
2899 case XML_TOK_PARTIAL_CHAR:
2902 return XML_ERROR_NONE;
2904 return XML_ERROR_PARTIAL_CHAR;
2905 case XML_TOK_PARTIAL:
2909 return XML_ERROR_NONE;
2911 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2914 return XML_ERROR_UNEXPECTED_STATE;
2919 #endif /* XML_DTD */
2921 static enum XML_Error
2922 initializeEncoding(XML_Parser parser)
2926 char encodingBuf[128];
2927 if (!protocolEncodingName)
2931 for (i = 0; protocolEncodingName[i]; i++) {
2932 if (i == sizeof(encodingBuf) - 1
2933 || (protocolEncodingName[i] & ~0x7f) != 0) {
2934 encodingBuf[0] = '\0';
2937 encodingBuf[i] = (char)protocolEncodingName[i];
2939 encodingBuf[i] = '\0';
2943 s = protocolEncodingName;
2945 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
2946 return XML_ERROR_NONE;
2947 return handleUnknownEncoding(parser, protocolEncodingName);
2950 static enum XML_Error
2951 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
2952 const char *s, const char *next)
2954 const char *encodingName = NULL;
2955 const XML_Char *storedEncName = NULL;
2956 const ENCODING *newEncoding = NULL;
2957 const char *version = NULL;
2958 const char *versionend;
2959 const XML_Char *storedversion = NULL;
2960 int standalone = -1;
2963 : XmlParseXmlDecl)(isGeneralTextEntity,
2973 return XML_ERROR_SYNTAX;
2974 if (!isGeneralTextEntity && standalone == 1) {
2975 _dtd->standalone = XML_TRUE;
2977 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
2978 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
2979 #endif /* XML_DTD */
2981 if (xmlDeclHandler) {
2982 if (encodingName != NULL) {
2983 storedEncName = poolStoreString(&temp2Pool,
2987 + XmlNameLength(encoding, encodingName));
2989 return XML_ERROR_NO_MEMORY;
2990 poolFinish(&temp2Pool);
2993 storedversion = poolStoreString(&temp2Pool,
2996 versionend - encoding->minBytesPerChar);
2998 return XML_ERROR_NO_MEMORY;
3000 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3002 else if (defaultHandler)
3003 reportDefault(parser, encoding, s, next);
3004 if (protocolEncodingName == NULL) {
3006 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
3007 eventPtr = encodingName;
3008 return XML_ERROR_INCORRECT_ENCODING;
3010 encoding = newEncoding;
3012 else if (encodingName) {
3013 enum XML_Error result;
3014 if (!storedEncName) {
3015 storedEncName = poolStoreString(
3016 &temp2Pool, encoding, encodingName,
3017 encodingName + XmlNameLength(encoding, encodingName));
3019 return XML_ERROR_NO_MEMORY;
3021 result = handleUnknownEncoding(parser, storedEncName);
3022 poolClear(&temp2Pool);
3023 if (result == XML_ERROR_UNKNOWN_ENCODING)
3024 eventPtr = encodingName;
3029 if (storedEncName || storedversion)
3030 poolClear(&temp2Pool);
3032 return XML_ERROR_NONE;
3035 static enum XML_Error
3036 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3038 if (unknownEncodingHandler) {
3041 for (i = 0; i < 256; i++)
3043 info.convert = NULL;
3045 info.release = NULL;
3046 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3049 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3050 if (!unknownEncodingMem) {
3052 info.release(info.data);
3053 return XML_ERROR_NO_MEMORY;
3056 ? XmlInitUnknownEncodingNS
3057 : XmlInitUnknownEncoding)(unknownEncodingMem,
3062 unknownEncodingData = info.data;
3063 unknownEncodingRelease = info.release;
3065 return XML_ERROR_NONE;
3068 if (info.release != NULL)
3069 info.release(info.data);
3071 return XML_ERROR_UNKNOWN_ENCODING;
3074 static enum XML_Error PTRCALL
3075 prologInitProcessor(XML_Parser parser,
3078 const char **nextPtr)
3080 enum XML_Error result = initializeEncoding(parser);
3081 if (result != XML_ERROR_NONE)
3083 processor = prologProcessor;
3084 return prologProcessor(parser, s, end, nextPtr);
3089 static enum XML_Error PTRCALL
3090 externalParEntInitProcessor(XML_Parser parser,
3093 const char **nextPtr)
3095 enum XML_Error result = initializeEncoding(parser);
3096 if (result != XML_ERROR_NONE)
3099 /* we know now that XML_Parse(Buffer) has been called,
3100 so we consider the external parameter entity read */
3101 _dtd->paramEntityRead = XML_TRUE;
3103 if (prologState.inEntityValue) {
3104 processor = entityValueInitProcessor;
3105 return entityValueInitProcessor(parser, s, end, nextPtr);
3108 processor = externalParEntProcessor;
3109 return externalParEntProcessor(parser, s, end, nextPtr);
3113 static enum XML_Error PTRCALL
3114 entityValueInitProcessor(XML_Parser parser,
3117 const char **nextPtr)
3119 const char *start = s;
3120 const char *next = s;
3124 tok = XmlPrologTok(encoding, start, end, &next);
3126 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3128 return XML_ERROR_NONE;
3131 case XML_TOK_INVALID:
3132 return XML_ERROR_INVALID_TOKEN;
3133 case XML_TOK_PARTIAL:
3134 return XML_ERROR_UNCLOSED_TOKEN;
3135 case XML_TOK_PARTIAL_CHAR:
3136 return XML_ERROR_PARTIAL_CHAR;
3137 case XML_TOK_NONE: /* start == end */
3141 return storeEntityValue(parser, encoding, s, end);
3143 else if (tok == XML_TOK_XML_DECL) {
3144 enum XML_Error result = processXmlDecl(parser, 0, start, next);
3145 if (result != XML_ERROR_NONE)
3147 if (nextPtr) *nextPtr = next;
3148 /* stop scanning for text declaration - we found one */
3149 processor = entityValueProcessor;
3150 return entityValueProcessor(parser, next, end, nextPtr);
3152 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3153 return XML_TOK_NONE on the next call, which would then cause the
3154 function to exit with *nextPtr set to s - that is what we want for other
3155 tokens, but not for the BOM - we would rather like to skip it;
3156 then, when this routine is entered the next time, XmlPrologTok will
3157 return XML_TOK_INVALID, since the BOM is still in the buffer
3159 else if (tok == XML_TOK_BOM && next == end && nextPtr) {
3161 return XML_ERROR_NONE;
3167 static enum XML_Error PTRCALL
3168 externalParEntProcessor(XML_Parser parser,
3171 const char **nextPtr)
3173 const char *start = s;
3174 const char *next = s;
3177 tok = XmlPrologTok(encoding, start, end, &next);
3179 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3181 return XML_ERROR_NONE;
3184 case XML_TOK_INVALID:
3185 return XML_ERROR_INVALID_TOKEN;
3186 case XML_TOK_PARTIAL:
3187 return XML_ERROR_UNCLOSED_TOKEN;
3188 case XML_TOK_PARTIAL_CHAR:
3189 return XML_ERROR_PARTIAL_CHAR;
3190 case XML_TOK_NONE: /* start == end */
3195 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3196 However, when parsing an external subset, doProlog will not accept a BOM
3197 as valid, and report a syntax error, so we have to skip the BOM
3199 else if (tok == XML_TOK_BOM) {
3201 tok = XmlPrologTok(encoding, s, end, &next);
3204 processor = prologProcessor;
3205 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3208 static enum XML_Error PTRCALL
3209 entityValueProcessor(XML_Parser parser,
3212 const char **nextPtr)
3214 const char *start = s;
3215 const char *next = s;
3216 const ENCODING *enc = encoding;
3220 tok = XmlPrologTok(enc, start, end, &next);
3222 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3224 return XML_ERROR_NONE;
3227 case XML_TOK_INVALID:
3228 return XML_ERROR_INVALID_TOKEN;
3229 case XML_TOK_PARTIAL:
3230 return XML_ERROR_UNCLOSED_TOKEN;
3231 case XML_TOK_PARTIAL_CHAR:
3232 return XML_ERROR_PARTIAL_CHAR;
3233 case XML_TOK_NONE: /* start == end */
3237 return storeEntityValue(parser, enc, s, end);
3243 #endif /* XML_DTD */
3245 static enum XML_Error PTRCALL
3246 prologProcessor(XML_Parser parser,
3249 const char **nextPtr)
3251 const char *next = s;
3252 int tok = XmlPrologTok(encoding, s, end, &next);
3253 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3256 static enum XML_Error
3257 doProlog(XML_Parser parser,
3258 const ENCODING *enc,
3263 const char **nextPtr)
3266 static const XML_Char externalSubsetName[] = { '#' , '\0' };
3267 #endif /* XML_DTD */
3268 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3269 static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3270 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3271 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3272 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3273 static const XML_Char atypeENTITIES[] =
3274 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3275 static const XML_Char atypeNMTOKEN[] = {
3276 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3277 static const XML_Char atypeNMTOKENS[] = {
3278 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3279 static const XML_Char notationPrefix[] = {
3280 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3281 static const XML_Char enumValueSep[] = { '|', '\0' };
3282 static const XML_Char enumValueStart[] = { '(', '\0' };
3284 DTD * const dtd = _dtd; /* save one level of indirection */
3286 const char **eventPP;
3287 const char **eventEndPP;
3288 enum XML_Content_Quant quant;
3290 if (enc == encoding) {
3291 eventPP = &eventPtr;
3292 eventEndPP = &eventEndPtr;
3295 eventPP = &(openInternalEntities->internalEventPtr);
3296 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3300 XML_Bool handleDefault = XML_TRUE;
3304 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3306 return XML_ERROR_NONE;
3309 case XML_TOK_INVALID:
3311 return XML_ERROR_INVALID_TOKEN;
3312 case XML_TOK_PARTIAL:
3313 return XML_ERROR_UNCLOSED_TOKEN;
3314 case XML_TOK_PARTIAL_CHAR:
3315 return XML_ERROR_PARTIAL_CHAR;
3318 if (enc != encoding)
3319 return XML_ERROR_NONE;
3320 if (isParamEntity) {
3321 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3323 return XML_ERROR_SYNTAX;
3324 return XML_ERROR_NONE;
3326 #endif /* XML_DTD */
3327 return XML_ERROR_NO_ELEMENTS;
3334 role = XmlTokenRole(&prologState, tok, s, next, enc);
3336 case XML_ROLE_XML_DECL:
3338 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3339 if (result != XML_ERROR_NONE)
3342 handleDefault = XML_FALSE;
3345 case XML_ROLE_DOCTYPE_NAME:
3346 if (startDoctypeDeclHandler) {
3347 doctypeName = poolStoreString(&tempPool, enc, s, next);
3349 return XML_ERROR_NO_MEMORY;
3350 poolFinish(&tempPool);
3351 doctypePubid = NULL;
3352 handleDefault = XML_FALSE;
3354 doctypeSysid = NULL; /* always initialize to NULL */
3356 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3357 if (startDoctypeDeclHandler) {
3358 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3361 poolClear(&tempPool);
3362 handleDefault = XML_FALSE;
3366 case XML_ROLE_TEXT_DECL:
3368 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3369 if (result != XML_ERROR_NONE)
3372 handleDefault = XML_FALSE;
3375 #endif /* XML_DTD */
3376 case XML_ROLE_DOCTYPE_PUBLIC_ID:
3378 useForeignDTD = XML_FALSE;
3379 #endif /* XML_DTD */
3380 dtd->hasParamEntityRefs = XML_TRUE;
3381 if (startDoctypeDeclHandler) {
3382 doctypePubid = poolStoreString(&tempPool, enc,
3383 s + enc->minBytesPerChar,
3384 next - enc->minBytesPerChar);
3386 return XML_ERROR_NO_MEMORY;
3387 poolFinish(&tempPool);
3388 handleDefault = XML_FALSE;
3391 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3395 return XML_ERROR_NO_MEMORY;
3396 #endif /* XML_DTD */
3398 case XML_ROLE_ENTITY_PUBLIC_ID:
3399 if (!XmlIsPublicId(enc, s, next, eventPP))
3400 return XML_ERROR_SYNTAX;
3401 if (dtd->keepProcessing && declEntity) {
3402 XML_Char *tem = poolStoreString(&dtd->pool,
3404 s + enc->minBytesPerChar,
3405 next - enc->minBytesPerChar);
3407 return XML_ERROR_NO_MEMORY;
3408 normalizePublicId(tem);
3409 declEntity->publicId = tem;
3410 poolFinish(&dtd->pool);
3411 if (entityDeclHandler)
3412 handleDefault = XML_FALSE;
3415 case XML_ROLE_DOCTYPE_CLOSE:
3417 startDoctypeDeclHandler(handlerArg, doctypeName,
3418 doctypeSysid, doctypePubid, 0);
3419 poolClear(&tempPool);
3420 handleDefault = XML_FALSE;
3422 /* doctypeSysid will be non-NULL in the case of a previous
3423 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3424 was not set, indicating an external subset
3427 if (doctypeSysid || useForeignDTD) {
3428 dtd->hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */
3429 if (paramEntityParsing && externalEntityRefHandler) {
3430 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3434 return XML_ERROR_NO_MEMORY;
3436 entity->base = curBase;
3437 dtd->paramEntityRead = XML_FALSE;
3438 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3443 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3444 if (dtd->paramEntityRead &&
3446 notStandaloneHandler &&
3447 !notStandaloneHandler(handlerArg))
3448 return XML_ERROR_NOT_STANDALONE;
3449 /* end of DTD - no need to update dtd->keepProcessing */
3451 useForeignDTD = XML_FALSE;
3453 #endif /* XML_DTD */
3454 if (endDoctypeDeclHandler) {
3455 endDoctypeDeclHandler(handlerArg);
3456 handleDefault = XML_FALSE;
3459 case XML_ROLE_INSTANCE_START:
3461 /* if there is no DOCTYPE declaration then now is the
3462 last chance to read the foreign DTD
3464 if (useForeignDTD) {
3465 dtd->hasParamEntityRefs = XML_TRUE;
3466 if (paramEntityParsing && externalEntityRefHandler) {
3467 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3471 return XML_ERROR_NO_MEMORY;
3472 entity->base = curBase;
3473 dtd->paramEntityRead = XML_FALSE;
3474 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3479 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3480 if (dtd->paramEntityRead &&
3482 notStandaloneHandler &&
3483 !notStandaloneHandler(handlerArg))
3484 return XML_ERROR_NOT_STANDALONE;
3485 /* end of DTD - no need to update dtd->keepProcessing */
3488 #endif /* XML_DTD */
3489 processor = contentProcessor;
3490 return contentProcessor(parser, s, end, nextPtr);
3491 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3492 declElementType = getElementType(parser, enc, s, next);
3493 if (!declElementType)
3494 return XML_ERROR_NO_MEMORY;
3495 goto checkAttListDeclHandler;
3496 case XML_ROLE_ATTRIBUTE_NAME:
3497 declAttributeId = getAttributeId(parser, enc, s, next);
3498 if (!declAttributeId)
3499 return XML_ERROR_NO_MEMORY;
3500 declAttributeIsCdata = XML_FALSE;
3501 declAttributeType = NULL;
3502 declAttributeIsId = XML_FALSE;
3503 goto checkAttListDeclHandler;
3504 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
3505 declAttributeIsCdata = XML_TRUE;
3506 declAttributeType = atypeCDATA;
3507 goto checkAttListDeclHandler;
3508 case XML_ROLE_ATTRIBUTE_TYPE_ID:
3509 declAttributeIsId = XML_TRUE;
3510 declAttributeType = atypeID;
3511 goto checkAttListDeclHandler;
3512 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
3513 declAttributeType = atypeIDREF;
3514 goto checkAttListDeclHandler;
3515 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
3516 declAttributeType = atypeIDREFS;
3517 goto checkAttListDeclHandler;
3518 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
3519 declAttributeType = atypeENTITY;
3520 goto checkAttListDeclHandler;
3521 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
3522 declAttributeType = atypeENTITIES;
3523 goto checkAttListDeclHandler;
3524 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
3525 declAttributeType = atypeNMTOKEN;
3526 goto checkAttListDeclHandler;
3527 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
3528 declAttributeType = atypeNMTOKENS;
3529 checkAttListDeclHandler:
3530 if (dtd->keepProcessing && attlistDeclHandler)
3531 handleDefault = XML_FALSE;
3533 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3534 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
3535 if (dtd->keepProcessing && attlistDeclHandler) {
3536 const XML_Char *prefix;
3537 if (declAttributeType) {
3538 prefix = enumValueSep;
3541 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3545 if (!poolAppendString(&tempPool, prefix))
3546 return XML_ERROR_NO_MEMORY;
3547 if (!poolAppend(&tempPool, enc, s, next))
3548 return XML_ERROR_NO_MEMORY;
3549 declAttributeType = tempPool.start;
3550 handleDefault = XML_FALSE;
3553 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3554 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
3555 if (dtd->keepProcessing) {
3556 if (!defineAttribute(declElementType, declAttributeId,
3557 declAttributeIsCdata, declAttributeIsId,
3559 return XML_ERROR_NO_MEMORY;
3560 if (attlistDeclHandler && declAttributeType) {
3561 if (*declAttributeType == XML_T('(')
3562 || (*declAttributeType == XML_T('N')
3563 && declAttributeType[1] == XML_T('O'))) {
3564 /* Enumerated or Notation type */
3565 if (!poolAppendChar(&tempPool, XML_T(')'))
3566 || !poolAppendChar(&tempPool, XML_T('\0')))
3567 return XML_ERROR_NO_MEMORY;
3568 declAttributeType = tempPool.start;
3569 poolFinish(&tempPool);
3572 attlistDeclHandler(handlerArg, declElementType->name,
3573 declAttributeId->name, declAttributeType,
3574 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
3575 poolClear(&tempPool);
3576 handleDefault = XML_FALSE;
3580 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3581 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
3582 if (dtd->keepProcessing) {
3583 const XML_Char *attVal;
3584 enum XML_Error result =
3585 storeAttributeValue(parser, enc, declAttributeIsCdata,
3586 s + enc->minBytesPerChar,
3587 next - enc->minBytesPerChar,
3591 attVal = poolStart(&dtd->pool);
3592 poolFinish(&dtd->pool);
3593 /* ID attributes aren't allowed to have a default */
3594 if (!defineAttribute(declElementType, declAttributeId,
3595 declAttributeIsCdata, XML_FALSE, attVal, parser))
3596 return XML_ERROR_NO_MEMORY;
3597 if (attlistDeclHandler && declAttributeType) {
3598 if (*declAttributeType == XML_T('(')
3599 || (*declAttributeType == XML_T('N')
3600 && declAttributeType[1] == XML_T('O'))) {
3601 /* Enumerated or Notation type */
3602 if (!poolAppendChar(&tempPool, XML_T(')'))
3603 || !poolAppendChar(&tempPool, XML_T('\0')))
3604 return XML_ERROR_NO_MEMORY;
3605 declAttributeType = tempPool.start;
3606 poolFinish(&tempPool);
3609 attlistDeclHandler(handlerArg, declElementType->name,
3610 declAttributeId->name, declAttributeType,
3612 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
3613 poolClear(&tempPool);
3614 handleDefault = XML_FALSE;
3618 case XML_ROLE_ENTITY_VALUE:
3619 if (dtd->keepProcessing) {
3620 enum XML_Error result = storeEntityValue(parser, enc,
3621 s + enc->minBytesPerChar,
3622 next - enc->minBytesPerChar);
3624 declEntity->textPtr = poolStart(&dtd->entityValuePool);
3625 declEntity->textLen = poolLength(&dtd->entityValuePool);
3626 poolFinish(&dtd->entityValuePool);
3627 if (entityDeclHandler) {
3629 entityDeclHandler(handlerArg,
3631 declEntity->is_param,
3632 declEntity->textPtr,
3633 declEntity->textLen,
3635 handleDefault = XML_FALSE;
3639 poolDiscard(&dtd->entityValuePool);
3640 if (result != XML_ERROR_NONE)
3644 case XML_ROLE_DOCTYPE_SYSTEM_ID:
3646 useForeignDTD = XML_FALSE;
3647 #endif /* XML_DTD */
3648 dtd->hasParamEntityRefs = XML_TRUE;
3649 if (startDoctypeDeclHandler) {
3650 doctypeSysid = poolStoreString(&tempPool, enc,
3651 s + enc->minBytesPerChar,
3652 next - enc->minBytesPerChar);
3653 if (doctypeSysid == NULL)
3654 return XML_ERROR_NO_MEMORY;
3655 poolFinish(&tempPool);
3656 handleDefault = XML_FALSE;
3660 /* use externalSubsetName to make doctypeSysid non-NULL
3661 for the case where no startDoctypeDeclHandler is set */
3662 doctypeSysid = externalSubsetName;
3663 #endif /* XML_DTD */
3664 if (!dtd->standalone
3666 && !paramEntityParsing
3667 #endif /* XML_DTD */
3668 && notStandaloneHandler
3669 && !notStandaloneHandler(handlerArg))
3670 return XML_ERROR_NOT_STANDALONE;
3675 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3679 return XML_ERROR_NO_MEMORY;
3680 declEntity->publicId = NULL;
3683 #endif /* XML_DTD */
3684 case XML_ROLE_ENTITY_SYSTEM_ID:
3685 if (dtd->keepProcessing && declEntity) {
3686 declEntity->systemId = poolStoreString(&dtd->pool, enc,
3687 s + enc->minBytesPerChar,
3688 next - enc->minBytesPerChar);
3689 if (!declEntity->systemId)
3690 return XML_ERROR_NO_MEMORY;
3691 declEntity->base = curBase;
3692 poolFinish(&dtd->pool);
3693 if (entityDeclHandler)
3694 handleDefault = XML_FALSE;
3697 case XML_ROLE_ENTITY_COMPLETE:
3698 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
3700 entityDeclHandler(handlerArg,
3702 declEntity->is_param,
3705 declEntity->systemId,
3706 declEntity->publicId,
3708 handleDefault = XML_FALSE;
3711 case XML_ROLE_ENTITY_NOTATION_NAME:
3712 if (dtd->keepProcessing && declEntity) {
3713 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
3714 if (!declEntity->notation)
3715 return XML_ERROR_NO_MEMORY;
3716 poolFinish(&dtd->pool);
3717 if (unparsedEntityDeclHandler) {
3719 unparsedEntityDeclHandler(handlerArg,
3722 declEntity->systemId,
3723 declEntity->publicId,
3724 declEntity->notation);
3725 handleDefault = XML_FALSE;
3727 else if (entityDeclHandler) {
3729 entityDeclHandler(handlerArg,
3733 declEntity->systemId,
3734 declEntity->publicId,
3735 declEntity->notation);
3736 handleDefault = XML_FALSE;
3740 case XML_ROLE_GENERAL_ENTITY_NAME:
3742 if (XmlPredefinedEntityName(enc, s, next)) {
3746 if (dtd->keepProcessing) {
3747 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
3749 return XML_ERROR_NO_MEMORY;
3750 declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
3753 return XML_ERROR_NO_MEMORY;
3754 if (declEntity->name != name) {
3755 poolDiscard(&dtd->pool);
3759 poolFinish(&dtd->pool);
3760 declEntity->publicId = NULL;
3761 declEntity->is_param = XML_FALSE;
3762 /* if we have a parent parser or are reading an internal parameter
3763 entity, then the entity declaration is not considered "internal"
3765 declEntity->is_internal = !(parentParser || openInternalEntities);
3766 if (entityDeclHandler)
3767 handleDefault = XML_FALSE;
3771 poolDiscard(&dtd->pool);
3776 case XML_ROLE_PARAM_ENTITY_NAME:
3778 if (dtd->keepProcessing) {
3779 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
3781 return XML_ERROR_NO_MEMORY;
3782 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3783 name, sizeof(ENTITY));
3785 return XML_ERROR_NO_MEMORY;
3786 if (declEntity->name != name) {
3787 poolDiscard(&dtd->pool);
3791 poolFinish(&dtd->pool);
3792 declEntity->publicId = NULL;
3793 declEntity->is_param = XML_TRUE;
3794 /* if we have a parent parser or are reading an internal parameter
3795 entity, then the entity declaration is not considered "internal"
3797 declEntity->is_internal = !(parentParser || openInternalEntities);
3798 if (entityDeclHandler)
3799 handleDefault = XML_FALSE;
3803 poolDiscard(&dtd->pool);
3806 #else /* not XML_DTD */
3808 #endif /* XML_DTD */
3810 case XML_ROLE_NOTATION_NAME:
3811 declNotationPublicId = NULL;
3812 declNotationName = NULL;
3813 if (notationDeclHandler) {
3814 declNotationName = poolStoreString(&tempPool, enc, s, next);
3815 if (!declNotationName)
3816 return XML_ERROR_NO_MEMORY;
3817 poolFinish(&tempPool);
3818 handleDefault = XML_FALSE;
3821 case XML_ROLE_NOTATION_PUBLIC_ID:
3822 if (!XmlIsPublicId(enc, s, next, eventPP))
3823 return XML_ERROR_SYNTAX;
3824 if (declNotationName) { /* means notationDeclHandler != NULL */
3825 XML_Char *tem = poolStoreString(&tempPool,
3827 s + enc->minBytesPerChar,
3828 next - enc->minBytesPerChar);
3830 return XML_ERROR_NO_MEMORY;
3831 normalizePublicId(tem);
3832 declNotationPublicId = tem;
3833 poolFinish(&tempPool);
3834 handleDefault = XML_FALSE;
3837 case XML_ROLE_NOTATION_SYSTEM_ID:
3838 if (declNotationName && notationDeclHandler) {
3839 const XML_Char *systemId
3840 = poolStoreString(&tempPool, enc,
3841 s + enc->minBytesPerChar,
3842 next - enc->minBytesPerChar);
3844 return XML_ERROR_NO_MEMORY;
3846 notationDeclHandler(handlerArg,
3850 declNotationPublicId);
3851 handleDefault = XML_FALSE;
3853 poolClear(&tempPool);
3855 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
3856 if (declNotationPublicId && notationDeclHandler) {
3858 notationDeclHandler(handlerArg,
3862 declNotationPublicId);
3863 handleDefault = XML_FALSE;
3865 poolClear(&tempPool);
3867 case XML_ROLE_ERROR:
3869 case XML_TOK_PARAM_ENTITY_REF:
3870 return XML_ERROR_PARAM_ENTITY_REF;
3871 case XML_TOK_XML_DECL:
3872 return XML_ERROR_MISPLACED_XML_PI;
3874 return XML_ERROR_SYNTAX;
3877 case XML_ROLE_IGNORE_SECT:
3879 enum XML_Error result;
3881 reportDefault(parser, enc, s, next);
3882 handleDefault = XML_FALSE;
3883 result = doIgnoreSection(parser, enc, &next, end, nextPtr);
3885 processor = ignoreSectionProcessor;
3890 #endif /* XML_DTD */
3891 case XML_ROLE_GROUP_OPEN:
3892 if (prologState.level >= groupSize) {
3894 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
3896 return XML_ERROR_NO_MEMORY;
3897 groupConnector = temp;
3898 if (dtd->scaffIndex) {
3899 int *temp = (int *)REALLOC(dtd->scaffIndex,
3900 groupSize * sizeof(int));
3902 return XML_ERROR_NO_MEMORY;
3903 dtd->scaffIndex = temp;
3907 groupConnector = (char *)MALLOC(groupSize = 32);
3908 if (!groupConnector)
3909 return XML_ERROR_NO_MEMORY;
3912 groupConnector[prologState.level] = 0;
3913 if (dtd->in_eldecl) {
3914 int myindex = nextScaffoldPart(parser);
3916 return XML_ERROR_NO_MEMORY;
3917 dtd->scaffIndex[dtd->scaffLevel] = myindex;
3919 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
3920 if (elementDeclHandler)
3921 handleDefault = XML_FALSE;
3924 case XML_ROLE_GROUP_SEQUENCE:
3925 if (groupConnector[prologState.level] == '|')
3926 return XML_ERROR_SYNTAX;
3927 groupConnector[prologState.level] = ',';
3928 if (dtd->in_eldecl && elementDeclHandler)
3929 handleDefault = XML_FALSE;
3931 case XML_ROLE_GROUP_CHOICE:
3932 if (groupConnector[prologState.level] == ',')
3933 return XML_ERROR_SYNTAX;
3935 && !groupConnector[prologState.level]
3936 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
3939 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
3941 if (elementDeclHandler)
3942 handleDefault = XML_FALSE;
3944 groupConnector[prologState.level] = '|';
3946 case XML_ROLE_PARAM_ENTITY_REF:
3948 case XML_ROLE_INNER_PARAM_ENTITY_REF:
3949 /* PE references in internal subset are
3950 not allowed within declarations */
3951 if (prologState.documentEntity &&
3952 role == XML_ROLE_INNER_PARAM_ENTITY_REF)
3953 return XML_ERROR_PARAM_ENTITY_REF;
3954 dtd->hasParamEntityRefs = XML_TRUE;
3955 if (!paramEntityParsing)
3956 dtd->keepProcessing = dtd->standalone;
3958 const XML_Char *name;
3960 name = poolStoreString(&dtd->pool, enc,
3961 s + enc->minBytesPerChar,
3962 next - enc->minBytesPerChar);
3964 return XML_ERROR_NO_MEMORY;
3965 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
3966 poolDiscard(&dtd->pool);
3967 /* first, determine if a check for an existing declaration is needed;
3968 if yes, check that the entity exists, and that it is internal,
3969 otherwise call the skipped entity handler
3971 if (prologState.documentEntity &&
3973 ? !openInternalEntities
3974 : !dtd->hasParamEntityRefs)) {
3976 return XML_ERROR_UNDEFINED_ENTITY;
3977 else if (!entity->is_internal)
3978 return XML_ERROR_ENTITY_DECLARED_IN_PE;
3981 dtd->keepProcessing = dtd->standalone;
3982 /* cannot report skipped entities in declarations */
3983 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
3984 skippedEntityHandler(handlerArg, name, 1);
3985 handleDefault = XML_FALSE;
3990 return XML_ERROR_RECURSIVE_ENTITY_REF;
3991 if (entity->textPtr) {
3992 enum XML_Error result;
3993 result = processInternalParamEntity(parser, entity);
3994 if (result != XML_ERROR_NONE)
3996 handleDefault = XML_FALSE;
3999 if (externalEntityRefHandler) {
4000 dtd->paramEntityRead = XML_FALSE;
4001 entity->open = XML_TRUE;
4002 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4006 entity->publicId)) {
4007 entity->open = XML_FALSE;
4008 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4010 entity->open = XML_FALSE;
4011 handleDefault = XML_FALSE;
4012 if (!dtd->paramEntityRead) {
4013 dtd->keepProcessing = dtd->standalone;
4018 dtd->keepProcessing = dtd->standalone;
4022 #endif /* XML_DTD */
4023 if (!dtd->standalone &&
4024 notStandaloneHandler &&
4025 !notStandaloneHandler(handlerArg))
4026 return XML_ERROR_NOT_STANDALONE;
4029 /* Element declaration stuff */
4031 case XML_ROLE_ELEMENT_NAME:
4032 if (elementDeclHandler) {
4033 declElementType = getElementType(parser, enc, s, next);
4034 if (!declElementType)
4035 return XML_ERROR_NO_MEMORY;
4036 dtd->scaffLevel = 0;
4037 dtd->scaffCount = 0;
4038 dtd->in_eldecl = XML_TRUE;
4039 handleDefault = XML_FALSE;
4043 case XML_ROLE_CONTENT_ANY:
4044 case XML_ROLE_CONTENT_EMPTY:
4045 if (dtd->in_eldecl) {
4046 if (elementDeclHandler) {
4047 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4049 return XML_ERROR_NO_MEMORY;
4050 content->quant = XML_CQUANT_NONE;
4051 content->name = NULL;
4052 content->numchildren = 0;
4053 content->children = NULL;
4054 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4058 elementDeclHandler(handlerArg, declElementType->name, content);
4059 handleDefault = XML_FALSE;
4061 dtd->in_eldecl = XML_FALSE;
4065 case XML_ROLE_CONTENT_PCDATA:
4066 if (dtd->in_eldecl) {
4067 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4069 if (elementDeclHandler)
4070 handleDefault = XML_FALSE;
4074 case XML_ROLE_CONTENT_ELEMENT:
4075 quant = XML_CQUANT_NONE;
4076 goto elementContent;
4077 case XML_ROLE_CONTENT_ELEMENT_OPT:
4078 quant = XML_CQUANT_OPT;
4079 goto elementContent;
4080 case XML_ROLE_CONTENT_ELEMENT_REP:
4081 quant = XML_CQUANT_REP;
4082 goto elementContent;
4083 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4084 quant = XML_CQUANT_PLUS;
4086 if (dtd->in_eldecl) {
4088 const XML_Char *name;
4090 const char *nxt = (quant == XML_CQUANT_NONE
4092 : next - enc->minBytesPerChar);
4093 int myindex = nextScaffoldPart(parser);
4095 return XML_ERROR_NO_MEMORY;
4096 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4097 dtd->scaffold[myindex].quant = quant;
4098 el = getElementType(parser, enc, s, nxt);
4100 return XML_ERROR_NO_MEMORY;
4102 dtd->scaffold[myindex].name = name;
4104 for (; name[nameLen++]; );
4105 dtd->contentStringLen += nameLen;
4106 if (elementDeclHandler)
4107 handleDefault = XML_FALSE;
4111 case XML_ROLE_GROUP_CLOSE:
4112 quant = XML_CQUANT_NONE;
4114 case XML_ROLE_GROUP_CLOSE_OPT:
4115 quant = XML_CQUANT_OPT;
4117 case XML_ROLE_GROUP_CLOSE_REP:
4118 quant = XML_CQUANT_REP;
4120 case XML_ROLE_GROUP_CLOSE_PLUS:
4121 quant = XML_CQUANT_PLUS;
4123 if (dtd->in_eldecl) {
4124 if (elementDeclHandler)
4125 handleDefault = XML_FALSE;
4127 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4128 if (dtd->scaffLevel == 0) {
4129 if (!handleDefault) {
4130 XML_Content *model = build_model(parser);
4132 return XML_ERROR_NO_MEMORY;
4134 elementDeclHandler(handlerArg, declElementType->name, model);
4136 dtd->in_eldecl = XML_FALSE;
4137 dtd->contentStringLen = 0;
4141 /* End element declaration stuff */
4144 if (!reportProcessingInstruction(parser, enc, s, next))
4145 return XML_ERROR_NO_MEMORY;
4146 handleDefault = XML_FALSE;
4148 case XML_ROLE_COMMENT:
4149 if (!reportComment(parser, enc, s, next))
4150 return XML_ERROR_NO_MEMORY;
4151 handleDefault = XML_FALSE;
4156 handleDefault = XML_FALSE;
4160 case XML_ROLE_DOCTYPE_NONE:
4161 if (startDoctypeDeclHandler)
4162 handleDefault = XML_FALSE;
4164 case XML_ROLE_ENTITY_NONE:
4165 if (dtd->keepProcessing && entityDeclHandler)
4166 handleDefault = XML_FALSE;
4168 case XML_ROLE_NOTATION_NONE:
4169 if (notationDeclHandler)
4170 handleDefault = XML_FALSE;
4172 case XML_ROLE_ATTLIST_NONE:
4173 if (dtd->keepProcessing && attlistDeclHandler)
4174 handleDefault = XML_FALSE;
4176 case XML_ROLE_ELEMENT_NONE:
4177 if (elementDeclHandler)
4178 handleDefault = XML_FALSE;
4180 } /* end of big switch */
4182 if (handleDefault && defaultHandler)
4183 reportDefault(parser, enc, s, next);
4186 tok = XmlPrologTok(enc, s, end, &next);
4191 static enum XML_Error PTRCALL
4192 epilogProcessor(XML_Parser parser,
4195 const char **nextPtr)
4197 processor = epilogProcessor;
4200 const char *next = NULL;
4201 int tok = XmlPrologTok(encoding, s, end, &next);
4204 /* report partial linebreak - it might be the last token */
4205 case -XML_TOK_PROLOG_S:
4206 if (defaultHandler) {
4208 reportDefault(parser, encoding, s, next);
4212 return XML_ERROR_NONE;
4216 return XML_ERROR_NONE;
4217 case XML_TOK_PROLOG_S:
4219 reportDefault(parser, encoding, s, next);
4222 if (!reportProcessingInstruction(parser, encoding, s, next))
4223 return XML_ERROR_NO_MEMORY;
4225 case XML_TOK_COMMENT:
4226 if (!reportComment(parser, encoding, s, next))
4227 return XML_ERROR_NO_MEMORY;
4229 case XML_TOK_INVALID:
4231 return XML_ERROR_INVALID_TOKEN;
4232 case XML_TOK_PARTIAL:
4235 return XML_ERROR_NONE;
4237 return XML_ERROR_UNCLOSED_TOKEN;
4238 case XML_TOK_PARTIAL_CHAR:
4241 return XML_ERROR_NONE;
4243 return XML_ERROR_PARTIAL_CHAR;
4245 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4247 eventPtr = s = next;
4253 static enum XML_Error
4254 processInternalParamEntity(XML_Parser parser, ENTITY *entity)
4256 const char *s, *end, *next;
4258 enum XML_Error result;
4259 OPEN_INTERNAL_ENTITY openEntity;
4260 entity->open = XML_TRUE;
4261 openEntity.next = openInternalEntities;
4262 openInternalEntities = &openEntity;
4263 openEntity.entity = entity;
4264 openEntity.internalEventPtr = NULL;
4265 openEntity.internalEventEndPtr = NULL;
4266 s = (char *)entity->textPtr;
4267 end = (char *)(entity->textPtr + entity->textLen);
4268 tok = XmlPrologTok(internalEncoding, s, end, &next);
4269 result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
4270 entity->open = XML_FALSE;
4271 openInternalEntities = openEntity.next;
4275 #endif /* XML_DTD */
4277 static enum XML_Error PTRCALL
4278 errorProcessor(XML_Parser parser,
4281 const char **nextPtr)
4286 static enum XML_Error
4287 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4288 const char *ptr, const char *end,
4291 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4295 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4297 if (!poolAppendChar(pool, XML_T('\0')))
4298 return XML_ERROR_NO_MEMORY;
4299 return XML_ERROR_NONE;
4302 static enum XML_Error
4303 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4304 const char *ptr, const char *end,
4307 DTD * const dtd = _dtd; /* save one level of indirection */
4310 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4313 return XML_ERROR_NONE;
4314 case XML_TOK_INVALID:
4315 if (enc == encoding)
4317 return XML_ERROR_INVALID_TOKEN;
4318 case XML_TOK_PARTIAL:
4319 if (enc == encoding)
4321 return XML_ERROR_INVALID_TOKEN;
4322 case XML_TOK_CHAR_REF:
4324 XML_Char buf[XML_ENCODE_MAX];
4326 int n = XmlCharRefNumber(enc, ptr);
4328 if (enc == encoding)
4330 return XML_ERROR_BAD_CHAR_REF;
4333 && n == 0x20 /* space */
4334 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4336 n = XmlEncode(n, (ICHAR *)buf);
4338 if (enc == encoding)
4340 return XML_ERROR_BAD_CHAR_REF;
4342 for (i = 0; i < n; i++) {
4343 if (!poolAppendChar(pool, buf[i]))
4344 return XML_ERROR_NO_MEMORY;
4348 case XML_TOK_DATA_CHARS:
4349 if (!poolAppend(pool, enc, ptr, next))
4350 return XML_ERROR_NO_MEMORY;
4352 case XML_TOK_TRAILING_CR:
4353 next = ptr + enc->minBytesPerChar;
4355 case XML_TOK_ATTRIBUTE_VALUE_S:
4356 case XML_TOK_DATA_NEWLINE:
4357 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4359 if (!poolAppendChar(pool, 0x20))
4360 return XML_ERROR_NO_MEMORY;
4362 case XML_TOK_ENTITY_REF:
4364 const XML_Char *name;
4366 char checkEntityDecl;
4367 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4368 ptr + enc->minBytesPerChar,
4369 next - enc->minBytesPerChar);
4371 if (!poolAppendChar(pool, ch))
4372 return XML_ERROR_NO_MEMORY;
4375 name = poolStoreString(&temp2Pool, enc,
4376 ptr + enc->minBytesPerChar,
4377 next - enc->minBytesPerChar);
4379 return XML_ERROR_NO_MEMORY;
4380 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
4381 poolDiscard(&temp2Pool);
4382 /* first, determine if a check for an existing declaration is needed;
4383 if yes, check that the entity exists, and that it is internal,
4384 otherwise call the default handler (if called from content)
4386 if (pool == &dtd->pool) /* are we called from prolog? */
4389 prologState.documentEntity &&
4390 #endif /* XML_DTD */
4392 ? !openInternalEntities
4393 : !dtd->hasParamEntityRefs);
4394 else /* if (pool == &tempPool): we are called from content */
4395 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4396 if (checkEntityDecl) {
4398 return XML_ERROR_UNDEFINED_ENTITY;
4399 else if (!entity->is_internal)
4400 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4403 /* cannot report skipped entity here - see comments on
4404 skippedEntityHandler
4405 if (skippedEntityHandler)
4406 skippedEntityHandler(handlerArg, name, 0);
4408 if ((pool == &tempPool) && defaultHandler)
4409 reportDefault(parser, enc, ptr, next);
4413 if (enc == encoding)
4415 return XML_ERROR_RECURSIVE_ENTITY_REF;
4417 if (entity->notation) {
4418 if (enc == encoding)
4420 return XML_ERROR_BINARY_ENTITY_REF;
4422 if (!entity->textPtr) {
4423 if (enc == encoding)
4425 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4428 enum XML_Error result;
4429 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4430 entity->open = XML_TRUE;
4431 result = appendAttributeValue(parser, internalEncoding, isCdata,
4432 (char *)entity->textPtr,
4433 (char *)textEnd, pool);
4434 entity->open = XML_FALSE;
4441 if (enc == encoding)
4443 return XML_ERROR_UNEXPECTED_STATE;
4450 static enum XML_Error
4451 storeEntityValue(XML_Parser parser,
4452 const ENCODING *enc,
4453 const char *entityTextPtr,
4454 const char *entityTextEnd)
4456 DTD * const dtd = _dtd; /* save one level of indirection */
4457 STRING_POOL *pool = &(dtd->entityValuePool);
4458 enum XML_Error result = XML_ERROR_NONE;
4460 int oldInEntityValue = prologState.inEntityValue;
4461 prologState.inEntityValue = 1;
4462 #endif /* XML_DTD */
4463 /* never return Null for the value argument in EntityDeclHandler,
4464 since this would indicate an external entity; therefore we
4465 have to make sure that entityValuePool.start is not null */
4466 if (!pool->blocks) {
4467 if (!poolGrow(pool))
4468 return XML_ERROR_NO_MEMORY;
4473 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4475 case XML_TOK_PARAM_ENTITY_REF:
4477 if (isParamEntity || enc != encoding) {
4478 const XML_Char *name;
4480 name = poolStoreString(&tempPool, enc,
4481 entityTextPtr + enc->minBytesPerChar,
4482 next - enc->minBytesPerChar);
4484 result = XML_ERROR_NO_MEMORY;
4485 goto endEntityValue;
4487 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4488 poolDiscard(&tempPool);
4490 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4491 /* cannot report skipped entity here - see comments on
4492 skippedEntityHandler
4493 if (skippedEntityHandler)
4494 skippedEntityHandler(handlerArg, name, 0);
4496 dtd->keepProcessing = dtd->standalone;
4497 goto endEntityValue;
4500 if (enc == encoding)
4501 eventPtr = entityTextPtr;
4502 result = XML_ERROR_RECURSIVE_ENTITY_REF;
4503 goto endEntityValue;
4505 if (entity->systemId) {
4506 if (externalEntityRefHandler) {
4507 dtd->paramEntityRead = XML_FALSE;
4508 entity->open = XML_TRUE;
4509 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4513 entity->publicId)) {
4514 entity->open = XML_FALSE;
4515 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4516 goto endEntityValue;
4518 entity->open = XML_FALSE;
4519 if (!dtd->paramEntityRead)
4520 dtd->keepProcessing = dtd->standalone;
4523 dtd->keepProcessing = dtd->standalone;
4526 entity->open = XML_TRUE;
4527 result = storeEntityValue(parser,
4529 (char *)entity->textPtr,
4530 (char *)(entity->textPtr
4531 + entity->textLen));
4532 entity->open = XML_FALSE;
4534 goto endEntityValue;
4538 #endif /* XML_DTD */
4539 /* in the internal subset, PE references are not legal
4540 within markup declarations, e.g entity values in this case */
4541 eventPtr = entityTextPtr;
4542 result = XML_ERROR_PARAM_ENTITY_REF;
4543 goto endEntityValue;
4545 result = XML_ERROR_NONE;
4546 goto endEntityValue;
4547 case XML_TOK_ENTITY_REF:
4548 case XML_TOK_DATA_CHARS:
4549 if (!poolAppend(pool, enc, entityTextPtr, next)) {
4550 result = XML_ERROR_NO_MEMORY;
4551 goto endEntityValue;
4554 case XML_TOK_TRAILING_CR:
4555 next = entityTextPtr + enc->minBytesPerChar;
4557 case XML_TOK_DATA_NEWLINE:
4558 if (pool->end == pool->ptr && !poolGrow(pool)) {
4559 result = XML_ERROR_NO_MEMORY;
4560 goto endEntityValue;
4562 *(pool->ptr)++ = 0xA;
4564 case XML_TOK_CHAR_REF:
4566 XML_Char buf[XML_ENCODE_MAX];
4568 int n = XmlCharRefNumber(enc, entityTextPtr);
4570 if (enc == encoding)
4571 eventPtr = entityTextPtr;
4572 result = XML_ERROR_BAD_CHAR_REF;
4573 goto endEntityValue;
4575 n = XmlEncode(n, (ICHAR *)buf);
4577 if (enc == encoding)
4578 eventPtr = entityTextPtr;
4579 result = XML_ERROR_BAD_CHAR_REF;
4580 goto endEntityValue;
4582 for (i = 0; i < n; i++) {
4583 if (pool->end == pool->ptr && !poolGrow(pool)) {
4584 result = XML_ERROR_NO_MEMORY;
4585 goto endEntityValue;
4587 *(pool->ptr)++ = buf[i];
4591 case XML_TOK_PARTIAL:
4592 if (enc == encoding)
4593 eventPtr = entityTextPtr;
4594 result = XML_ERROR_INVALID_TOKEN;
4595 goto endEntityValue;
4596 case XML_TOK_INVALID:
4597 if (enc == encoding)
4599 result = XML_ERROR_INVALID_TOKEN;
4600 goto endEntityValue;
4602 if (enc == encoding)
4603 eventPtr = entityTextPtr;
4604 result = XML_ERROR_UNEXPECTED_STATE;
4605 goto endEntityValue;
4607 entityTextPtr = next;
4611 prologState.inEntityValue = oldInEntityValue;
4612 #endif /* XML_DTD */
4616 static void FASTCALL
4617 normalizeLines(XML_Char *s)
4621 if (*s == XML_T('\0'))
4640 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
4641 const char *start, const char *end)
4643 const XML_Char *target;
4646 if (!processingInstructionHandler) {
4648 reportDefault(parser, enc, start, end);
4651 start += enc->minBytesPerChar * 2;
4652 tem = start + XmlNameLength(enc, start);
4653 target = poolStoreString(&tempPool, enc, start, tem);
4656 poolFinish(&tempPool);
4657 data = poolStoreString(&tempPool, enc,
4659 end - enc->minBytesPerChar*2);
4662 normalizeLines(data);
4663 processingInstructionHandler(handlerArg, target, data);
4664 poolClear(&tempPool);
4669 reportComment(XML_Parser parser, const ENCODING *enc,
4670 const char *start, const char *end)
4673 if (!commentHandler) {
4675 reportDefault(parser, enc, start, end);
4678 data = poolStoreString(&tempPool,
4680 start + enc->minBytesPerChar * 4,
4681 end - enc->minBytesPerChar * 3);
4684 normalizeLines(data);
4685 commentHandler(handlerArg, data);
4686 poolClear(&tempPool);
4691 reportDefault(XML_Parser parser, const ENCODING *enc,
4692 const char *s, const char *end)
4694 if (MUST_CONVERT(enc, s)) {
4695 const char **eventPP;
4696 const char **eventEndPP;
4697 if (enc == encoding) {
4698 eventPP = &eventPtr;
4699 eventEndPP = &eventEndPtr;
4702 eventPP = &(openInternalEntities->internalEventPtr);
4703 eventEndPP = &(openInternalEntities->internalEventEndPtr);
4706 ICHAR *dataPtr = (ICHAR *)dataBuf;
4707 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
4709 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
4714 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
4719 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
4720 XML_Bool isId, const XML_Char *value, XML_Parser parser)
4722 DEFAULT_ATTRIBUTE *att;
4723 if (value || isId) {
4724 /* The handling of default attributes gets messed up if we have
4725 a default which duplicates a non-default. */
4727 for (i = 0; i < type->nDefaultAtts; i++)
4728 if (attId == type->defaultAtts[i].id)
4730 if (isId && !type->idAtt && !attId->xmlns)
4731 type->idAtt = attId;
4733 if (type->nDefaultAtts == type->allocDefaultAtts) {
4734 if (type->allocDefaultAtts == 0) {
4735 type->allocDefaultAtts = 8;
4736 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
4737 * sizeof(DEFAULT_ATTRIBUTE));
4738 if (!type->defaultAtts)
4742 DEFAULT_ATTRIBUTE *temp;
4743 int count = type->allocDefaultAtts * 2;
4744 temp = (DEFAULT_ATTRIBUTE *)
4745 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
4748 type->allocDefaultAtts = count;
4749 type->defaultAtts = temp;
4752 att = type->defaultAtts + type->nDefaultAtts;
4755 att->isCdata = isCdata;
4757 attId->maybeTokenized = XML_TRUE;
4758 type->nDefaultAtts += 1;
4763 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
4765 DTD * const dtd = _dtd; /* save one level of indirection */
4766 const XML_Char *name;
4767 for (name = elementType->name; *name; name++) {
4768 if (*name == XML_T(':')) {
4771 for (s = elementType->name; s != name; s++) {
4772 if (!poolAppendChar(&dtd->pool, *s))
4775 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4777 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4781 if (prefix->name == poolStart(&dtd->pool))
4782 poolFinish(&dtd->pool);
4784 poolDiscard(&dtd->pool);
4785 elementType->prefix = prefix;
4792 static ATTRIBUTE_ID *
4793 getAttributeId(XML_Parser parser, const ENCODING *enc,
4794 const char *start, const char *end)
4796 DTD * const dtd = _dtd; /* save one level of indirection */
4798 const XML_Char *name;
4799 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4801 name = poolStoreString(&dtd->pool, enc, start, end);
4804 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
4806 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
4809 if (id->name != name)
4810 poolDiscard(&dtd->pool);
4812 poolFinish(&dtd->pool);
4815 else if (name[0] == XML_T('x')
4816 && name[1] == XML_T('m')
4817 && name[2] == XML_T('l')
4818 && name[3] == XML_T('n')
4819 && name[4] == XML_T('s')
4820 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
4821 if (name[5] == XML_T('\0'))
4822 id->prefix = &dtd->defaultPrefix;
4824 id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
4825 id->xmlns = XML_TRUE;
4829 for (i = 0; name[i]; i++) {
4830 /* attributes without prefix are *not* in the default namespace */
4831 if (name[i] == XML_T(':')) {
4833 for (j = 0; j < i; j++) {
4834 if (!poolAppendChar(&dtd->pool, name[j]))
4837 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4839 id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4841 if (id->prefix->name == poolStart(&dtd->pool))
4842 poolFinish(&dtd->pool);
4844 poolDiscard(&dtd->pool);
4853 #define CONTEXT_SEP XML_T('\f')
4855 static const XML_Char *
4856 getContext(XML_Parser parser)
4858 DTD * const dtd = _dtd; /* save one level of indirection */
4859 HASH_TABLE_ITER iter;
4860 XML_Bool needSep = XML_FALSE;
4862 if (dtd->defaultPrefix.binding) {
4865 if (!poolAppendChar(&tempPool, XML_T('=')))
4867 len = dtd->defaultPrefix.binding->uriLen;
4868 if (namespaceSeparator != XML_T('\0'))
4870 for (i = 0; i < len; i++)
4871 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
4876 hashTableIterInit(&iter, &(dtd->prefixes));
4881 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
4884 if (!prefix->binding)
4886 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
4888 for (s = prefix->name; *s; s++)
4889 if (!poolAppendChar(&tempPool, *s))
4891 if (!poolAppendChar(&tempPool, XML_T('=')))
4893 len = prefix->binding->uriLen;
4894 if (namespaceSeparator != XML_T('\0'))
4896 for (i = 0; i < len; i++)
4897 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
4903 hashTableIterInit(&iter, &(dtd->generalEntities));
4906 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
4911 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
4913 for (s = e->name; *s; s++)
4914 if (!poolAppendChar(&tempPool, *s))
4919 if (!poolAppendChar(&tempPool, XML_T('\0')))
4921 return tempPool.start;
4925 setContext(XML_Parser parser, const XML_Char *context)
4927 DTD * const dtd = _dtd; /* save one level of indirection */
4928 const XML_Char *s = context;
4930 while (*context != XML_T('\0')) {
4931 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
4933 if (!poolAppendChar(&tempPool, XML_T('\0')))
4935 e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
4938 if (*s != XML_T('\0'))
4941 poolDiscard(&tempPool);
4943 else if (*s == XML_T('=')) {
4945 if (poolLength(&tempPool) == 0)
4946 prefix = &dtd->defaultPrefix;
4948 if (!poolAppendChar(&tempPool, XML_T('\0')))
4950 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
4954 if (prefix->name == poolStart(&tempPool)) {
4955 prefix->name = poolCopyString(&dtd->pool, prefix->name);
4959 poolDiscard(&tempPool);
4961 for (context = s + 1;
4962 *context != CONTEXT_SEP && *context != XML_T('\0');
4964 if (!poolAppendChar(&tempPool, *context))
4966 if (!poolAppendChar(&tempPool, XML_T('\0')))
4968 if (addBinding(parser, prefix, 0, poolStart(&tempPool),
4969 &inheritedBindings) != XML_ERROR_NONE)
4971 poolDiscard(&tempPool);
4972 if (*context != XML_T('\0'))
4977 if (!poolAppendChar(&tempPool, *s))
4985 static void FASTCALL
4986 normalizePublicId(XML_Char *publicId)
4988 XML_Char *p = publicId;
4990 for (s = publicId; *s; s++) {
4995 if (p != publicId && p[-1] != 0x20)
5002 if (p != publicId && p[-1] == 0x20)
5008 dtdCreate(const XML_Memory_Handling_Suite *ms)
5010 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5013 poolInit(&(p->pool), ms);
5015 poolInit(&(p->entityValuePool), ms);
5016 #endif /* XML_DTD */
5017 hashTableInit(&(p->generalEntities), ms);
5018 hashTableInit(&(p->elementTypes), ms);
5019 hashTableInit(&(p->attributeIds), ms);
5020 hashTableInit(&(p->prefixes), ms);
5022 p->paramEntityRead = XML_FALSE;
5023 hashTableInit(&(p->paramEntities), ms);
5024 #endif /* XML_DTD */
5025 p->defaultPrefix.name = NULL;
5026 p->defaultPrefix.binding = NULL;
5028 p->in_eldecl = XML_FALSE;
5029 p->scaffIndex = NULL;
5034 p->contentStringLen = 0;
5036 p->keepProcessing = XML_TRUE;
5037 p->hasParamEntityRefs = XML_FALSE;
5038 p->standalone = XML_FALSE;
5043 dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
5045 HASH_TABLE_ITER iter;
5046 hashTableIterInit(&iter, &(p->elementTypes));
5048 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5051 if (e->allocDefaultAtts != 0)
5052 ms->free_fcn(e->defaultAtts);
5054 hashTableClear(&(p->generalEntities));
5056 p->paramEntityRead = XML_FALSE;
5057 hashTableClear(&(p->paramEntities));
5058 #endif /* XML_DTD */
5059 hashTableClear(&(p->elementTypes));
5060 hashTableClear(&(p->attributeIds));
5061 hashTableClear(&(p->prefixes));
5062 poolClear(&(p->pool));
5064 poolClear(&(p->entityValuePool));
5065 #endif /* XML_DTD */
5066 p->defaultPrefix.name = NULL;
5067 p->defaultPrefix.binding = NULL;
5069 p->in_eldecl = XML_FALSE;
5071 ms->free_fcn(p->scaffIndex);
5072 p->scaffIndex = NULL;
5073 ms->free_fcn(p->scaffold);
5079 p->contentStringLen = 0;
5081 p->keepProcessing = XML_TRUE;
5082 p->hasParamEntityRefs = XML_FALSE;
5083 p->standalone = XML_FALSE;
5087 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5089 HASH_TABLE_ITER iter;
5090 hashTableIterInit(&iter, &(p->elementTypes));
5092 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5095 if (e->allocDefaultAtts != 0)
5096 ms->free_fcn(e->defaultAtts);
5098 hashTableDestroy(&(p->generalEntities));
5100 hashTableDestroy(&(p->paramEntities));
5101 #endif /* XML_DTD */
5102 hashTableDestroy(&(p->elementTypes));
5103 hashTableDestroy(&(p->attributeIds));
5104 hashTableDestroy(&(p->prefixes));
5105 poolDestroy(&(p->pool));
5107 poolDestroy(&(p->entityValuePool));
5108 #endif /* XML_DTD */
5110 ms->free_fcn(p->scaffIndex);
5111 ms->free_fcn(p->scaffold);
5116 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5117 The new DTD has already been initialized.
5120 dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
5122 HASH_TABLE_ITER iter;
5124 /* Copy the prefix table. */
5126 hashTableIterInit(&iter, &(oldDtd->prefixes));
5128 const XML_Char *name;
5129 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5132 name = poolCopyString(&(newDtd->pool), oldP->name);
5135 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5139 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5141 /* Copy the attribute id table. */
5145 const XML_Char *name;
5146 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5150 /* Remember to allocate the scratch byte before the name. */
5151 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5153 name = poolCopyString(&(newDtd->pool), oldA->name);
5157 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5158 sizeof(ATTRIBUTE_ID));
5161 newA->maybeTokenized = oldA->maybeTokenized;
5163 newA->xmlns = oldA->xmlns;
5164 if (oldA->prefix == &oldDtd->defaultPrefix)
5165 newA->prefix = &newDtd->defaultPrefix;
5167 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5168 oldA->prefix->name, 0);
5172 /* Copy the element type table. */
5174 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5179 const XML_Char *name;
5180 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5183 name = poolCopyString(&(newDtd->pool), oldE->name);
5186 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5187 sizeof(ELEMENT_TYPE));
5190 if (oldE->nDefaultAtts) {
5191 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5192 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5193 if (!newE->defaultAtts) {
5199 newE->idAtt = (ATTRIBUTE_ID *)
5200 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
5201 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5203 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5204 oldE->prefix->name, 0);
5205 for (i = 0; i < newE->nDefaultAtts; i++) {
5206 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5207 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5208 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5209 if (oldE->defaultAtts[i].value) {
5210 newE->defaultAtts[i].value
5211 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5212 if (!newE->defaultAtts[i].value)
5216 newE->defaultAtts[i].value = NULL;
5220 /* Copy the entity tables. */
5221 if (!copyEntityTable(&(newDtd->generalEntities),
5223 &(oldDtd->generalEntities)))
5227 if (!copyEntityTable(&(newDtd->paramEntities),
5229 &(oldDtd->paramEntities)))
5231 newDtd->paramEntityRead = oldDtd->paramEntityRead;
5232 #endif /* XML_DTD */
5234 newDtd->keepProcessing = oldDtd->keepProcessing;
5235 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
5236 newDtd->standalone = oldDtd->standalone;
5238 /* Don't want deep copying for scaffolding */
5239 newDtd->in_eldecl = oldDtd->in_eldecl;
5240 newDtd->scaffold = oldDtd->scaffold;
5241 newDtd->contentStringLen = oldDtd->contentStringLen;
5242 newDtd->scaffSize = oldDtd->scaffSize;
5243 newDtd->scaffLevel = oldDtd->scaffLevel;
5244 newDtd->scaffIndex = oldDtd->scaffIndex;
5250 copyEntityTable(HASH_TABLE *newTable,
5251 STRING_POOL *newPool,
5252 const HASH_TABLE *oldTable)
5254 HASH_TABLE_ITER iter;
5255 const XML_Char *cachedOldBase = NULL;
5256 const XML_Char *cachedNewBase = NULL;
5258 hashTableIterInit(&iter, oldTable);
5262 const XML_Char *name;
5263 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5266 name = poolCopyString(newPool, oldE->name);
5269 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5272 if (oldE->systemId) {
5273 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5276 newE->systemId = tem;
5278 if (oldE->base == cachedOldBase)
5279 newE->base = cachedNewBase;
5281 cachedOldBase = oldE->base;
5282 tem = poolCopyString(newPool, cachedOldBase);
5285 cachedNewBase = newE->base = tem;
5288 if (oldE->publicId) {
5289 tem = poolCopyString(newPool, oldE->publicId);
5292 newE->publicId = tem;
5296 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5300 newE->textPtr = tem;
5301 newE->textLen = oldE->textLen;
5303 if (oldE->notation) {
5304 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5307 newE->notation = tem;
5309 newE->is_param = oldE->is_param;
5310 newE->is_internal = oldE->is_internal;
5315 #define INIT_SIZE 64
5317 static XML_Bool FASTCALL
5318 keyeq(KEY s1, KEY s2)
5320 for (; *s1 == *s2; s1++, s2++)
5326 static unsigned long FASTCALL
5329 unsigned long h = 0;
5331 h = (h << 5) + h + (unsigned char)*s++;
5336 lookup(HASH_TABLE *table, KEY name, size_t createSize)
5339 if (table->size == 0) {
5344 tsize = INIT_SIZE * sizeof(NAMED *);
5345 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
5348 memset(table->v, 0, tsize);
5349 table->size = INIT_SIZE;
5350 table->usedLim = INIT_SIZE / 2;
5351 i = hash(name) & (table->size - 1);
5354 unsigned long h = hash(name);
5355 for (i = h & (table->size - 1);
5357 i == 0 ? i = table->size - 1 : --i) {
5358 if (keyeq(name, table->v[i]->name))
5363 if (table->used == table->usedLim) {
5364 /* check for overflow */
5365 size_t newSize = table->size * 2;
5366 size_t tsize = newSize * sizeof(NAMED *);
5367 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
5370 memset(newV, 0, tsize);
5371 for (i = 0; i < table->size; i++)
5374 for (j = hash(table->v[i]->name) & (newSize - 1);
5376 j == 0 ? j = newSize - 1 : --j)
5378 newV[j] = table->v[i];
5380 table->mem->free_fcn(table->v);
5382 table->size = newSize;
5383 table->usedLim = newSize/2;
5384 for (i = h & (table->size - 1);
5386 i == 0 ? i = table->size - 1 : --i)
5390 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
5393 memset(table->v[i], 0, createSize);
5394 table->v[i]->name = name;
5399 static void FASTCALL
5400 hashTableClear(HASH_TABLE *table)
5403 for (i = 0; i < table->size; i++) {
5404 table->mem->free_fcn(table->v[i]);
5407 table->usedLim = table->size / 2;
5411 static void FASTCALL
5412 hashTableDestroy(HASH_TABLE *table)
5415 for (i = 0; i < table->size; i++)
5416 table->mem->free_fcn(table->v[i]);
5417 table->mem->free_fcn(table->v);
5420 static void FASTCALL
5421 hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
5430 static void FASTCALL
5431 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
5434 iter->end = iter->p + table->size;
5437 static NAMED * FASTCALL
5438 hashTableIterNext(HASH_TABLE_ITER *iter)
5440 while (iter->p != iter->end) {
5441 NAMED *tem = *(iter->p)++;
5448 static void FASTCALL
5449 poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
5451 pool->blocks = NULL;
5452 pool->freeBlocks = NULL;
5459 static void FASTCALL
5460 poolClear(STRING_POOL *pool)
5462 if (!pool->freeBlocks)
5463 pool->freeBlocks = pool->blocks;
5465 BLOCK *p = pool->blocks;
5467 BLOCK *tem = p->next;
5468 p->next = pool->freeBlocks;
5469 pool->freeBlocks = p;
5473 pool->blocks = NULL;
5479 static void FASTCALL
5480 poolDestroy(STRING_POOL *pool)
5482 BLOCK *p = pool->blocks;
5484 BLOCK *tem = p->next;
5485 pool->mem->free_fcn(p);
5488 p = pool->freeBlocks;
5490 BLOCK *tem = p->next;
5491 pool->mem->free_fcn(p);
5497 poolAppend(STRING_POOL *pool, const ENCODING *enc,
5498 const char *ptr, const char *end)
5500 if (!pool->ptr && !poolGrow(pool))
5503 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
5506 if (!poolGrow(pool))
5512 static const XML_Char * FASTCALL
5513 poolCopyString(STRING_POOL *pool, const XML_Char *s)
5516 if (!poolAppendChar(pool, *s))
5524 static const XML_Char *
5525 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
5527 if (!pool->ptr && !poolGrow(pool))
5529 for (; n > 0; --n, s++) {
5530 if (!poolAppendChar(pool, *s))
5538 static const XML_Char * FASTCALL
5539 poolAppendString(STRING_POOL *pool, const XML_Char *s)
5542 if (!poolAppendChar(pool, *s))
5550 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
5551 const char *ptr, const char *end)
5553 if (!poolAppend(pool, enc, ptr, end))
5555 if (pool->ptr == pool->end && !poolGrow(pool))
5561 static XML_Bool FASTCALL
5562 poolGrow(STRING_POOL *pool)
5564 if (pool->freeBlocks) {
5565 if (pool->start == 0) {
5566 pool->blocks = pool->freeBlocks;
5567 pool->freeBlocks = pool->freeBlocks->next;
5568 pool->blocks->next = NULL;
5569 pool->start = pool->blocks->s;
5570 pool->end = pool->start + pool->blocks->size;
5571 pool->ptr = pool->start;
5574 if (pool->end - pool->start < pool->freeBlocks->size) {
5575 BLOCK *tem = pool->freeBlocks->next;
5576 pool->freeBlocks->next = pool->blocks;
5577 pool->blocks = pool->freeBlocks;
5578 pool->freeBlocks = tem;
5579 memcpy(pool->blocks->s, pool->start,
5580 (pool->end - pool->start) * sizeof(XML_Char));
5581 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5582 pool->start = pool->blocks->s;
5583 pool->end = pool->start + pool->blocks->size;
5587 if (pool->blocks && pool->start == pool->blocks->s) {
5588 int blockSize = (pool->end - pool->start)*2;
5589 pool->blocks = (BLOCK *)
5590 pool->mem->realloc_fcn(pool->blocks,
5592 + blockSize * sizeof(XML_Char)));
5593 if (pool->blocks == NULL)
5595 pool->blocks->size = blockSize;
5596 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5597 pool->start = pool->blocks->s;
5598 pool->end = pool->start + blockSize;
5602 int blockSize = pool->end - pool->start;
5603 if (blockSize < INIT_BLOCK_SIZE)
5604 blockSize = INIT_BLOCK_SIZE;
5607 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
5608 + blockSize * sizeof(XML_Char));
5611 tem->size = blockSize;
5612 tem->next = pool->blocks;
5614 if (pool->ptr != pool->start)
5615 memcpy(tem->s, pool->start,
5616 (pool->ptr - pool->start) * sizeof(XML_Char));
5617 pool->ptr = tem->s + (pool->ptr - pool->start);
5618 pool->start = tem->s;
5619 pool->end = tem->s + blockSize;
5625 nextScaffoldPart(XML_Parser parser)
5627 DTD * const dtd = _dtd; /* save one level of indirection */
5628 CONTENT_SCAFFOLD * me;
5631 if (!dtd->scaffIndex) {
5632 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
5633 if (!dtd->scaffIndex)
5635 dtd->scaffIndex[0] = 0;
5638 if (dtd->scaffCount >= dtd->scaffSize) {
5639 CONTENT_SCAFFOLD *temp;
5640 if (dtd->scaffold) {
5641 temp = (CONTENT_SCAFFOLD *)
5642 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
5645 dtd->scaffSize *= 2;
5648 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
5649 * sizeof(CONTENT_SCAFFOLD));
5652 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
5654 dtd->scaffold = temp;
5656 next = dtd->scaffCount++;
5657 me = &dtd->scaffold[next];
5658 if (dtd->scaffLevel) {
5659 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
5660 if (parent->lastchild) {
5661 dtd->scaffold[parent->lastchild].nextsib = next;
5663 if (!parent->childcnt)
5664 parent->firstchild = next;
5665 parent->lastchild = next;
5668 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
5673 build_node(XML_Parser parser,
5676 XML_Content **contpos,
5679 DTD * const dtd = _dtd; /* save one level of indirection */
5680 dest->type = dtd->scaffold[src_node].type;
5681 dest->quant = dtd->scaffold[src_node].quant;
5682 if (dest->type == XML_CTYPE_NAME) {
5683 const XML_Char *src;
5684 dest->name = *strpos;
5685 src = dtd->scaffold[src_node].name;
5687 *(*strpos)++ = *src;
5692 dest->numchildren = 0;
5693 dest->children = NULL;
5698 dest->numchildren = dtd->scaffold[src_node].childcnt;
5699 dest->children = *contpos;
5700 *contpos += dest->numchildren;
5701 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
5702 i < dest->numchildren;
5703 i++, cn = dtd->scaffold[cn].nextsib) {
5704 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
5710 static XML_Content *
5711 build_model (XML_Parser parser)
5713 DTD * const dtd = _dtd; /* save one level of indirection */
5717 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
5718 + (dtd->contentStringLen * sizeof(XML_Char)));
5720 ret = (XML_Content *)MALLOC(allocsize);
5724 str = (XML_Char *) (&ret[dtd->scaffCount]);
5727 build_node(parser, 0, ret, &cpos, &str);
5731 static ELEMENT_TYPE *
5732 getElementType(XML_Parser parser,
5733 const ENCODING *enc,
5737 DTD * const dtd = _dtd; /* save one level of indirection */
5738 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
5743 ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
5746 if (ret->name != name)
5747 poolDiscard(&dtd->pool);
5749 poolFinish(&dtd->pool);
5750 if (!setElementTypePrefix(parser, ret))