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"
12 #define XMLPARSEAPI(type) type __cdecl
14 #define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
19 #elif defined(MACOS_CLASSIC)
21 #include "macconfig.h"
26 #include <expat_config.h>
29 #define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
37 #endif /* ndef COMPILED_FROM_DSP */
40 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
41 #define XmlConvert XmlUtf16Convert
42 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
43 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
44 #define XmlEncode XmlUtf16Encode
45 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
46 typedef unsigned short ICHAR;
48 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
49 #define XmlConvert XmlUtf8Convert
50 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
51 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
52 #define XmlEncode XmlUtf8Encode
53 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
60 #define XmlInitEncodingNS XmlInitEncoding
61 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
62 #undef XmlGetInternalEncodingNS
63 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
64 #define XmlParseXmlDeclNS XmlParseXmlDecl
70 #ifdef XML_UNICODE_WCHAR_T
71 #define XML_T(x) (const wchar_t)x
72 #define XML_L(x) L ## x
74 #define XML_T(x) (const unsigned short)x
85 /* Round up n to be a multiple of sz, where sz is a power of 2. */
86 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
88 /* Handle the case where memmove() doesn't exist. */
91 #define memmove(d,s,l) bcopy((s),(d),(l))
93 #error memmove does not exist on this platform, nor is a substitute available
94 #endif /* HAVE_BCOPY */
95 #endif /* HAVE_MEMMOVE */
101 typedef const XML_Char *KEY;
112 XML_Memory_Handling_Suite *mem;
120 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
121 #define INIT_DATA_BUF_SIZE 1024
122 #define INIT_ATTS_SIZE 16
123 #define INIT_BLOCK_SIZE 1024
124 #define INIT_BUFFER_SIZE 1024
126 #define EXPAND_SPARE 24
128 typedef struct binding {
129 struct prefix *prefix;
130 struct binding *nextTagBinding;
131 struct binding *prevPrefixBinding;
132 const struct attribute_id *attId;
138 typedef struct prefix {
139 const XML_Char *name;
145 const XML_Char *localPart;
146 const XML_Char *prefix;
152 /* TAG represents an open element.
153 The name of the element is stored in both the document and API
154 encodings. The memory buffer 'buf' is a separately-allocated
155 memory area which stores the name. During the XML_Parse()/
156 XMLParseBuffer() when the element is open, the memory for the 'raw'
157 version of the name (in the document encoding) is shared with the
158 document buffer. If the element is open across calls to
159 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
160 contain the 'raw' name as well.
162 A parser re-uses these structures, maintaining a list of allocated
163 TAG objects in a free list.
166 struct tag *parent; /* parent of this element */
167 const char *rawName; /* tagName in the original encoding */
169 TAG_NAME name; /* tagName in the API encoding */
170 char *buf; /* buffer for name components */
171 char *bufEnd; /* end of the buffer */
176 const XML_Char *name;
177 const XML_Char *textPtr;
179 const XML_Char *systemId;
180 const XML_Char *base;
181 const XML_Char *publicId;
182 const XML_Char *notation;
185 XML_Bool is_internal; /* true if declared in internal subset outside PE */
189 enum XML_Content_Type type;
190 enum XML_Content_Quant quant;
191 const XML_Char * name;
198 #define INIT_SCAFFOLD_ELEMENTS 32
200 typedef struct block {
212 XML_Memory_Handling_Suite *mem;
215 /* The XML_Char before the name is used to determine whether
216 an attribute has been specified. */
217 typedef struct attribute_id {
220 XML_Bool maybeTokenized;
225 const ATTRIBUTE_ID *id;
227 const XML_Char *value;
231 const XML_Char *name;
233 const ATTRIBUTE_ID *idAtt;
235 int allocDefaultAtts;
236 DEFAULT_ATTRIBUTE *defaultAtts;
240 HASH_TABLE generalEntities;
241 HASH_TABLE elementTypes;
242 HASH_TABLE attributeIds;
245 STRING_POOL entityValuePool;
246 /* false once a parameter entity reference has been skipped */
247 XML_Bool keepProcessing;
248 /* true once an internal or external PE reference has been encountered;
249 any external subset is considered an external PE reference */
250 XML_Bool hasParamEntityRefs;
253 /* indicates if external PE has been read */
254 XML_Bool paramEntityRead;
255 HASH_TABLE paramEntities;
257 PREFIX defaultPrefix;
258 /* === scaffolding for building content model === */
260 CONTENT_SCAFFOLD *scaffold;
261 unsigned contentStringLen;
268 typedef struct open_internal_entity {
269 const char *internalEventPtr;
270 const char *internalEventEndPtr;
271 struct open_internal_entity *next;
273 } OPEN_INTERNAL_ENTITY;
275 typedef enum XML_Error FASTCALL Processor(XML_Parser parser,
278 const char **endPtr);
280 static Processor prologProcessor;
281 static Processor prologInitProcessor;
282 static Processor contentProcessor;
283 static Processor cdataSectionProcessor;
285 static Processor ignoreSectionProcessor;
286 static Processor externalParEntProcessor;
287 static Processor externalParEntInitProcessor;
288 static Processor entityValueProcessor;
289 static Processor entityValueInitProcessor;
291 static Processor epilogProcessor;
292 static Processor errorProcessor;
293 static Processor externalEntityInitProcessor;
294 static Processor externalEntityInitProcessor2;
295 static Processor externalEntityInitProcessor3;
296 static Processor externalEntityContentProcessor;
298 static enum XML_Error FASTCALL
299 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
300 static enum XML_Error FASTCALL
301 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
302 const char *, const char *);
303 static enum XML_Error FASTCALL
304 initializeEncoding(XML_Parser parser);
305 static enum XML_Error FASTCALL
306 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
307 const char *end, int tok, const char *next, const char **nextPtr);
308 static enum XML_Error FASTCALL
309 processInternalParamEntity(XML_Parser parser, ENTITY *entity);
310 static enum XML_Error FASTCALL
311 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
312 const char *start, const char *end, const char **endPtr);
313 static enum XML_Error FASTCALL
314 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
315 const char *end, const char **nextPtr);
317 static enum XML_Error FASTCALL
318 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
319 const char *end, const char **nextPtr);
321 static enum XML_Error FASTCALL
322 storeAtts(XML_Parser parser, const ENCODING *,
323 const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
325 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
326 const XML_Char *uri, BINDING **bindingsPtr);
329 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
330 XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue,
333 static enum XML_Error FASTCALL
334 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
335 const char *, const char *, STRING_POOL *);
336 static enum XML_Error FASTCALL
337 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
338 const char *, const char *, STRING_POOL *);
339 static ATTRIBUTE_ID * FASTCALL
340 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
343 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
344 static enum XML_Error FASTCALL
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 * FASTCALL getContext(XML_Parser parser);
358 static XML_Bool FASTCALL
359 setContext(XML_Parser parser, const XML_Char *context);
360 static void FASTCALL normalizePublicId(XML_Char *s);
361 static void FASTCALL dtdInit(DTD *, XML_Parser parser);
363 /* do not call if parentParser != NULL */
364 static void FASTCALL dtdReset(DTD *, XML_Parser parser);
365 static void FASTCALL dtdDestroy(DTD *, XML_Parser parser);
367 static int FASTCALL dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
369 static int FASTCALL copyEntityTable(HASH_TABLE *, STRING_POOL *,
370 const HASH_TABLE *, XML_Parser parser);
373 static void FASTCALL dtdSwap(DTD *, DTD *);
376 static NAMED * FASTCALL
377 lookup(HASH_TABLE *table, KEY name, size_t createSize);
380 hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
382 static void FASTCALL hashTableClear(HASH_TABLE *);
383 static void FASTCALL hashTableDestroy(HASH_TABLE *);
384 static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
385 static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
386 static void FASTCALL poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
387 static void FASTCALL poolClear(STRING_POOL *);
388 static void FASTCALL poolDestroy(STRING_POOL *);
389 static XML_Char * FASTCALL
390 poolAppend(STRING_POOL *pool, const ENCODING *enc,
391 const char *ptr, const char *end);
392 static XML_Char * FASTCALL
393 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
394 const char *ptr, const char *end);
396 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
398 static int FASTCALL nextScaffoldPart(XML_Parser parser);
399 static XML_Content * FASTCALL build_model(XML_Parser parser);
401 static const XML_Char * FASTCALL
402 poolCopyString(STRING_POOL *pool, const XML_Char *s);
403 static const XML_Char * FASTCALL
404 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
405 static const XML_Char * FASTCALL
406 poolAppendString(STRING_POOL *pool, const XML_Char *s);
407 static ELEMENT_TYPE * FASTCALL
408 getElementType(XML_Parser Paraser, const ENCODING *enc,
409 const char *ptr, const char *end);
412 parserInit(XML_Parser parser, const XML_Char *encodingName);
414 #define poolStart(pool) ((pool)->start)
415 #define poolEnd(pool) ((pool)->ptr)
416 #define poolLength(pool) ((pool)->ptr - (pool)->start)
417 #define poolChop(pool) ((void)--(pool->ptr))
418 #define poolLastChar(pool) (((pool)->ptr)[-1])
419 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
420 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
421 #define poolAppendChar(pool, c) \
422 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
424 : ((*((pool)->ptr)++ = c), 1))
426 struct XML_ParserStruct {
427 /* The first member must be userData so that the XML_GetUserData
432 XML_Memory_Handling_Suite m_mem;
433 /* first character to be parsed */
434 const char *m_bufferPtr;
435 /* past last character to be parsed */
437 /* allocated end of buffer */
438 const char *m_bufferLim;
439 long m_parseEndByteIndex;
440 const char *m_parseEndPtr;
442 XML_Char *m_dataBufEnd;
443 XML_StartElementHandler m_startElementHandler;
444 XML_EndElementHandler m_endElementHandler;
445 XML_CharacterDataHandler m_characterDataHandler;
446 XML_ProcessingInstructionHandler m_processingInstructionHandler;
447 XML_CommentHandler m_commentHandler;
448 XML_StartCdataSectionHandler m_startCdataSectionHandler;
449 XML_EndCdataSectionHandler m_endCdataSectionHandler;
450 XML_DefaultHandler m_defaultHandler;
451 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
452 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
453 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
454 XML_NotationDeclHandler m_notationDeclHandler;
455 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
456 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
457 XML_NotStandaloneHandler m_notStandaloneHandler;
458 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
459 void *m_externalEntityRefHandlerArg;
460 XML_SkippedEntityHandler m_skippedEntityHandler;
461 XML_UnknownEncodingHandler m_unknownEncodingHandler;
462 XML_ElementDeclHandler m_elementDeclHandler;
463 XML_AttlistDeclHandler m_attlistDeclHandler;
464 XML_EntityDeclHandler m_entityDeclHandler;
465 XML_XmlDeclHandler m_xmlDeclHandler;
466 const ENCODING *m_encoding;
467 INIT_ENCODING m_initEncoding;
468 const ENCODING *m_internalEncoding;
469 const XML_Char *m_protocolEncodingName;
471 XML_Bool m_ns_triplets;
472 void *m_unknownEncodingMem;
473 void *m_unknownEncodingData;
474 void *m_unknownEncodingHandlerData;
475 void (*m_unknownEncodingRelease)(void *);
476 PROLOG_STATE m_prologState;
477 Processor *m_processor;
478 enum XML_Error m_errorCode;
479 const char *m_eventPtr;
480 const char *m_eventEndPtr;
481 const char *m_positionPtr;
482 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
483 XML_Bool m_defaultExpandInternalEntities;
485 ENTITY *m_declEntity;
486 const XML_Char *m_doctypeName;
487 const XML_Char *m_doctypeSysid;
488 const XML_Char *m_doctypePubid;
489 const XML_Char *m_declAttributeType;
490 const XML_Char *m_declNotationName;
491 const XML_Char *m_declNotationPublicId;
492 ELEMENT_TYPE *m_declElementType;
493 ATTRIBUTE_ID *m_declAttributeId;
494 XML_Bool m_declAttributeIsCdata;
495 XML_Bool m_declAttributeIsId;
497 const XML_Char *m_curBase;
500 BINDING *m_inheritedBindings;
501 BINDING *m_freeBindingList;
503 int m_nSpecifiedAtts;
507 STRING_POOL m_tempPool;
508 STRING_POOL m_temp2Pool;
509 char *m_groupConnector;
510 unsigned m_groupSize;
511 XML_Char m_namespaceSeparator;
512 XML_Parser m_parentParser;
514 XML_Bool m_isParamEntity;
515 XML_Bool m_useForeignDTD;
516 enum XML_ParamEntityParsing m_paramEntityParsing;
520 #define MALLOC(s) ((parser)->m_mem.malloc_fcn((s)))
521 #define REALLOC(p,s) ((parser)->m_mem.realloc_fcn((p),(s)))
522 #define FREE(p) ((parser)->m_mem.free_fcn((p)))
524 #define userData (parser->m_userData)
525 #define handlerArg (parser->m_handlerArg)
526 #define startElementHandler (parser->m_startElementHandler)
527 #define endElementHandler (parser->m_endElementHandler)
528 #define characterDataHandler (parser->m_characterDataHandler)
529 #define processingInstructionHandler \
530 (parser->m_processingInstructionHandler)
531 #define commentHandler (parser->m_commentHandler)
532 #define startCdataSectionHandler \
533 (parser->m_startCdataSectionHandler)
534 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
535 #define defaultHandler (parser->m_defaultHandler)
536 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
537 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
538 #define unparsedEntityDeclHandler \
539 (parser->m_unparsedEntityDeclHandler)
540 #define notationDeclHandler (parser->m_notationDeclHandler)
541 #define startNamespaceDeclHandler \
542 (parser->m_startNamespaceDeclHandler)
543 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
544 #define notStandaloneHandler (parser->m_notStandaloneHandler)
545 #define externalEntityRefHandler \
546 (parser->m_externalEntityRefHandler)
547 #define externalEntityRefHandlerArg \
548 (parser->m_externalEntityRefHandlerArg)
549 #define internalEntityRefHandler \
550 (parser->m_internalEntityRefHandler)
551 #define skippedEntityHandler (parser->m_skippedEntityHandler)
552 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
553 #define elementDeclHandler (parser->m_elementDeclHandler)
554 #define attlistDeclHandler (parser->m_attlistDeclHandler)
555 #define entityDeclHandler (parser->m_entityDeclHandler)
556 #define xmlDeclHandler (parser->m_xmlDeclHandler)
557 #define encoding (parser->m_encoding)
558 #define initEncoding (parser->m_initEncoding)
559 #define internalEncoding (parser->m_internalEncoding)
560 #define unknownEncodingMem (parser->m_unknownEncodingMem)
561 #define unknownEncodingData (parser->m_unknownEncodingData)
562 #define unknownEncodingHandlerData \
563 (parser->m_unknownEncodingHandlerData)
564 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
565 #define protocolEncodingName (parser->m_protocolEncodingName)
566 #define ns (parser->m_ns)
567 #define ns_triplets (parser->m_ns_triplets)
568 #define prologState (parser->m_prologState)
569 #define processor (parser->m_processor)
570 #define errorCode (parser->m_errorCode)
571 #define eventPtr (parser->m_eventPtr)
572 #define eventEndPtr (parser->m_eventEndPtr)
573 #define positionPtr (parser->m_positionPtr)
574 #define position (parser->m_position)
575 #define openInternalEntities (parser->m_openInternalEntities)
576 #define defaultExpandInternalEntities \
577 (parser->m_defaultExpandInternalEntities)
578 #define tagLevel (parser->m_tagLevel)
579 #define buffer (parser->m_buffer)
580 #define bufferPtr (parser->m_bufferPtr)
581 #define bufferEnd (parser->m_bufferEnd)
582 #define parseEndByteIndex (parser->m_parseEndByteIndex)
583 #define parseEndPtr (parser->m_parseEndPtr)
584 #define bufferLim (parser->m_bufferLim)
585 #define dataBuf (parser->m_dataBuf)
586 #define dataBufEnd (parser->m_dataBufEnd)
587 #define dtd (parser->m_dtd)
588 #define curBase (parser->m_curBase)
589 #define declEntity (parser->m_declEntity)
590 #define doctypeName (parser->m_doctypeName)
591 #define doctypeSysid (parser->m_doctypeSysid)
592 #define doctypePubid (parser->m_doctypePubid)
593 #define declAttributeType (parser->m_declAttributeType)
594 #define declNotationName (parser->m_declNotationName)
595 #define declNotationPublicId (parser->m_declNotationPublicId)
596 #define declElementType (parser->m_declElementType)
597 #define declAttributeId (parser->m_declAttributeId)
598 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
599 #define declAttributeIsId (parser->m_declAttributeIsId)
600 #define freeTagList (parser->m_freeTagList)
601 #define freeBindingList (parser->m_freeBindingList)
602 #define inheritedBindings (parser->m_inheritedBindings)
603 #define tagStack (parser->m_tagStack)
604 #define atts (parser->m_atts)
605 #define attsSize (parser->m_attsSize)
606 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
607 #define idAttIndex (parser->m_idAttIndex)
608 #define tempPool (parser->m_tempPool)
609 #define temp2Pool (parser->m_temp2Pool)
610 #define groupConnector (parser->m_groupConnector)
611 #define groupSize (parser->m_groupSize)
612 #define namespaceSeparator (parser->m_namespaceSeparator)
613 #define parentParser (parser->m_parentParser)
615 #define isParamEntity (parser->m_isParamEntity)
616 #define useForeignDTD (parser->m_useForeignDTD)
617 #define paramEntityParsing (parser->m_paramEntityParsing)
620 #define parsing (processor != prologInitProcessor)
623 XML_ParserCreate(const XML_Char *encodingName)
625 return XML_ParserCreate_MM(encodingName, NULL, NULL);
629 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
633 return XML_ParserCreate_MM(encodingName, NULL, tmp);
637 XML_ParserCreate_MM(const XML_Char *encodingName,
638 const XML_Memory_Handling_Suite *memsuite,
639 const XML_Char *nameSep) {
641 static const XML_Char implicitContext[] = {
642 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
643 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
644 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
645 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
650 XML_Memory_Handling_Suite *mtemp;
651 parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
652 if (parser != NULL) {
653 mtemp = &(parser->m_mem);
654 mtemp->malloc_fcn = memsuite->malloc_fcn;
655 mtemp->realloc_fcn = memsuite->realloc_fcn;
656 mtemp->free_fcn = memsuite->free_fcn;
660 XML_Memory_Handling_Suite *mtemp;
661 parser = malloc(sizeof(struct XML_ParserStruct));
662 if (parser != NULL) {
663 mtemp = &(parser->m_mem);
664 mtemp->malloc_fcn = malloc;
665 mtemp->realloc_fcn = realloc;
666 mtemp->free_fcn = free;
676 attsSize = INIT_ATTS_SIZE;
677 atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
682 dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
683 if (dataBuf == NULL) {
688 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
690 freeBindingList = NULL;
694 groupConnector = NULL;
696 unknownEncodingHandler = NULL;
697 unknownEncodingHandlerData = NULL;
699 namespaceSeparator = '!';
701 ns_triplets = XML_FALSE;
703 poolInit(&tempPool, &(parser->m_mem));
704 poolInit(&temp2Pool, &(parser->m_mem));
705 parserInit(parser, encodingName);
706 dtdInit(&dtd, parser);
708 if (!atts || !dataBuf || (encodingName && !protocolEncodingName)) {
709 XML_ParserFree(parser);
715 internalEncoding = XmlGetInternalEncodingNS();
716 namespaceSeparator = *nameSep;
718 if (!setContext(parser, implicitContext)) {
719 XML_ParserFree(parser);
724 internalEncoding = XmlGetInternalEncoding();
731 parserInit(XML_Parser parser, const XML_Char *encodingName)
733 processor = prologInitProcessor;
734 XmlPrologStateInit(&prologState);
735 protocolEncodingName = (encodingName != NULL
736 ? poolCopyString(&tempPool, encodingName)
739 XmlInitEncoding(&initEncoding, &encoding, 0);
742 startElementHandler = NULL;
743 endElementHandler = NULL;
744 characterDataHandler = NULL;
745 processingInstructionHandler = NULL;
746 commentHandler = NULL;
747 startCdataSectionHandler = NULL;
748 endCdataSectionHandler = NULL;
749 defaultHandler = NULL;
750 startDoctypeDeclHandler = NULL;
751 endDoctypeDeclHandler = NULL;
752 unparsedEntityDeclHandler = NULL;
753 notationDeclHandler = NULL;
754 startNamespaceDeclHandler = NULL;
755 endNamespaceDeclHandler = NULL;
756 notStandaloneHandler = NULL;
757 externalEntityRefHandler = NULL;
758 externalEntityRefHandlerArg = parser;
759 skippedEntityHandler = NULL;
760 elementDeclHandler = NULL;
761 attlistDeclHandler = NULL;
762 entityDeclHandler = NULL;
763 xmlDeclHandler = NULL;
766 parseEndByteIndex = 0;
768 declElementType = NULL;
769 declAttributeId = NULL;
774 declAttributeType = NULL;
775 declNotationName = NULL;
776 declNotationPublicId = NULL;
777 declAttributeIsCdata = XML_FALSE;
778 declAttributeIsId = XML_FALSE;
779 memset(&position, 0, sizeof(POSITION));
780 errorCode = XML_ERROR_NONE;
784 openInternalEntities = 0;
785 defaultExpandInternalEntities = XML_TRUE;
788 inheritedBindings = NULL;
790 unknownEncodingMem = NULL;
791 unknownEncodingRelease = NULL;
792 unknownEncodingData = NULL;
795 isParamEntity = XML_FALSE;
796 useForeignDTD = XML_FALSE;
797 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
801 /* moves list of bindings to freeBindingList */
803 moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
806 BINDING *b = bindings;
807 bindings = bindings->nextTagBinding;
808 b->nextTagBinding = freeBindingList;
814 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
819 /* move tagStack to freeTagList */
824 tag->parent = freeTagList;
825 moveToFreeBindingList(parser, tag->bindings);
826 tag->bindings = NULL;
829 moveToFreeBindingList(parser, inheritedBindings);
830 if (unknownEncodingMem)
831 FREE(unknownEncodingMem);
832 if (unknownEncodingRelease)
833 unknownEncodingRelease(unknownEncodingData);
834 poolClear(&tempPool);
835 poolClear(&temp2Pool);
836 parserInit(parser, encodingName);
837 dtdReset(&dtd, parser);
842 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
844 /* block after XML_Parse()/XML_ParseBuffer() has been called */
847 if (encodingName == NULL)
848 protocolEncodingName = NULL;
850 protocolEncodingName = poolCopyString(&tempPool, encodingName);
851 if (!protocolEncodingName)
858 XML_ExternalEntityParserCreate(XML_Parser oldParser,
859 const XML_Char *context,
860 const XML_Char *encodingName)
862 XML_Parser parser = oldParser;
864 XML_StartElementHandler oldStartElementHandler = startElementHandler;
865 XML_EndElementHandler oldEndElementHandler = endElementHandler;
866 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
867 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
868 = processingInstructionHandler;
869 XML_CommentHandler oldCommentHandler = commentHandler;
870 XML_StartCdataSectionHandler oldStartCdataSectionHandler
871 = startCdataSectionHandler;
872 XML_EndCdataSectionHandler oldEndCdataSectionHandler
873 = endCdataSectionHandler;
874 XML_DefaultHandler oldDefaultHandler = defaultHandler;
875 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
876 = unparsedEntityDeclHandler;
877 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
878 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
879 = startNamespaceDeclHandler;
880 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
881 = endNamespaceDeclHandler;
882 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
883 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
884 = externalEntityRefHandler;
885 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
886 XML_UnknownEncodingHandler oldUnknownEncodingHandler
887 = unknownEncodingHandler;
888 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
889 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
890 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
891 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
892 ELEMENT_TYPE * oldDeclElementType = declElementType;
894 void *oldUserData = userData;
895 void *oldHandlerArg = handlerArg;
896 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
897 void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
899 int oldParamEntityParsing = paramEntityParsing;
900 int oldInEntityValue = prologState.inEntityValue;
902 XML_Bool oldns_triplets = ns_triplets;
904 /* Note that the magical uses of the pre-processor to make field
905 access look more like C++ require that `parser' be overwritten
906 here. This makes this function more painful to follow than it
912 *tmp = namespaceSeparator;
913 parser = XML_ParserCreate_MM(encodingName, &parser->m_mem,
917 parser = XML_ParserCreate_MM(encodingName, &parser->m_mem,
924 startElementHandler = oldStartElementHandler;
925 endElementHandler = oldEndElementHandler;
926 characterDataHandler = oldCharacterDataHandler;
927 processingInstructionHandler = oldProcessingInstructionHandler;
928 commentHandler = oldCommentHandler;
929 startCdataSectionHandler = oldStartCdataSectionHandler;
930 endCdataSectionHandler = oldEndCdataSectionHandler;
931 defaultHandler = oldDefaultHandler;
932 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
933 notationDeclHandler = oldNotationDeclHandler;
934 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
935 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
936 notStandaloneHandler = oldNotStandaloneHandler;
937 externalEntityRefHandler = oldExternalEntityRefHandler;
938 skippedEntityHandler = oldSkippedEntityHandler;
939 unknownEncodingHandler = oldUnknownEncodingHandler;
940 elementDeclHandler = oldElementDeclHandler;
941 attlistDeclHandler = oldAttlistDeclHandler;
942 entityDeclHandler = oldEntityDeclHandler;
943 xmlDeclHandler = oldXmlDeclHandler;
944 declElementType = oldDeclElementType;
945 userData = oldUserData;
946 if (oldUserData == oldHandlerArg)
947 handlerArg = userData;
950 if (oldExternalEntityRefHandlerArg != oldParser)
951 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
952 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
953 ns_triplets = oldns_triplets;
954 parentParser = oldParser;
956 paramEntityParsing = oldParamEntityParsing;
957 prologState.inEntityValue = oldInEntityValue;
960 if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
961 XML_ParserFree(parser);
964 processor = externalEntityInitProcessor;
968 dtdSwap(&dtd, oldDtd);
969 isParamEntity = XML_TRUE;
970 XmlPrologStateInitExternalEntity(&prologState);
971 processor = externalParEntInitProcessor;
978 destroyBindings(BINDING *bindings, XML_Parser parser)
981 BINDING *b = bindings;
984 bindings = b->nextTagBinding;
991 XML_ParserFree(XML_Parser parser)
996 if (freeTagList == NULL)
998 tagStack = freeTagList;
1002 tagStack = tagStack->parent;
1004 destroyBindings(p->bindings, parser);
1007 destroyBindings(freeBindingList, parser);
1008 destroyBindings(inheritedBindings, parser);
1009 poolDestroy(&tempPool);
1010 poolDestroy(&temp2Pool);
1013 dtdSwap(&dtd, &parentParser->m_dtd);
1014 #endif /* XML_DTD */
1015 dtdDestroy(&dtd, parser);
1018 FREE(groupConnector);
1022 if (unknownEncodingMem)
1023 FREE(unknownEncodingMem);
1024 if (unknownEncodingRelease)
1025 unknownEncodingRelease(unknownEncodingData);
1030 XML_UseParserAsHandlerArg(XML_Parser parser)
1032 handlerArg = parser;
1036 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1039 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1041 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1042 useForeignDTD = useDTD;
1043 return XML_ERROR_NONE;
1045 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1050 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1052 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1055 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1059 XML_SetUserData(XML_Parser parser, void *p)
1061 if (handlerArg == userData)
1062 handlerArg = userData = p;
1068 XML_SetBase(XML_Parser parser, const XML_Char *p)
1071 p = poolCopyString(&dtd.pool, p);
1082 XML_GetBase(XML_Parser parser)
1088 XML_GetSpecifiedAttributeCount(XML_Parser parser)
1090 return nSpecifiedAtts;
1094 XML_GetIdAttributeIndex(XML_Parser parser)
1100 XML_SetElementHandler(XML_Parser parser,
1101 XML_StartElementHandler start,
1102 XML_EndElementHandler end)
1104 startElementHandler = start;
1105 endElementHandler = end;
1109 XML_SetStartElementHandler(XML_Parser parser,
1110 XML_StartElementHandler start) {
1111 startElementHandler = start;
1115 XML_SetEndElementHandler(XML_Parser parser,
1116 XML_EndElementHandler end) {
1117 endElementHandler = end;
1121 XML_SetCharacterDataHandler(XML_Parser parser,
1122 XML_CharacterDataHandler handler)
1124 characterDataHandler = handler;
1128 XML_SetProcessingInstructionHandler(XML_Parser parser,
1129 XML_ProcessingInstructionHandler handler)
1131 processingInstructionHandler = handler;
1135 XML_SetCommentHandler(XML_Parser parser,
1136 XML_CommentHandler handler)
1138 commentHandler = handler;
1142 XML_SetCdataSectionHandler(XML_Parser parser,
1143 XML_StartCdataSectionHandler start,
1144 XML_EndCdataSectionHandler end)
1146 startCdataSectionHandler = start;
1147 endCdataSectionHandler = end;
1151 XML_SetStartCdataSectionHandler(XML_Parser parser,
1152 XML_StartCdataSectionHandler start) {
1153 startCdataSectionHandler = start;
1157 XML_SetEndCdataSectionHandler(XML_Parser parser,
1158 XML_EndCdataSectionHandler end) {
1159 endCdataSectionHandler = end;
1163 XML_SetDefaultHandler(XML_Parser parser,
1164 XML_DefaultHandler handler)
1166 defaultHandler = handler;
1167 defaultExpandInternalEntities = XML_FALSE;
1171 XML_SetDefaultHandlerExpand(XML_Parser parser,
1172 XML_DefaultHandler handler)
1174 defaultHandler = handler;
1175 defaultExpandInternalEntities = XML_TRUE;
1179 XML_SetDoctypeDeclHandler(XML_Parser parser,
1180 XML_StartDoctypeDeclHandler start,
1181 XML_EndDoctypeDeclHandler end)
1183 startDoctypeDeclHandler = start;
1184 endDoctypeDeclHandler = end;
1188 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1189 XML_StartDoctypeDeclHandler start) {
1190 startDoctypeDeclHandler = start;
1194 XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1195 XML_EndDoctypeDeclHandler end) {
1196 endDoctypeDeclHandler = end;
1200 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1201 XML_UnparsedEntityDeclHandler handler)
1203 unparsedEntityDeclHandler = handler;
1207 XML_SetNotationDeclHandler(XML_Parser parser,
1208 XML_NotationDeclHandler handler)
1210 notationDeclHandler = handler;
1214 XML_SetNamespaceDeclHandler(XML_Parser parser,
1215 XML_StartNamespaceDeclHandler start,
1216 XML_EndNamespaceDeclHandler end)
1218 startNamespaceDeclHandler = start;
1219 endNamespaceDeclHandler = end;
1223 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1224 XML_StartNamespaceDeclHandler start) {
1225 startNamespaceDeclHandler = start;
1229 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1230 XML_EndNamespaceDeclHandler end) {
1231 endNamespaceDeclHandler = end;
1235 XML_SetNotStandaloneHandler(XML_Parser parser,
1236 XML_NotStandaloneHandler handler)
1238 notStandaloneHandler = handler;
1242 XML_SetExternalEntityRefHandler(XML_Parser parser,
1243 XML_ExternalEntityRefHandler handler)
1245 externalEntityRefHandler = handler;
1249 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1252 externalEntityRefHandlerArg = arg;
1254 externalEntityRefHandlerArg = parser;
1258 XML_SetSkippedEntityHandler(XML_Parser parser,
1259 XML_SkippedEntityHandler handler)
1261 skippedEntityHandler = handler;
1265 XML_SetUnknownEncodingHandler(XML_Parser parser,
1266 XML_UnknownEncodingHandler handler,
1269 unknownEncodingHandler = handler;
1270 unknownEncodingHandlerData = data;
1274 XML_SetElementDeclHandler(XML_Parser parser,
1275 XML_ElementDeclHandler eldecl)
1277 elementDeclHandler = eldecl;
1281 XML_SetAttlistDeclHandler(XML_Parser parser,
1282 XML_AttlistDeclHandler attdecl)
1284 attlistDeclHandler = attdecl;
1288 XML_SetEntityDeclHandler(XML_Parser parser,
1289 XML_EntityDeclHandler handler)
1291 entityDeclHandler = handler;
1295 XML_SetXmlDeclHandler(XML_Parser parser,
1296 XML_XmlDeclHandler handler) {
1297 xmlDeclHandler = handler;
1301 XML_SetParamEntityParsing(XML_Parser parser,
1302 enum XML_ParamEntityParsing peParsing)
1304 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1308 paramEntityParsing = peParsing;
1311 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1316 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1320 return XML_STATUS_OK;
1321 positionPtr = bufferPtr;
1322 errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
1323 if (errorCode == XML_ERROR_NONE)
1324 return XML_STATUS_OK;
1325 eventEndPtr = eventPtr;
1326 processor = errorProcessor;
1327 return XML_STATUS_ERROR;
1329 #ifndef XML_CONTEXT_BYTES
1330 else if (bufferPtr == bufferEnd) {
1333 parseEndByteIndex += len;
1336 errorCode = processor(parser, s, parseEndPtr = s + len, 0);
1337 if (errorCode == XML_ERROR_NONE)
1338 return XML_STATUS_OK;
1339 eventEndPtr = eventPtr;
1340 processor = errorProcessor;
1341 return XML_STATUS_ERROR;
1343 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1344 if (errorCode != XML_ERROR_NONE) {
1345 eventEndPtr = eventPtr;
1346 processor = errorProcessor;
1347 return XML_STATUS_ERROR;
1349 XmlUpdatePosition(encoding, positionPtr, end, &position);
1350 nLeftOver = s + len - end;
1352 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1353 /* FIXME avoid integer overflow */
1355 temp = buffer == NULL ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
1357 errorCode = XML_ERROR_NO_MEMORY;
1358 return XML_STATUS_ERROR;
1362 errorCode = XML_ERROR_NO_MEMORY;
1363 eventPtr = eventEndPtr = NULL;
1364 processor = errorProcessor;
1365 return XML_STATUS_ERROR;
1367 bufferLim = buffer + len * 2;
1369 memcpy(buffer, end, nLeftOver);
1371 bufferEnd = buffer + nLeftOver;
1373 return XML_STATUS_OK;
1375 #endif /* not defined XML_CONTEXT_BYTES */
1377 void *buff = XML_GetBuffer(parser, len);
1379 return XML_STATUS_ERROR;
1381 memcpy(buff, s, len);
1382 return XML_ParseBuffer(parser, len, isFinal);
1388 XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1390 const char *start = bufferPtr;
1391 positionPtr = start;
1393 parseEndByteIndex += len;
1394 errorCode = processor(parser, start, parseEndPtr = bufferEnd,
1395 isFinal ? (const char **)NULL : &bufferPtr);
1396 if (errorCode == XML_ERROR_NONE) {
1398 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1399 return XML_STATUS_OK;
1402 eventEndPtr = eventPtr;
1403 processor = errorProcessor;
1404 return XML_STATUS_ERROR;
1409 XML_GetBuffer(XML_Parser parser, int len)
1411 if (len > bufferLim - bufferEnd) {
1412 /* FIXME avoid integer overflow */
1413 int neededSize = len + (bufferEnd - bufferPtr);
1414 #ifdef XML_CONTEXT_BYTES
1415 int keep = bufferPtr - buffer;
1417 if (keep > XML_CONTEXT_BYTES)
1418 keep = XML_CONTEXT_BYTES;
1420 #endif /* defined XML_CONTEXT_BYTES */
1421 if (neededSize <= bufferLim - buffer) {
1422 #ifdef XML_CONTEXT_BYTES
1423 if (keep < bufferPtr - buffer) {
1424 int offset = (bufferPtr - buffer) - keep;
1425 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1426 bufferEnd -= offset;
1427 bufferPtr -= offset;
1430 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1431 bufferEnd = buffer + (bufferEnd - bufferPtr);
1433 #endif /* not defined XML_CONTEXT_BYTES */
1437 int bufferSize = bufferLim - bufferPtr;
1438 if (bufferSize == 0)
1439 bufferSize = INIT_BUFFER_SIZE;
1442 } while (bufferSize < neededSize);
1443 newBuf = MALLOC(bufferSize);
1445 errorCode = XML_ERROR_NO_MEMORY;
1448 bufferLim = newBuf + bufferSize;
1449 #ifdef XML_CONTEXT_BYTES
1451 int keep = bufferPtr - buffer;
1452 if (keep > XML_CONTEXT_BYTES)
1453 keep = XML_CONTEXT_BYTES;
1454 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1457 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1458 bufferPtr = buffer + keep;
1461 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1462 bufferPtr = buffer = newBuf;
1466 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1469 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1470 bufferPtr = buffer = newBuf;
1471 #endif /* not defined XML_CONTEXT_BYTES */
1478 XML_GetErrorCode(XML_Parser parser)
1484 XML_GetCurrentByteIndex(XML_Parser parser)
1487 return parseEndByteIndex - (parseEndPtr - eventPtr);
1492 XML_GetCurrentByteCount(XML_Parser parser)
1494 if (eventEndPtr && eventPtr)
1495 return eventEndPtr - eventPtr;
1500 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1502 #ifdef XML_CONTEXT_BYTES
1503 if (eventPtr && buffer) {
1504 *offset = eventPtr - buffer;
1505 *size = bufferEnd - buffer;
1508 #endif /* defined XML_CONTEXT_BYTES */
1513 XML_GetCurrentLineNumber(XML_Parser parser)
1516 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1517 positionPtr = eventPtr;
1519 return position.lineNumber + 1;
1523 XML_GetCurrentColumnNumber(XML_Parser parser)
1526 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1527 positionPtr = eventPtr;
1529 return position.columnNumber;
1533 XML_DefaultCurrent(XML_Parser parser)
1535 if (defaultHandler) {
1536 if (openInternalEntities)
1537 reportDefault(parser,
1539 openInternalEntities->internalEventPtr,
1540 openInternalEntities->internalEventEndPtr);
1542 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1547 XML_ErrorString(enum XML_Error code)
1549 static const XML_LChar *message[] = {
1551 XML_L("out of memory"),
1552 XML_L("syntax error"),
1553 XML_L("no element found"),
1554 XML_L("not well-formed (invalid token)"),
1555 XML_L("unclosed token"),
1556 XML_L("partial character"),
1557 XML_L("mismatched tag"),
1558 XML_L("duplicate attribute"),
1559 XML_L("junk after document element"),
1560 XML_L("illegal parameter entity reference"),
1561 XML_L("undefined entity"),
1562 XML_L("recursive entity reference"),
1563 XML_L("asynchronous entity"),
1564 XML_L("reference to invalid character number"),
1565 XML_L("reference to binary entity"),
1566 XML_L("reference to external entity in attribute"),
1567 XML_L("xml declaration not at start of external entity"),
1568 XML_L("unknown encoding"),
1569 XML_L("encoding specified in XML declaration is incorrect"),
1570 XML_L("unclosed CDATA section"),
1571 XML_L("error in processing external entity reference"),
1572 XML_L("document is not standalone"),
1573 XML_L("unexpected parser state - please send a bug report"),
1574 XML_L("entity declared in parameter entity"),
1575 XML_L("requested feature requires XML_DTD support in Expat"),
1576 XML_L("cannot change setting once parsing has begun")
1578 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1579 return message[code];
1584 XML_ExpatVersion(void) {
1586 /* V1 is used to string-ize the version number. However, it would
1587 string-ize the actual version macro *names* unless we get them
1588 substituted before being passed to V1. CPP is defined to expand
1589 a macro, then rescan for more expansions. Thus, we use V2 to expand
1590 the version macros, then CPP will expand the resulting V1() macro
1591 with the correct numerals. */
1592 /* ### I'm assuming cpp is portable in this respect... */
1594 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1595 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1597 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1604 XML_ExpatVersionInfo(void)
1606 XML_Expat_Version version;
1608 version.major = XML_MAJOR_VERSION;
1609 version.minor = XML_MINOR_VERSION;
1610 version.micro = XML_MICRO_VERSION;
1616 XML_GetFeatureList(void)
1618 static XML_Feature features[] = {
1619 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)")},
1620 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)")},
1622 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE")},
1624 #ifdef XML_UNICODE_WCHAR_T
1625 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T")},
1628 {XML_FEATURE_DTD, XML_L("XML_DTD")},
1630 #ifdef XML_CONTEXT_BYTES
1631 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
1635 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE")},
1637 {XML_FEATURE_END, NULL}
1640 features[0].value = sizeof(XML_Char);
1641 features[1].value = sizeof(XML_LChar);
1645 /* Initially tag->rawName always points into the parse buffer;
1646 for those TAG instances opened while the current parse buffer was
1647 processed, and not yet closed, we need to store tag->rawName in a more
1648 permanent location, since the parse buffer is about to be discarded.
1650 static XML_Bool FASTCALL
1651 storeRawNames(XML_Parser parser)
1653 TAG *tag = tagStack;
1656 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
1657 char *rawNameBuf = tag->buf + nameLen;
1658 /* Stop if already stored. Since tagStack is a stack, we can stop
1659 at the first entry that has already been copied; everything
1660 below it in the stack is already been accounted for in a
1661 previous call to this function.
1663 if (tag->rawName == rawNameBuf)
1665 /* For re-use purposes we need to ensure that the
1666 size of tag->buf is a multiple of sizeof(XML_Char).
1668 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
1669 if (bufSize > tag->bufEnd - tag->buf) {
1670 char *temp = REALLOC(tag->buf, bufSize);
1674 tag->name.str = (XML_Char *)temp;
1675 tag->bufEnd = temp + bufSize;
1676 rawNameBuf = temp + nameLen;
1678 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
1679 tag->rawName = rawNameBuf;
1685 static enum XML_Error FASTCALL
1686 contentProcessor(XML_Parser parser,
1689 const char **endPtr)
1691 enum XML_Error result =
1692 doContent(parser, 0, encoding, start, end, endPtr);
1693 if (result != XML_ERROR_NONE)
1695 if (!storeRawNames(parser))
1696 return XML_ERROR_NO_MEMORY;
1700 static enum XML_Error FASTCALL
1701 externalEntityInitProcessor(XML_Parser parser,
1704 const char **endPtr)
1706 enum XML_Error result = initializeEncoding(parser);
1707 if (result != XML_ERROR_NONE)
1709 processor = externalEntityInitProcessor2;
1710 return externalEntityInitProcessor2(parser, start, end, endPtr);
1713 static enum XML_Error FASTCALL
1714 externalEntityInitProcessor2(XML_Parser parser,
1717 const char **endPtr)
1719 const char *next = start; /* XmlContentTok doesn't always set the last arg */
1720 int tok = XmlContentTok(encoding, start, end, &next);
1723 /* If we are at the end of the buffer, this would cause the next stage,
1724 i.e. externalEntityInitProcessor3, to pass control directly to
1725 doContent (by detecting XML_TOK_NONE) without processing any xml text
1726 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1728 if (next == end && endPtr) {
1730 return XML_ERROR_NONE;
1734 case XML_TOK_PARTIAL:
1737 return XML_ERROR_NONE;
1740 return XML_ERROR_UNCLOSED_TOKEN;
1741 case XML_TOK_PARTIAL_CHAR:
1744 return XML_ERROR_NONE;
1747 return XML_ERROR_PARTIAL_CHAR;
1749 processor = externalEntityInitProcessor3;
1750 return externalEntityInitProcessor3(parser, start, end, endPtr);
1753 static enum XML_Error FASTCALL
1754 externalEntityInitProcessor3(XML_Parser parser,
1757 const char **endPtr)
1759 const char *next = start; /* XmlContentTok doesn't always set the last arg */
1760 int tok = XmlContentTok(encoding, start, end, &next);
1762 case XML_TOK_XML_DECL:
1764 enum XML_Error result = processXmlDecl(parser, 1, start, next);
1765 if (result != XML_ERROR_NONE)
1770 case XML_TOK_PARTIAL:
1773 return XML_ERROR_NONE;
1776 return XML_ERROR_UNCLOSED_TOKEN;
1777 case XML_TOK_PARTIAL_CHAR:
1780 return XML_ERROR_NONE;
1783 return XML_ERROR_PARTIAL_CHAR;
1785 processor = externalEntityContentProcessor;
1787 return externalEntityContentProcessor(parser, start, end, endPtr);
1790 static enum XML_Error FASTCALL
1791 externalEntityContentProcessor(XML_Parser parser,
1794 const char **endPtr)
1796 enum XML_Error result =
1797 doContent(parser, 1, encoding, start, end, endPtr);
1798 if (result != XML_ERROR_NONE)
1800 if (!storeRawNames(parser))
1801 return XML_ERROR_NO_MEMORY;
1805 static enum XML_Error FASTCALL
1806 doContent(XML_Parser parser,
1808 const ENCODING *enc,
1811 const char **nextPtr)
1813 const char **eventPP;
1814 const char **eventEndPP;
1815 if (enc == encoding) {
1816 eventPP = &eventPtr;
1817 eventEndPP = &eventEndPtr;
1820 eventPP = &(openInternalEntities->internalEventPtr);
1821 eventEndPP = &(openInternalEntities->internalEventEndPtr);
1825 const char *next = s; /* XmlContentTok doesn't always set the last arg */
1826 int tok = XmlContentTok(enc, s, end, &next);
1829 case XML_TOK_TRAILING_CR:
1832 return XML_ERROR_NONE;
1835 if (characterDataHandler) {
1837 characterDataHandler(handlerArg, &c, 1);
1839 else if (defaultHandler)
1840 reportDefault(parser, enc, s, end);
1841 if (startTagLevel == 0)
1842 return XML_ERROR_NO_ELEMENTS;
1843 if (tagLevel != startTagLevel)
1844 return XML_ERROR_ASYNC_ENTITY;
1845 return XML_ERROR_NONE;
1849 return XML_ERROR_NONE;
1851 if (startTagLevel > 0) {
1852 if (tagLevel != startTagLevel)
1853 return XML_ERROR_ASYNC_ENTITY;
1854 return XML_ERROR_NONE;
1856 return XML_ERROR_NO_ELEMENTS;
1857 case XML_TOK_INVALID:
1859 return XML_ERROR_INVALID_TOKEN;
1860 case XML_TOK_PARTIAL:
1863 return XML_ERROR_NONE;
1865 return XML_ERROR_UNCLOSED_TOKEN;
1866 case XML_TOK_PARTIAL_CHAR:
1869 return XML_ERROR_NONE;
1871 return XML_ERROR_PARTIAL_CHAR;
1872 case XML_TOK_ENTITY_REF:
1874 const XML_Char *name;
1876 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
1877 s + enc->minBytesPerChar,
1878 next - enc->minBytesPerChar);
1880 if (characterDataHandler)
1881 characterDataHandler(handlerArg, &ch, 1);
1882 else if (defaultHandler)
1883 reportDefault(parser, enc, s, next);
1886 name = poolStoreString(&dtd.pool, enc,
1887 s + enc->minBytesPerChar,
1888 next - enc->minBytesPerChar);
1890 return XML_ERROR_NO_MEMORY;
1891 entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
1892 poolDiscard(&dtd.pool);
1893 /* First, determine if a check for an existing declaration is needed;
1894 if yes, check that the entity exists, and that it is internal,
1895 otherwise call the skipped entity or default handler.
1897 if (!dtd.hasParamEntityRefs || dtd.standalone) {
1899 return XML_ERROR_UNDEFINED_ENTITY;
1900 else if (!entity->is_internal)
1901 return XML_ERROR_ENTITY_DECLARED_IN_PE;
1904 if (skippedEntityHandler)
1905 skippedEntityHandler(handlerArg, name, 0);
1906 else if (defaultHandler)
1907 reportDefault(parser, enc, s, next);
1911 return XML_ERROR_RECURSIVE_ENTITY_REF;
1912 if (entity->notation)
1913 return XML_ERROR_BINARY_ENTITY_REF;
1914 if (entity->textPtr) {
1915 enum XML_Error result;
1916 OPEN_INTERNAL_ENTITY openEntity;
1917 if (!defaultExpandInternalEntities) {
1918 if (skippedEntityHandler)
1919 skippedEntityHandler(handlerArg, entity->name, 0);
1920 else if (defaultHandler)
1921 reportDefault(parser, enc, s, next);
1924 entity->open = XML_TRUE;
1925 openEntity.next = openInternalEntities;
1926 openInternalEntities = &openEntity;
1927 openEntity.entity = entity;
1928 openEntity.internalEventPtr = NULL;
1929 openEntity.internalEventEndPtr = NULL;
1930 result = doContent(parser,
1933 (char *)entity->textPtr,
1934 (char *)(entity->textPtr + entity->textLen),
1936 entity->open = XML_FALSE;
1937 openInternalEntities = openEntity.next;
1941 else if (externalEntityRefHandler) {
1942 const XML_Char *context;
1943 entity->open = XML_TRUE;
1944 context = getContext(parser);
1945 entity->open = XML_FALSE;
1947 return XML_ERROR_NO_MEMORY;
1948 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
1953 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
1954 poolDiscard(&tempPool);
1956 else if (defaultHandler)
1957 reportDefault(parser, enc, s, next);
1960 case XML_TOK_START_TAG_WITH_ATTS:
1961 if (!startElementHandler) {
1962 enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
1967 case XML_TOK_START_TAG_NO_ATTS:
1970 enum XML_Error result;
1974 freeTagList = freeTagList->parent;
1977 tag = MALLOC(sizeof(TAG));
1979 return XML_ERROR_NO_MEMORY;
1980 tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
1983 return XML_ERROR_NO_MEMORY;
1985 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
1987 tag->bindings = NULL;
1988 tag->parent = tagStack;
1990 tag->name.localPart = NULL;
1991 tag->name.prefix = NULL;
1992 tag->rawName = s + enc->minBytesPerChar;
1993 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
1996 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
1997 const char *fromPtr = tag->rawName;
1998 toPtr = (XML_Char *)tag->buf;
2003 &fromPtr, rawNameEnd,
2004 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2005 convLen = toPtr - (XML_Char *)tag->buf;
2006 if (fromPtr == rawNameEnd) {
2007 tag->name.strLen = convLen;
2010 bufSize = (tag->bufEnd - tag->buf) << 1;
2012 char *temp = REALLOC(tag->buf, bufSize);
2014 return XML_ERROR_NO_MEMORY;
2016 tag->bufEnd = temp + bufSize;
2017 toPtr = (XML_Char *)temp + convLen;
2021 tag->name.str = (XML_Char *)tag->buf;
2022 *toPtr = XML_T('\0');
2023 if (startElementHandler) {
2024 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2027 startElementHandler(handlerArg, tag->name.str,
2028 (const XML_Char **)atts);
2030 else if (defaultHandler)
2031 reportDefault(parser, enc, s, next);
2032 poolClear(&tempPool);
2035 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2036 if (!startElementHandler) {
2037 enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
2042 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2043 if (startElementHandler || endElementHandler) {
2044 const char *rawName = s + enc->minBytesPerChar;
2045 enum XML_Error result;
2046 BINDING *bindings = NULL;
2048 name.str = poolStoreString(&tempPool, enc, rawName,
2049 rawName + XmlNameLength(enc, rawName));
2051 return XML_ERROR_NO_MEMORY;
2052 poolFinish(&tempPool);
2053 result = storeAtts(parser, enc, s, &name, &bindings);
2056 poolFinish(&tempPool);
2057 if (startElementHandler)
2058 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2059 if (endElementHandler) {
2060 if (startElementHandler)
2061 *eventPP = *eventEndPP;
2062 endElementHandler(handlerArg, name.str);
2064 poolClear(&tempPool);
2066 BINDING *b = bindings;
2067 if (endNamespaceDeclHandler)
2068 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2069 bindings = bindings->nextTagBinding;
2070 b->nextTagBinding = freeBindingList;
2071 freeBindingList = b;
2072 b->prefix->binding = b->prevPrefixBinding;
2075 else if (defaultHandler)
2076 reportDefault(parser, enc, s, next);
2078 return epilogProcessor(parser, next, end, nextPtr);
2080 case XML_TOK_END_TAG:
2081 if (tagLevel == startTagLevel)
2082 return XML_ERROR_ASYNC_ENTITY;
2085 const char *rawName;
2086 TAG *tag = tagStack;
2087 tagStack = tag->parent;
2088 tag->parent = freeTagList;
2090 rawName = s + enc->minBytesPerChar*2;
2091 len = XmlNameLength(enc, rawName);
2092 if (len != tag->rawNameLength
2093 || memcmp(tag->rawName, rawName, len) != 0) {
2095 return XML_ERROR_TAG_MISMATCH;
2098 if (endElementHandler) {
2099 const XML_Char *localPart;
2100 const XML_Char *prefix;
2102 localPart = tag->name.localPart;
2103 if (ns && localPart) {
2104 /* localPart and prefix may have been overwritten in
2105 tag->name.str, since this points to the binding->uri
2106 buffer which gets re-used; so we have to add them again
2108 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2109 /* don't need to check for space - already done in storeAtts() */
2110 while (*localPart) *uri++ = *localPart++;
2111 prefix = (XML_Char *)tag->name.prefix;
2112 if (ns_triplets && prefix) {
2113 *uri++ = namespaceSeparator;
2114 while (*prefix) *uri++ = *prefix++;
2118 endElementHandler(handlerArg, tag->name.str);
2120 else if (defaultHandler)
2121 reportDefault(parser, enc, s, next);
2122 while (tag->bindings) {
2123 BINDING *b = tag->bindings;
2124 if (endNamespaceDeclHandler)
2125 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2126 tag->bindings = tag->bindings->nextTagBinding;
2127 b->nextTagBinding = freeBindingList;
2128 freeBindingList = b;
2129 b->prefix->binding = b->prevPrefixBinding;
2132 return epilogProcessor(parser, next, end, nextPtr);
2135 case XML_TOK_CHAR_REF:
2137 int n = XmlCharRefNumber(enc, s);
2139 return XML_ERROR_BAD_CHAR_REF;
2140 if (characterDataHandler) {
2141 XML_Char buf[XML_ENCODE_MAX];
2142 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2144 else if (defaultHandler)
2145 reportDefault(parser, enc, s, next);
2148 case XML_TOK_XML_DECL:
2149 return XML_ERROR_MISPLACED_XML_PI;
2150 case XML_TOK_DATA_NEWLINE:
2151 if (characterDataHandler) {
2153 characterDataHandler(handlerArg, &c, 1);
2155 else if (defaultHandler)
2156 reportDefault(parser, enc, s, next);
2158 case XML_TOK_CDATA_SECT_OPEN:
2160 enum XML_Error result;
2161 if (startCdataSectionHandler)
2162 startCdataSectionHandler(handlerArg);
2164 /* Suppose you doing a transformation on a document that involves
2165 changing only the character data. You set up a defaultHandler
2166 and a characterDataHandler. The defaultHandler simply copies
2167 characters through. The characterDataHandler does the
2168 transformation and writes the characters out escaping them as
2169 necessary. This case will fail to work if we leave out the
2170 following two lines (because & and < inside CDATA sections will
2171 be incorrectly escaped).
2173 However, now we have a start/endCdataSectionHandler, so it seems
2174 easier to let the user deal with this.
2176 else if (characterDataHandler)
2177 characterDataHandler(handlerArg, dataBuf, 0);
2179 else if (defaultHandler)
2180 reportDefault(parser, enc, s, next);
2181 result = doCdataSection(parser, enc, &next, end, nextPtr);
2183 processor = cdataSectionProcessor;
2188 case XML_TOK_TRAILING_RSQB:
2191 return XML_ERROR_NONE;
2193 if (characterDataHandler) {
2194 if (MUST_CONVERT(enc, s)) {
2195 ICHAR *dataPtr = (ICHAR *)dataBuf;
2196 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2197 characterDataHandler(handlerArg, dataBuf,
2198 dataPtr - (ICHAR *)dataBuf);
2201 characterDataHandler(handlerArg,
2203 (XML_Char *)end - (XML_Char *)s);
2205 else if (defaultHandler)
2206 reportDefault(parser, enc, s, end);
2207 if (startTagLevel == 0) {
2209 return XML_ERROR_NO_ELEMENTS;
2211 if (tagLevel != startTagLevel) {
2213 return XML_ERROR_ASYNC_ENTITY;
2215 return XML_ERROR_NONE;
2216 case XML_TOK_DATA_CHARS:
2217 if (characterDataHandler) {
2218 if (MUST_CONVERT(enc, s)) {
2220 ICHAR *dataPtr = (ICHAR *)dataBuf;
2221 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2223 characterDataHandler(handlerArg, dataBuf,
2224 dataPtr - (ICHAR *)dataBuf);
2231 characterDataHandler(handlerArg,
2233 (XML_Char *)next - (XML_Char *)s);
2235 else if (defaultHandler)
2236 reportDefault(parser, enc, s, next);
2239 if (!reportProcessingInstruction(parser, enc, s, next))
2240 return XML_ERROR_NO_MEMORY;
2242 case XML_TOK_COMMENT:
2243 if (!reportComment(parser, enc, s, next))
2244 return XML_ERROR_NO_MEMORY;
2248 reportDefault(parser, enc, s, next);
2251 *eventPP = s = next;
2256 /* If tagNamePtr is non-null, build a real list of attributes,
2257 otherwise just check the attributes for well-formedness.
2259 static enum XML_Error FASTCALL
2260 storeAtts(XML_Parser parser, const ENCODING *enc,
2261 const char *attStr, TAG_NAME *tagNamePtr,
2262 BINDING **bindingsPtr)
2264 ELEMENT_TYPE *elementType = NULL;
2265 int nDefaultAtts = 0;
2266 const XML_Char **appAtts; /* the attribute list for the application */
2274 const XML_Char *localPart;
2276 /* lookup the element type name */
2278 elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
2280 tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
2281 if (!tagNamePtr->str)
2282 return XML_ERROR_NO_MEMORY;
2283 elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,
2284 sizeof(ELEMENT_TYPE));
2286 return XML_ERROR_NO_MEMORY;
2287 if (ns && !setElementTypePrefix(parser, elementType))
2288 return XML_ERROR_NO_MEMORY;
2290 nDefaultAtts = elementType->nDefaultAtts;
2292 /* get the attributes from the tokenizer */
2293 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2294 if (n + nDefaultAtts > attsSize) {
2295 int oldAttsSize = attsSize;
2297 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2298 temp = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2300 return XML_ERROR_NO_MEMORY;
2302 if (n > oldAttsSize)
2303 XmlGetAttributes(enc, attStr, n, atts);
2305 appAtts = (const XML_Char **)atts;
2306 for (i = 0; i < n; i++) {
2307 /* add the name and value to the attribute list */
2308 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
2310 + XmlNameLength(enc, atts[i].name));
2312 return XML_ERROR_NO_MEMORY;
2313 /* detect duplicate attributes */
2314 if ((attId->name)[-1]) {
2315 if (enc == encoding)
2316 eventPtr = atts[i].name;
2317 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2319 (attId->name)[-1] = 1;
2320 appAtts[attIndex++] = attId->name;
2321 if (!atts[i].normalized) {
2322 enum XML_Error result;
2323 XML_Bool isCdata = XML_TRUE;
2325 /* figure out whether declared as other than CDATA */
2326 if (attId->maybeTokenized) {
2328 for (j = 0; j < nDefaultAtts; j++) {
2329 if (attId == elementType->defaultAtts[j].id) {
2330 isCdata = elementType->defaultAtts[j].isCdata;
2336 /* normalize the attribute value */
2337 result = storeAttributeValue(parser, enc, isCdata,
2338 atts[i].valuePtr, atts[i].valueEnd,
2343 appAtts[attIndex] = poolStart(&tempPool);
2344 poolFinish(&tempPool);
2347 poolDiscard(&tempPool);
2349 else if (tagNamePtr) {
2350 /* the value did not need normalizing */
2351 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2353 if (appAtts[attIndex] == 0)
2354 return XML_ERROR_NO_MEMORY;
2355 poolFinish(&tempPool);
2357 /* handle prefixed attribute names */
2358 if (attId->prefix && tagNamePtr) {
2360 /* deal with namespace declarations here */
2361 if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex],
2363 return XML_ERROR_NO_MEMORY;
2367 /* deal with other prefixed names later */
2370 (attId->name)[-1] = 2;
2378 nSpecifiedAtts = attIndex;
2379 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2380 for (i = 0; i < attIndex; i += 2)
2381 if (appAtts[i] == elementType->idAtt->name) {
2388 /* do attribute defaulting */
2389 for (j = 0; j < nDefaultAtts; j++) {
2390 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
2391 if (!(da->id->name)[-1] && da->value) {
2392 if (da->id->prefix) {
2393 if (da->id->xmlns) {
2394 if (!addBinding(parser, da->id->prefix, da->id, da->value,
2396 return XML_ERROR_NO_MEMORY;
2399 (da->id->name)[-1] = 2;
2401 appAtts[attIndex++] = da->id->name;
2402 appAtts[attIndex++] = da->value;
2406 (da->id->name)[-1] = 1;
2407 appAtts[attIndex++] = da->id->name;
2408 appAtts[attIndex++] = da->value;
2412 appAtts[attIndex] = 0;
2416 /* expand prefixed attribute names */
2417 for (; i < attIndex; i += 2) {
2418 if (appAtts[i][-1] == 2) {
2420 ((XML_Char *)(appAtts[i]))[-1] = 0;
2421 id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
2422 if (id->prefix->binding) {
2424 const BINDING *b = id->prefix->binding;
2425 const XML_Char *s = appAtts[i];
2426 for (j = 0; j < b->uriLen; j++) {
2427 if (!poolAppendChar(&tempPool, b->uri[j]))
2428 return XML_ERROR_NO_MEMORY;
2430 while (*s++ != XML_T(':'))
2433 if (!poolAppendChar(&tempPool, *s))
2434 return XML_ERROR_NO_MEMORY;
2437 tempPool.ptr[-1] = namespaceSeparator;
2438 s = b->prefix->name;
2440 if (!poolAppendChar(&tempPool, *s))
2441 return XML_ERROR_NO_MEMORY;
2445 appAtts[i] = poolStart(&tempPool);
2446 poolFinish(&tempPool);
2452 ((XML_Char *)(appAtts[i]))[-1] = 0;
2455 /* clear the flags that say whether attributes were specified */
2456 for (; i < attIndex; i += 2)
2457 ((XML_Char *)(appAtts[i]))[-1] = 0;
2459 return XML_ERROR_NONE;
2460 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2461 binding->attId->name[-1] = 0;
2462 /* expand the element type name */
2463 if (elementType->prefix) {
2464 binding = elementType->prefix->binding;
2466 return XML_ERROR_NONE;
2467 localPart = tagNamePtr->str;
2468 while (*localPart++ != XML_T(':'))
2471 else if (dtd.defaultPrefix.binding) {
2472 binding = dtd.defaultPrefix.binding;
2473 localPart = tagNamePtr->str;
2476 return XML_ERROR_NONE;
2478 if (ns && ns_triplets && binding->prefix->name) {
2479 for (; binding->prefix->name[prefixLen++];)
2482 tagNamePtr->localPart = localPart;
2483 tagNamePtr->uriLen = binding->uriLen;
2484 tagNamePtr->prefix = binding->prefix->name;
2485 tagNamePtr->prefixLen = prefixLen;
2486 for (i = 0; localPart[i++];)
2488 n = i + binding->uriLen + prefixLen;
2489 if (n > binding->uriAlloc) {
2491 uri = MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
2493 return XML_ERROR_NO_MEMORY;
2494 binding->uriAlloc = n + EXPAND_SPARE;
2495 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2496 for (p = tagStack; p; p = p->parent)
2497 if (p->name.str == binding->uri)
2502 uri = binding->uri + binding->uriLen;
2503 memcpy(uri, localPart, i * sizeof(XML_Char));
2505 uri = uri + (i - 1);
2506 if (namespaceSeparator) { *(uri) = namespaceSeparator; }
2507 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2509 tagNamePtr->str = binding->uri;
2510 return XML_ERROR_NONE;
2514 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2515 const XML_Char *uri, BINDING **bindingsPtr)
2519 for (len = 0; uri[len]; len++)
2521 if (namespaceSeparator)
2523 if (freeBindingList) {
2524 b = freeBindingList;
2525 if (len > b->uriAlloc) {
2526 XML_Char *temp = REALLOC(b->uri,
2527 sizeof(XML_Char) * (len + EXPAND_SPARE));
2531 b->uriAlloc = len + EXPAND_SPARE;
2533 freeBindingList = b->nextTagBinding;
2536 b = MALLOC(sizeof(BINDING));
2539 b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
2544 b->uriAlloc = len + EXPAND_SPARE;
2547 memcpy(b->uri, uri, len * sizeof(XML_Char));
2548 if (namespaceSeparator)
2549 b->uri[len - 1] = namespaceSeparator;
2552 b->prevPrefixBinding = prefix->binding;
2553 if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
2554 prefix->binding = NULL;
2556 prefix->binding = b;
2557 b->nextTagBinding = *bindingsPtr;
2559 if (startNamespaceDeclHandler)
2560 startNamespaceDeclHandler(handlerArg, prefix->name,
2561 prefix->binding ? uri : 0);
2565 /* The idea here is to avoid using stack for each CDATA section when
2566 the whole file is parsed with one call.
2568 static enum XML_Error FASTCALL
2569 cdataSectionProcessor(XML_Parser parser,
2572 const char **endPtr)
2574 enum XML_Error result = doCdataSection(parser, encoding, &start,
2577 if (parentParser) { /* we are parsing an external entity */
2578 processor = externalEntityContentProcessor;
2579 return externalEntityContentProcessor(parser, start, end, endPtr);
2582 processor = contentProcessor;
2583 return contentProcessor(parser, start, end, endPtr);
2589 /* startPtr gets set to non-null is the section is closed, and to null if
2590 the section is not yet closed.
2592 static enum XML_Error FASTCALL
2593 doCdataSection(XML_Parser parser,
2594 const ENCODING *enc,
2595 const char **startPtr,
2597 const char **nextPtr)
2599 const char *s = *startPtr;
2600 const char **eventPP;
2601 const char **eventEndPP;
2602 if (enc == encoding) {
2603 eventPP = &eventPtr;
2605 eventEndPP = &eventEndPtr;
2608 eventPP = &(openInternalEntities->internalEventPtr);
2609 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2615 int tok = XmlCdataSectionTok(enc, s, end, &next);
2618 case XML_TOK_CDATA_SECT_CLOSE:
2619 if (endCdataSectionHandler)
2620 endCdataSectionHandler(handlerArg);
2622 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2623 else if (characterDataHandler)
2624 characterDataHandler(handlerArg, dataBuf, 0);
2626 else if (defaultHandler)
2627 reportDefault(parser, enc, s, next);
2629 return XML_ERROR_NONE;
2630 case XML_TOK_DATA_NEWLINE:
2631 if (characterDataHandler) {
2633 characterDataHandler(handlerArg, &c, 1);
2635 else if (defaultHandler)
2636 reportDefault(parser, enc, s, next);
2638 case XML_TOK_DATA_CHARS:
2639 if (characterDataHandler) {
2640 if (MUST_CONVERT(enc, s)) {
2642 ICHAR *dataPtr = (ICHAR *)dataBuf;
2643 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2645 characterDataHandler(handlerArg, dataBuf,
2646 dataPtr - (ICHAR *)dataBuf);
2653 characterDataHandler(handlerArg,
2655 (XML_Char *)next - (XML_Char *)s);
2657 else if (defaultHandler)
2658 reportDefault(parser, enc, s, next);
2660 case XML_TOK_INVALID:
2662 return XML_ERROR_INVALID_TOKEN;
2663 case XML_TOK_PARTIAL_CHAR:
2666 return XML_ERROR_NONE;
2668 return XML_ERROR_PARTIAL_CHAR;
2669 case XML_TOK_PARTIAL:
2673 return XML_ERROR_NONE;
2675 return XML_ERROR_UNCLOSED_CDATA_SECTION;
2678 return XML_ERROR_UNEXPECTED_STATE;
2680 *eventPP = s = next;
2687 /* The idea here is to avoid using stack for each IGNORE section when
2688 the whole file is parsed with one call.
2690 static enum XML_Error FASTCALL
2691 ignoreSectionProcessor(XML_Parser parser,
2694 const char **endPtr)
2696 enum XML_Error result = doIgnoreSection(parser, encoding, &start,
2699 processor = prologProcessor;
2700 return prologProcessor(parser, start, end, endPtr);
2705 /* startPtr gets set to non-null is the section is closed, and to null
2706 if the section is not yet closed.
2708 static enum XML_Error FASTCALL
2709 doIgnoreSection(XML_Parser parser,
2710 const ENCODING *enc,
2711 const char **startPtr,
2713 const char **nextPtr)
2717 const char *s = *startPtr;
2718 const char **eventPP;
2719 const char **eventEndPP;
2720 if (enc == encoding) {
2721 eventPP = &eventPtr;
2723 eventEndPP = &eventEndPtr;
2726 eventPP = &(openInternalEntities->internalEventPtr);
2727 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2731 tok = XmlIgnoreSectionTok(enc, s, end, &next);
2734 case XML_TOK_IGNORE_SECT:
2736 reportDefault(parser, enc, s, next);
2738 return XML_ERROR_NONE;
2739 case XML_TOK_INVALID:
2741 return XML_ERROR_INVALID_TOKEN;
2742 case XML_TOK_PARTIAL_CHAR:
2745 return XML_ERROR_NONE;
2747 return XML_ERROR_PARTIAL_CHAR;
2748 case XML_TOK_PARTIAL:
2752 return XML_ERROR_NONE;
2754 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2757 return XML_ERROR_UNEXPECTED_STATE;
2762 #endif /* XML_DTD */
2764 static enum XML_Error FASTCALL
2765 initializeEncoding(XML_Parser parser)
2769 char encodingBuf[128];
2770 if (!protocolEncodingName)
2774 for (i = 0; protocolEncodingName[i]; i++) {
2775 if (i == sizeof(encodingBuf) - 1
2776 || (protocolEncodingName[i] & ~0x7f) != 0) {
2777 encodingBuf[0] = '\0';
2780 encodingBuf[i] = (char)protocolEncodingName[i];
2782 encodingBuf[i] = '\0';
2786 s = protocolEncodingName;
2788 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
2789 return XML_ERROR_NONE;
2790 return handleUnknownEncoding(parser, protocolEncodingName);
2793 static enum XML_Error FASTCALL
2794 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
2795 const char *s, const char *next)
2797 const char *encodingName = NULL;
2798 const XML_Char *storedEncName = NULL;
2799 const ENCODING *newEncoding = NULL;
2800 const char *version = NULL;
2801 const char *versionend;
2802 const XML_Char *storedversion = NULL;
2803 int standalone = -1;
2806 : XmlParseXmlDecl)(isGeneralTextEntity,
2816 return XML_ERROR_SYNTAX;
2817 if (!isGeneralTextEntity && standalone == 1) {
2818 dtd.standalone = XML_TRUE;
2820 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
2821 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
2822 #endif /* XML_DTD */
2824 if (xmlDeclHandler) {
2825 if (encodingName != NULL) {
2826 storedEncName = poolStoreString(&temp2Pool,
2830 + XmlNameLength(encoding, encodingName));
2832 return XML_ERROR_NO_MEMORY;
2833 poolFinish(&temp2Pool);
2836 storedversion = poolStoreString(&temp2Pool,
2839 versionend - encoding->minBytesPerChar);
2841 return XML_ERROR_NO_MEMORY;
2843 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
2845 else if (defaultHandler)
2846 reportDefault(parser, encoding, s, next);
2847 if (protocolEncodingName == NULL) {
2849 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
2850 eventPtr = encodingName;
2851 return XML_ERROR_INCORRECT_ENCODING;
2853 encoding = newEncoding;
2855 else if (encodingName) {
2856 enum XML_Error result;
2857 if (!storedEncName) {
2858 storedEncName = poolStoreString(
2859 &temp2Pool, encoding, encodingName,
2860 encodingName + XmlNameLength(encoding, encodingName));
2862 return XML_ERROR_NO_MEMORY;
2864 result = handleUnknownEncoding(parser, storedEncName);
2865 poolClear(&temp2Pool);
2866 if (result == XML_ERROR_UNKNOWN_ENCODING)
2867 eventPtr = encodingName;
2872 if (storedEncName || storedversion)
2873 poolClear(&temp2Pool);
2875 return XML_ERROR_NONE;
2878 static enum XML_Error FASTCALL
2879 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
2881 if (unknownEncodingHandler) {
2884 for (i = 0; i < 256; i++)
2886 info.convert = NULL;
2888 info.release = NULL;
2889 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
2892 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
2893 if (!unknownEncodingMem) {
2895 info.release(info.data);
2896 return XML_ERROR_NO_MEMORY;
2899 ? XmlInitUnknownEncodingNS
2900 : XmlInitUnknownEncoding)(unknownEncodingMem,
2905 unknownEncodingData = info.data;
2906 unknownEncodingRelease = info.release;
2908 return XML_ERROR_NONE;
2911 if (info.release != NULL)
2912 info.release(info.data);
2914 return XML_ERROR_UNKNOWN_ENCODING;
2917 static enum XML_Error FASTCALL
2918 prologInitProcessor(XML_Parser parser,
2921 const char **nextPtr)
2923 enum XML_Error result = initializeEncoding(parser);
2924 if (result != XML_ERROR_NONE)
2926 processor = prologProcessor;
2927 return prologProcessor(parser, s, end, nextPtr);
2932 static enum XML_Error FASTCALL
2933 externalParEntInitProcessor(XML_Parser parser,
2936 const char **nextPtr)
2938 enum XML_Error result = initializeEncoding(parser);
2939 if (result != XML_ERROR_NONE)
2942 /* we know now that XML_Parse(Buffer) has been called,
2943 so we consider the external parameter entity read */
2944 dtd.paramEntityRead = XML_TRUE;
2946 if (prologState.inEntityValue) {
2947 processor = entityValueInitProcessor;
2948 return entityValueInitProcessor(parser, s, end, nextPtr);
2951 processor = externalParEntProcessor;
2952 return externalParEntProcessor(parser, s, end, nextPtr);
2956 static enum XML_Error FASTCALL
2957 entityValueInitProcessor(XML_Parser parser,
2960 const char **nextPtr)
2962 const char *start = s;
2963 const char *next = s;
2967 tok = XmlPrologTok(encoding, start, end, &next);
2969 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
2971 return XML_ERROR_NONE;
2974 case XML_TOK_INVALID:
2975 return XML_ERROR_INVALID_TOKEN;
2976 case XML_TOK_PARTIAL:
2977 return XML_ERROR_UNCLOSED_TOKEN;
2978 case XML_TOK_PARTIAL_CHAR:
2979 return XML_ERROR_PARTIAL_CHAR;
2980 case XML_TOK_NONE: /* start == end */
2984 return storeEntityValue(parser, encoding, s, end);
2986 else if (tok == XML_TOK_XML_DECL) {
2987 enum XML_Error result = processXmlDecl(parser, 0, start, next);
2988 if (result != XML_ERROR_NONE)
2990 if (nextPtr) *nextPtr = next;
2991 /* stop scanning for text declaration - we found one */
2992 processor = entityValueProcessor;
2993 return entityValueProcessor(parser, next, end, nextPtr);
2995 /* If we are at the end of the buffer, this would cause XmlPrologTok to
2996 return XML_TOK_NONE on the next call, which would then cause the
2997 function to exit with *nextPtr set to s - that is what we want for other
2998 tokens, but not for the BOM - we would rather like to skip it;
2999 then, when this routine is entered the next time, XmlPrologTok will
3000 return XML_TOK_INVALID, since the BOM is still in the buffer
3002 else if (tok == XML_TOK_BOM && next == end && nextPtr) {
3004 return XML_ERROR_NONE;
3010 static enum XML_Error FASTCALL
3011 externalParEntProcessor(XML_Parser parser,
3014 const char **nextPtr)
3016 const char *start = s;
3017 const char *next = s;
3020 tok = XmlPrologTok(encoding, start, end, &next);
3022 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3024 return XML_ERROR_NONE;
3027 case XML_TOK_INVALID:
3028 return XML_ERROR_INVALID_TOKEN;
3029 case XML_TOK_PARTIAL:
3030 return XML_ERROR_UNCLOSED_TOKEN;
3031 case XML_TOK_PARTIAL_CHAR:
3032 return XML_ERROR_PARTIAL_CHAR;
3033 case XML_TOK_NONE: /* start == end */
3038 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3039 However, when parsing an external subset, doProlog will not accept a BOM
3040 as valid, and report a syntax error, so we have to skip the BOM
3042 else if (tok == XML_TOK_BOM) {
3044 tok = XmlPrologTok(encoding, s, end, &next);
3047 processor = prologProcessor;
3048 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3051 static enum XML_Error FASTCALL
3052 entityValueProcessor(XML_Parser parser,
3055 const char **nextPtr)
3057 const char *start = s;
3058 const char *next = s;
3059 const ENCODING *enc = encoding;
3063 tok = XmlPrologTok(enc, start, end, &next);
3065 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3067 return XML_ERROR_NONE;
3070 case XML_TOK_INVALID:
3071 return XML_ERROR_INVALID_TOKEN;
3072 case XML_TOK_PARTIAL:
3073 return XML_ERROR_UNCLOSED_TOKEN;
3074 case XML_TOK_PARTIAL_CHAR:
3075 return XML_ERROR_PARTIAL_CHAR;
3076 case XML_TOK_NONE: /* start == end */
3080 return storeEntityValue(parser, enc, s, end);
3086 #endif /* XML_DTD */
3088 static enum XML_Error FASTCALL
3089 prologProcessor(XML_Parser parser,
3092 const char **nextPtr)
3094 const char *next = s;
3095 int tok = XmlPrologTok(encoding, s, end, &next);
3096 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3099 static enum XML_Error FASTCALL
3100 doProlog(XML_Parser parser,
3101 const ENCODING *enc,
3106 const char **nextPtr)
3109 static const XML_Char externalSubsetName[] = { '#' , '\0' };
3110 #endif /* XML_DTD */
3111 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3112 static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3113 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3114 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3115 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3116 static const XML_Char atypeENTITIES[] =
3117 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3118 static const XML_Char atypeNMTOKEN[] = {
3119 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3120 static const XML_Char atypeNMTOKENS[] = {
3121 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3122 static const XML_Char notationPrefix[] = {
3123 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3124 static const XML_Char enumValueSep[] = { '|', '\0' };
3125 static const XML_Char enumValueStart[] = { '(', '\0' };
3127 const char **eventPP;
3128 const char **eventEndPP;
3129 enum XML_Content_Quant quant;
3131 if (enc == encoding) {
3132 eventPP = &eventPtr;
3133 eventEndPP = &eventEndPtr;
3136 eventPP = &(openInternalEntities->internalEventPtr);
3137 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3141 XML_Bool handleDefault = XML_TRUE;
3145 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3147 return XML_ERROR_NONE;
3150 case XML_TOK_INVALID:
3152 return XML_ERROR_INVALID_TOKEN;
3153 case XML_TOK_PARTIAL:
3154 return XML_ERROR_UNCLOSED_TOKEN;
3155 case XML_TOK_PARTIAL_CHAR:
3156 return XML_ERROR_PARTIAL_CHAR;
3159 if (enc != encoding)
3160 return XML_ERROR_NONE;
3161 if (isParamEntity) {
3162 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3164 return XML_ERROR_SYNTAX;
3165 return XML_ERROR_NONE;
3167 #endif /* XML_DTD */
3168 return XML_ERROR_NO_ELEMENTS;
3175 role = XmlTokenRole(&prologState, tok, s, next, enc);
3177 case XML_ROLE_XML_DECL:
3179 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3180 if (result != XML_ERROR_NONE)
3183 handleDefault = XML_FALSE;
3186 case XML_ROLE_DOCTYPE_NAME:
3187 if (startDoctypeDeclHandler) {
3188 doctypeName = poolStoreString(&tempPool, enc, s, next);
3190 return XML_ERROR_NO_MEMORY;
3191 poolFinish(&tempPool);
3192 doctypePubid = NULL;
3193 handleDefault = XML_FALSE;
3195 doctypeSysid = NULL; /* always initialize to NULL */
3197 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3198 if (startDoctypeDeclHandler) {
3199 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3202 poolClear(&tempPool);
3203 handleDefault = XML_FALSE;
3207 case XML_ROLE_TEXT_DECL:
3209 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3210 if (result != XML_ERROR_NONE)
3213 handleDefault = XML_FALSE;
3216 #endif /* XML_DTD */
3217 case XML_ROLE_DOCTYPE_PUBLIC_ID:
3219 useForeignDTD = XML_FALSE;
3220 #endif /* XML_DTD */
3221 dtd.hasParamEntityRefs = XML_TRUE;
3222 if (startDoctypeDeclHandler) {
3223 doctypePubid = poolStoreString(&tempPool, enc,
3224 s + enc->minBytesPerChar,
3225 next - enc->minBytesPerChar);
3227 return XML_ERROR_NO_MEMORY;
3228 poolFinish(&tempPool);
3229 handleDefault = XML_FALSE;
3232 declEntity = (ENTITY *)lookup(&dtd.paramEntities,
3236 return XML_ERROR_NO_MEMORY;
3237 #endif /* XML_DTD */
3239 case XML_ROLE_ENTITY_PUBLIC_ID:
3240 if (!XmlIsPublicId(enc, s, next, eventPP))
3241 return XML_ERROR_SYNTAX;
3242 if (dtd.keepProcessing && declEntity) {
3243 XML_Char *tem = poolStoreString(&dtd.pool,
3245 s + enc->minBytesPerChar,
3246 next - enc->minBytesPerChar);
3248 return XML_ERROR_NO_MEMORY;
3249 normalizePublicId(tem);
3250 declEntity->publicId = tem;
3251 poolFinish(&dtd.pool);
3252 if (entityDeclHandler)
3253 handleDefault = XML_FALSE;
3256 case XML_ROLE_DOCTYPE_CLOSE:
3258 startDoctypeDeclHandler(handlerArg, doctypeName,
3259 doctypeSysid, doctypePubid, 0);
3260 poolClear(&tempPool);
3261 handleDefault = XML_FALSE;
3263 /* doctypeSysid will be non-NULL in the case of a previous
3264 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3265 was not set, indicating an external subset
3268 if (doctypeSysid || useForeignDTD) {
3269 dtd.hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */
3270 if (paramEntityParsing && externalEntityRefHandler) {
3271 ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
3275 return XML_ERROR_NO_MEMORY;
3277 entity->base = curBase;
3278 dtd.paramEntityRead = XML_FALSE;
3279 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3284 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3285 if (dtd.paramEntityRead &&
3287 notStandaloneHandler &&
3288 !notStandaloneHandler(handlerArg))
3289 return XML_ERROR_NOT_STANDALONE;
3290 /* end of DTD - no need to update dtd.keepProcessing */
3292 useForeignDTD = XML_FALSE;
3294 #endif /* XML_DTD */
3295 if (endDoctypeDeclHandler) {
3296 endDoctypeDeclHandler(handlerArg);
3297 handleDefault = XML_FALSE;
3300 case XML_ROLE_INSTANCE_START:
3302 /* if there is no DOCTYPE declaration then now is the
3303 last chance to read the foreign DTD
3305 if (useForeignDTD) {
3306 dtd.hasParamEntityRefs = XML_TRUE;
3307 if (paramEntityParsing && externalEntityRefHandler) {
3308 ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
3312 return XML_ERROR_NO_MEMORY;
3313 entity->base = curBase;
3314 dtd.paramEntityRead = XML_FALSE;
3315 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3320 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3321 if (dtd.paramEntityRead &&
3323 notStandaloneHandler &&
3324 !notStandaloneHandler(handlerArg))
3325 return XML_ERROR_NOT_STANDALONE;
3326 /* end of DTD - no need to update dtd.keepProcessing */
3329 #endif /* XML_DTD */
3330 processor = contentProcessor;
3331 return contentProcessor(parser, s, end, nextPtr);
3332 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3333 declElementType = getElementType(parser, enc, s, next);
3334 if (!declElementType)
3335 return XML_ERROR_NO_MEMORY;
3336 goto checkAttListDeclHandler;
3337 case XML_ROLE_ATTRIBUTE_NAME:
3338 declAttributeId = getAttributeId(parser, enc, s, next);
3339 if (!declAttributeId)
3340 return XML_ERROR_NO_MEMORY;
3341 declAttributeIsCdata = XML_FALSE;
3342 declAttributeType = NULL;
3343 declAttributeIsId = XML_FALSE;
3344 goto checkAttListDeclHandler;
3345 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
3346 declAttributeIsCdata = XML_TRUE;
3347 declAttributeType = atypeCDATA;
3348 goto checkAttListDeclHandler;
3349 case XML_ROLE_ATTRIBUTE_TYPE_ID:
3350 declAttributeIsId = XML_TRUE;
3351 declAttributeType = atypeID;
3352 goto checkAttListDeclHandler;
3353 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
3354 declAttributeType = atypeIDREF;
3355 goto checkAttListDeclHandler;
3356 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
3357 declAttributeType = atypeIDREFS;
3358 goto checkAttListDeclHandler;
3359 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
3360 declAttributeType = atypeENTITY;
3361 goto checkAttListDeclHandler;
3362 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
3363 declAttributeType = atypeENTITIES;
3364 goto checkAttListDeclHandler;
3365 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
3366 declAttributeType = atypeNMTOKEN;
3367 goto checkAttListDeclHandler;
3368 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
3369 declAttributeType = atypeNMTOKENS;
3370 checkAttListDeclHandler:
3371 if (dtd.keepProcessing && attlistDeclHandler)
3372 handleDefault = XML_FALSE;
3374 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3375 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
3376 if (dtd.keepProcessing && attlistDeclHandler) {
3377 const XML_Char *prefix;
3378 if (declAttributeType) {
3379 prefix = enumValueSep;
3382 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3386 if (!poolAppendString(&tempPool, prefix))
3387 return XML_ERROR_NO_MEMORY;
3388 if (!poolAppend(&tempPool, enc, s, next))
3389 return XML_ERROR_NO_MEMORY;
3390 declAttributeType = tempPool.start;
3391 handleDefault = XML_FALSE;
3394 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3395 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
3396 if (dtd.keepProcessing) {
3397 if (!defineAttribute(declElementType, declAttributeId,
3398 declAttributeIsCdata, declAttributeIsId, 0,
3400 return XML_ERROR_NO_MEMORY;
3401 if (attlistDeclHandler && declAttributeType) {
3402 if (*declAttributeType == XML_T('(')
3403 || (*declAttributeType == XML_T('N')
3404 && declAttributeType[1] == XML_T('O'))) {
3405 /* Enumerated or Notation type */
3406 if (!poolAppendChar(&tempPool, XML_T(')'))
3407 || !poolAppendChar(&tempPool, XML_T('\0')))
3408 return XML_ERROR_NO_MEMORY;
3409 declAttributeType = tempPool.start;
3410 poolFinish(&tempPool);
3413 attlistDeclHandler(handlerArg, declElementType->name,
3414 declAttributeId->name, declAttributeType,
3415 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
3416 poolClear(&tempPool);
3417 handleDefault = XML_FALSE;
3421 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3422 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
3423 if (dtd.keepProcessing) {
3424 const XML_Char *attVal;
3425 enum XML_Error result
3426 = storeAttributeValue(parser, enc, declAttributeIsCdata,
3427 s + enc->minBytesPerChar,
3428 next - enc->minBytesPerChar,
3432 attVal = poolStart(&dtd.pool);
3433 poolFinish(&dtd.pool);
3434 /* ID attributes aren't allowed to have a default */
3435 if (!defineAttribute(declElementType, declAttributeId,
3436 declAttributeIsCdata, XML_FALSE, attVal, parser))
3437 return XML_ERROR_NO_MEMORY;
3438 if (attlistDeclHandler && declAttributeType) {
3439 if (*declAttributeType == XML_T('(')
3440 || (*declAttributeType == XML_T('N')
3441 && declAttributeType[1] == XML_T('O'))) {
3442 /* Enumerated or Notation type */
3443 if (!poolAppendChar(&tempPool, XML_T(')'))
3444 || !poolAppendChar(&tempPool, XML_T('\0')))
3445 return XML_ERROR_NO_MEMORY;
3446 declAttributeType = tempPool.start;
3447 poolFinish(&tempPool);
3450 attlistDeclHandler(handlerArg, declElementType->name,
3451 declAttributeId->name, declAttributeType,
3453 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
3454 poolClear(&tempPool);
3455 handleDefault = XML_FALSE;
3459 case XML_ROLE_ENTITY_VALUE:
3460 if (dtd.keepProcessing) {
3461 enum XML_Error result = storeEntityValue(parser, enc,
3462 s + enc->minBytesPerChar,
3463 next - enc->minBytesPerChar);
3465 declEntity->textPtr = poolStart(&dtd.entityValuePool);
3466 declEntity->textLen = poolLength(&dtd.entityValuePool);
3467 poolFinish(&dtd.entityValuePool);
3468 if (entityDeclHandler) {
3470 entityDeclHandler(handlerArg,
3472 declEntity->is_param,
3473 declEntity->textPtr,
3474 declEntity->textLen,
3476 handleDefault = XML_FALSE;
3480 poolDiscard(&dtd.entityValuePool);
3481 if (result != XML_ERROR_NONE)
3485 case XML_ROLE_DOCTYPE_SYSTEM_ID:
3487 useForeignDTD = XML_FALSE;
3488 #endif /* XML_DTD */
3489 dtd.hasParamEntityRefs = XML_TRUE;
3490 if (startDoctypeDeclHandler) {
3491 doctypeSysid = poolStoreString(&tempPool, enc,
3492 s + enc->minBytesPerChar,
3493 next - enc->minBytesPerChar);
3494 if (doctypeSysid == NULL)
3495 return XML_ERROR_NO_MEMORY;
3496 poolFinish(&tempPool);
3497 handleDefault = XML_FALSE;
3501 /* use externalSubsetName to make doctypeSysid non-NULL
3502 for the case where no startDoctypeDeclHandler is set */
3503 doctypeSysid = externalSubsetName;
3504 #endif /* XML_DTD */
3507 && !paramEntityParsing
3508 #endif /* XML_DTD */
3509 && notStandaloneHandler
3510 && !notStandaloneHandler(handlerArg))
3511 return XML_ERROR_NOT_STANDALONE;
3516 declEntity = (ENTITY *)lookup(&dtd.paramEntities,
3520 return XML_ERROR_NO_MEMORY;
3521 declEntity->publicId = NULL;
3524 #endif /* XML_DTD */
3525 case XML_ROLE_ENTITY_SYSTEM_ID:
3526 if (dtd.keepProcessing && declEntity) {
3527 declEntity->systemId = poolStoreString(&dtd.pool, enc,
3528 s + enc->minBytesPerChar,
3529 next - enc->minBytesPerChar);
3530 if (!declEntity->systemId)
3531 return XML_ERROR_NO_MEMORY;
3532 declEntity->base = curBase;
3533 poolFinish(&dtd.pool);
3534 if (entityDeclHandler)
3535 handleDefault = XML_FALSE;
3538 case XML_ROLE_ENTITY_COMPLETE:
3539 if (dtd.keepProcessing && declEntity && entityDeclHandler) {
3541 entityDeclHandler(handlerArg,
3543 declEntity->is_param,
3546 declEntity->systemId,
3547 declEntity->publicId,
3549 handleDefault = XML_FALSE;
3552 case XML_ROLE_ENTITY_NOTATION_NAME:
3553 if (dtd.keepProcessing && declEntity) {
3554 declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
3555 if (!declEntity->notation)
3556 return XML_ERROR_NO_MEMORY;
3557 poolFinish(&dtd.pool);
3558 if (unparsedEntityDeclHandler) {
3560 unparsedEntityDeclHandler(handlerArg,
3563 declEntity->systemId,
3564 declEntity->publicId,
3565 declEntity->notation);
3566 handleDefault = XML_FALSE;
3568 else if (entityDeclHandler) {
3570 entityDeclHandler(handlerArg,
3574 declEntity->systemId,
3575 declEntity->publicId,
3576 declEntity->notation);
3577 handleDefault = XML_FALSE;
3581 case XML_ROLE_GENERAL_ENTITY_NAME:
3583 if (XmlPredefinedEntityName(enc, s, next)) {
3587 if (dtd.keepProcessing) {
3588 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
3590 return XML_ERROR_NO_MEMORY;
3591 declEntity = (ENTITY *)lookup(&dtd.generalEntities, name,
3594 return XML_ERROR_NO_MEMORY;
3595 if (declEntity->name != name) {
3596 poolDiscard(&dtd.pool);
3600 poolFinish(&dtd.pool);
3601 declEntity->publicId = NULL;
3602 declEntity->is_param = XML_FALSE;
3603 /* if we have a parent parser or are reading an internal parameter
3604 entity, then the entity declaration is not considered "internal"
3606 declEntity->is_internal = !(parentParser || openInternalEntities);
3607 if (entityDeclHandler)
3608 handleDefault = XML_FALSE;
3612 poolDiscard(&dtd.pool);
3617 case XML_ROLE_PARAM_ENTITY_NAME:
3619 if (dtd.keepProcessing) {
3620 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
3622 return XML_ERROR_NO_MEMORY;
3623 declEntity = (ENTITY *)lookup(&dtd.paramEntities,
3624 name, sizeof(ENTITY));
3626 return XML_ERROR_NO_MEMORY;
3627 if (declEntity->name != name) {
3628 poolDiscard(&dtd.pool);
3632 poolFinish(&dtd.pool);
3633 declEntity->publicId = NULL;
3634 declEntity->is_param = XML_TRUE;
3635 /* if we have a parent parser or are reading an internal parameter
3636 entity, then the entity declaration is not considered "internal"
3638 declEntity->is_internal = !(parentParser || openInternalEntities);
3639 if (entityDeclHandler)
3640 handleDefault = XML_FALSE;
3644 poolDiscard(&dtd.pool);
3647 #else /* not XML_DTD */
3649 #endif /* XML_DTD */
3651 case XML_ROLE_NOTATION_NAME:
3652 declNotationPublicId = NULL;
3653 declNotationName = NULL;
3654 if (notationDeclHandler) {
3655 declNotationName = poolStoreString(&tempPool, enc, s, next);
3656 if (!declNotationName)
3657 return XML_ERROR_NO_MEMORY;
3658 poolFinish(&tempPool);
3659 handleDefault = XML_FALSE;
3662 case XML_ROLE_NOTATION_PUBLIC_ID:
3663 if (!XmlIsPublicId(enc, s, next, eventPP))
3664 return XML_ERROR_SYNTAX;
3665 if (declNotationName) { /* means notationDeclHandler != NULL */
3666 XML_Char *tem = poolStoreString(&tempPool,
3668 s + enc->minBytesPerChar,
3669 next - enc->minBytesPerChar);
3671 return XML_ERROR_NO_MEMORY;
3672 normalizePublicId(tem);
3673 declNotationPublicId = tem;
3674 poolFinish(&tempPool);
3675 handleDefault = XML_FALSE;
3678 case XML_ROLE_NOTATION_SYSTEM_ID:
3679 if (declNotationName && notationDeclHandler) {
3680 const XML_Char *systemId
3681 = poolStoreString(&tempPool, enc,
3682 s + enc->minBytesPerChar,
3683 next - enc->minBytesPerChar);
3685 return XML_ERROR_NO_MEMORY;
3687 notationDeclHandler(handlerArg,
3691 declNotationPublicId);
3692 handleDefault = XML_FALSE;
3694 poolClear(&tempPool);
3696 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
3697 if (declNotationPublicId && notationDeclHandler) {
3699 notationDeclHandler(handlerArg,
3703 declNotationPublicId);
3704 handleDefault = XML_FALSE;
3706 poolClear(&tempPool);
3708 case XML_ROLE_ERROR:
3710 case XML_TOK_PARAM_ENTITY_REF:
3711 return XML_ERROR_PARAM_ENTITY_REF;
3712 case XML_TOK_XML_DECL:
3713 return XML_ERROR_MISPLACED_XML_PI;
3715 return XML_ERROR_SYNTAX;
3718 case XML_ROLE_IGNORE_SECT:
3720 enum XML_Error result;
3722 reportDefault(parser, enc, s, next);
3723 handleDefault = XML_FALSE;
3724 result = doIgnoreSection(parser, enc, &next, end, nextPtr);
3726 processor = ignoreSectionProcessor;
3731 #endif /* XML_DTD */
3732 case XML_ROLE_GROUP_OPEN:
3733 if (prologState.level >= groupSize) {
3735 char *temp = REALLOC(groupConnector, groupSize *= 2);
3737 return XML_ERROR_NO_MEMORY;
3738 groupConnector = temp;
3739 if (dtd.scaffIndex) {
3740 int *temp = REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
3742 return XML_ERROR_NO_MEMORY;
3743 dtd.scaffIndex = temp;
3747 groupConnector = MALLOC(groupSize = 32);
3748 if (!groupConnector)
3749 return XML_ERROR_NO_MEMORY;
3752 groupConnector[prologState.level] = 0;
3753 if (dtd.in_eldecl) {
3754 int myindex = nextScaffoldPart(parser);
3756 return XML_ERROR_NO_MEMORY;
3757 dtd.scaffIndex[dtd.scaffLevel] = myindex;
3759 dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
3760 if (elementDeclHandler)
3761 handleDefault = XML_FALSE;
3764 case XML_ROLE_GROUP_SEQUENCE:
3765 if (groupConnector[prologState.level] == '|')
3766 return XML_ERROR_SYNTAX;
3767 groupConnector[prologState.level] = ',';
3768 if (dtd.in_eldecl && elementDeclHandler)
3769 handleDefault = XML_FALSE;
3771 case XML_ROLE_GROUP_CHOICE:
3772 if (groupConnector[prologState.level] == ',')
3773 return XML_ERROR_SYNTAX;
3775 && !groupConnector[prologState.level]
3776 && (dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type
3779 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type
3781 if (elementDeclHandler)
3782 handleDefault = XML_FALSE;
3784 groupConnector[prologState.level] = '|';
3786 case XML_ROLE_PARAM_ENTITY_REF:
3788 case XML_ROLE_INNER_PARAM_ENTITY_REF:
3789 /* PE references in internal subset are
3790 not allowed within declarations */
3791 if (prologState.documentEntity &&
3792 role == XML_ROLE_INNER_PARAM_ENTITY_REF)
3793 return XML_ERROR_PARAM_ENTITY_REF;
3794 dtd.hasParamEntityRefs = XML_TRUE;
3795 if (!paramEntityParsing)
3796 dtd.keepProcessing = dtd.standalone;
3798 const XML_Char *name;
3800 name = poolStoreString(&dtd.pool, enc,
3801 s + enc->minBytesPerChar,
3802 next - enc->minBytesPerChar);
3804 return XML_ERROR_NO_MEMORY;
3805 entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
3806 poolDiscard(&dtd.pool);
3807 /* first, determine if a check for an existing declaration is needed;
3808 if yes, check that the entity exists, and that it is internal,
3809 otherwise call the skipped entity handler
3811 if (prologState.documentEntity &&
3813 ? !openInternalEntities
3814 : !dtd.hasParamEntityRefs)) {
3816 return XML_ERROR_UNDEFINED_ENTITY;
3817 else if (!entity->is_internal)
3818 return XML_ERROR_ENTITY_DECLARED_IN_PE;
3821 dtd.keepProcessing = dtd.standalone;
3822 /* cannot report skipped entities in declarations */
3823 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
3824 skippedEntityHandler(handlerArg, name, 1);
3825 handleDefault = XML_FALSE;
3830 return XML_ERROR_RECURSIVE_ENTITY_REF;
3831 if (entity->textPtr) {
3832 enum XML_Error result;
3833 result = processInternalParamEntity(parser, entity);
3834 if (result != XML_ERROR_NONE)
3836 handleDefault = XML_FALSE;
3839 if (externalEntityRefHandler) {
3840 dtd.paramEntityRead = XML_FALSE;
3841 entity->open = XML_TRUE;
3842 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3846 entity->publicId)) {
3847 entity->open = XML_FALSE;
3848 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3850 entity->open = XML_FALSE;
3851 handleDefault = XML_FALSE;
3852 if (!dtd.paramEntityRead) {
3853 dtd.keepProcessing = dtd.standalone;
3858 dtd.keepProcessing = dtd.standalone;
3862 #endif /* XML_DTD */
3863 if (!dtd.standalone &&
3864 notStandaloneHandler &&
3865 !notStandaloneHandler(handlerArg))
3866 return XML_ERROR_NOT_STANDALONE;
3869 /* Element declaration stuff */
3871 case XML_ROLE_ELEMENT_NAME:
3872 if (elementDeclHandler) {
3873 declElementType = getElementType(parser, enc, s, next);
3874 if (!declElementType)
3875 return XML_ERROR_NO_MEMORY;
3878 dtd.in_eldecl = XML_TRUE;
3879 handleDefault = XML_FALSE;
3883 case XML_ROLE_CONTENT_ANY:
3884 case XML_ROLE_CONTENT_EMPTY:
3885 if (dtd.in_eldecl) {
3886 if (elementDeclHandler) {
3887 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
3889 return XML_ERROR_NO_MEMORY;
3890 content->quant = XML_CQUANT_NONE;
3891 content->name = NULL;
3892 content->numchildren = 0;
3893 content->children = NULL;
3894 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
3898 elementDeclHandler(handlerArg, declElementType->name, content);
3899 handleDefault = XML_FALSE;
3901 dtd.in_eldecl = XML_FALSE;
3905 case XML_ROLE_CONTENT_PCDATA:
3906 if (dtd.in_eldecl) {
3907 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type
3909 if (elementDeclHandler)
3910 handleDefault = XML_FALSE;
3914 case XML_ROLE_CONTENT_ELEMENT:
3915 quant = XML_CQUANT_NONE;
3916 goto elementContent;
3917 case XML_ROLE_CONTENT_ELEMENT_OPT:
3918 quant = XML_CQUANT_OPT;
3919 goto elementContent;
3920 case XML_ROLE_CONTENT_ELEMENT_REP:
3921 quant = XML_CQUANT_REP;
3922 goto elementContent;
3923 case XML_ROLE_CONTENT_ELEMENT_PLUS:
3924 quant = XML_CQUANT_PLUS;
3926 if (dtd.in_eldecl) {
3928 const XML_Char *name;
3930 const char *nxt = (quant == XML_CQUANT_NONE
3932 : next - enc->minBytesPerChar);
3933 int myindex = nextScaffoldPart(parser);
3935 return XML_ERROR_NO_MEMORY;
3936 dtd.scaffold[myindex].type = XML_CTYPE_NAME;
3937 dtd.scaffold[myindex].quant = quant;
3938 el = getElementType(parser, enc, s, nxt);
3940 return XML_ERROR_NO_MEMORY;
3942 dtd.scaffold[myindex].name = name;
3944 for (; name[nameLen++]; );
3945 dtd.contentStringLen += nameLen;
3946 if (elementDeclHandler)
3947 handleDefault = XML_FALSE;
3951 case XML_ROLE_GROUP_CLOSE:
3952 quant = XML_CQUANT_NONE;
3954 case XML_ROLE_GROUP_CLOSE_OPT:
3955 quant = XML_CQUANT_OPT;
3957 case XML_ROLE_GROUP_CLOSE_REP:
3958 quant = XML_CQUANT_REP;
3960 case XML_ROLE_GROUP_CLOSE_PLUS:
3961 quant = XML_CQUANT_PLUS;
3963 if (dtd.in_eldecl) {
3964 if (elementDeclHandler)
3965 handleDefault = XML_FALSE;
3967 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
3968 if (dtd.scaffLevel == 0) {
3969 if (!handleDefault) {
3970 XML_Content *model = build_model(parser);
3972 return XML_ERROR_NO_MEMORY;
3974 elementDeclHandler(handlerArg, declElementType->name, model);
3976 dtd.in_eldecl = XML_FALSE;
3977 dtd.contentStringLen = 0;
3981 /* End element declaration stuff */
3984 if (!reportProcessingInstruction(parser, enc, s, next))
3985 return XML_ERROR_NO_MEMORY;
3986 handleDefault = XML_FALSE;
3988 case XML_ROLE_COMMENT:
3989 if (!reportComment(parser, enc, s, next))
3990 return XML_ERROR_NO_MEMORY;
3991 handleDefault = XML_FALSE;
3996 handleDefault = XML_FALSE;
4000 case XML_ROLE_DOCTYPE_NONE:
4001 if (startDoctypeDeclHandler)
4002 handleDefault = XML_FALSE;
4004 case XML_ROLE_ENTITY_NONE:
4005 if (dtd.keepProcessing && entityDeclHandler)
4006 handleDefault = XML_FALSE;
4008 case XML_ROLE_NOTATION_NONE:
4009 if (notationDeclHandler)
4010 handleDefault = XML_FALSE;
4012 case XML_ROLE_ATTLIST_NONE:
4013 if (dtd.keepProcessing && attlistDeclHandler)
4014 handleDefault = XML_FALSE;
4016 case XML_ROLE_ELEMENT_NONE:
4017 if (elementDeclHandler)
4018 handleDefault = XML_FALSE;
4020 } /* end of big switch */
4022 if (handleDefault && defaultHandler)
4023 reportDefault(parser, enc, s, next);
4026 tok = XmlPrologTok(enc, s, end, &next);
4031 static enum XML_Error FASTCALL
4032 epilogProcessor(XML_Parser parser,
4035 const char **nextPtr)
4037 processor = epilogProcessor;
4040 const char *next = NULL;
4041 int tok = XmlPrologTok(encoding, s, end, &next);
4044 /* report partial linebreak - it might be the last token */
4045 case -XML_TOK_PROLOG_S:
4046 if (defaultHandler) {
4048 reportDefault(parser, encoding, s, next);
4052 return XML_ERROR_NONE;
4056 return XML_ERROR_NONE;
4057 case XML_TOK_PROLOG_S:
4059 reportDefault(parser, encoding, s, next);
4062 if (!reportProcessingInstruction(parser, encoding, s, next))
4063 return XML_ERROR_NO_MEMORY;
4065 case XML_TOK_COMMENT:
4066 if (!reportComment(parser, encoding, s, next))
4067 return XML_ERROR_NO_MEMORY;
4069 case XML_TOK_INVALID:
4071 return XML_ERROR_INVALID_TOKEN;
4072 case XML_TOK_PARTIAL:
4075 return XML_ERROR_NONE;
4077 return XML_ERROR_UNCLOSED_TOKEN;
4078 case XML_TOK_PARTIAL_CHAR:
4081 return XML_ERROR_NONE;
4083 return XML_ERROR_PARTIAL_CHAR;
4085 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4087 eventPtr = s = next;
4093 static enum XML_Error FASTCALL
4094 processInternalParamEntity(XML_Parser parser, ENTITY *entity)
4096 const char *s, *end, *next;
4098 enum XML_Error result;
4099 OPEN_INTERNAL_ENTITY openEntity;
4100 entity->open = XML_TRUE;
4101 openEntity.next = openInternalEntities;
4102 openInternalEntities = &openEntity;
4103 openEntity.entity = entity;
4104 openEntity.internalEventPtr = NULL;
4105 openEntity.internalEventEndPtr = NULL;
4106 s = (char *)entity->textPtr;
4107 end = (char *)(entity->textPtr + entity->textLen);
4108 tok = XmlPrologTok(internalEncoding, s, end, &next);
4109 result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
4110 entity->open = XML_FALSE;
4111 openInternalEntities = openEntity.next;
4115 #endif /* XML_DTD */
4117 static enum XML_Error FASTCALL
4118 errorProcessor(XML_Parser parser,
4121 const char **nextPtr)
4126 static enum XML_Error FASTCALL
4127 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4128 const char *ptr, const char *end,
4131 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4135 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4137 if (!poolAppendChar(pool, XML_T('\0')))
4138 return XML_ERROR_NO_MEMORY;
4139 return XML_ERROR_NONE;
4142 static enum XML_Error FASTCALL
4143 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4144 const char *ptr, const char *end,
4149 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4152 return XML_ERROR_NONE;
4153 case XML_TOK_INVALID:
4154 if (enc == encoding)
4156 return XML_ERROR_INVALID_TOKEN;
4157 case XML_TOK_PARTIAL:
4158 if (enc == encoding)
4160 return XML_ERROR_INVALID_TOKEN;
4161 case XML_TOK_CHAR_REF:
4163 XML_Char buf[XML_ENCODE_MAX];
4165 int n = XmlCharRefNumber(enc, ptr);
4167 if (enc == encoding)
4169 return XML_ERROR_BAD_CHAR_REF;
4172 && n == 0x20 /* space */
4173 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4175 n = XmlEncode(n, (ICHAR *)buf);
4177 if (enc == encoding)
4179 return XML_ERROR_BAD_CHAR_REF;
4181 for (i = 0; i < n; i++) {
4182 if (!poolAppendChar(pool, buf[i]))
4183 return XML_ERROR_NO_MEMORY;
4187 case XML_TOK_DATA_CHARS:
4188 if (!poolAppend(pool, enc, ptr, next))
4189 return XML_ERROR_NO_MEMORY;
4191 case XML_TOK_TRAILING_CR:
4192 next = ptr + enc->minBytesPerChar;
4194 case XML_TOK_ATTRIBUTE_VALUE_S:
4195 case XML_TOK_DATA_NEWLINE:
4196 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4198 if (!poolAppendChar(pool, 0x20))
4199 return XML_ERROR_NO_MEMORY;
4201 case XML_TOK_ENTITY_REF:
4203 const XML_Char *name;
4205 char checkEntityDecl;
4206 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4207 ptr + enc->minBytesPerChar,
4208 next - enc->minBytesPerChar);
4210 if (!poolAppendChar(pool, ch))
4211 return XML_ERROR_NO_MEMORY;
4214 name = poolStoreString(&temp2Pool, enc,
4215 ptr + enc->minBytesPerChar,
4216 next - enc->minBytesPerChar);
4218 return XML_ERROR_NO_MEMORY;
4219 entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
4220 poolDiscard(&temp2Pool);
4221 /* first, determine if a check for an existing declaration is needed;
4222 if yes, check that the entity exists, and that it is internal,
4223 otherwise call the default handler (if called from content)
4225 if (pool == &dtd.pool) /* are we called from prolog? */
4228 prologState.documentEntity &&
4229 #endif /* XML_DTD */
4231 ? !openInternalEntities
4232 : !dtd.hasParamEntityRefs);
4233 else /* if (pool == &tempPool): we are called from content */
4234 checkEntityDecl = !dtd.hasParamEntityRefs || dtd.standalone;
4235 if (checkEntityDecl) {
4237 return XML_ERROR_UNDEFINED_ENTITY;
4238 else if (!entity->is_internal)
4239 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4242 /* cannot report skipped entity here - see comments on
4243 skippedEntityHandler
4244 if (skippedEntityHandler)
4245 skippedEntityHandler(handlerArg, name, 0);
4247 if ((pool == &tempPool) && defaultHandler)
4248 reportDefault(parser, enc, ptr, next);
4252 if (enc == encoding)
4254 return XML_ERROR_RECURSIVE_ENTITY_REF;
4256 if (entity->notation) {
4257 if (enc == encoding)
4259 return XML_ERROR_BINARY_ENTITY_REF;
4261 if (!entity->textPtr) {
4262 if (enc == encoding)
4264 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4267 enum XML_Error result;
4268 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4269 entity->open = XML_TRUE;
4270 result = appendAttributeValue(parser, internalEncoding, isCdata,
4271 (char *)entity->textPtr,
4272 (char *)textEnd, pool);
4273 entity->open = XML_FALSE;
4280 if (enc == encoding)
4282 return XML_ERROR_UNEXPECTED_STATE;
4289 static enum XML_Error FASTCALL
4290 storeEntityValue(XML_Parser parser,
4291 const ENCODING *enc,
4292 const char *entityTextPtr,
4293 const char *entityTextEnd)
4295 STRING_POOL *pool = &(dtd.entityValuePool);
4296 enum XML_Error result = XML_ERROR_NONE;
4298 int oldInEntityValue = prologState.inEntityValue;
4299 prologState.inEntityValue = 1;
4300 #endif /* XML_DTD */
4301 /* never return Null for the value argument in EntityDeclHandler,
4302 since this would indicate an external entity; therefore we
4303 have to make sure that entityValuePool.start is not null */
4304 if (!pool->blocks) {
4305 if (!poolGrow(pool))
4306 return XML_ERROR_NO_MEMORY;
4311 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4313 case XML_TOK_PARAM_ENTITY_REF:
4315 if (isParamEntity || enc != encoding) {
4316 const XML_Char *name;
4318 name = poolStoreString(&tempPool, enc,
4319 entityTextPtr + enc->minBytesPerChar,
4320 next - enc->minBytesPerChar);
4322 result = XML_ERROR_NO_MEMORY;
4323 goto endEntityValue;
4325 entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
4326 poolDiscard(&tempPool);
4328 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4329 /* cannot report skipped entity here - see comments on
4330 skippedEntityHandler
4331 if (skippedEntityHandler)
4332 skippedEntityHandler(handlerArg, name, 0);
4334 dtd.keepProcessing = dtd.standalone;
4335 goto endEntityValue;
4338 if (enc == encoding)
4339 eventPtr = entityTextPtr;
4340 result = XML_ERROR_RECURSIVE_ENTITY_REF;
4341 goto endEntityValue;
4343 if (entity->systemId) {
4344 if (externalEntityRefHandler) {
4345 dtd.paramEntityRead = XML_FALSE;
4346 entity->open = XML_TRUE;
4347 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4351 entity->publicId)) {
4352 entity->open = XML_FALSE;
4353 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4354 goto endEntityValue;
4356 entity->open = XML_FALSE;
4357 if (!dtd.paramEntityRead)
4358 dtd.keepProcessing = dtd.standalone;
4361 dtd.keepProcessing = dtd.standalone;
4364 entity->open = XML_TRUE;
4365 result = storeEntityValue(parser,
4367 (char *)entity->textPtr,
4368 (char *)(entity->textPtr
4369 + entity->textLen));
4370 entity->open = XML_FALSE;
4372 goto endEntityValue;
4376 #endif /* XML_DTD */
4377 /* in the internal subset, PE references are not legal
4378 within markup declarations, e.g entity values in this case */
4379 eventPtr = entityTextPtr;
4380 result = XML_ERROR_PARAM_ENTITY_REF;
4381 goto endEntityValue;
4383 result = XML_ERROR_NONE;
4384 goto endEntityValue;
4385 case XML_TOK_ENTITY_REF:
4386 case XML_TOK_DATA_CHARS:
4387 if (!poolAppend(pool, enc, entityTextPtr, next)) {
4388 result = XML_ERROR_NO_MEMORY;
4389 goto endEntityValue;
4392 case XML_TOK_TRAILING_CR:
4393 next = entityTextPtr + enc->minBytesPerChar;
4395 case XML_TOK_DATA_NEWLINE:
4396 if (pool->end == pool->ptr && !poolGrow(pool)) {
4397 result = XML_ERROR_NO_MEMORY;
4398 goto endEntityValue;
4400 *(pool->ptr)++ = 0xA;
4402 case XML_TOK_CHAR_REF:
4404 XML_Char buf[XML_ENCODE_MAX];
4406 int n = XmlCharRefNumber(enc, entityTextPtr);
4408 if (enc == encoding)
4409 eventPtr = entityTextPtr;
4410 result = XML_ERROR_BAD_CHAR_REF;
4411 goto endEntityValue;
4413 n = XmlEncode(n, (ICHAR *)buf);
4415 if (enc == encoding)
4416 eventPtr = entityTextPtr;
4417 result = XML_ERROR_BAD_CHAR_REF;
4418 goto endEntityValue;
4420 for (i = 0; i < n; i++) {
4421 if (pool->end == pool->ptr && !poolGrow(pool)) {
4422 result = XML_ERROR_NO_MEMORY;
4423 goto endEntityValue;
4425 *(pool->ptr)++ = buf[i];
4429 case XML_TOK_PARTIAL:
4430 if (enc == encoding)
4431 eventPtr = entityTextPtr;
4432 result = XML_ERROR_INVALID_TOKEN;
4433 goto endEntityValue;
4434 case XML_TOK_INVALID:
4435 if (enc == encoding)
4437 result = XML_ERROR_INVALID_TOKEN;
4438 goto endEntityValue;
4440 if (enc == encoding)
4441 eventPtr = entityTextPtr;
4442 result = XML_ERROR_UNEXPECTED_STATE;
4443 goto endEntityValue;
4445 entityTextPtr = next;
4449 prologState.inEntityValue = oldInEntityValue;
4450 #endif /* XML_DTD */
4454 static void FASTCALL
4455 normalizeLines(XML_Char *s)
4459 if (*s == XML_T('\0'))
4478 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
4479 const char *start, const char *end)
4481 const XML_Char *target;
4484 if (!processingInstructionHandler) {
4486 reportDefault(parser, enc, start, end);
4489 start += enc->minBytesPerChar * 2;
4490 tem = start + XmlNameLength(enc, start);
4491 target = poolStoreString(&tempPool, enc, start, tem);
4494 poolFinish(&tempPool);
4495 data = poolStoreString(&tempPool, enc,
4497 end - enc->minBytesPerChar*2);
4500 normalizeLines(data);
4501 processingInstructionHandler(handlerArg, target, data);
4502 poolClear(&tempPool);
4507 reportComment(XML_Parser parser, const ENCODING *enc,
4508 const char *start, const char *end)
4511 if (!commentHandler) {
4513 reportDefault(parser, enc, start, end);
4516 data = poolStoreString(&tempPool,
4518 start + enc->minBytesPerChar * 4,
4519 end - enc->minBytesPerChar * 3);
4522 normalizeLines(data);
4523 commentHandler(handlerArg, data);
4524 poolClear(&tempPool);
4528 static void FASTCALL
4529 reportDefault(XML_Parser parser, const ENCODING *enc,
4530 const char *s, const char *end)
4532 if (MUST_CONVERT(enc, s)) {
4533 const char **eventPP;
4534 const char **eventEndPP;
4535 if (enc == encoding) {
4536 eventPP = &eventPtr;
4537 eventEndPP = &eventEndPtr;
4540 eventPP = &(openInternalEntities->internalEventPtr);
4541 eventEndPP = &(openInternalEntities->internalEventEndPtr);
4544 ICHAR *dataPtr = (ICHAR *)dataBuf;
4545 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
4547 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
4552 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
4557 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
4558 XML_Bool isId, const XML_Char *value, XML_Parser parser)
4560 DEFAULT_ATTRIBUTE *att;
4561 if (value || isId) {
4562 /* The handling of default attributes gets messed up if we have
4563 a default which duplicates a non-default. */
4565 for (i = 0; i < type->nDefaultAtts; i++)
4566 if (attId == type->defaultAtts[i].id)
4568 if (isId && !type->idAtt && !attId->xmlns)
4569 type->idAtt = attId;
4571 if (type->nDefaultAtts == type->allocDefaultAtts) {
4572 if (type->allocDefaultAtts == 0) {
4573 type->allocDefaultAtts = 8;
4574 type->defaultAtts = MALLOC(type->allocDefaultAtts
4575 * sizeof(DEFAULT_ATTRIBUTE));
4576 if (!type->defaultAtts)
4580 DEFAULT_ATTRIBUTE *temp;
4581 int count = type->allocDefaultAtts * 2;
4582 temp = REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
4585 type->allocDefaultAtts = count;
4586 type->defaultAtts = temp;
4589 att = type->defaultAtts + type->nDefaultAtts;
4592 att->isCdata = isCdata;
4594 attId->maybeTokenized = XML_TRUE;
4595 type->nDefaultAtts += 1;
4600 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
4602 const XML_Char *name;
4603 for (name = elementType->name; *name; name++) {
4604 if (*name == XML_T(':')) {
4607 for (s = elementType->name; s != name; s++) {
4608 if (!poolAppendChar(&dtd.pool, *s))
4611 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
4613 prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool),
4617 if (prefix->name == poolStart(&dtd.pool))
4618 poolFinish(&dtd.pool);
4620 poolDiscard(&dtd.pool);
4621 elementType->prefix = prefix;
4628 static ATTRIBUTE_ID * FASTCALL
4629 getAttributeId(XML_Parser parser, const ENCODING *enc,
4630 const char *start, const char *end)
4633 const XML_Char *name;
4634 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
4636 name = poolStoreString(&dtd.pool, enc, start, end);
4640 id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
4643 if (id->name != name)
4644 poolDiscard(&dtd.pool);
4646 poolFinish(&dtd.pool);
4649 else if (name[0] == 'x'
4654 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
4655 if (name[5] == '\0')
4656 id->prefix = &dtd.defaultPrefix;
4658 id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
4659 id->xmlns = XML_TRUE;
4663 for (i = 0; name[i]; i++) {
4664 if (name[i] == XML_T(':')) {
4666 for (j = 0; j < i; j++) {
4667 if (!poolAppendChar(&dtd.pool, name[j]))
4670 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
4672 id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool),
4674 if (id->prefix->name == poolStart(&dtd.pool))
4675 poolFinish(&dtd.pool);
4677 poolDiscard(&dtd.pool);
4686 #define CONTEXT_SEP XML_T('\f')
4688 static const XML_Char * FASTCALL
4689 getContext(XML_Parser parser)
4691 HASH_TABLE_ITER iter;
4692 XML_Bool needSep = XML_FALSE;
4694 if (dtd.defaultPrefix.binding) {
4697 if (!poolAppendChar(&tempPool, XML_T('=')))
4699 len = dtd.defaultPrefix.binding->uriLen;
4700 if (namespaceSeparator != XML_T('\0'))
4702 for (i = 0; i < len; i++)
4703 if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
4708 hashTableIterInit(&iter, &(dtd.prefixes));
4713 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
4716 if (!prefix->binding)
4718 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
4720 for (s = prefix->name; *s; s++)
4721 if (!poolAppendChar(&tempPool, *s))
4723 if (!poolAppendChar(&tempPool, XML_T('=')))
4725 len = prefix->binding->uriLen;
4726 if (namespaceSeparator != XML_T('\0'))
4728 for (i = 0; i < len; i++)
4729 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
4735 hashTableIterInit(&iter, &(dtd.generalEntities));
4738 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
4743 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
4745 for (s = e->name; *s; s++)
4746 if (!poolAppendChar(&tempPool, *s))
4751 if (!poolAppendChar(&tempPool, XML_T('\0')))
4753 return tempPool.start;
4756 static XML_Bool FASTCALL
4757 setContext(XML_Parser parser, const XML_Char *context)
4759 const XML_Char *s = context;
4761 while (*context != XML_T('\0')) {
4762 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
4764 if (!poolAppendChar(&tempPool, XML_T('\0')))
4766 e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
4769 if (*s != XML_T('\0'))
4772 poolDiscard(&tempPool);
4774 else if (*s == XML_T('=')) {
4776 if (poolLength(&tempPool) == 0)
4777 prefix = &dtd.defaultPrefix;
4779 if (!poolAppendChar(&tempPool, XML_T('\0')))
4781 prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool),
4785 if (prefix->name == poolStart(&tempPool)) {
4786 prefix->name = poolCopyString(&dtd.pool, prefix->name);
4790 poolDiscard(&tempPool);
4792 for (context = s + 1;
4793 *context != CONTEXT_SEP && *context != XML_T('\0');
4795 if (!poolAppendChar(&tempPool, *context))
4797 if (!poolAppendChar(&tempPool, XML_T('\0')))
4799 if (!addBinding(parser, prefix, 0, poolStart(&tempPool),
4800 &inheritedBindings))
4802 poolDiscard(&tempPool);
4803 if (*context != XML_T('\0'))
4808 if (!poolAppendChar(&tempPool, *s))
4816 static void FASTCALL
4817 normalizePublicId(XML_Char *publicId)
4819 XML_Char *p = publicId;
4821 for (s = publicId; *s; s++) {
4826 if (p != publicId && p[-1] != 0x20)
4833 if (p != publicId && p[-1] == 0x20)
4838 static void FASTCALL
4839 dtdInit(DTD *p, XML_Parser parser)
4841 XML_Memory_Handling_Suite *ms = &parser->m_mem;
4842 poolInit(&(p->pool), ms);
4844 poolInit(&(p->entityValuePool), ms);
4845 #endif /* XML_DTD */
4846 hashTableInit(&(p->generalEntities), ms);
4847 hashTableInit(&(p->elementTypes), ms);
4848 hashTableInit(&(p->attributeIds), ms);
4849 hashTableInit(&(p->prefixes), ms);
4851 p->paramEntityRead = XML_FALSE;
4852 hashTableInit(&(p->paramEntities), ms);
4853 #endif /* XML_DTD */
4854 p->defaultPrefix.name = NULL;
4855 p->defaultPrefix.binding = NULL;
4857 p->in_eldecl = XML_FALSE;
4858 p->scaffIndex = NULL;
4863 p->contentStringLen = 0;
4865 p->keepProcessing = XML_TRUE;
4866 p->hasParamEntityRefs = XML_FALSE;
4867 p->standalone = XML_FALSE;
4872 static void FASTCALL
4873 dtdSwap(DTD *p1, DTD *p2)
4876 memcpy(&tem, p1, sizeof(DTD));
4877 memcpy(p1, p2, sizeof(DTD));
4878 memcpy(p2, &tem, sizeof(DTD));
4881 #endif /* XML_DTD */
4883 static void FASTCALL
4884 dtdReset(DTD *p, XML_Parser parser)
4886 HASH_TABLE_ITER iter;
4887 hashTableIterInit(&iter, &(p->elementTypes));
4889 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4892 if (e->allocDefaultAtts != 0)
4893 FREE(e->defaultAtts);
4895 hashTableClear(&(p->generalEntities));
4897 p->paramEntityRead = XML_FALSE;
4898 hashTableClear(&(p->paramEntities));
4899 #endif /* XML_DTD */
4900 hashTableClear(&(p->elementTypes));
4901 hashTableClear(&(p->attributeIds));
4902 hashTableClear(&(p->prefixes));
4903 poolClear(&(p->pool));
4905 poolClear(&(p->entityValuePool));
4906 #endif /* XML_DTD */
4907 p->defaultPrefix.name = NULL;
4908 p->defaultPrefix.binding = NULL;
4910 p->in_eldecl = XML_FALSE;
4911 if (p->scaffIndex) {
4912 FREE(p->scaffIndex);
4913 p->scaffIndex = NULL;
4922 p->contentStringLen = 0;
4924 p->keepProcessing = XML_TRUE;
4925 p->hasParamEntityRefs = XML_FALSE;
4926 p->standalone = XML_FALSE;
4929 static void FASTCALL
4930 dtdDestroy(DTD *p, XML_Parser parser)
4932 HASH_TABLE_ITER iter;
4933 hashTableIterInit(&iter, &(p->elementTypes));
4935 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4938 if (e->allocDefaultAtts != 0)
4939 FREE(e->defaultAtts);
4941 hashTableDestroy(&(p->generalEntities));
4943 hashTableDestroy(&(p->paramEntities));
4944 #endif /* XML_DTD */
4945 hashTableDestroy(&(p->elementTypes));
4946 hashTableDestroy(&(p->attributeIds));
4947 hashTableDestroy(&(p->prefixes));
4948 poolDestroy(&(p->pool));
4950 poolDestroy(&(p->entityValuePool));
4951 #endif /* XML_DTD */
4952 if (!parentParser) {
4954 FREE(p->scaffIndex);
4960 /* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.
4961 The new DTD has already been initialized.
4964 dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser)
4966 HASH_TABLE_ITER iter;
4968 /* Copy the prefix table. */
4970 hashTableIterInit(&iter, &(oldDtd->prefixes));
4972 const XML_Char *name;
4973 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
4976 name = poolCopyString(&(newDtd->pool), oldP->name);
4979 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
4983 hashTableIterInit(&iter, &(oldDtd->attributeIds));
4985 /* Copy the attribute id table. */
4989 const XML_Char *name;
4990 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
4994 /* Remember to allocate the scratch byte before the name. */
4995 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
4997 name = poolCopyString(&(newDtd->pool), oldA->name);
5001 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5002 sizeof(ATTRIBUTE_ID));
5005 newA->maybeTokenized = oldA->maybeTokenized;
5007 newA->xmlns = oldA->xmlns;
5008 if (oldA->prefix == &oldDtd->defaultPrefix)
5009 newA->prefix = &newDtd->defaultPrefix;
5011 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5012 oldA->prefix->name, 0);
5016 /* Copy the element type table. */
5018 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5023 const XML_Char *name;
5024 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5027 name = poolCopyString(&(newDtd->pool), oldE->name);
5030 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5031 sizeof(ELEMENT_TYPE));
5034 if (oldE->nDefaultAtts) {
5035 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5036 MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5037 if (!newE->defaultAtts) {
5043 newE->idAtt = (ATTRIBUTE_ID *)
5044 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
5045 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5047 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5048 oldE->prefix->name, 0);
5049 for (i = 0; i < newE->nDefaultAtts; i++) {
5050 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5051 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5052 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5053 if (oldE->defaultAtts[i].value) {
5054 newE->defaultAtts[i].value
5055 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5056 if (!newE->defaultAtts[i].value)
5060 newE->defaultAtts[i].value = NULL;
5064 /* Copy the entity tables. */
5065 if (!copyEntityTable(&(newDtd->generalEntities),
5067 &(oldDtd->generalEntities), parser))
5071 if (!copyEntityTable(&(newDtd->paramEntities),
5073 &(oldDtd->paramEntities), parser))
5075 newDtd->paramEntityRead = oldDtd->paramEntityRead;
5076 #endif /* XML_DTD */
5078 newDtd->keepProcessing = oldDtd->keepProcessing;
5079 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
5080 newDtd->standalone = oldDtd->standalone;
5082 /* Don't want deep copying for scaffolding */
5083 newDtd->in_eldecl = oldDtd->in_eldecl;
5084 newDtd->scaffold = oldDtd->scaffold;
5085 newDtd->contentStringLen = oldDtd->contentStringLen;
5086 newDtd->scaffSize = oldDtd->scaffSize;
5087 newDtd->scaffLevel = oldDtd->scaffLevel;
5088 newDtd->scaffIndex = oldDtd->scaffIndex;
5094 copyEntityTable(HASH_TABLE *newTable,
5095 STRING_POOL *newPool,
5096 const HASH_TABLE *oldTable,
5099 HASH_TABLE_ITER iter;
5100 const XML_Char *cachedOldBase = NULL;
5101 const XML_Char *cachedNewBase = NULL;
5103 hashTableIterInit(&iter, oldTable);
5107 const XML_Char *name;
5108 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5111 name = poolCopyString(newPool, oldE->name);
5114 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5117 if (oldE->systemId) {
5118 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5121 newE->systemId = tem;
5123 if (oldE->base == cachedOldBase)
5124 newE->base = cachedNewBase;
5126 cachedOldBase = oldE->base;
5127 tem = poolCopyString(newPool, cachedOldBase);
5130 cachedNewBase = newE->base = tem;
5133 if (oldE->publicId) {
5134 tem = poolCopyString(newPool, oldE->publicId);
5137 newE->publicId = tem;
5141 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5145 newE->textPtr = tem;
5146 newE->textLen = oldE->textLen;
5148 if (oldE->notation) {
5149 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5152 newE->notation = tem;
5154 newE->is_param = oldE->is_param;
5155 newE->is_internal = oldE->is_internal;
5160 #define INIT_SIZE 64
5163 keyeq(KEY s1, KEY s2)
5165 for (; *s1 == *s2; s1++, s2++)
5171 static unsigned long FASTCALL
5174 unsigned long h = 0;
5176 h = (h << 5) + h + (unsigned char)*s++;
5180 static NAMED * FASTCALL
5181 lookup(HASH_TABLE *table, KEY name, size_t createSize)
5184 if (table->size == 0) {
5189 tsize = INIT_SIZE * sizeof(NAMED *);
5190 table->v = table->mem->malloc_fcn(tsize);
5193 memset(table->v, 0, tsize);
5194 table->size = INIT_SIZE;
5195 table->usedLim = INIT_SIZE / 2;
5196 i = hash(name) & (table->size - 1);
5199 unsigned long h = hash(name);
5200 for (i = h & (table->size - 1);
5202 i == 0 ? i = table->size - 1 : --i) {
5203 if (keyeq(name, table->v[i]->name))
5208 if (table->used == table->usedLim) {
5209 /* check for overflow */
5210 size_t newSize = table->size * 2;
5211 size_t tsize = newSize * sizeof(NAMED *);
5212 NAMED **newV = table->mem->malloc_fcn(tsize);
5215 memset(newV, 0, tsize);
5216 for (i = 0; i < table->size; i++)
5219 for (j = hash(table->v[i]->name) & (newSize - 1);
5221 j == 0 ? j = newSize - 1 : --j)
5223 newV[j] = table->v[i];
5225 table->mem->free_fcn(table->v);
5227 table->size = newSize;
5228 table->usedLim = newSize/2;
5229 for (i = h & (table->size - 1);
5231 i == 0 ? i = table->size - 1 : --i)
5235 table->v[i] = table->mem->malloc_fcn(createSize);
5238 memset(table->v[i], 0, createSize);
5239 table->v[i]->name = name;
5244 static void FASTCALL
5245 hashTableClear(HASH_TABLE *table)
5248 for (i = 0; i < table->size; i++) {
5249 NAMED *p = table->v[i];
5251 table->mem->free_fcn(p);
5255 table->usedLim = table->size / 2;
5259 static void FASTCALL
5260 hashTableDestroy(HASH_TABLE *table)
5263 for (i = 0; i < table->size; i++) {
5264 NAMED *p = table->v[i];
5266 table->mem->free_fcn(p);
5269 table->mem->free_fcn(table->v);
5272 static void FASTCALL
5273 hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms)
5282 static void FASTCALL
5283 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
5286 iter->end = iter->p + table->size;
5289 static NAMED * FASTCALL
5290 hashTableIterNext(HASH_TABLE_ITER *iter)
5292 while (iter->p != iter->end) {
5293 NAMED *tem = *(iter->p)++;
5300 static void FASTCALL
5301 poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms)
5303 pool->blocks = NULL;
5304 pool->freeBlocks = NULL;
5311 static void FASTCALL
5312 poolClear(STRING_POOL *pool)
5314 if (!pool->freeBlocks)
5315 pool->freeBlocks = pool->blocks;
5317 BLOCK *p = pool->blocks;
5319 BLOCK *tem = p->next;
5320 p->next = pool->freeBlocks;
5321 pool->freeBlocks = p;
5325 pool->blocks = NULL;
5331 static void FASTCALL
5332 poolDestroy(STRING_POOL *pool)
5334 BLOCK *p = pool->blocks;
5336 BLOCK *tem = p->next;
5337 pool->mem->free_fcn(p);
5340 p = pool->freeBlocks;
5342 BLOCK *tem = p->next;
5343 pool->mem->free_fcn(p);
5348 static XML_Char * FASTCALL
5349 poolAppend(STRING_POOL *pool, const ENCODING *enc,
5350 const char *ptr, const char *end)
5352 if (!pool->ptr && !poolGrow(pool))
5355 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
5358 if (!poolGrow(pool))
5364 static const XML_Char * FASTCALL
5365 poolCopyString(STRING_POOL *pool, const XML_Char *s)
5368 if (!poolAppendChar(pool, *s))
5376 static const XML_Char * FASTCALL
5377 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
5379 if (!pool->ptr && !poolGrow(pool))
5381 for (; n > 0; --n, s++) {
5382 if (!poolAppendChar(pool, *s))
5390 static const XML_Char * FASTCALL
5391 poolAppendString(STRING_POOL *pool, const XML_Char *s)
5394 if (!poolAppendChar(pool, *s))
5401 static XML_Char * FASTCALL
5402 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
5403 const char *ptr, const char *end)
5405 if (!poolAppend(pool, enc, ptr, end))
5407 if (pool->ptr == pool->end && !poolGrow(pool))
5413 static XML_Bool FASTCALL
5414 poolGrow(STRING_POOL *pool)
5416 if (pool->freeBlocks) {
5417 if (pool->start == 0) {
5418 pool->blocks = pool->freeBlocks;
5419 pool->freeBlocks = pool->freeBlocks->next;
5420 pool->blocks->next = NULL;
5421 pool->start = pool->blocks->s;
5422 pool->end = pool->start + pool->blocks->size;
5423 pool->ptr = pool->start;
5426 if (pool->end - pool->start < pool->freeBlocks->size) {
5427 BLOCK *tem = pool->freeBlocks->next;
5428 pool->freeBlocks->next = pool->blocks;
5429 pool->blocks = pool->freeBlocks;
5430 pool->freeBlocks = tem;
5431 memcpy(pool->blocks->s, pool->start,
5432 (pool->end - pool->start) * sizeof(XML_Char));
5433 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5434 pool->start = pool->blocks->s;
5435 pool->end = pool->start + pool->blocks->size;
5439 if (pool->blocks && pool->start == pool->blocks->s) {
5440 int blockSize = (pool->end - pool->start)*2;
5441 pool->blocks = pool->mem->realloc_fcn(pool->blocks,
5443 + blockSize * sizeof(XML_Char));
5444 if (pool->blocks == NULL)
5446 pool->blocks->size = blockSize;
5447 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5448 pool->start = pool->blocks->s;
5449 pool->end = pool->start + blockSize;
5453 int blockSize = pool->end - pool->start;
5454 if (blockSize < INIT_BLOCK_SIZE)
5455 blockSize = INIT_BLOCK_SIZE;
5458 tem = pool->mem->malloc_fcn(offsetof(BLOCK, s)
5459 + blockSize * sizeof(XML_Char));
5462 tem->size = blockSize;
5463 tem->next = pool->blocks;
5465 if (pool->ptr != pool->start)
5466 memcpy(tem->s, pool->start,
5467 (pool->ptr - pool->start) * sizeof(XML_Char));
5468 pool->ptr = tem->s + (pool->ptr - pool->start);
5469 pool->start = tem->s;
5470 pool->end = tem->s + blockSize;
5476 nextScaffoldPart(XML_Parser parser)
5478 CONTENT_SCAFFOLD * me;
5481 if (!dtd.scaffIndex) {
5482 dtd.scaffIndex = MALLOC(groupSize * sizeof(int));
5483 if (!dtd.scaffIndex)
5485 dtd.scaffIndex[0] = 0;
5488 if (dtd.scaffCount >= dtd.scaffSize) {
5489 CONTENT_SCAFFOLD *temp;
5491 temp = (CONTENT_SCAFFOLD *)
5492 REALLOC(dtd.scaffold, dtd.scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
5498 temp = MALLOC(INIT_SCAFFOLD_ELEMENTS * sizeof(CONTENT_SCAFFOLD));
5501 dtd.scaffSize = INIT_SCAFFOLD_ELEMENTS;
5503 dtd.scaffold = temp;
5505 next = dtd.scaffCount++;
5506 me = &dtd.scaffold[next];
5507 if (dtd.scaffLevel) {
5508 CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel-1]];
5509 if (parent->lastchild) {
5510 dtd.scaffold[parent->lastchild].nextsib = next;
5512 if (!parent->childcnt)
5513 parent->firstchild = next;
5514 parent->lastchild = next;
5517 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
5521 static void FASTCALL
5522 build_node(XML_Parser parser,
5525 XML_Content **contpos,
5528 dest->type = dtd.scaffold[src_node].type;
5529 dest->quant = dtd.scaffold[src_node].quant;
5530 if (dest->type == XML_CTYPE_NAME) {
5531 const XML_Char *src;
5532 dest->name = *strpos;
5533 src = dtd.scaffold[src_node].name;
5535 *(*strpos)++ = *src;
5540 dest->numchildren = 0;
5541 dest->children = NULL;
5546 dest->numchildren = dtd.scaffold[src_node].childcnt;
5547 dest->children = *contpos;
5548 *contpos += dest->numchildren;
5549 for (i = 0, cn = dtd.scaffold[src_node].firstchild;
5550 i < dest->numchildren;
5551 i++, cn = dtd.scaffold[cn].nextsib) {
5552 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
5558 static XML_Content * FASTCALL
5559 build_model (XML_Parser parser)
5564 int allocsize = (dtd.scaffCount * sizeof(XML_Content)
5565 + (dtd.contentStringLen * sizeof(XML_Char)));
5567 ret = MALLOC(allocsize);
5571 str = (XML_Char *) (&ret[dtd.scaffCount]);
5574 build_node(parser, 0, ret, &cpos, &str);
5578 static ELEMENT_TYPE * FASTCALL
5579 getElementType(XML_Parser parser,
5580 const ENCODING *enc,
5584 const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
5589 ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
5592 if (ret->name != name)
5593 poolDiscard(&dtd.pool);
5595 poolFinish(&dtd.pool);
5596 if (!setElementTypePrefix(parser, ret))