1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
5 #include "amigaconfig.h"
8 #include <string.h> /* memset(), memcpy() */
12 #define XML_BUILDING_EXPAT 1
14 #ifdef COMPILED_FROM_DSP
15 #include "winconfig.h"
16 #elif defined(MACOS_CLASSIC)
17 #include "macconfig.h"
18 #elif defined(__amigaos4__)
19 #include "amigaconfig.h"
20 #elif defined(__WATCOMC__)
21 #include "watcomconfig.h"
22 #elif defined(HAVE_EXPAT_CONFIG_H)
23 #include <expat_config.h>
24 #endif /* ndef COMPILED_FROM_DSP */
30 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
31 #define XmlConvert XmlUtf16Convert
32 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
33 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
34 #define XmlEncode XmlUtf16Encode
35 /* Using pointer subtraction to convert to integer type. */
36 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
37 typedef unsigned short ICHAR
;
39 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
40 #define XmlConvert XmlUtf8Convert
41 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
42 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
43 #define XmlEncode XmlUtf8Encode
44 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
51 #define XmlInitEncodingNS XmlInitEncoding
52 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
53 #undef XmlGetInternalEncodingNS
54 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
55 #define XmlParseXmlDeclNS XmlParseXmlDecl
61 #ifdef XML_UNICODE_WCHAR_T
62 #define XML_T(x) (const wchar_t)x
63 #define XML_L(x) L ## x
65 #define XML_T(x) (const unsigned short)x
76 /* Round up n to be a multiple of sz, where sz is a power of 2. */
77 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
79 /* Handle the case where memmove() doesn't exist. */
82 #define memmove(d,s,l) bcopy((s),(d),(l))
84 #error memmove does not exist on this platform, nor is a substitute available
85 #endif /* HAVE_BCOPY */
86 #endif /* HAVE_MEMMOVE */
92 typedef const XML_Char
*KEY
;
103 const XML_Memory_Handling_Suite
*mem
;
106 /* Basic character hash algorithm, taken from Python's string hash:
107 h = h * 1000003 ^ character, the constant being a prime number.
111 #define CHAR_HASH(h, c) \
112 (((h) * 0xF4243) ^ (unsigned short)(c))
114 #define CHAR_HASH(h, c) \
115 (((h) * 0xF4243) ^ (unsigned char)(c))
118 /* For probing (after a collision) we need a step size relative prime
119 to the hash table size, which is a power of 2. We use double-hashing,
120 since we can calculate a second hash value cheaply by taking those bits
121 of the first hash value that were discarded (masked out) when the table
122 index was calculated: index = hash & mask, where mask = table->size - 1.
123 We limit the maximum step size to table->size / 4 (mask >> 2) and make
124 it odd, since odd numbers are always relative prime to a power of 2.
126 #define SECOND_HASH(hash, mask, power) \
127 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
128 #define PROBE_STEP(hash, mask, power) \
129 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
136 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
137 #define INIT_DATA_BUF_SIZE 1024
138 #define INIT_ATTS_SIZE 16
139 #define INIT_ATTS_VERSION 0xFFFFFFFF
140 #define INIT_BLOCK_SIZE 1024
141 #define INIT_BUFFER_SIZE 1024
143 #define EXPAND_SPARE 24
145 typedef struct binding
{
146 struct prefix
*prefix
;
147 struct binding
*nextTagBinding
;
148 struct binding
*prevPrefixBinding
;
149 const struct attribute_id
*attId
;
155 typedef struct prefix
{
156 const XML_Char
*name
;
162 const XML_Char
*localPart
;
163 const XML_Char
*prefix
;
169 /* TAG represents an open element.
170 The name of the element is stored in both the document and API
171 encodings. The memory buffer 'buf' is a separately-allocated
172 memory area which stores the name. During the XML_Parse()/
173 XMLParseBuffer() when the element is open, the memory for the 'raw'
174 version of the name (in the document encoding) is shared with the
175 document buffer. If the element is open across calls to
176 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
177 contain the 'raw' name as well.
179 A parser re-uses these structures, maintaining a list of allocated
180 TAG objects in a free list.
183 struct tag
*parent
; /* parent of this element */
184 const char *rawName
; /* tagName in the original encoding */
186 TAG_NAME name
; /* tagName in the API encoding */
187 char *buf
; /* buffer for name components */
188 char *bufEnd
; /* end of the buffer */
193 const XML_Char
*name
;
194 const XML_Char
*textPtr
;
195 int textLen
; /* length in XML_Chars */
196 int processed
; /* # of processed bytes - when suspended */
197 const XML_Char
*systemId
;
198 const XML_Char
*base
;
199 const XML_Char
*publicId
;
200 const XML_Char
*notation
;
203 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
207 enum XML_Content_Type type
;
208 enum XML_Content_Quant quant
;
209 const XML_Char
* name
;
216 #define INIT_SCAFFOLD_ELEMENTS 32
218 typedef struct block
{
230 const XML_Memory_Handling_Suite
*mem
;
233 /* The XML_Char before the name is used to determine whether
234 an attribute has been specified. */
235 typedef struct attribute_id
{
238 XML_Bool maybeTokenized
;
243 const ATTRIBUTE_ID
*id
;
245 const XML_Char
*value
;
249 unsigned long version
;
251 const XML_Char
*uriName
;
255 const XML_Char
*name
;
257 const ATTRIBUTE_ID
*idAtt
;
259 int allocDefaultAtts
;
260 DEFAULT_ATTRIBUTE
*defaultAtts
;
264 HASH_TABLE generalEntities
;
265 HASH_TABLE elementTypes
;
266 HASH_TABLE attributeIds
;
269 STRING_POOL entityValuePool
;
270 /* false once a parameter entity reference has been skipped */
271 XML_Bool keepProcessing
;
272 /* true once an internal or external PE reference has been encountered;
273 this includes the reference to an external subset */
274 XML_Bool hasParamEntityRefs
;
277 /* indicates if external PE has been read */
278 XML_Bool paramEntityRead
;
279 HASH_TABLE paramEntities
;
281 PREFIX defaultPrefix
;
282 /* === scaffolding for building content model === */
284 CONTENT_SCAFFOLD
*scaffold
;
285 unsigned contentStringLen
;
292 typedef struct open_internal_entity
{
293 const char *internalEventPtr
;
294 const char *internalEventEndPtr
;
295 struct open_internal_entity
*next
;
298 XML_Bool betweenDecl
; /* WFC: PE Between Declarations */
299 } OPEN_INTERNAL_ENTITY
;
301 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
304 const char **endPtr
);
306 static Processor prologProcessor
;
307 static Processor prologInitProcessor
;
308 static Processor contentProcessor
;
309 static Processor cdataSectionProcessor
;
311 static Processor ignoreSectionProcessor
;
312 static Processor externalParEntProcessor
;
313 static Processor externalParEntInitProcessor
;
314 static Processor entityValueProcessor
;
315 static Processor entityValueInitProcessor
;
317 static Processor epilogProcessor
;
318 static Processor errorProcessor
;
319 static Processor externalEntityInitProcessor
;
320 static Processor externalEntityInitProcessor2
;
321 static Processor externalEntityInitProcessor3
;
322 static Processor externalEntityContentProcessor
;
323 static Processor internalEntityProcessor
;
325 static enum XML_Error
326 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
327 static enum XML_Error
328 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
329 const char *s
, const char *next
);
330 static enum XML_Error
331 initializeEncoding(XML_Parser parser
);
332 static enum XML_Error
333 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
334 const char *end
, int tok
, const char *next
, const char **nextPtr
,
336 static enum XML_Error
337 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
338 XML_Bool betweenDecl
);
339 static enum XML_Error
340 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
341 const char *start
, const char *end
, const char **endPtr
,
343 static enum XML_Error
344 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
345 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
347 static enum XML_Error
348 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
349 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
352 static enum XML_Error
353 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
354 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
355 static enum XML_Error
356 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
357 const XML_Char
*uri
, BINDING
**bindingsPtr
);
359 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*, XML_Bool isCdata
,
360 XML_Bool isId
, const XML_Char
*dfltValue
, XML_Parser parser
);
361 static enum XML_Error
362 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
363 const char *, const char *, STRING_POOL
*);
364 static enum XML_Error
365 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
366 const char *, const char *, STRING_POOL
*);
367 static ATTRIBUTE_ID
*
368 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
371 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
372 static enum XML_Error
373 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
376 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
377 const char *start
, const char *end
);
379 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
382 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
385 static const XML_Char
* getContext(XML_Parser parser
);
387 setContext(XML_Parser parser
, const XML_Char
*context
);
389 static void FASTCALL
normalizePublicId(XML_Char
*s
);
391 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
392 /* do not call if parentParser != NULL */
393 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
395 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
397 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
399 copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
402 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
404 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
405 static void FASTCALL
hashTableClear(HASH_TABLE
*);
406 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
408 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
409 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
412 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
413 static void FASTCALL
poolClear(STRING_POOL
*);
414 static void FASTCALL
poolDestroy(STRING_POOL
*);
416 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
417 const char *ptr
, const char *end
);
419 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
420 const char *ptr
, const char *end
);
421 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
422 static const XML_Char
* FASTCALL
423 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
424 static const XML_Char
*
425 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
426 static const XML_Char
* FASTCALL
427 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
429 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
430 static XML_Content
* build_model(XML_Parser parser
);
431 static ELEMENT_TYPE
*
432 getElementType(XML_Parser parser
, const ENCODING
*enc
,
433 const char *ptr
, const char *end
);
436 parserCreate(const XML_Char
*encodingName
,
437 const XML_Memory_Handling_Suite
*memsuite
,
438 const XML_Char
*nameSep
,
441 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
443 #define poolStart(pool) ((pool)->start)
444 #define poolEnd(pool) ((pool)->ptr)
445 #define poolLength(pool) ((pool)->ptr - (pool)->start)
446 #define poolChop(pool) ((void)--(pool->ptr))
447 #define poolLastChar(pool) (((pool)->ptr)[-1])
448 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
449 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
450 #define poolAppendChar(pool, c) \
451 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
453 : ((*((pool)->ptr)++ = c), 1))
455 struct XML_ParserStruct
{
456 /* The first member must be userData so that the XML_GetUserData
461 const XML_Memory_Handling_Suite m_mem
;
462 /* first character to be parsed */
463 const char *m_bufferPtr
;
464 /* past last character to be parsed */
466 /* allocated end of buffer */
467 const char *m_bufferLim
;
468 XML_Index m_parseEndByteIndex
;
469 const char *m_parseEndPtr
;
471 XML_Char
*m_dataBufEnd
;
472 XML_StartElementHandler m_startElementHandler
;
473 XML_EndElementHandler m_endElementHandler
;
474 XML_CharacterDataHandler m_characterDataHandler
;
475 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
476 XML_CommentHandler m_commentHandler
;
477 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
478 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
479 XML_DefaultHandler m_defaultHandler
;
480 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
481 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
482 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
483 XML_NotationDeclHandler m_notationDeclHandler
;
484 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
485 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
486 XML_NotStandaloneHandler m_notStandaloneHandler
;
487 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
488 XML_Parser m_externalEntityRefHandlerArg
;
489 XML_SkippedEntityHandler m_skippedEntityHandler
;
490 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
491 XML_ElementDeclHandler m_elementDeclHandler
;
492 XML_AttlistDeclHandler m_attlistDeclHandler
;
493 XML_EntityDeclHandler m_entityDeclHandler
;
494 XML_XmlDeclHandler m_xmlDeclHandler
;
495 const ENCODING
*m_encoding
;
496 INIT_ENCODING m_initEncoding
;
497 const ENCODING
*m_internalEncoding
;
498 const XML_Char
*m_protocolEncodingName
;
500 XML_Bool m_ns_triplets
;
501 void *m_unknownEncodingMem
;
502 void *m_unknownEncodingData
;
503 void *m_unknownEncodingHandlerData
;
504 void (XMLCALL
*m_unknownEncodingRelease
)(void *);
505 PROLOG_STATE m_prologState
;
506 Processor
*m_processor
;
507 enum XML_Error m_errorCode
;
508 const char *m_eventPtr
;
509 const char *m_eventEndPtr
;
510 const char *m_positionPtr
;
511 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
512 OPEN_INTERNAL_ENTITY
*m_freeInternalEntities
;
513 XML_Bool m_defaultExpandInternalEntities
;
515 ENTITY
*m_declEntity
;
516 const XML_Char
*m_doctypeName
;
517 const XML_Char
*m_doctypeSysid
;
518 const XML_Char
*m_doctypePubid
;
519 const XML_Char
*m_declAttributeType
;
520 const XML_Char
*m_declNotationName
;
521 const XML_Char
*m_declNotationPublicId
;
522 ELEMENT_TYPE
*m_declElementType
;
523 ATTRIBUTE_ID
*m_declAttributeId
;
524 XML_Bool m_declAttributeIsCdata
;
525 XML_Bool m_declAttributeIsId
;
527 const XML_Char
*m_curBase
;
530 BINDING
*m_inheritedBindings
;
531 BINDING
*m_freeBindingList
;
533 int m_nSpecifiedAtts
;
537 unsigned long m_nsAttsVersion
;
538 unsigned char m_nsAttsPower
;
540 STRING_POOL m_tempPool
;
541 STRING_POOL m_temp2Pool
;
542 char *m_groupConnector
;
543 unsigned int m_groupSize
;
544 XML_Char m_namespaceSeparator
;
545 XML_Parser m_parentParser
;
546 XML_ParsingStatus m_parsingStatus
;
548 XML_Bool m_isParamEntity
;
549 XML_Bool m_useForeignDTD
;
550 enum XML_ParamEntityParsing m_paramEntityParsing
;
554 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
555 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
556 #define FREE(p) (parser->m_mem.free_fcn((p)))
558 #define userData (parser->m_userData)
559 #define handlerArg (parser->m_handlerArg)
560 #define startElementHandler (parser->m_startElementHandler)
561 #define endElementHandler (parser->m_endElementHandler)
562 #define characterDataHandler (parser->m_characterDataHandler)
563 #define processingInstructionHandler \
564 (parser->m_processingInstructionHandler)
565 #define commentHandler (parser->m_commentHandler)
566 #define startCdataSectionHandler \
567 (parser->m_startCdataSectionHandler)
568 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
569 #define defaultHandler (parser->m_defaultHandler)
570 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
571 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
572 #define unparsedEntityDeclHandler \
573 (parser->m_unparsedEntityDeclHandler)
574 #define notationDeclHandler (parser->m_notationDeclHandler)
575 #define startNamespaceDeclHandler \
576 (parser->m_startNamespaceDeclHandler)
577 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
578 #define notStandaloneHandler (parser->m_notStandaloneHandler)
579 #define externalEntityRefHandler \
580 (parser->m_externalEntityRefHandler)
581 #define externalEntityRefHandlerArg \
582 (parser->m_externalEntityRefHandlerArg)
583 #define internalEntityRefHandler \
584 (parser->m_internalEntityRefHandler)
585 #define skippedEntityHandler (parser->m_skippedEntityHandler)
586 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
587 #define elementDeclHandler (parser->m_elementDeclHandler)
588 #define attlistDeclHandler (parser->m_attlistDeclHandler)
589 #define entityDeclHandler (parser->m_entityDeclHandler)
590 #define xmlDeclHandler (parser->m_xmlDeclHandler)
591 #define encoding (parser->m_encoding)
592 #define initEncoding (parser->m_initEncoding)
593 #define internalEncoding (parser->m_internalEncoding)
594 #define unknownEncodingMem (parser->m_unknownEncodingMem)
595 #define unknownEncodingData (parser->m_unknownEncodingData)
596 #define unknownEncodingHandlerData \
597 (parser->m_unknownEncodingHandlerData)
598 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
599 #define protocolEncodingName (parser->m_protocolEncodingName)
600 #define ns (parser->m_ns)
601 #define ns_triplets (parser->m_ns_triplets)
602 #define prologState (parser->m_prologState)
603 #define processor (parser->m_processor)
604 #define errorCode (parser->m_errorCode)
605 #define eventPtr (parser->m_eventPtr)
606 #define eventEndPtr (parser->m_eventEndPtr)
607 #define positionPtr (parser->m_positionPtr)
608 #define position (parser->m_position)
609 #define openInternalEntities (parser->m_openInternalEntities)
610 #define freeInternalEntities (parser->m_freeInternalEntities)
611 #define defaultExpandInternalEntities \
612 (parser->m_defaultExpandInternalEntities)
613 #define tagLevel (parser->m_tagLevel)
614 #define buffer (parser->m_buffer)
615 #define bufferPtr (parser->m_bufferPtr)
616 #define bufferEnd (parser->m_bufferEnd)
617 #define parseEndByteIndex (parser->m_parseEndByteIndex)
618 #define parseEndPtr (parser->m_parseEndPtr)
619 #define bufferLim (parser->m_bufferLim)
620 #define dataBuf (parser->m_dataBuf)
621 #define dataBufEnd (parser->m_dataBufEnd)
622 #define _dtd (parser->m_dtd)
623 #define curBase (parser->m_curBase)
624 #define declEntity (parser->m_declEntity)
625 #define doctypeName (parser->m_doctypeName)
626 #define doctypeSysid (parser->m_doctypeSysid)
627 #define doctypePubid (parser->m_doctypePubid)
628 #define declAttributeType (parser->m_declAttributeType)
629 #define declNotationName (parser->m_declNotationName)
630 #define declNotationPublicId (parser->m_declNotationPublicId)
631 #define declElementType (parser->m_declElementType)
632 #define declAttributeId (parser->m_declAttributeId)
633 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
634 #define declAttributeIsId (parser->m_declAttributeIsId)
635 #define freeTagList (parser->m_freeTagList)
636 #define freeBindingList (parser->m_freeBindingList)
637 #define inheritedBindings (parser->m_inheritedBindings)
638 #define tagStack (parser->m_tagStack)
639 #define atts (parser->m_atts)
640 #define attsSize (parser->m_attsSize)
641 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
642 #define idAttIndex (parser->m_idAttIndex)
643 #define nsAtts (parser->m_nsAtts)
644 #define nsAttsVersion (parser->m_nsAttsVersion)
645 #define nsAttsPower (parser->m_nsAttsPower)
646 #define tempPool (parser->m_tempPool)
647 #define temp2Pool (parser->m_temp2Pool)
648 #define groupConnector (parser->m_groupConnector)
649 #define groupSize (parser->m_groupSize)
650 #define namespaceSeparator (parser->m_namespaceSeparator)
651 #define parentParser (parser->m_parentParser)
652 #define ps_parsing (parser->m_parsingStatus.parsing)
653 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
655 #define isParamEntity (parser->m_isParamEntity)
656 #define useForeignDTD (parser->m_useForeignDTD)
657 #define paramEntityParsing (parser->m_paramEntityParsing)
661 XML_ParserCreate(const XML_Char
*encodingName
)
663 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
667 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
671 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
674 static const XML_Char implicitContext
[] = {
675 ASCII_x
, ASCII_m
, ASCII_l
, ASCII_EQUALS
, ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
,
676 ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
, ASCII_w
, ASCII_w
, ASCII_w
,
677 ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
, ASCII_o
, ASCII_r
, ASCII_g
,
678 ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
, ASCII_SLASH
, ASCII_1
, ASCII_9
,
679 ASCII_9
, ASCII_8
, ASCII_SLASH
, ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
,
680 ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
, ASCII_e
, '\0'
684 XML_ParserCreate_MM(const XML_Char
*encodingName
,
685 const XML_Memory_Handling_Suite
*memsuite
,
686 const XML_Char
*nameSep
)
688 XML_Parser parser
= parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
689 if (parser
!= NULL
&& ns
) {
690 /* implicit context only set for root parser, since child
691 parsers (i.e. external entity parsers) will inherit it
693 if (!setContext(parser
, implicitContext
)) {
694 XML_ParserFree(parser
);
702 parserCreate(const XML_Char
*encodingName
,
703 const XML_Memory_Handling_Suite
*memsuite
,
704 const XML_Char
*nameSep
,
710 XML_Memory_Handling_Suite
*mtemp
;
711 parser
= (XML_Parser
)
712 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
713 if (parser
!= NULL
) {
714 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
715 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
716 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
717 mtemp
->free_fcn
= memsuite
->free_fcn
;
721 XML_Memory_Handling_Suite
*mtemp
;
722 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
723 if (parser
!= NULL
) {
724 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
725 mtemp
->malloc_fcn
= malloc
;
726 mtemp
->realloc_fcn
= realloc
;
727 mtemp
->free_fcn
= free
;
737 attsSize
= INIT_ATTS_SIZE
;
738 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
743 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
744 if (dataBuf
== NULL
) {
749 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
754 _dtd
= dtdCreate(&parser
->m_mem
);
763 freeBindingList
= NULL
;
765 freeInternalEntities
= NULL
;
768 groupConnector
= NULL
;
770 unknownEncodingHandler
= NULL
;
771 unknownEncodingHandlerData
= NULL
;
773 namespaceSeparator
= ASCII_EXCL
;
775 ns_triplets
= XML_FALSE
;
781 poolInit(&tempPool
, &(parser
->m_mem
));
782 poolInit(&temp2Pool
, &(parser
->m_mem
));
783 parserInit(parser
, encodingName
);
785 if (encodingName
&& !protocolEncodingName
) {
786 XML_ParserFree(parser
);
792 internalEncoding
= XmlGetInternalEncodingNS();
793 namespaceSeparator
= *nameSep
;
796 internalEncoding
= XmlGetInternalEncoding();
803 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
805 processor
= prologInitProcessor
;
806 XmlPrologStateInit(&prologState
);
807 protocolEncodingName
= (encodingName
!= NULL
808 ? poolCopyString(&tempPool
, encodingName
)
811 XmlInitEncoding(&initEncoding
, &encoding
, 0);
814 startElementHandler
= NULL
;
815 endElementHandler
= NULL
;
816 characterDataHandler
= NULL
;
817 processingInstructionHandler
= NULL
;
818 commentHandler
= NULL
;
819 startCdataSectionHandler
= NULL
;
820 endCdataSectionHandler
= NULL
;
821 defaultHandler
= NULL
;
822 startDoctypeDeclHandler
= NULL
;
823 endDoctypeDeclHandler
= NULL
;
824 unparsedEntityDeclHandler
= NULL
;
825 notationDeclHandler
= NULL
;
826 startNamespaceDeclHandler
= NULL
;
827 endNamespaceDeclHandler
= NULL
;
828 notStandaloneHandler
= NULL
;
829 externalEntityRefHandler
= NULL
;
830 externalEntityRefHandlerArg
= parser
;
831 skippedEntityHandler
= NULL
;
832 elementDeclHandler
= NULL
;
833 attlistDeclHandler
= NULL
;
834 entityDeclHandler
= NULL
;
835 xmlDeclHandler
= NULL
;
838 parseEndByteIndex
= 0;
840 declElementType
= NULL
;
841 declAttributeId
= NULL
;
846 declAttributeType
= NULL
;
847 declNotationName
= NULL
;
848 declNotationPublicId
= NULL
;
849 declAttributeIsCdata
= XML_FALSE
;
850 declAttributeIsId
= XML_FALSE
;
851 memset(&position
, 0, sizeof(POSITION
));
852 errorCode
= XML_ERROR_NONE
;
856 openInternalEntities
= NULL
;
857 defaultExpandInternalEntities
= XML_TRUE
;
860 inheritedBindings
= NULL
;
862 unknownEncodingMem
= NULL
;
863 unknownEncodingRelease
= NULL
;
864 unknownEncodingData
= NULL
;
866 ps_parsing
= XML_INITIALIZED
;
868 isParamEntity
= XML_FALSE
;
869 useForeignDTD
= XML_FALSE
;
870 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
874 /* moves list of bindings to freeBindingList */
876 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
879 BINDING
*b
= bindings
;
880 bindings
= bindings
->nextTagBinding
;
881 b
->nextTagBinding
= freeBindingList
;
887 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
890 OPEN_INTERNAL_ENTITY
*openEntityList
;
893 /* move tagStack to freeTagList */
898 tag
->parent
= freeTagList
;
899 moveToFreeBindingList(parser
, tag
->bindings
);
900 tag
->bindings
= NULL
;
903 /* move openInternalEntities to freeInternalEntities */
904 openEntityList
= openInternalEntities
;
905 while (openEntityList
) {
906 OPEN_INTERNAL_ENTITY
*openEntity
= openEntityList
;
907 openEntityList
= openEntity
->next
;
908 openEntity
->next
= freeInternalEntities
;
909 freeInternalEntities
= openEntity
;
911 moveToFreeBindingList(parser
, inheritedBindings
);
912 FREE(unknownEncodingMem
);
913 if (unknownEncodingRelease
)
914 unknownEncodingRelease(unknownEncodingData
);
915 poolClear(&tempPool
);
916 poolClear(&temp2Pool
);
917 parserInit(parser
, encodingName
);
918 dtdReset(_dtd
, &parser
->m_mem
);
919 return setContext(parser
, implicitContext
);
922 enum XML_Status XMLCALL
923 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
925 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
926 XXX There's no way for the caller to determine which of the
927 XXX possible error cases caused the XML_STATUS_ERROR return.
929 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
930 return XML_STATUS_ERROR
;
931 if (encodingName
== NULL
)
932 protocolEncodingName
= NULL
;
934 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
935 if (!protocolEncodingName
)
936 return XML_STATUS_ERROR
;
938 return XML_STATUS_OK
;
942 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
943 const XML_Char
*context
,
944 const XML_Char
*encodingName
)
946 XML_Parser parser
= oldParser
;
949 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
950 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
951 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
952 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
953 = processingInstructionHandler
;
954 XML_CommentHandler oldCommentHandler
= commentHandler
;
955 XML_StartCdataSectionHandler oldStartCdataSectionHandler
956 = startCdataSectionHandler
;
957 XML_EndCdataSectionHandler oldEndCdataSectionHandler
958 = endCdataSectionHandler
;
959 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
960 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
961 = unparsedEntityDeclHandler
;
962 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
963 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
964 = startNamespaceDeclHandler
;
965 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
966 = endNamespaceDeclHandler
;
967 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
968 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
969 = externalEntityRefHandler
;
970 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
971 XML_UnknownEncodingHandler oldUnknownEncodingHandler
972 = unknownEncodingHandler
;
973 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
974 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
975 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
976 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
977 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
979 void *oldUserData
= userData
;
980 void *oldHandlerArg
= handlerArg
;
981 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
982 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
984 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
985 int oldInEntityValue
= prologState
.inEntityValue
;
987 XML_Bool oldns_triplets
= ns_triplets
;
994 /* Note that the magical uses of the pre-processor to make field
995 access look more like C++ require that `parser' be overwritten
996 here. This makes this function more painful to follow than it
1001 *tmp
= namespaceSeparator
;
1002 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
1005 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
1011 startElementHandler
= oldStartElementHandler
;
1012 endElementHandler
= oldEndElementHandler
;
1013 characterDataHandler
= oldCharacterDataHandler
;
1014 processingInstructionHandler
= oldProcessingInstructionHandler
;
1015 commentHandler
= oldCommentHandler
;
1016 startCdataSectionHandler
= oldStartCdataSectionHandler
;
1017 endCdataSectionHandler
= oldEndCdataSectionHandler
;
1018 defaultHandler
= oldDefaultHandler
;
1019 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
1020 notationDeclHandler
= oldNotationDeclHandler
;
1021 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
1022 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
1023 notStandaloneHandler
= oldNotStandaloneHandler
;
1024 externalEntityRefHandler
= oldExternalEntityRefHandler
;
1025 skippedEntityHandler
= oldSkippedEntityHandler
;
1026 unknownEncodingHandler
= oldUnknownEncodingHandler
;
1027 elementDeclHandler
= oldElementDeclHandler
;
1028 attlistDeclHandler
= oldAttlistDeclHandler
;
1029 entityDeclHandler
= oldEntityDeclHandler
;
1030 xmlDeclHandler
= oldXmlDeclHandler
;
1031 declElementType
= oldDeclElementType
;
1032 userData
= oldUserData
;
1033 if (oldUserData
== oldHandlerArg
)
1034 handlerArg
= userData
;
1036 handlerArg
= parser
;
1037 if (oldExternalEntityRefHandlerArg
!= oldParser
)
1038 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
1039 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
1040 ns_triplets
= oldns_triplets
;
1041 parentParser
= oldParser
;
1043 paramEntityParsing
= oldParamEntityParsing
;
1044 prologState
.inEntityValue
= oldInEntityValue
;
1046 #endif /* XML_DTD */
1047 if (!dtdCopy(_dtd
, oldDtd
, &parser
->m_mem
)
1048 || !setContext(parser
, context
)) {
1049 XML_ParserFree(parser
);
1052 processor
= externalEntityInitProcessor
;
1056 /* The DTD instance referenced by _dtd is shared between the document's
1057 root parser and external PE parsers, therefore one does not need to
1058 call setContext. In addition, one also *must* not call setContext,
1059 because this would overwrite existing prefix->binding pointers in
1060 _dtd with ones that get destroyed with the external PE parser.
1061 This would leave those prefixes with dangling pointers.
1063 isParamEntity
= XML_TRUE
;
1064 XmlPrologStateInitExternalEntity(&prologState
);
1065 processor
= externalParEntInitProcessor
;
1067 #endif /* XML_DTD */
1071 static void FASTCALL
1072 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1075 BINDING
*b
= bindings
;
1078 bindings
= b
->nextTagBinding
;
1085 XML_ParserFree(XML_Parser parser
)
1088 OPEN_INTERNAL_ENTITY
*entityList
;
1091 /* free tagStack and freeTagList */
1095 if (tagList
== NULL
) {
1096 if (freeTagList
== NULL
)
1098 tagList
= freeTagList
;
1102 tagList
= tagList
->parent
;
1104 destroyBindings(p
->bindings
, parser
);
1107 /* free openInternalEntities and freeInternalEntities */
1108 entityList
= openInternalEntities
;
1110 OPEN_INTERNAL_ENTITY
*openEntity
;
1111 if (entityList
== NULL
) {
1112 if (freeInternalEntities
== NULL
)
1114 entityList
= freeInternalEntities
;
1115 freeInternalEntities
= NULL
;
1117 openEntity
= entityList
;
1118 entityList
= entityList
->next
;
1122 destroyBindings(freeBindingList
, parser
);
1123 destroyBindings(inheritedBindings
, parser
);
1124 poolDestroy(&tempPool
);
1125 poolDestroy(&temp2Pool
);
1127 /* external parameter entity parsers share the DTD structure
1128 parser->m_dtd with the root parser, so we must not destroy it
1130 if (!isParamEntity
&& _dtd
)
1133 #endif /* XML_DTD */
1134 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1136 FREE(groupConnector
);
1140 FREE(unknownEncodingMem
);
1141 if (unknownEncodingRelease
)
1142 unknownEncodingRelease(unknownEncodingData
);
1147 XML_UseParserAsHandlerArg(XML_Parser parser
)
1149 handlerArg
= parser
;
1152 enum XML_Error XMLCALL
1153 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1156 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1157 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1158 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1159 useForeignDTD
= useDTD
;
1160 return XML_ERROR_NONE
;
1162 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1167 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1169 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1170 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1172 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1176 XML_SetUserData(XML_Parser parser
, void *p
)
1178 if (handlerArg
== userData
)
1179 handlerArg
= userData
= p
;
1184 enum XML_Status XMLCALL
1185 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1188 p
= poolCopyString(&_dtd
->pool
, p
);
1190 return XML_STATUS_ERROR
;
1195 return XML_STATUS_OK
;
1198 const XML_Char
* XMLCALL
1199 XML_GetBase(XML_Parser parser
)
1205 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1207 return nSpecifiedAtts
;
1211 XML_GetIdAttributeIndex(XML_Parser parser
)
1217 XML_SetElementHandler(XML_Parser parser
,
1218 XML_StartElementHandler start
,
1219 XML_EndElementHandler end
)
1221 startElementHandler
= start
;
1222 endElementHandler
= end
;
1226 XML_SetStartElementHandler(XML_Parser parser
,
1227 XML_StartElementHandler start
) {
1228 startElementHandler
= start
;
1232 XML_SetEndElementHandler(XML_Parser parser
,
1233 XML_EndElementHandler end
) {
1234 endElementHandler
= end
;
1238 XML_SetCharacterDataHandler(XML_Parser parser
,
1239 XML_CharacterDataHandler handler
)
1241 characterDataHandler
= handler
;
1245 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1246 XML_ProcessingInstructionHandler handler
)
1248 processingInstructionHandler
= handler
;
1252 XML_SetCommentHandler(XML_Parser parser
,
1253 XML_CommentHandler handler
)
1255 commentHandler
= handler
;
1259 XML_SetCdataSectionHandler(XML_Parser parser
,
1260 XML_StartCdataSectionHandler start
,
1261 XML_EndCdataSectionHandler end
)
1263 startCdataSectionHandler
= start
;
1264 endCdataSectionHandler
= end
;
1268 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1269 XML_StartCdataSectionHandler start
) {
1270 startCdataSectionHandler
= start
;
1274 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1275 XML_EndCdataSectionHandler end
) {
1276 endCdataSectionHandler
= end
;
1280 XML_SetDefaultHandler(XML_Parser parser
,
1281 XML_DefaultHandler handler
)
1283 defaultHandler
= handler
;
1284 defaultExpandInternalEntities
= XML_FALSE
;
1288 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1289 XML_DefaultHandler handler
)
1291 defaultHandler
= handler
;
1292 defaultExpandInternalEntities
= XML_TRUE
;
1296 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1297 XML_StartDoctypeDeclHandler start
,
1298 XML_EndDoctypeDeclHandler end
)
1300 startDoctypeDeclHandler
= start
;
1301 endDoctypeDeclHandler
= end
;
1305 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1306 XML_StartDoctypeDeclHandler start
) {
1307 startDoctypeDeclHandler
= start
;
1311 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1312 XML_EndDoctypeDeclHandler end
) {
1313 endDoctypeDeclHandler
= end
;
1317 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1318 XML_UnparsedEntityDeclHandler handler
)
1320 unparsedEntityDeclHandler
= handler
;
1324 XML_SetNotationDeclHandler(XML_Parser parser
,
1325 XML_NotationDeclHandler handler
)
1327 notationDeclHandler
= handler
;
1331 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1332 XML_StartNamespaceDeclHandler start
,
1333 XML_EndNamespaceDeclHandler end
)
1335 startNamespaceDeclHandler
= start
;
1336 endNamespaceDeclHandler
= end
;
1340 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1341 XML_StartNamespaceDeclHandler start
) {
1342 startNamespaceDeclHandler
= start
;
1346 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1347 XML_EndNamespaceDeclHandler end
) {
1348 endNamespaceDeclHandler
= end
;
1352 XML_SetNotStandaloneHandler(XML_Parser parser
,
1353 XML_NotStandaloneHandler handler
)
1355 notStandaloneHandler
= handler
;
1359 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1360 XML_ExternalEntityRefHandler handler
)
1362 externalEntityRefHandler
= handler
;
1366 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1369 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1371 externalEntityRefHandlerArg
= parser
;
1375 XML_SetSkippedEntityHandler(XML_Parser parser
,
1376 XML_SkippedEntityHandler handler
)
1378 skippedEntityHandler
= handler
;
1382 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1383 XML_UnknownEncodingHandler handler
,
1386 unknownEncodingHandler
= handler
;
1387 unknownEncodingHandlerData
= data
;
1391 XML_SetElementDeclHandler(XML_Parser parser
,
1392 XML_ElementDeclHandler eldecl
)
1394 elementDeclHandler
= eldecl
;
1398 XML_SetAttlistDeclHandler(XML_Parser parser
,
1399 XML_AttlistDeclHandler attdecl
)
1401 attlistDeclHandler
= attdecl
;
1405 XML_SetEntityDeclHandler(XML_Parser parser
,
1406 XML_EntityDeclHandler handler
)
1408 entityDeclHandler
= handler
;
1412 XML_SetXmlDeclHandler(XML_Parser parser
,
1413 XML_XmlDeclHandler handler
) {
1414 xmlDeclHandler
= handler
;
1418 XML_SetParamEntityParsing(XML_Parser parser
,
1419 enum XML_ParamEntityParsing peParsing
)
1421 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1422 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1425 paramEntityParsing
= peParsing
;
1428 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1432 enum XML_Status XMLCALL
1433 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1435 switch (ps_parsing
) {
1437 errorCode
= XML_ERROR_SUSPENDED
;
1438 return XML_STATUS_ERROR
;
1440 errorCode
= XML_ERROR_FINISHED
;
1441 return XML_STATUS_ERROR
;
1443 ps_parsing
= XML_PARSING
;
1447 ps_finalBuffer
= (XML_Bool
)isFinal
;
1449 return XML_STATUS_OK
;
1450 positionPtr
= bufferPtr
;
1451 parseEndPtr
= bufferEnd
;
1453 /* If data are left over from last buffer, and we now know that these
1454 data are the final chunk of input, then we have to check them again
1455 to detect errors based on that fact.
1457 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1459 if (errorCode
== XML_ERROR_NONE
) {
1460 switch (ps_parsing
) {
1462 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1463 positionPtr
= bufferPtr
;
1464 return XML_STATUS_SUSPENDED
;
1465 case XML_INITIALIZED
:
1467 ps_parsing
= XML_FINISHED
;
1470 return XML_STATUS_OK
;
1473 eventEndPtr
= eventPtr
;
1474 processor
= errorProcessor
;
1475 return XML_STATUS_ERROR
;
1477 #ifndef XML_CONTEXT_BYTES
1478 else if (bufferPtr
== bufferEnd
) {
1481 enum XML_Error result
;
1482 parseEndByteIndex
+= len
;
1484 ps_finalBuffer
= (XML_Bool
)isFinal
;
1486 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1488 if (errorCode
!= XML_ERROR_NONE
) {
1489 eventEndPtr
= eventPtr
;
1490 processor
= errorProcessor
;
1491 return XML_STATUS_ERROR
;
1494 switch (ps_parsing
) {
1496 result
= XML_STATUS_SUSPENDED
;
1498 case XML_INITIALIZED
:
1500 result
= XML_STATUS_OK
;
1502 ps_parsing
= XML_FINISHED
;
1508 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1509 nLeftOver
= s
+ len
- end
;
1511 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1512 /* FIXME avoid integer overflow */
1514 temp
= (buffer
== NULL
1515 ? (char *)MALLOC(len
* 2)
1516 : (char *)REALLOC(buffer
, len
* 2));
1518 errorCode
= XML_ERROR_NO_MEMORY
;
1519 return XML_STATUS_ERROR
;
1523 errorCode
= XML_ERROR_NO_MEMORY
;
1524 eventPtr
= eventEndPtr
= NULL
;
1525 processor
= errorProcessor
;
1526 return XML_STATUS_ERROR
;
1528 bufferLim
= buffer
+ len
* 2;
1530 memcpy(buffer
, end
, nLeftOver
);
1533 bufferEnd
= buffer
+ nLeftOver
;
1534 positionPtr
= bufferPtr
;
1535 parseEndPtr
= bufferEnd
;
1536 eventPtr
= bufferPtr
;
1537 eventEndPtr
= bufferPtr
;
1540 #endif /* not defined XML_CONTEXT_BYTES */
1542 void *buff
= XML_GetBuffer(parser
, len
);
1544 return XML_STATUS_ERROR
;
1546 memcpy(buff
, s
, len
);
1547 return XML_ParseBuffer(parser
, len
, isFinal
);
1552 enum XML_Status XMLCALL
1553 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1556 enum XML_Status result
= XML_STATUS_OK
;
1558 switch (ps_parsing
) {
1560 errorCode
= XML_ERROR_SUSPENDED
;
1561 return XML_STATUS_ERROR
;
1563 errorCode
= XML_ERROR_FINISHED
;
1564 return XML_STATUS_ERROR
;
1566 ps_parsing
= XML_PARSING
;
1570 positionPtr
= start
;
1572 parseEndPtr
= bufferEnd
;
1573 parseEndByteIndex
+= len
;
1574 ps_finalBuffer
= (XML_Bool
)isFinal
;
1576 errorCode
= processor(parser
, start
, parseEndPtr
, &bufferPtr
);
1578 if (errorCode
!= XML_ERROR_NONE
) {
1579 eventEndPtr
= eventPtr
;
1580 processor
= errorProcessor
;
1581 return XML_STATUS_ERROR
;
1584 switch (ps_parsing
) {
1586 result
= XML_STATUS_SUSPENDED
;
1588 case XML_INITIALIZED
:
1591 ps_parsing
= XML_FINISHED
;
1594 default: ; /* should not happen */
1598 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1599 positionPtr
= bufferPtr
;
1604 XML_GetBuffer(XML_Parser parser
, int len
)
1606 switch (ps_parsing
) {
1608 errorCode
= XML_ERROR_SUSPENDED
;
1611 errorCode
= XML_ERROR_FINISHED
;
1616 if (len
> bufferLim
- bufferEnd
) {
1617 /* FIXME avoid integer overflow */
1618 int neededSize
= len
+ (int)(bufferEnd
- bufferPtr
);
1619 #ifdef XML_CONTEXT_BYTES
1620 int keep
= (int)(bufferPtr
- buffer
);
1622 if (keep
> XML_CONTEXT_BYTES
)
1623 keep
= XML_CONTEXT_BYTES
;
1625 #endif /* defined XML_CONTEXT_BYTES */
1626 if (neededSize
<= bufferLim
- buffer
) {
1627 #ifdef XML_CONTEXT_BYTES
1628 if (keep
< bufferPtr
- buffer
) {
1629 int offset
= (int)(bufferPtr
- buffer
) - keep
;
1630 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1631 bufferEnd
-= offset
;
1632 bufferPtr
-= offset
;
1635 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1636 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1638 #endif /* not defined XML_CONTEXT_BYTES */
1642 int bufferSize
= (int)(bufferLim
- bufferPtr
);
1643 if (bufferSize
== 0)
1644 bufferSize
= INIT_BUFFER_SIZE
;
1647 } while (bufferSize
< neededSize
);
1648 newBuf
= (char *)MALLOC(bufferSize
);
1650 errorCode
= XML_ERROR_NO_MEMORY
;
1653 bufferLim
= newBuf
+ bufferSize
;
1654 #ifdef XML_CONTEXT_BYTES
1656 int keep
= (int)(bufferPtr
- buffer
);
1657 if (keep
> XML_CONTEXT_BYTES
)
1658 keep
= XML_CONTEXT_BYTES
;
1659 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1662 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1663 bufferPtr
= buffer
+ keep
;
1666 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1667 bufferPtr
= buffer
= newBuf
;
1671 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1674 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1675 bufferPtr
= buffer
= newBuf
;
1676 #endif /* not defined XML_CONTEXT_BYTES */
1682 enum XML_Status XMLCALL
1683 XML_StopParser(XML_Parser parser
, XML_Bool resumable
)
1685 switch (ps_parsing
) {
1688 errorCode
= XML_ERROR_SUSPENDED
;
1689 return XML_STATUS_ERROR
;
1691 ps_parsing
= XML_FINISHED
;
1694 errorCode
= XML_ERROR_FINISHED
;
1695 return XML_STATUS_ERROR
;
1699 if (isParamEntity
) {
1700 errorCode
= XML_ERROR_SUSPEND_PE
;
1701 return XML_STATUS_ERROR
;
1704 ps_parsing
= XML_SUSPENDED
;
1707 ps_parsing
= XML_FINISHED
;
1709 return XML_STATUS_OK
;
1712 enum XML_Status XMLCALL
1713 XML_ResumeParser(XML_Parser parser
)
1715 enum XML_Status result
= XML_STATUS_OK
;
1717 if (ps_parsing
!= XML_SUSPENDED
) {
1718 errorCode
= XML_ERROR_NOT_SUSPENDED
;
1719 return XML_STATUS_ERROR
;
1721 ps_parsing
= XML_PARSING
;
1723 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1725 if (errorCode
!= XML_ERROR_NONE
) {
1726 eventEndPtr
= eventPtr
;
1727 processor
= errorProcessor
;
1728 return XML_STATUS_ERROR
;
1731 switch (ps_parsing
) {
1733 result
= XML_STATUS_SUSPENDED
;
1735 case XML_INITIALIZED
:
1737 if (ps_finalBuffer
) {
1738 ps_parsing
= XML_FINISHED
;
1745 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1746 positionPtr
= bufferPtr
;
1751 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus
*status
)
1753 assert(status
!= NULL
);
1754 *status
= parser
->m_parsingStatus
;
1757 enum XML_Error XMLCALL
1758 XML_GetErrorCode(XML_Parser parser
)
1764 XML_GetCurrentByteIndex(XML_Parser parser
)
1767 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1772 XML_GetCurrentByteCount(XML_Parser parser
)
1774 if (eventEndPtr
&& eventPtr
)
1775 return (int)(eventEndPtr
- eventPtr
);
1779 const char * XMLCALL
1780 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1782 #ifdef XML_CONTEXT_BYTES
1783 if (eventPtr
&& buffer
) {
1784 *offset
= (int)(eventPtr
- buffer
);
1785 *size
= (int)(bufferEnd
- buffer
);
1788 #endif /* defined XML_CONTEXT_BYTES */
1793 XML_GetCurrentLineNumber(XML_Parser parser
)
1795 if (eventPtr
&& eventPtr
>= positionPtr
) {
1796 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1797 positionPtr
= eventPtr
;
1799 return position
.lineNumber
+ 1;
1803 XML_GetCurrentColumnNumber(XML_Parser parser
)
1805 if (eventPtr
&& eventPtr
>= positionPtr
) {
1806 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1807 positionPtr
= eventPtr
;
1809 return position
.columnNumber
;
1813 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1819 XML_MemMalloc(XML_Parser parser
, size_t size
)
1821 return MALLOC(size
);
1825 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1827 return REALLOC(ptr
, size
);
1831 XML_MemFree(XML_Parser parser
, void *ptr
)
1837 XML_DefaultCurrent(XML_Parser parser
)
1839 if (defaultHandler
) {
1840 if (openInternalEntities
)
1841 reportDefault(parser
,
1843 openInternalEntities
->internalEventPtr
,
1844 openInternalEntities
->internalEventEndPtr
);
1846 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1850 const XML_LChar
* XMLCALL
1851 XML_ErrorString(enum XML_Error code
)
1853 static const XML_LChar
* const message
[] = {
1855 XML_L("out of memory"),
1856 XML_L("syntax error"),
1857 XML_L("no element found"),
1858 XML_L("not well-formed (invalid token)"),
1859 XML_L("unclosed token"),
1860 XML_L("partial character"),
1861 XML_L("mismatched tag"),
1862 XML_L("duplicate attribute"),
1863 XML_L("junk after document element"),
1864 XML_L("illegal parameter entity reference"),
1865 XML_L("undefined entity"),
1866 XML_L("recursive entity reference"),
1867 XML_L("asynchronous entity"),
1868 XML_L("reference to invalid character number"),
1869 XML_L("reference to binary entity"),
1870 XML_L("reference to external entity in attribute"),
1871 XML_L("XML or text declaration not at start of entity"),
1872 XML_L("unknown encoding"),
1873 XML_L("encoding specified in XML declaration is incorrect"),
1874 XML_L("unclosed CDATA section"),
1875 XML_L("error in processing external entity reference"),
1876 XML_L("document is not standalone"),
1877 XML_L("unexpected parser state - please send a bug report"),
1878 XML_L("entity declared in parameter entity"),
1879 XML_L("requested feature requires XML_DTD support in Expat"),
1880 XML_L("cannot change setting once parsing has begun"),
1881 XML_L("unbound prefix"),
1882 XML_L("must not undeclare prefix"),
1883 XML_L("incomplete markup in parameter entity"),
1884 XML_L("XML declaration not well-formed"),
1885 XML_L("text declaration not well-formed"),
1886 XML_L("illegal character(s) in public id"),
1887 XML_L("parser suspended"),
1888 XML_L("parser not suspended"),
1889 XML_L("parsing aborted"),
1890 XML_L("parsing finished"),
1891 XML_L("cannot suspend in external parameter entity"),
1892 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1893 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1894 XML_L("prefix must not be bound to one of the reserved namespace names")
1896 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1897 return message
[code
];
1901 const XML_LChar
* XMLCALL
1902 XML_ExpatVersion(void) {
1904 /* V1 is used to string-ize the version number. However, it would
1905 string-ize the actual version macro *names* unless we get them
1906 substituted before being passed to V1. CPP is defined to expand
1907 a macro, then rescan for more expansions. Thus, we use V2 to expand
1908 the version macros, then CPP will expand the resulting V1() macro
1909 with the correct numerals. */
1910 /* ### I'm assuming cpp is portable in this respect... */
1912 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1913 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1915 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
1921 XML_Expat_Version XMLCALL
1922 XML_ExpatVersionInfo(void)
1924 XML_Expat_Version version
;
1926 version
.major
= XML_MAJOR_VERSION
;
1927 version
.minor
= XML_MINOR_VERSION
;
1928 version
.micro
= XML_MICRO_VERSION
;
1933 const XML_Feature
* XMLCALL
1934 XML_GetFeatureList(void)
1936 static const XML_Feature features
[] = {
1937 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)"),
1939 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"),
1942 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE"), 0},
1944 #ifdef XML_UNICODE_WCHAR_T
1945 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T"), 0},
1948 {XML_FEATURE_DTD
, XML_L("XML_DTD"), 0},
1950 #ifdef XML_CONTEXT_BYTES
1951 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
1955 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE"), 0},
1958 {XML_FEATURE_NS
, XML_L("XML_NS"), 0},
1960 #ifdef XML_LARGE_SIZE
1961 {XML_FEATURE_LARGE_SIZE
, XML_L("XML_LARGE_SIZE"), 0},
1963 {XML_FEATURE_END
, NULL
, 0}
1969 /* Initially tag->rawName always points into the parse buffer;
1970 for those TAG instances opened while the current parse buffer was
1971 processed, and not yet closed, we need to store tag->rawName in a more
1972 permanent location, since the parse buffer is about to be discarded.
1975 storeRawNames(XML_Parser parser
)
1977 TAG
*tag
= tagStack
;
1980 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
1981 char *rawNameBuf
= tag
->buf
+ nameLen
;
1982 /* Stop if already stored. Since tagStack is a stack, we can stop
1983 at the first entry that has already been copied; everything
1984 below it in the stack is already been accounted for in a
1985 previous call to this function.
1987 if (tag
->rawName
== rawNameBuf
)
1989 /* For re-use purposes we need to ensure that the
1990 size of tag->buf is a multiple of sizeof(XML_Char).
1992 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
1993 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
1994 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
1997 /* if tag->name.str points to tag->buf (only when namespace
1998 processing is off) then we have to update it
2000 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
2001 tag
->name
.str
= (XML_Char
*)temp
;
2002 /* if tag->name.localPart is set (when namespace processing is on)
2003 then update it as well, since it will always point into tag->buf
2005 if (tag
->name
.localPart
)
2006 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
2007 (XML_Char
*)tag
->buf
);
2009 tag
->bufEnd
= temp
+ bufSize
;
2010 rawNameBuf
= temp
+ nameLen
;
2012 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
2013 tag
->rawName
= rawNameBuf
;
2019 static enum XML_Error PTRCALL
2020 contentProcessor(XML_Parser parser
,
2023 const char **endPtr
)
2025 enum XML_Error result
= doContent(parser
, 0, encoding
, start
, end
,
2026 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2027 if (result
== XML_ERROR_NONE
) {
2028 if (!storeRawNames(parser
))
2029 return XML_ERROR_NO_MEMORY
;
2034 static enum XML_Error PTRCALL
2035 externalEntityInitProcessor(XML_Parser parser
,
2038 const char **endPtr
)
2040 enum XML_Error result
= initializeEncoding(parser
);
2041 if (result
!= XML_ERROR_NONE
)
2043 processor
= externalEntityInitProcessor2
;
2044 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
2047 static enum XML_Error PTRCALL
2048 externalEntityInitProcessor2(XML_Parser parser
,
2051 const char **endPtr
)
2053 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2054 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
2057 /* If we are at the end of the buffer, this would cause the next stage,
2058 i.e. externalEntityInitProcessor3, to pass control directly to
2059 doContent (by detecting XML_TOK_NONE) without processing any xml text
2060 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2062 if (next
== end
&& !ps_finalBuffer
) {
2064 return XML_ERROR_NONE
;
2068 case XML_TOK_PARTIAL
:
2069 if (!ps_finalBuffer
) {
2071 return XML_ERROR_NONE
;
2074 return XML_ERROR_UNCLOSED_TOKEN
;
2075 case XML_TOK_PARTIAL_CHAR
:
2076 if (!ps_finalBuffer
) {
2078 return XML_ERROR_NONE
;
2081 return XML_ERROR_PARTIAL_CHAR
;
2083 processor
= externalEntityInitProcessor3
;
2084 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
2087 static enum XML_Error PTRCALL
2088 externalEntityInitProcessor3(XML_Parser parser
,
2091 const char **endPtr
)
2094 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2096 tok
= XmlContentTok(encoding
, start
, end
, &next
);
2100 case XML_TOK_XML_DECL
:
2102 enum XML_Error result
;
2103 result
= processXmlDecl(parser
, 1, start
, next
);
2104 if (result
!= XML_ERROR_NONE
)
2106 switch (ps_parsing
) {
2109 return XML_ERROR_NONE
;
2111 return XML_ERROR_ABORTED
;
2117 case XML_TOK_PARTIAL
:
2118 if (!ps_finalBuffer
) {
2120 return XML_ERROR_NONE
;
2122 return XML_ERROR_UNCLOSED_TOKEN
;
2123 case XML_TOK_PARTIAL_CHAR
:
2124 if (!ps_finalBuffer
) {
2126 return XML_ERROR_NONE
;
2128 return XML_ERROR_PARTIAL_CHAR
;
2130 processor
= externalEntityContentProcessor
;
2132 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2135 static enum XML_Error PTRCALL
2136 externalEntityContentProcessor(XML_Parser parser
,
2139 const char **endPtr
)
2141 enum XML_Error result
= doContent(parser
, 1, encoding
, start
, end
,
2142 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2143 if (result
== XML_ERROR_NONE
) {
2144 if (!storeRawNames(parser
))
2145 return XML_ERROR_NO_MEMORY
;
2150 static enum XML_Error
2151 doContent(XML_Parser parser
,
2153 const ENCODING
*enc
,
2156 const char **nextPtr
,
2159 /* save one level of indirection */
2160 DTD
* const dtd
= _dtd
;
2162 const char **eventPP
;
2163 const char **eventEndPP
;
2164 if (enc
== encoding
) {
2165 eventPP
= &eventPtr
;
2166 eventEndPP
= &eventEndPtr
;
2169 eventPP
= &(openInternalEntities
->internalEventPtr
);
2170 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2175 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
2176 int tok
= XmlContentTok(enc
, s
, end
, &next
);
2179 case XML_TOK_TRAILING_CR
:
2182 return XML_ERROR_NONE
;
2185 if (characterDataHandler
) {
2187 characterDataHandler(handlerArg
, &c
, 1);
2189 else if (defaultHandler
)
2190 reportDefault(parser
, enc
, s
, end
);
2191 /* We are at the end of the final buffer, should we check for
2192 XML_SUSPENDED, XML_FINISHED?
2194 if (startTagLevel
== 0)
2195 return XML_ERROR_NO_ELEMENTS
;
2196 if (tagLevel
!= startTagLevel
)
2197 return XML_ERROR_ASYNC_ENTITY
;
2199 return XML_ERROR_NONE
;
2203 return XML_ERROR_NONE
;
2205 if (startTagLevel
> 0) {
2206 if (tagLevel
!= startTagLevel
)
2207 return XML_ERROR_ASYNC_ENTITY
;
2209 return XML_ERROR_NONE
;
2211 return XML_ERROR_NO_ELEMENTS
;
2212 case XML_TOK_INVALID
:
2214 return XML_ERROR_INVALID_TOKEN
;
2215 case XML_TOK_PARTIAL
:
2218 return XML_ERROR_NONE
;
2220 return XML_ERROR_UNCLOSED_TOKEN
;
2221 case XML_TOK_PARTIAL_CHAR
:
2224 return XML_ERROR_NONE
;
2226 return XML_ERROR_PARTIAL_CHAR
;
2227 case XML_TOK_ENTITY_REF
:
2229 const XML_Char
*name
;
2231 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
2232 s
+ enc
->minBytesPerChar
,
2233 next
- enc
->minBytesPerChar
);
2235 if (characterDataHandler
)
2236 characterDataHandler(handlerArg
, &ch
, 1);
2237 else if (defaultHandler
)
2238 reportDefault(parser
, enc
, s
, next
);
2241 name
= poolStoreString(&dtd
->pool
, enc
,
2242 s
+ enc
->minBytesPerChar
,
2243 next
- enc
->minBytesPerChar
);
2245 return XML_ERROR_NO_MEMORY
;
2246 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
2247 poolDiscard(&dtd
->pool
);
2248 /* First, determine if a check for an existing declaration is needed;
2249 if yes, check that the entity exists, and that it is internal,
2250 otherwise call the skipped entity or default handler.
2252 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
2254 return XML_ERROR_UNDEFINED_ENTITY
;
2255 else if (!entity
->is_internal
)
2256 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2259 if (skippedEntityHandler
)
2260 skippedEntityHandler(handlerArg
, name
, 0);
2261 else if (defaultHandler
)
2262 reportDefault(parser
, enc
, s
, next
);
2266 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2267 if (entity
->notation
)
2268 return XML_ERROR_BINARY_ENTITY_REF
;
2269 if (entity
->textPtr
) {
2270 enum XML_Error result
;
2271 if (!defaultExpandInternalEntities
) {
2272 if (skippedEntityHandler
)
2273 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2274 else if (defaultHandler
)
2275 reportDefault(parser
, enc
, s
, next
);
2278 result
= processInternalEntity(parser
, entity
, XML_FALSE
);
2279 if (result
!= XML_ERROR_NONE
)
2282 else if (externalEntityRefHandler
) {
2283 const XML_Char
*context
;
2284 entity
->open
= XML_TRUE
;
2285 context
= getContext(parser
);
2286 entity
->open
= XML_FALSE
;
2288 return XML_ERROR_NO_MEMORY
;
2289 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2294 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2295 poolDiscard(&tempPool
);
2297 else if (defaultHandler
)
2298 reportDefault(parser
, enc
, s
, next
);
2301 case XML_TOK_START_TAG_NO_ATTS
:
2303 case XML_TOK_START_TAG_WITH_ATTS
:
2306 enum XML_Error result
;
2310 freeTagList
= freeTagList
->parent
;
2313 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2315 return XML_ERROR_NO_MEMORY
;
2316 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2319 return XML_ERROR_NO_MEMORY
;
2321 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2323 tag
->bindings
= NULL
;
2324 tag
->parent
= tagStack
;
2326 tag
->name
.localPart
= NULL
;
2327 tag
->name
.prefix
= NULL
;
2328 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2329 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2332 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2333 const char *fromPtr
= tag
->rawName
;
2334 toPtr
= (XML_Char
*)tag
->buf
;
2339 &fromPtr
, rawNameEnd
,
2340 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2341 convLen
= (int)(toPtr
- (XML_Char
*)tag
->buf
);
2342 if (fromPtr
== rawNameEnd
) {
2343 tag
->name
.strLen
= convLen
;
2346 bufSize
= (int)(tag
->bufEnd
- tag
->buf
) << 1;
2348 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2350 return XML_ERROR_NO_MEMORY
;
2352 tag
->bufEnd
= temp
+ bufSize
;
2353 toPtr
= (XML_Char
*)temp
+ convLen
;
2357 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2358 *toPtr
= XML_T('\0');
2359 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2362 if (startElementHandler
)
2363 startElementHandler(handlerArg
, tag
->name
.str
,
2364 (const XML_Char
**)atts
);
2365 else if (defaultHandler
)
2366 reportDefault(parser
, enc
, s
, next
);
2367 poolClear(&tempPool
);
2370 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2372 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2374 const char *rawName
= s
+ enc
->minBytesPerChar
;
2375 enum XML_Error result
;
2376 BINDING
*bindings
= NULL
;
2377 XML_Bool noElmHandlers
= XML_TRUE
;
2379 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2380 rawName
+ XmlNameLength(enc
, rawName
));
2382 return XML_ERROR_NO_MEMORY
;
2383 poolFinish(&tempPool
);
2384 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2387 poolFinish(&tempPool
);
2388 if (startElementHandler
) {
2389 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2390 noElmHandlers
= XML_FALSE
;
2392 if (endElementHandler
) {
2393 if (startElementHandler
)
2394 *eventPP
= *eventEndPP
;
2395 endElementHandler(handlerArg
, name
.str
);
2396 noElmHandlers
= XML_FALSE
;
2398 if (noElmHandlers
&& defaultHandler
)
2399 reportDefault(parser
, enc
, s
, next
);
2400 poolClear(&tempPool
);
2402 BINDING
*b
= bindings
;
2403 if (endNamespaceDeclHandler
)
2404 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2405 bindings
= bindings
->nextTagBinding
;
2406 b
->nextTagBinding
= freeBindingList
;
2407 freeBindingList
= b
;
2408 b
->prefix
->binding
= b
->prevPrefixBinding
;
2412 return epilogProcessor(parser
, next
, end
, nextPtr
);
2414 case XML_TOK_END_TAG
:
2415 if (tagLevel
== startTagLevel
)
2416 return XML_ERROR_ASYNC_ENTITY
;
2419 const char *rawName
;
2420 TAG
*tag
= tagStack
;
2421 tagStack
= tag
->parent
;
2422 tag
->parent
= freeTagList
;
2424 rawName
= s
+ enc
->minBytesPerChar
*2;
2425 len
= XmlNameLength(enc
, rawName
);
2426 if (len
!= tag
->rawNameLength
2427 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2429 return XML_ERROR_TAG_MISMATCH
;
2432 if (endElementHandler
) {
2433 const XML_Char
*localPart
;
2434 const XML_Char
*prefix
;
2436 localPart
= tag
->name
.localPart
;
2437 if (ns
&& localPart
) {
2438 /* localPart and prefix may have been overwritten in
2439 tag->name.str, since this points to the binding->uri
2440 buffer which gets re-used; so we have to add them again
2442 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2443 /* don't need to check for space - already done in storeAtts() */
2444 while (*localPart
) *uri
++ = *localPart
++;
2445 prefix
= (XML_Char
*)tag
->name
.prefix
;
2446 if (ns_triplets
&& prefix
) {
2447 *uri
++ = namespaceSeparator
;
2448 while (*prefix
) *uri
++ = *prefix
++;
2452 endElementHandler(handlerArg
, tag
->name
.str
);
2454 else if (defaultHandler
)
2455 reportDefault(parser
, enc
, s
, next
);
2456 while (tag
->bindings
) {
2457 BINDING
*b
= tag
->bindings
;
2458 if (endNamespaceDeclHandler
)
2459 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2460 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2461 b
->nextTagBinding
= freeBindingList
;
2462 freeBindingList
= b
;
2463 b
->prefix
->binding
= b
->prevPrefixBinding
;
2466 return epilogProcessor(parser
, next
, end
, nextPtr
);
2469 case XML_TOK_CHAR_REF
:
2471 int n
= XmlCharRefNumber(enc
, s
);
2473 return XML_ERROR_BAD_CHAR_REF
;
2474 if (characterDataHandler
) {
2475 XML_Char buf
[XML_ENCODE_MAX
];
2476 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2478 else if (defaultHandler
)
2479 reportDefault(parser
, enc
, s
, next
);
2482 case XML_TOK_XML_DECL
:
2483 return XML_ERROR_MISPLACED_XML_PI
;
2484 case XML_TOK_DATA_NEWLINE
:
2485 if (characterDataHandler
) {
2487 characterDataHandler(handlerArg
, &c
, 1);
2489 else if (defaultHandler
)
2490 reportDefault(parser
, enc
, s
, next
);
2492 case XML_TOK_CDATA_SECT_OPEN
:
2494 enum XML_Error result
;
2495 if (startCdataSectionHandler
)
2496 startCdataSectionHandler(handlerArg
);
2498 /* Suppose you doing a transformation on a document that involves
2499 changing only the character data. You set up a defaultHandler
2500 and a characterDataHandler. The defaultHandler simply copies
2501 characters through. The characterDataHandler does the
2502 transformation and writes the characters out escaping them as
2503 necessary. This case will fail to work if we leave out the
2504 following two lines (because & and < inside CDATA sections will
2505 be incorrectly escaped).
2507 However, now we have a start/endCdataSectionHandler, so it seems
2508 easier to let the user deal with this.
2510 else if (characterDataHandler
)
2511 characterDataHandler(handlerArg
, dataBuf
, 0);
2513 else if (defaultHandler
)
2514 reportDefault(parser
, enc
, s
, next
);
2515 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
2516 if (result
!= XML_ERROR_NONE
)
2519 processor
= cdataSectionProcessor
;
2524 case XML_TOK_TRAILING_RSQB
:
2527 return XML_ERROR_NONE
;
2529 if (characterDataHandler
) {
2530 if (MUST_CONVERT(enc
, s
)) {
2531 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2532 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2533 characterDataHandler(handlerArg
, dataBuf
,
2534 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2537 characterDataHandler(handlerArg
,
2539 (int)((XML_Char
*)end
- (XML_Char
*)s
));
2541 else if (defaultHandler
)
2542 reportDefault(parser
, enc
, s
, end
);
2543 /* We are at the end of the final buffer, should we check for
2544 XML_SUSPENDED, XML_FINISHED?
2546 if (startTagLevel
== 0) {
2548 return XML_ERROR_NO_ELEMENTS
;
2550 if (tagLevel
!= startTagLevel
) {
2552 return XML_ERROR_ASYNC_ENTITY
;
2555 return XML_ERROR_NONE
;
2556 case XML_TOK_DATA_CHARS
:
2558 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
2559 if (charDataHandler
) {
2560 if (MUST_CONVERT(enc
, s
)) {
2562 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2563 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2565 charDataHandler(handlerArg
, dataBuf
,
2566 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2573 charDataHandler(handlerArg
,
2575 (int)((XML_Char
*)next
- (XML_Char
*)s
));
2577 else if (defaultHandler
)
2578 reportDefault(parser
, enc
, s
, next
);
2582 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2583 return XML_ERROR_NO_MEMORY
;
2585 case XML_TOK_COMMENT
:
2586 if (!reportComment(parser
, enc
, s
, next
))
2587 return XML_ERROR_NO_MEMORY
;
2591 reportDefault(parser
, enc
, s
, next
);
2594 *eventPP
= s
= next
;
2595 switch (ps_parsing
) {
2598 return XML_ERROR_NONE
;
2600 return XML_ERROR_ABORTED
;
2607 /* Precondition: all arguments must be non-NULL;
2609 - normalize attributes
2610 - check attributes for well-formedness
2611 - generate namespace aware attribute names (URI, prefix)
2612 - build list of attributes for startElementHandler
2613 - default attributes
2614 - process namespace declarations (check and report them)
2615 - generate namespace aware element name (URI, prefix)
2617 static enum XML_Error
2618 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2619 const char *attStr
, TAG_NAME
*tagNamePtr
,
2620 BINDING
**bindingsPtr
)
2622 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2623 ELEMENT_TYPE
*elementType
;
2625 const XML_Char
**appAtts
; /* the attribute list for the application */
2633 const XML_Char
*localPart
;
2635 /* lookup the element type name */
2636 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, tagNamePtr
->str
,0);
2638 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2640 return XML_ERROR_NO_MEMORY
;
2641 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
->elementTypes
, name
,
2642 sizeof(ELEMENT_TYPE
));
2644 return XML_ERROR_NO_MEMORY
;
2645 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2646 return XML_ERROR_NO_MEMORY
;
2648 nDefaultAtts
= elementType
->nDefaultAtts
;
2650 /* get the attributes from the tokenizer */
2651 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2652 if (n
+ nDefaultAtts
> attsSize
) {
2653 int oldAttsSize
= attsSize
;
2655 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2656 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2658 return XML_ERROR_NO_MEMORY
;
2660 if (n
> oldAttsSize
)
2661 XmlGetAttributes(enc
, attStr
, n
, atts
);
2664 appAtts
= (const XML_Char
**)atts
;
2665 for (i
= 0; i
< n
; i
++) {
2666 /* add the name and value to the attribute list */
2667 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
2669 + XmlNameLength(enc
, atts
[i
].name
));
2671 return XML_ERROR_NO_MEMORY
;
2672 /* Detect duplicate attributes by their QNames. This does not work when
2673 namespace processing is turned on and different prefixes for the same
2674 namespace are used. For this case we have a check further down.
2676 if ((attId
->name
)[-1]) {
2677 if (enc
== encoding
)
2678 eventPtr
= atts
[i
].name
;
2679 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2681 (attId
->name
)[-1] = 1;
2682 appAtts
[attIndex
++] = attId
->name
;
2683 if (!atts
[i
].normalized
) {
2684 enum XML_Error result
;
2685 XML_Bool isCdata
= XML_TRUE
;
2687 /* figure out whether declared as other than CDATA */
2688 if (attId
->maybeTokenized
) {
2690 for (j
= 0; j
< nDefaultAtts
; j
++) {
2691 if (attId
== elementType
->defaultAtts
[j
].id
) {
2692 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2698 /* normalize the attribute value */
2699 result
= storeAttributeValue(parser
, enc
, isCdata
,
2700 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2704 appAtts
[attIndex
] = poolStart(&tempPool
);
2705 poolFinish(&tempPool
);
2708 /* the value did not need normalizing */
2709 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2711 if (appAtts
[attIndex
] == 0)
2712 return XML_ERROR_NO_MEMORY
;
2713 poolFinish(&tempPool
);
2715 /* handle prefixed attribute names */
2716 if (attId
->prefix
) {
2718 /* deal with namespace declarations here */
2719 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2720 appAtts
[attIndex
], bindingsPtr
);
2726 /* deal with other prefixed names later */
2729 (attId
->name
)[-1] = 2;
2736 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2737 nSpecifiedAtts
= attIndex
;
2738 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2739 for (i
= 0; i
< attIndex
; i
+= 2)
2740 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2748 /* do attribute defaulting */
2749 for (i
= 0; i
< nDefaultAtts
; i
++) {
2750 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2751 if (!(da
->id
->name
)[-1] && da
->value
) {
2752 if (da
->id
->prefix
) {
2753 if (da
->id
->xmlns
) {
2754 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2755 da
->value
, bindingsPtr
);
2760 (da
->id
->name
)[-1] = 2;
2762 appAtts
[attIndex
++] = da
->id
->name
;
2763 appAtts
[attIndex
++] = da
->value
;
2767 (da
->id
->name
)[-1] = 1;
2768 appAtts
[attIndex
++] = da
->id
->name
;
2769 appAtts
[attIndex
++] = da
->value
;
2773 appAtts
[attIndex
] = 0;
2775 /* expand prefixed attribute names, check for duplicates,
2776 and clear flags that say whether attributes were specified */
2779 int j
; /* hash table index */
2780 unsigned long version
= nsAttsVersion
;
2781 int nsAttsSize
= (int)1 << nsAttsPower
;
2782 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2783 if ((nPrefixes
<< 1) >> nsAttsPower
) { /* true for nsAttsPower = 0 */
2785 /* hash table size must also be a power of 2 and >= 8 */
2786 while (nPrefixes
>> nsAttsPower
++);
2787 if (nsAttsPower
< 3)
2789 nsAttsSize
= (int)1 << nsAttsPower
;
2790 temp
= (NS_ATT
*)REALLOC(nsAtts
, nsAttsSize
* sizeof(NS_ATT
));
2792 return XML_ERROR_NO_MEMORY
;
2794 version
= 0; /* force re-initialization of nsAtts hash table */
2796 /* using a version flag saves us from initializing nsAtts every time */
2797 if (!version
) { /* initialize version flags when version wraps around */
2798 version
= INIT_ATTS_VERSION
;
2799 for (j
= nsAttsSize
; j
!= 0; )
2800 nsAtts
[--j
].version
= version
;
2802 nsAttsVersion
= --version
;
2804 /* expand prefixed names and check for duplicates */
2805 for (; i
< attIndex
; i
+= 2) {
2806 const XML_Char
*s
= appAtts
[i
];
2807 if (s
[-1] == 2) { /* prefixed */
2810 unsigned long uriHash
= 0;
2811 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2812 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, s
, 0);
2813 b
= id
->prefix
->binding
;
2815 return XML_ERROR_UNBOUND_PREFIX
;
2817 /* as we expand the name we also calculate its hash value */
2818 for (j
= 0; j
< b
->uriLen
; j
++) {
2819 const XML_Char c
= b
->uri
[j
];
2820 if (!poolAppendChar(&tempPool
, c
))
2821 return XML_ERROR_NO_MEMORY
;
2822 uriHash
= CHAR_HASH(uriHash
, c
);
2824 while (*s
++ != XML_T(ASCII_COLON
))
2826 do { /* copies null terminator */
2827 const XML_Char c
= *s
;
2828 if (!poolAppendChar(&tempPool
, *s
))
2829 return XML_ERROR_NO_MEMORY
;
2830 uriHash
= CHAR_HASH(uriHash
, c
);
2833 { /* Check hash table for duplicate of expanded name (uriName).
2834 Derived from code in lookup(HASH_TABLE *table, ...).
2836 unsigned char step
= 0;
2837 unsigned long mask
= nsAttsSize
- 1;
2838 j
= uriHash
& mask
; /* index into hash table */
2839 while (nsAtts
[j
].version
== version
) {
2840 /* for speed we compare stored hash values first */
2841 if (uriHash
== nsAtts
[j
].hash
) {
2842 const XML_Char
*s1
= poolStart(&tempPool
);
2843 const XML_Char
*s2
= nsAtts
[j
].uriName
;
2844 /* s1 is null terminated, but not s2 */
2845 for (; *s1
== *s2
&& *s1
!= 0; s1
++, s2
++);
2847 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2850 step
= PROBE_STEP(uriHash
, mask
, nsAttsPower
);
2851 j
< step
? (j
+= nsAttsSize
- step
) : (j
-= step
);
2855 if (ns_triplets
) { /* append namespace separator and prefix */
2856 tempPool
.ptr
[-1] = namespaceSeparator
;
2857 s
= b
->prefix
->name
;
2859 if (!poolAppendChar(&tempPool
, *s
))
2860 return XML_ERROR_NO_MEMORY
;
2864 /* store expanded name in attribute list */
2865 s
= poolStart(&tempPool
);
2866 poolFinish(&tempPool
);
2869 /* fill empty slot with new version, uriName and hash value */
2870 nsAtts
[j
].version
= version
;
2871 nsAtts
[j
].hash
= uriHash
;
2872 nsAtts
[j
].uriName
= s
;
2879 else /* not prefixed */
2880 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2883 /* clear flags for the remaining attributes */
2884 for (; i
< attIndex
; i
+= 2)
2885 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2886 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2887 binding
->attId
->name
[-1] = 0;
2890 return XML_ERROR_NONE
;
2892 /* expand the element type name */
2893 if (elementType
->prefix
) {
2894 binding
= elementType
->prefix
->binding
;
2896 return XML_ERROR_UNBOUND_PREFIX
;
2897 localPart
= tagNamePtr
->str
;
2898 while (*localPart
++ != XML_T(ASCII_COLON
))
2901 else if (dtd
->defaultPrefix
.binding
) {
2902 binding
= dtd
->defaultPrefix
.binding
;
2903 localPart
= tagNamePtr
->str
;
2906 return XML_ERROR_NONE
;
2908 if (ns_triplets
&& binding
->prefix
->name
) {
2909 for (; binding
->prefix
->name
[prefixLen
++];)
2910 ; /* prefixLen includes null terminator */
2912 tagNamePtr
->localPart
= localPart
;
2913 tagNamePtr
->uriLen
= binding
->uriLen
;
2914 tagNamePtr
->prefix
= binding
->prefix
->name
;
2915 tagNamePtr
->prefixLen
= prefixLen
;
2916 for (i
= 0; localPart
[i
++];)
2917 ; /* i includes null terminator */
2918 n
= i
+ binding
->uriLen
+ prefixLen
;
2919 if (n
> binding
->uriAlloc
) {
2921 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2923 return XML_ERROR_NO_MEMORY
;
2924 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2925 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2926 for (p
= tagStack
; p
; p
= p
->parent
)
2927 if (p
->name
.str
== binding
->uri
)
2932 /* if namespaceSeparator != '\0' then uri includes it already */
2933 uri
= binding
->uri
+ binding
->uriLen
;
2934 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
2935 /* we always have a namespace separator between localPart and prefix */
2938 *uri
= namespaceSeparator
; /* replace null terminator */
2939 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
2941 tagNamePtr
->str
= binding
->uri
;
2942 return XML_ERROR_NONE
;
2945 /* addBinding() overwrites the value of prefix->binding without checking.
2946 Therefore one must keep track of the old value outside of addBinding().
2948 static enum XML_Error
2949 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
2950 const XML_Char
*uri
, BINDING
**bindingsPtr
)
2952 static const XML_Char xmlNamespace
[] = {
2953 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
2954 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
2955 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
,
2956 ASCII_SLASH
, ASCII_1
, ASCII_9
, ASCII_9
, ASCII_8
, ASCII_SLASH
,
2957 ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
, ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
,
2960 static const int xmlLen
=
2961 (int)sizeof(xmlNamespace
)/sizeof(XML_Char
) - 1;
2962 static const XML_Char xmlnsNamespace
[] = {
2963 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
2964 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
2965 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_2
, ASCII_0
, ASCII_0
,
2966 ASCII_0
, ASCII_SLASH
, ASCII_x
, ASCII_m
, ASCII_l
, ASCII_n
, ASCII_s
,
2969 static const int xmlnsLen
=
2970 (int)sizeof(xmlnsNamespace
)/sizeof(XML_Char
) - 1;
2972 XML_Bool mustBeXML
= XML_FALSE
;
2973 XML_Bool isXML
= XML_TRUE
;
2974 XML_Bool isXMLNS
= XML_TRUE
;
2979 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
2980 if (*uri
== XML_T('\0') && prefix
->name
)
2981 return XML_ERROR_UNDECLARING_PREFIX
;
2984 && prefix
->name
[0] == XML_T(ASCII_x
)
2985 && prefix
->name
[1] == XML_T(ASCII_m
)
2986 && prefix
->name
[2] == XML_T(ASCII_l
)) {
2988 /* Not allowed to bind xmlns */
2989 if (prefix
->name
[3] == XML_T(ASCII_n
)
2990 && prefix
->name
[4] == XML_T(ASCII_s
)
2991 && prefix
->name
[5] == XML_T('\0'))
2992 return XML_ERROR_RESERVED_PREFIX_XMLNS
;
2994 if (prefix
->name
[3] == XML_T('\0'))
2995 mustBeXML
= XML_TRUE
;
2998 for (len
= 0; uri
[len
]; len
++) {
2999 if (isXML
&& (len
> xmlLen
|| uri
[len
] != xmlNamespace
[len
]))
3002 if (!mustBeXML
&& isXMLNS
3003 && (len
> xmlnsLen
|| uri
[len
] != xmlnsNamespace
[len
]))
3004 isXMLNS
= XML_FALSE
;
3006 isXML
= isXML
&& len
== xmlLen
;
3007 isXMLNS
= isXMLNS
&& len
== xmlnsLen
;
3009 if (mustBeXML
!= isXML
)
3010 return mustBeXML
? XML_ERROR_RESERVED_PREFIX_XML
3011 : XML_ERROR_RESERVED_NAMESPACE_URI
;
3014 return XML_ERROR_RESERVED_NAMESPACE_URI
;
3016 if (namespaceSeparator
)
3018 if (freeBindingList
) {
3019 b
= freeBindingList
;
3020 if (len
> b
->uriAlloc
) {
3021 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
3022 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3024 return XML_ERROR_NO_MEMORY
;
3026 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3028 freeBindingList
= b
->nextTagBinding
;
3031 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
3033 return XML_ERROR_NO_MEMORY
;
3034 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3037 return XML_ERROR_NO_MEMORY
;
3039 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3042 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
3043 if (namespaceSeparator
)
3044 b
->uri
[len
- 1] = namespaceSeparator
;
3047 b
->prevPrefixBinding
= prefix
->binding
;
3048 /* NULL binding when default namespace undeclared */
3049 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
3050 prefix
->binding
= NULL
;
3052 prefix
->binding
= b
;
3053 b
->nextTagBinding
= *bindingsPtr
;
3055 /* if attId == NULL then we are not starting a namespace scope */
3056 if (attId
&& startNamespaceDeclHandler
)
3057 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
3058 prefix
->binding
? uri
: 0);
3059 return XML_ERROR_NONE
;
3062 /* The idea here is to avoid using stack for each CDATA section when
3063 the whole file is parsed with one call.
3065 static enum XML_Error PTRCALL
3066 cdataSectionProcessor(XML_Parser parser
,
3069 const char **endPtr
)
3071 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
,
3072 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3073 if (result
!= XML_ERROR_NONE
)
3076 if (parentParser
) { /* we are parsing an external entity */
3077 processor
= externalEntityContentProcessor
;
3078 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
3081 processor
= contentProcessor
;
3082 return contentProcessor(parser
, start
, end
, endPtr
);
3088 /* startPtr gets set to non-null if the section is closed, and to null if
3089 the section is not yet closed.
3091 static enum XML_Error
3092 doCdataSection(XML_Parser parser
,
3093 const ENCODING
*enc
,
3094 const char **startPtr
,
3096 const char **nextPtr
,
3099 const char *s
= *startPtr
;
3100 const char **eventPP
;
3101 const char **eventEndPP
;
3102 if (enc
== encoding
) {
3103 eventPP
= &eventPtr
;
3105 eventEndPP
= &eventEndPtr
;
3108 eventPP
= &(openInternalEntities
->internalEventPtr
);
3109 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3116 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
3119 case XML_TOK_CDATA_SECT_CLOSE
:
3120 if (endCdataSectionHandler
)
3121 endCdataSectionHandler(handlerArg
);
3123 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3124 else if (characterDataHandler
)
3125 characterDataHandler(handlerArg
, dataBuf
, 0);
3127 else if (defaultHandler
)
3128 reportDefault(parser
, enc
, s
, next
);
3131 if (ps_parsing
== XML_FINISHED
)
3132 return XML_ERROR_ABORTED
;
3134 return XML_ERROR_NONE
;
3135 case XML_TOK_DATA_NEWLINE
:
3136 if (characterDataHandler
) {
3138 characterDataHandler(handlerArg
, &c
, 1);
3140 else if (defaultHandler
)
3141 reportDefault(parser
, enc
, s
, next
);
3143 case XML_TOK_DATA_CHARS
:
3145 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
3146 if (charDataHandler
) {
3147 if (MUST_CONVERT(enc
, s
)) {
3149 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3150 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3152 charDataHandler(handlerArg
, dataBuf
,
3153 (int)(dataPtr
- (ICHAR
*)dataBuf
));
3160 charDataHandler(handlerArg
,
3162 (int)((XML_Char
*)next
- (XML_Char
*)s
));
3164 else if (defaultHandler
)
3165 reportDefault(parser
, enc
, s
, next
);
3168 case XML_TOK_INVALID
:
3170 return XML_ERROR_INVALID_TOKEN
;
3171 case XML_TOK_PARTIAL_CHAR
:
3174 return XML_ERROR_NONE
;
3176 return XML_ERROR_PARTIAL_CHAR
;
3177 case XML_TOK_PARTIAL
:
3181 return XML_ERROR_NONE
;
3183 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
3186 return XML_ERROR_UNEXPECTED_STATE
;
3189 *eventPP
= s
= next
;
3190 switch (ps_parsing
) {
3193 return XML_ERROR_NONE
;
3195 return XML_ERROR_ABORTED
;
3204 /* The idea here is to avoid using stack for each IGNORE section when
3205 the whole file is parsed with one call.
3207 static enum XML_Error PTRCALL
3208 ignoreSectionProcessor(XML_Parser parser
,
3211 const char **endPtr
)
3213 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
,
3214 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3215 if (result
!= XML_ERROR_NONE
)
3218 processor
= prologProcessor
;
3219 return prologProcessor(parser
, start
, end
, endPtr
);
3224 /* startPtr gets set to non-null is the section is closed, and to null
3225 if the section is not yet closed.
3227 static enum XML_Error
3228 doIgnoreSection(XML_Parser parser
,
3229 const ENCODING
*enc
,
3230 const char **startPtr
,
3232 const char **nextPtr
,
3237 const char *s
= *startPtr
;
3238 const char **eventPP
;
3239 const char **eventEndPP
;
3240 if (enc
== encoding
) {
3241 eventPP
= &eventPtr
;
3243 eventEndPP
= &eventEndPtr
;
3246 eventPP
= &(openInternalEntities
->internalEventPtr
);
3247 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3251 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
3254 case XML_TOK_IGNORE_SECT
:
3256 reportDefault(parser
, enc
, s
, next
);
3259 if (ps_parsing
== XML_FINISHED
)
3260 return XML_ERROR_ABORTED
;
3262 return XML_ERROR_NONE
;
3263 case XML_TOK_INVALID
:
3265 return XML_ERROR_INVALID_TOKEN
;
3266 case XML_TOK_PARTIAL_CHAR
:
3269 return XML_ERROR_NONE
;
3271 return XML_ERROR_PARTIAL_CHAR
;
3272 case XML_TOK_PARTIAL
:
3276 return XML_ERROR_NONE
;
3278 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3281 return XML_ERROR_UNEXPECTED_STATE
;
3286 #endif /* XML_DTD */
3288 static enum XML_Error
3289 initializeEncoding(XML_Parser parser
)
3293 char encodingBuf
[128];
3294 if (!protocolEncodingName
)
3298 for (i
= 0; protocolEncodingName
[i
]; i
++) {
3299 if (i
== sizeof(encodingBuf
) - 1
3300 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
3301 encodingBuf
[0] = '\0';
3304 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
3306 encodingBuf
[i
] = '\0';
3310 s
= protocolEncodingName
;
3312 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
3313 return XML_ERROR_NONE
;
3314 return handleUnknownEncoding(parser
, protocolEncodingName
);
3317 static enum XML_Error
3318 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
3319 const char *s
, const char *next
)
3321 const char *encodingName
= NULL
;
3322 const XML_Char
*storedEncName
= NULL
;
3323 const ENCODING
*newEncoding
= NULL
;
3324 const char *version
= NULL
;
3325 const char *versionend
;
3326 const XML_Char
*storedversion
= NULL
;
3327 int standalone
= -1;
3330 : XmlParseXmlDecl
)(isGeneralTextEntity
,
3340 if (isGeneralTextEntity
)
3341 return XML_ERROR_TEXT_DECL
;
3343 return XML_ERROR_XML_DECL
;
3345 if (!isGeneralTextEntity
&& standalone
== 1) {
3346 _dtd
->standalone
= XML_TRUE
;
3348 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
3349 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
3350 #endif /* XML_DTD */
3352 if (xmlDeclHandler
) {
3353 if (encodingName
!= NULL
) {
3354 storedEncName
= poolStoreString(&temp2Pool
,
3358 + XmlNameLength(encoding
, encodingName
));
3360 return XML_ERROR_NO_MEMORY
;
3361 poolFinish(&temp2Pool
);
3364 storedversion
= poolStoreString(&temp2Pool
,
3367 versionend
- encoding
->minBytesPerChar
);
3369 return XML_ERROR_NO_MEMORY
;
3371 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
3373 else if (defaultHandler
)
3374 reportDefault(parser
, encoding
, s
, next
);
3375 if (protocolEncodingName
== NULL
) {
3377 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
3378 eventPtr
= encodingName
;
3379 return XML_ERROR_INCORRECT_ENCODING
;
3381 encoding
= newEncoding
;
3383 else if (encodingName
) {
3384 enum XML_Error result
;
3385 if (!storedEncName
) {
3386 storedEncName
= poolStoreString(
3387 &temp2Pool
, encoding
, encodingName
,
3388 encodingName
+ XmlNameLength(encoding
, encodingName
));
3390 return XML_ERROR_NO_MEMORY
;
3392 result
= handleUnknownEncoding(parser
, storedEncName
);
3393 poolClear(&temp2Pool
);
3394 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
3395 eventPtr
= encodingName
;
3400 if (storedEncName
|| storedversion
)
3401 poolClear(&temp2Pool
);
3403 return XML_ERROR_NONE
;
3406 static enum XML_Error
3407 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
3409 if (unknownEncodingHandler
) {
3412 for (i
= 0; i
< 256; i
++)
3414 info
.convert
= NULL
;
3416 info
.release
= NULL
;
3417 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
3420 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
3421 if (!unknownEncodingMem
) {
3423 info
.release(info
.data
);
3424 return XML_ERROR_NO_MEMORY
;
3427 ? XmlInitUnknownEncodingNS
3428 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3433 unknownEncodingData
= info
.data
;
3434 unknownEncodingRelease
= info
.release
;
3436 return XML_ERROR_NONE
;
3439 if (info
.release
!= NULL
)
3440 info
.release(info
.data
);
3442 return XML_ERROR_UNKNOWN_ENCODING
;
3445 static enum XML_Error PTRCALL
3446 prologInitProcessor(XML_Parser parser
,
3449 const char **nextPtr
)
3451 enum XML_Error result
= initializeEncoding(parser
);
3452 if (result
!= XML_ERROR_NONE
)
3454 processor
= prologProcessor
;
3455 return prologProcessor(parser
, s
, end
, nextPtr
);
3460 static enum XML_Error PTRCALL
3461 externalParEntInitProcessor(XML_Parser parser
,
3464 const char **nextPtr
)
3466 enum XML_Error result
= initializeEncoding(parser
);
3467 if (result
!= XML_ERROR_NONE
)
3470 /* we know now that XML_Parse(Buffer) has been called,
3471 so we consider the external parameter entity read */
3472 _dtd
->paramEntityRead
= XML_TRUE
;
3474 if (prologState
.inEntityValue
) {
3475 processor
= entityValueInitProcessor
;
3476 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3479 processor
= externalParEntProcessor
;
3480 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3484 static enum XML_Error PTRCALL
3485 entityValueInitProcessor(XML_Parser parser
,
3488 const char **nextPtr
)
3491 const char *start
= s
;
3492 const char *next
= start
;
3496 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3499 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3501 return XML_ERROR_NONE
;
3504 case XML_TOK_INVALID
:
3505 return XML_ERROR_INVALID_TOKEN
;
3506 case XML_TOK_PARTIAL
:
3507 return XML_ERROR_UNCLOSED_TOKEN
;
3508 case XML_TOK_PARTIAL_CHAR
:
3509 return XML_ERROR_PARTIAL_CHAR
;
3510 case XML_TOK_NONE
: /* start == end */
3514 /* found end of entity value - can store it now */
3515 return storeEntityValue(parser
, encoding
, s
, end
);
3517 else if (tok
== XML_TOK_XML_DECL
) {
3518 enum XML_Error result
;
3519 result
= processXmlDecl(parser
, 0, start
, next
);
3520 if (result
!= XML_ERROR_NONE
)
3522 switch (ps_parsing
) {
3525 return XML_ERROR_NONE
;
3527 return XML_ERROR_ABORTED
;
3531 /* stop scanning for text declaration - we found one */
3532 processor
= entityValueProcessor
;
3533 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3535 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3536 return XML_TOK_NONE on the next call, which would then cause the
3537 function to exit with *nextPtr set to s - that is what we want for other
3538 tokens, but not for the BOM - we would rather like to skip it;
3539 then, when this routine is entered the next time, XmlPrologTok will
3540 return XML_TOK_INVALID, since the BOM is still in the buffer
3542 else if (tok
== XML_TOK_BOM
&& next
== end
&& !ps_finalBuffer
) {
3544 return XML_ERROR_NONE
;
3551 static enum XML_Error PTRCALL
3552 externalParEntProcessor(XML_Parser parser
,
3555 const char **nextPtr
)
3557 const char *next
= s
;
3560 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3562 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3564 return XML_ERROR_NONE
;
3567 case XML_TOK_INVALID
:
3568 return XML_ERROR_INVALID_TOKEN
;
3569 case XML_TOK_PARTIAL
:
3570 return XML_ERROR_UNCLOSED_TOKEN
;
3571 case XML_TOK_PARTIAL_CHAR
:
3572 return XML_ERROR_PARTIAL_CHAR
;
3573 case XML_TOK_NONE
: /* start == end */
3578 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3579 However, when parsing an external subset, doProlog will not accept a BOM
3580 as valid, and report a syntax error, so we have to skip the BOM
3582 else if (tok
== XML_TOK_BOM
) {
3584 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3587 processor
= prologProcessor
;
3588 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3589 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3592 static enum XML_Error PTRCALL
3593 entityValueProcessor(XML_Parser parser
,
3596 const char **nextPtr
)
3598 const char *start
= s
;
3599 const char *next
= s
;
3600 const ENCODING
*enc
= encoding
;
3604 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3606 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3608 return XML_ERROR_NONE
;
3611 case XML_TOK_INVALID
:
3612 return XML_ERROR_INVALID_TOKEN
;
3613 case XML_TOK_PARTIAL
:
3614 return XML_ERROR_UNCLOSED_TOKEN
;
3615 case XML_TOK_PARTIAL_CHAR
:
3616 return XML_ERROR_PARTIAL_CHAR
;
3617 case XML_TOK_NONE
: /* start == end */
3621 /* found end of entity value - can store it now */
3622 return storeEntityValue(parser
, enc
, s
, end
);
3628 #endif /* XML_DTD */
3630 static enum XML_Error PTRCALL
3631 prologProcessor(XML_Parser parser
,
3634 const char **nextPtr
)
3636 const char *next
= s
;
3637 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3638 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3639 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3642 static enum XML_Error
3643 doProlog(XML_Parser parser
,
3644 const ENCODING
*enc
,
3649 const char **nextPtr
,
3653 static const XML_Char externalSubsetName
[] = { ASCII_HASH
, '\0' };
3654 #endif /* XML_DTD */
3655 static const XML_Char atypeCDATA
[] =
3656 { ASCII_C
, ASCII_D
, ASCII_A
, ASCII_T
, ASCII_A
, '\0' };
3657 static const XML_Char atypeID
[] = { ASCII_I
, ASCII_D
, '\0' };
3658 static const XML_Char atypeIDREF
[] =
3659 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, '\0' };
3660 static const XML_Char atypeIDREFS
[] =
3661 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, ASCII_S
, '\0' };
3662 static const XML_Char atypeENTITY
[] =
3663 { ASCII_E
, ASCII_N
, ASCII_T
, ASCII_I
, ASCII_T
, ASCII_Y
, '\0' };
3664 static const XML_Char atypeENTITIES
[] = { ASCII_E
, ASCII_N
,
3665 ASCII_T
, ASCII_I
, ASCII_T
, ASCII_I
, ASCII_E
, ASCII_S
, '\0' };
3666 static const XML_Char atypeNMTOKEN
[] = {
3667 ASCII_N
, ASCII_M
, ASCII_T
, ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, '\0' };
3668 static const XML_Char atypeNMTOKENS
[] = { ASCII_N
, ASCII_M
, ASCII_T
,
3669 ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, ASCII_S
, '\0' };
3670 static const XML_Char notationPrefix
[] = { ASCII_N
, ASCII_O
, ASCII_T
,
3671 ASCII_A
, ASCII_T
, ASCII_I
, ASCII_O
, ASCII_N
, ASCII_LPAREN
, '\0' };
3672 static const XML_Char enumValueSep
[] = { ASCII_PIPE
, '\0' };
3673 static const XML_Char enumValueStart
[] = { ASCII_LPAREN
, '\0' };
3675 /* save one level of indirection */
3676 DTD
* const dtd
= _dtd
;
3678 const char **eventPP
;
3679 const char **eventEndPP
;
3680 enum XML_Content_Quant quant
;
3682 if (enc
== encoding
) {
3683 eventPP
= &eventPtr
;
3684 eventEndPP
= &eventEndPtr
;
3687 eventPP
= &(openInternalEntities
->internalEventPtr
);
3688 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3693 XML_Bool handleDefault
= XML_TRUE
;
3697 if (haveMore
&& tok
!= XML_TOK_INVALID
) {
3699 return XML_ERROR_NONE
;
3702 case XML_TOK_INVALID
:
3704 return XML_ERROR_INVALID_TOKEN
;
3705 case XML_TOK_PARTIAL
:
3706 return XML_ERROR_UNCLOSED_TOKEN
;
3707 case XML_TOK_PARTIAL_CHAR
:
3708 return XML_ERROR_PARTIAL_CHAR
;
3711 /* for internal PE NOT referenced between declarations */
3712 if (enc
!= encoding
&& !openInternalEntities
->betweenDecl
) {
3714 return XML_ERROR_NONE
;
3716 /* WFC: PE Between Declarations - must check that PE contains
3717 complete markup, not only for external PEs, but also for
3718 internal PEs if the reference occurs between declarations.
3720 if (isParamEntity
|| enc
!= encoding
) {
3721 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3723 return XML_ERROR_INCOMPLETE_PE
;
3725 return XML_ERROR_NONE
;
3727 #endif /* XML_DTD */
3728 return XML_ERROR_NO_ELEMENTS
;
3735 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3737 case XML_ROLE_XML_DECL
:
3739 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3740 if (result
!= XML_ERROR_NONE
)
3743 handleDefault
= XML_FALSE
;
3746 case XML_ROLE_DOCTYPE_NAME
:
3747 if (startDoctypeDeclHandler
) {
3748 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3750 return XML_ERROR_NO_MEMORY
;
3751 poolFinish(&tempPool
);
3752 doctypePubid
= NULL
;
3753 handleDefault
= XML_FALSE
;
3755 doctypeSysid
= NULL
; /* always initialize to NULL */
3757 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3758 if (startDoctypeDeclHandler
) {
3759 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3762 poolClear(&tempPool
);
3763 handleDefault
= XML_FALSE
;
3767 case XML_ROLE_TEXT_DECL
:
3769 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3770 if (result
!= XML_ERROR_NONE
)
3773 handleDefault
= XML_FALSE
;
3776 #endif /* XML_DTD */
3777 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3779 useForeignDTD
= XML_FALSE
;
3780 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3784 return XML_ERROR_NO_MEMORY
;
3785 #endif /* XML_DTD */
3786 dtd
->hasParamEntityRefs
= XML_TRUE
;
3787 if (startDoctypeDeclHandler
) {
3788 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3789 return XML_ERROR_PUBLICID
;
3790 doctypePubid
= poolStoreString(&tempPool
, enc
,
3791 s
+ enc
->minBytesPerChar
,
3792 next
- enc
->minBytesPerChar
);
3794 return XML_ERROR_NO_MEMORY
;
3795 normalizePublicId((XML_Char
*)doctypePubid
);
3796 poolFinish(&tempPool
);
3797 handleDefault
= XML_FALSE
;
3798 goto alreadyChecked
;
3801 case XML_ROLE_ENTITY_PUBLIC_ID
:
3802 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3803 return XML_ERROR_PUBLICID
;
3805 if (dtd
->keepProcessing
&& declEntity
) {
3806 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3808 s
+ enc
->minBytesPerChar
,
3809 next
- enc
->minBytesPerChar
);
3811 return XML_ERROR_NO_MEMORY
;
3812 normalizePublicId(tem
);
3813 declEntity
->publicId
= tem
;
3814 poolFinish(&dtd
->pool
);
3815 if (entityDeclHandler
)
3816 handleDefault
= XML_FALSE
;
3819 case XML_ROLE_DOCTYPE_CLOSE
:
3821 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3822 doctypeSysid
, doctypePubid
, 0);
3823 poolClear(&tempPool
);
3824 handleDefault
= XML_FALSE
;
3826 /* doctypeSysid will be non-NULL in the case of a previous
3827 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3828 was not set, indicating an external subset
3831 if (doctypeSysid
|| useForeignDTD
) {
3832 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3833 dtd
->hasParamEntityRefs
= XML_TRUE
;
3834 if (paramEntityParsing
&& externalEntityRefHandler
) {
3835 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3839 return XML_ERROR_NO_MEMORY
;
3841 entity
->base
= curBase
;
3842 dtd
->paramEntityRead
= XML_FALSE
;
3843 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3848 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3849 if (dtd
->paramEntityRead
) {
3850 if (!dtd
->standalone
&&
3851 notStandaloneHandler
&&
3852 !notStandaloneHandler(handlerArg
))
3853 return XML_ERROR_NOT_STANDALONE
;
3855 /* if we didn't read the foreign DTD then this means that there
3856 is no external subset and we must reset dtd->hasParamEntityRefs
3858 else if (!doctypeSysid
)
3859 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3860 /* end of DTD - no need to update dtd->keepProcessing */
3862 useForeignDTD
= XML_FALSE
;
3864 #endif /* XML_DTD */
3865 if (endDoctypeDeclHandler
) {
3866 endDoctypeDeclHandler(handlerArg
);
3867 handleDefault
= XML_FALSE
;
3870 case XML_ROLE_INSTANCE_START
:
3872 /* if there is no DOCTYPE declaration then now is the
3873 last chance to read the foreign DTD
3875 if (useForeignDTD
) {
3876 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3877 dtd
->hasParamEntityRefs
= XML_TRUE
;
3878 if (paramEntityParsing
&& externalEntityRefHandler
) {
3879 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
3883 return XML_ERROR_NO_MEMORY
;
3884 entity
->base
= curBase
;
3885 dtd
->paramEntityRead
= XML_FALSE
;
3886 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3891 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3892 if (dtd
->paramEntityRead
) {
3893 if (!dtd
->standalone
&&
3894 notStandaloneHandler
&&
3895 !notStandaloneHandler(handlerArg
))
3896 return XML_ERROR_NOT_STANDALONE
;
3898 /* if we didn't read the foreign DTD then this means that there
3899 is no external subset and we must reset dtd->hasParamEntityRefs
3902 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3903 /* end of DTD - no need to update dtd->keepProcessing */
3906 #endif /* XML_DTD */
3907 processor
= contentProcessor
;
3908 return contentProcessor(parser
, s
, end
, nextPtr
);
3909 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
3910 declElementType
= getElementType(parser
, enc
, s
, next
);
3911 if (!declElementType
)
3912 return XML_ERROR_NO_MEMORY
;
3913 goto checkAttListDeclHandler
;
3914 case XML_ROLE_ATTRIBUTE_NAME
:
3915 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
3916 if (!declAttributeId
)
3917 return XML_ERROR_NO_MEMORY
;
3918 declAttributeIsCdata
= XML_FALSE
;
3919 declAttributeType
= NULL
;
3920 declAttributeIsId
= XML_FALSE
;
3921 goto checkAttListDeclHandler
;
3922 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
3923 declAttributeIsCdata
= XML_TRUE
;
3924 declAttributeType
= atypeCDATA
;
3925 goto checkAttListDeclHandler
;
3926 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
3927 declAttributeIsId
= XML_TRUE
;
3928 declAttributeType
= atypeID
;
3929 goto checkAttListDeclHandler
;
3930 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
3931 declAttributeType
= atypeIDREF
;
3932 goto checkAttListDeclHandler
;
3933 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
3934 declAttributeType
= atypeIDREFS
;
3935 goto checkAttListDeclHandler
;
3936 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
3937 declAttributeType
= atypeENTITY
;
3938 goto checkAttListDeclHandler
;
3939 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
3940 declAttributeType
= atypeENTITIES
;
3941 goto checkAttListDeclHandler
;
3942 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
3943 declAttributeType
= atypeNMTOKEN
;
3944 goto checkAttListDeclHandler
;
3945 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
3946 declAttributeType
= atypeNMTOKENS
;
3947 checkAttListDeclHandler
:
3948 if (dtd
->keepProcessing
&& attlistDeclHandler
)
3949 handleDefault
= XML_FALSE
;
3951 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
3952 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
3953 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
3954 const XML_Char
*prefix
;
3955 if (declAttributeType
) {
3956 prefix
= enumValueSep
;
3959 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3963 if (!poolAppendString(&tempPool
, prefix
))
3964 return XML_ERROR_NO_MEMORY
;
3965 if (!poolAppend(&tempPool
, enc
, s
, next
))
3966 return XML_ERROR_NO_MEMORY
;
3967 declAttributeType
= tempPool
.start
;
3968 handleDefault
= XML_FALSE
;
3971 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
3972 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
3973 if (dtd
->keepProcessing
) {
3974 if (!defineAttribute(declElementType
, declAttributeId
,
3975 declAttributeIsCdata
, declAttributeIsId
,
3977 return XML_ERROR_NO_MEMORY
;
3978 if (attlistDeclHandler
&& declAttributeType
) {
3979 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
3980 || (*declAttributeType
== XML_T(ASCII_N
)
3981 && declAttributeType
[1] == XML_T(ASCII_O
))) {
3982 /* Enumerated or Notation type */
3983 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
3984 || !poolAppendChar(&tempPool
, XML_T('\0')))
3985 return XML_ERROR_NO_MEMORY
;
3986 declAttributeType
= tempPool
.start
;
3987 poolFinish(&tempPool
);
3990 attlistDeclHandler(handlerArg
, declElementType
->name
,
3991 declAttributeId
->name
, declAttributeType
,
3992 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
3993 poolClear(&tempPool
);
3994 handleDefault
= XML_FALSE
;
3998 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
3999 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
4000 if (dtd
->keepProcessing
) {
4001 const XML_Char
*attVal
;
4002 enum XML_Error result
=
4003 storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
4004 s
+ enc
->minBytesPerChar
,
4005 next
- enc
->minBytesPerChar
,
4009 attVal
= poolStart(&dtd
->pool
);
4010 poolFinish(&dtd
->pool
);
4011 /* ID attributes aren't allowed to have a default */
4012 if (!defineAttribute(declElementType
, declAttributeId
,
4013 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
4014 return XML_ERROR_NO_MEMORY
;
4015 if (attlistDeclHandler
&& declAttributeType
) {
4016 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
4017 || (*declAttributeType
== XML_T(ASCII_N
)
4018 && declAttributeType
[1] == XML_T(ASCII_O
))) {
4019 /* Enumerated or Notation type */
4020 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
4021 || !poolAppendChar(&tempPool
, XML_T('\0')))
4022 return XML_ERROR_NO_MEMORY
;
4023 declAttributeType
= tempPool
.start
;
4024 poolFinish(&tempPool
);
4027 attlistDeclHandler(handlerArg
, declElementType
->name
,
4028 declAttributeId
->name
, declAttributeType
,
4030 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
4031 poolClear(&tempPool
);
4032 handleDefault
= XML_FALSE
;
4036 case XML_ROLE_ENTITY_VALUE
:
4037 if (dtd
->keepProcessing
) {
4038 enum XML_Error result
= storeEntityValue(parser
, enc
,
4039 s
+ enc
->minBytesPerChar
,
4040 next
- enc
->minBytesPerChar
);
4042 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
4043 declEntity
->textLen
= (int)(poolLength(&dtd
->entityValuePool
));
4044 poolFinish(&dtd
->entityValuePool
);
4045 if (entityDeclHandler
) {
4047 entityDeclHandler(handlerArg
,
4049 declEntity
->is_param
,
4050 declEntity
->textPtr
,
4051 declEntity
->textLen
,
4053 handleDefault
= XML_FALSE
;
4057 poolDiscard(&dtd
->entityValuePool
);
4058 if (result
!= XML_ERROR_NONE
)
4062 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
4064 useForeignDTD
= XML_FALSE
;
4065 #endif /* XML_DTD */
4066 dtd
->hasParamEntityRefs
= XML_TRUE
;
4067 if (startDoctypeDeclHandler
) {
4068 doctypeSysid
= poolStoreString(&tempPool
, enc
,
4069 s
+ enc
->minBytesPerChar
,
4070 next
- enc
->minBytesPerChar
);
4071 if (doctypeSysid
== NULL
)
4072 return XML_ERROR_NO_MEMORY
;
4073 poolFinish(&tempPool
);
4074 handleDefault
= XML_FALSE
;
4078 /* use externalSubsetName to make doctypeSysid non-NULL
4079 for the case where no startDoctypeDeclHandler is set */
4080 doctypeSysid
= externalSubsetName
;
4081 #endif /* XML_DTD */
4082 if (!dtd
->standalone
4084 && !paramEntityParsing
4085 #endif /* XML_DTD */
4086 && notStandaloneHandler
4087 && !notStandaloneHandler(handlerArg
))
4088 return XML_ERROR_NOT_STANDALONE
;
4093 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4097 return XML_ERROR_NO_MEMORY
;
4098 declEntity
->publicId
= NULL
;
4101 #endif /* XML_DTD */
4102 case XML_ROLE_ENTITY_SYSTEM_ID
:
4103 if (dtd
->keepProcessing
&& declEntity
) {
4104 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
4105 s
+ enc
->minBytesPerChar
,
4106 next
- enc
->minBytesPerChar
);
4107 if (!declEntity
->systemId
)
4108 return XML_ERROR_NO_MEMORY
;
4109 declEntity
->base
= curBase
;
4110 poolFinish(&dtd
->pool
);
4111 if (entityDeclHandler
)
4112 handleDefault
= XML_FALSE
;
4115 case XML_ROLE_ENTITY_COMPLETE
:
4116 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
4118 entityDeclHandler(handlerArg
,
4120 declEntity
->is_param
,
4123 declEntity
->systemId
,
4124 declEntity
->publicId
,
4126 handleDefault
= XML_FALSE
;
4129 case XML_ROLE_ENTITY_NOTATION_NAME
:
4130 if (dtd
->keepProcessing
&& declEntity
) {
4131 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4132 if (!declEntity
->notation
)
4133 return XML_ERROR_NO_MEMORY
;
4134 poolFinish(&dtd
->pool
);
4135 if (unparsedEntityDeclHandler
) {
4137 unparsedEntityDeclHandler(handlerArg
,
4140 declEntity
->systemId
,
4141 declEntity
->publicId
,
4142 declEntity
->notation
);
4143 handleDefault
= XML_FALSE
;
4145 else if (entityDeclHandler
) {
4147 entityDeclHandler(handlerArg
,
4151 declEntity
->systemId
,
4152 declEntity
->publicId
,
4153 declEntity
->notation
);
4154 handleDefault
= XML_FALSE
;
4158 case XML_ROLE_GENERAL_ENTITY_NAME
:
4160 if (XmlPredefinedEntityName(enc
, s
, next
)) {
4164 if (dtd
->keepProcessing
) {
4165 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4167 return XML_ERROR_NO_MEMORY
;
4168 declEntity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
,
4171 return XML_ERROR_NO_MEMORY
;
4172 if (declEntity
->name
!= name
) {
4173 poolDiscard(&dtd
->pool
);
4177 poolFinish(&dtd
->pool
);
4178 declEntity
->publicId
= NULL
;
4179 declEntity
->is_param
= XML_FALSE
;
4180 /* if we have a parent parser or are reading an internal parameter
4181 entity, then the entity declaration is not considered "internal"
4183 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4184 if (entityDeclHandler
)
4185 handleDefault
= XML_FALSE
;
4189 poolDiscard(&dtd
->pool
);
4194 case XML_ROLE_PARAM_ENTITY_NAME
:
4196 if (dtd
->keepProcessing
) {
4197 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4199 return XML_ERROR_NO_MEMORY
;
4200 declEntity
= (ENTITY
*)lookup(&dtd
->paramEntities
,
4201 name
, sizeof(ENTITY
));
4203 return XML_ERROR_NO_MEMORY
;
4204 if (declEntity
->name
!= name
) {
4205 poolDiscard(&dtd
->pool
);
4209 poolFinish(&dtd
->pool
);
4210 declEntity
->publicId
= NULL
;
4211 declEntity
->is_param
= XML_TRUE
;
4212 /* if we have a parent parser or are reading an internal parameter
4213 entity, then the entity declaration is not considered "internal"
4215 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4216 if (entityDeclHandler
)
4217 handleDefault
= XML_FALSE
;
4221 poolDiscard(&dtd
->pool
);
4224 #else /* not XML_DTD */
4226 #endif /* XML_DTD */
4228 case XML_ROLE_NOTATION_NAME
:
4229 declNotationPublicId
= NULL
;
4230 declNotationName
= NULL
;
4231 if (notationDeclHandler
) {
4232 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
4233 if (!declNotationName
)
4234 return XML_ERROR_NO_MEMORY
;
4235 poolFinish(&tempPool
);
4236 handleDefault
= XML_FALSE
;
4239 case XML_ROLE_NOTATION_PUBLIC_ID
:
4240 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
4241 return XML_ERROR_PUBLICID
;
4242 if (declNotationName
) { /* means notationDeclHandler != NULL */
4243 XML_Char
*tem
= poolStoreString(&tempPool
,
4245 s
+ enc
->minBytesPerChar
,
4246 next
- enc
->minBytesPerChar
);
4248 return XML_ERROR_NO_MEMORY
;
4249 normalizePublicId(tem
);
4250 declNotationPublicId
= tem
;
4251 poolFinish(&tempPool
);
4252 handleDefault
= XML_FALSE
;
4255 case XML_ROLE_NOTATION_SYSTEM_ID
:
4256 if (declNotationName
&& notationDeclHandler
) {
4257 const XML_Char
*systemId
4258 = poolStoreString(&tempPool
, enc
,
4259 s
+ enc
->minBytesPerChar
,
4260 next
- enc
->minBytesPerChar
);
4262 return XML_ERROR_NO_MEMORY
;
4264 notationDeclHandler(handlerArg
,
4268 declNotationPublicId
);
4269 handleDefault
= XML_FALSE
;
4271 poolClear(&tempPool
);
4273 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
4274 if (declNotationPublicId
&& notationDeclHandler
) {
4276 notationDeclHandler(handlerArg
,
4280 declNotationPublicId
);
4281 handleDefault
= XML_FALSE
;
4283 poolClear(&tempPool
);
4285 case XML_ROLE_ERROR
:
4287 case XML_TOK_PARAM_ENTITY_REF
:
4288 /* PE references in internal subset are
4289 not allowed within declarations. */
4290 return XML_ERROR_PARAM_ENTITY_REF
;
4291 case XML_TOK_XML_DECL
:
4292 return XML_ERROR_MISPLACED_XML_PI
;
4294 return XML_ERROR_SYNTAX
;
4297 case XML_ROLE_IGNORE_SECT
:
4299 enum XML_Error result
;
4301 reportDefault(parser
, enc
, s
, next
);
4302 handleDefault
= XML_FALSE
;
4303 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
4304 if (result
!= XML_ERROR_NONE
)
4307 processor
= ignoreSectionProcessor
;
4312 #endif /* XML_DTD */
4313 case XML_ROLE_GROUP_OPEN
:
4314 if (prologState
.level
>= groupSize
) {
4316 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
4318 return XML_ERROR_NO_MEMORY
;
4319 groupConnector
= temp
;
4320 if (dtd
->scaffIndex
) {
4321 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
4322 groupSize
* sizeof(int));
4324 return XML_ERROR_NO_MEMORY
;
4325 dtd
->scaffIndex
= temp
;
4329 groupConnector
= (char *)MALLOC(groupSize
= 32);
4330 if (!groupConnector
)
4331 return XML_ERROR_NO_MEMORY
;
4334 groupConnector
[prologState
.level
] = 0;
4335 if (dtd
->in_eldecl
) {
4336 int myindex
= nextScaffoldPart(parser
);
4338 return XML_ERROR_NO_MEMORY
;
4339 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
4341 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
4342 if (elementDeclHandler
)
4343 handleDefault
= XML_FALSE
;
4346 case XML_ROLE_GROUP_SEQUENCE
:
4347 if (groupConnector
[prologState
.level
] == ASCII_PIPE
)
4348 return XML_ERROR_SYNTAX
;
4349 groupConnector
[prologState
.level
] = ASCII_COMMA
;
4350 if (dtd
->in_eldecl
&& elementDeclHandler
)
4351 handleDefault
= XML_FALSE
;
4353 case XML_ROLE_GROUP_CHOICE
:
4354 if (groupConnector
[prologState
.level
] == ASCII_COMMA
)
4355 return XML_ERROR_SYNTAX
;
4357 && !groupConnector
[prologState
.level
]
4358 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4361 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4363 if (elementDeclHandler
)
4364 handleDefault
= XML_FALSE
;
4366 groupConnector
[prologState
.level
] = ASCII_PIPE
;
4368 case XML_ROLE_PARAM_ENTITY_REF
:
4370 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
4371 dtd
->hasParamEntityRefs
= XML_TRUE
;
4372 if (!paramEntityParsing
)
4373 dtd
->keepProcessing
= dtd
->standalone
;
4375 const XML_Char
*name
;
4377 name
= poolStoreString(&dtd
->pool
, enc
,
4378 s
+ enc
->minBytesPerChar
,
4379 next
- enc
->minBytesPerChar
);
4381 return XML_ERROR_NO_MEMORY
;
4382 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
4383 poolDiscard(&dtd
->pool
);
4384 /* first, determine if a check for an existing declaration is needed;
4385 if yes, check that the entity exists, and that it is internal,
4386 otherwise call the skipped entity handler
4388 if (prologState
.documentEntity
&&
4390 ? !openInternalEntities
4391 : !dtd
->hasParamEntityRefs
)) {
4393 return XML_ERROR_UNDEFINED_ENTITY
;
4394 else if (!entity
->is_internal
)
4395 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4398 dtd
->keepProcessing
= dtd
->standalone
;
4399 /* cannot report skipped entities in declarations */
4400 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
4401 skippedEntityHandler(handlerArg
, name
, 1);
4402 handleDefault
= XML_FALSE
;
4407 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4408 if (entity
->textPtr
) {
4409 enum XML_Error result
;
4410 XML_Bool betweenDecl
=
4411 (role
== XML_ROLE_PARAM_ENTITY_REF
? XML_TRUE
: XML_FALSE
);
4412 result
= processInternalEntity(parser
, entity
, betweenDecl
);
4413 if (result
!= XML_ERROR_NONE
)
4415 handleDefault
= XML_FALSE
;
4418 if (externalEntityRefHandler
) {
4419 dtd
->paramEntityRead
= XML_FALSE
;
4420 entity
->open
= XML_TRUE
;
4421 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4425 entity
->publicId
)) {
4426 entity
->open
= XML_FALSE
;
4427 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4429 entity
->open
= XML_FALSE
;
4430 handleDefault
= XML_FALSE
;
4431 if (!dtd
->paramEntityRead
) {
4432 dtd
->keepProcessing
= dtd
->standalone
;
4437 dtd
->keepProcessing
= dtd
->standalone
;
4441 #endif /* XML_DTD */
4442 if (!dtd
->standalone
&&
4443 notStandaloneHandler
&&
4444 !notStandaloneHandler(handlerArg
))
4445 return XML_ERROR_NOT_STANDALONE
;
4448 /* Element declaration stuff */
4450 case XML_ROLE_ELEMENT_NAME
:
4451 if (elementDeclHandler
) {
4452 declElementType
= getElementType(parser
, enc
, s
, next
);
4453 if (!declElementType
)
4454 return XML_ERROR_NO_MEMORY
;
4455 dtd
->scaffLevel
= 0;
4456 dtd
->scaffCount
= 0;
4457 dtd
->in_eldecl
= XML_TRUE
;
4458 handleDefault
= XML_FALSE
;
4462 case XML_ROLE_CONTENT_ANY
:
4463 case XML_ROLE_CONTENT_EMPTY
:
4464 if (dtd
->in_eldecl
) {
4465 if (elementDeclHandler
) {
4466 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
4468 return XML_ERROR_NO_MEMORY
;
4469 content
->quant
= XML_CQUANT_NONE
;
4470 content
->name
= NULL
;
4471 content
->numchildren
= 0;
4472 content
->children
= NULL
;
4473 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4477 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4478 handleDefault
= XML_FALSE
;
4480 dtd
->in_eldecl
= XML_FALSE
;
4484 case XML_ROLE_CONTENT_PCDATA
:
4485 if (dtd
->in_eldecl
) {
4486 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4488 if (elementDeclHandler
)
4489 handleDefault
= XML_FALSE
;
4493 case XML_ROLE_CONTENT_ELEMENT
:
4494 quant
= XML_CQUANT_NONE
;
4495 goto elementContent
;
4496 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4497 quant
= XML_CQUANT_OPT
;
4498 goto elementContent
;
4499 case XML_ROLE_CONTENT_ELEMENT_REP
:
4500 quant
= XML_CQUANT_REP
;
4501 goto elementContent
;
4502 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4503 quant
= XML_CQUANT_PLUS
;
4505 if (dtd
->in_eldecl
) {
4507 const XML_Char
*name
;
4509 const char *nxt
= (quant
== XML_CQUANT_NONE
4511 : next
- enc
->minBytesPerChar
);
4512 int myindex
= nextScaffoldPart(parser
);
4514 return XML_ERROR_NO_MEMORY
;
4515 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4516 dtd
->scaffold
[myindex
].quant
= quant
;
4517 el
= getElementType(parser
, enc
, s
, nxt
);
4519 return XML_ERROR_NO_MEMORY
;
4521 dtd
->scaffold
[myindex
].name
= name
;
4523 for (; name
[nameLen
++]; );
4524 dtd
->contentStringLen
+= nameLen
;
4525 if (elementDeclHandler
)
4526 handleDefault
= XML_FALSE
;
4530 case XML_ROLE_GROUP_CLOSE
:
4531 quant
= XML_CQUANT_NONE
;
4533 case XML_ROLE_GROUP_CLOSE_OPT
:
4534 quant
= XML_CQUANT_OPT
;
4536 case XML_ROLE_GROUP_CLOSE_REP
:
4537 quant
= XML_CQUANT_REP
;
4539 case XML_ROLE_GROUP_CLOSE_PLUS
:
4540 quant
= XML_CQUANT_PLUS
;
4542 if (dtd
->in_eldecl
) {
4543 if (elementDeclHandler
)
4544 handleDefault
= XML_FALSE
;
4546 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4547 if (dtd
->scaffLevel
== 0) {
4548 if (!handleDefault
) {
4549 XML_Content
*model
= build_model(parser
);
4551 return XML_ERROR_NO_MEMORY
;
4553 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4555 dtd
->in_eldecl
= XML_FALSE
;
4556 dtd
->contentStringLen
= 0;
4560 /* End element declaration stuff */
4563 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4564 return XML_ERROR_NO_MEMORY
;
4565 handleDefault
= XML_FALSE
;
4567 case XML_ROLE_COMMENT
:
4568 if (!reportComment(parser
, enc
, s
, next
))
4569 return XML_ERROR_NO_MEMORY
;
4570 handleDefault
= XML_FALSE
;
4575 handleDefault
= XML_FALSE
;
4579 case XML_ROLE_DOCTYPE_NONE
:
4580 if (startDoctypeDeclHandler
)
4581 handleDefault
= XML_FALSE
;
4583 case XML_ROLE_ENTITY_NONE
:
4584 if (dtd
->keepProcessing
&& entityDeclHandler
)
4585 handleDefault
= XML_FALSE
;
4587 case XML_ROLE_NOTATION_NONE
:
4588 if (notationDeclHandler
)
4589 handleDefault
= XML_FALSE
;
4591 case XML_ROLE_ATTLIST_NONE
:
4592 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4593 handleDefault
= XML_FALSE
;
4595 case XML_ROLE_ELEMENT_NONE
:
4596 if (elementDeclHandler
)
4597 handleDefault
= XML_FALSE
;
4599 } /* end of big switch */
4601 if (handleDefault
&& defaultHandler
)
4602 reportDefault(parser
, enc
, s
, next
);
4604 switch (ps_parsing
) {
4607 return XML_ERROR_NONE
;
4609 return XML_ERROR_ABORTED
;
4612 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4618 static enum XML_Error PTRCALL
4619 epilogProcessor(XML_Parser parser
,
4622 const char **nextPtr
)
4624 processor
= epilogProcessor
;
4627 const char *next
= NULL
;
4628 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4631 /* report partial linebreak - it might be the last token */
4632 case -XML_TOK_PROLOG_S
:
4633 if (defaultHandler
) {
4634 reportDefault(parser
, encoding
, s
, next
);
4635 if (ps_parsing
== XML_FINISHED
)
4636 return XML_ERROR_ABORTED
;
4639 return XML_ERROR_NONE
;
4642 return XML_ERROR_NONE
;
4643 case XML_TOK_PROLOG_S
:
4645 reportDefault(parser
, encoding
, s
, next
);
4648 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4649 return XML_ERROR_NO_MEMORY
;
4651 case XML_TOK_COMMENT
:
4652 if (!reportComment(parser
, encoding
, s
, next
))
4653 return XML_ERROR_NO_MEMORY
;
4655 case XML_TOK_INVALID
:
4657 return XML_ERROR_INVALID_TOKEN
;
4658 case XML_TOK_PARTIAL
:
4659 if (!ps_finalBuffer
) {
4661 return XML_ERROR_NONE
;
4663 return XML_ERROR_UNCLOSED_TOKEN
;
4664 case XML_TOK_PARTIAL_CHAR
:
4665 if (!ps_finalBuffer
) {
4667 return XML_ERROR_NONE
;
4669 return XML_ERROR_PARTIAL_CHAR
;
4671 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4673 eventPtr
= s
= next
;
4674 switch (ps_parsing
) {
4677 return XML_ERROR_NONE
;
4679 return XML_ERROR_ABORTED
;
4685 static enum XML_Error
4686 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
4687 XML_Bool betweenDecl
)
4689 const char *textStart
, *textEnd
;
4691 enum XML_Error result
;
4692 OPEN_INTERNAL_ENTITY
*openEntity
;
4694 if (freeInternalEntities
) {
4695 openEntity
= freeInternalEntities
;
4696 freeInternalEntities
= openEntity
->next
;
4699 openEntity
= (OPEN_INTERNAL_ENTITY
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
));
4701 return XML_ERROR_NO_MEMORY
;
4703 entity
->open
= XML_TRUE
;
4704 entity
->processed
= 0;
4705 openEntity
->next
= openInternalEntities
;
4706 openInternalEntities
= openEntity
;
4707 openEntity
->entity
= entity
;
4708 openEntity
->startTagLevel
= tagLevel
;
4709 openEntity
->betweenDecl
= betweenDecl
;
4710 openEntity
->internalEventPtr
= NULL
;
4711 openEntity
->internalEventEndPtr
= NULL
;
4712 textStart
= (char *)entity
->textPtr
;
4713 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4716 if (entity
->is_param
) {
4717 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4718 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4719 next
, &next
, XML_FALSE
);
4722 #endif /* XML_DTD */
4723 result
= doContent(parser
, tagLevel
, internalEncoding
, textStart
,
4724 textEnd
, &next
, XML_FALSE
);
4726 if (result
== XML_ERROR_NONE
) {
4727 if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4728 entity
->processed
= (int)(next
- textStart
);
4729 processor
= internalEntityProcessor
;
4732 entity
->open
= XML_FALSE
;
4733 openInternalEntities
= openEntity
->next
;
4734 /* put openEntity back in list of free instances */
4735 openEntity
->next
= freeInternalEntities
;
4736 freeInternalEntities
= openEntity
;
4742 static enum XML_Error PTRCALL
4743 internalEntityProcessor(XML_Parser parser
,
4746 const char **nextPtr
)
4749 const char *textStart
, *textEnd
;
4751 enum XML_Error result
;
4752 OPEN_INTERNAL_ENTITY
*openEntity
= openInternalEntities
;
4754 return XML_ERROR_UNEXPECTED_STATE
;
4756 entity
= openEntity
->entity
;
4757 textStart
= ((char *)entity
->textPtr
) + entity
->processed
;
4758 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4761 if (entity
->is_param
) {
4762 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4763 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4764 next
, &next
, XML_FALSE
);
4767 #endif /* XML_DTD */
4768 result
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
,
4769 textStart
, textEnd
, &next
, XML_FALSE
);
4771 if (result
!= XML_ERROR_NONE
)
4773 else if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4774 entity
->processed
= (int)(next
- (char *)entity
->textPtr
);
4778 entity
->open
= XML_FALSE
;
4779 openInternalEntities
= openEntity
->next
;
4780 /* put openEntity back in list of free instances */
4781 openEntity
->next
= freeInternalEntities
;
4782 freeInternalEntities
= openEntity
;
4786 if (entity
->is_param
) {
4788 processor
= prologProcessor
;
4789 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4790 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
,
4791 (XML_Bool
)!ps_finalBuffer
);
4794 #endif /* XML_DTD */
4796 processor
= contentProcessor
;
4797 /* see externalEntityContentProcessor vs contentProcessor */
4798 return doContent(parser
, parentParser
? 1 : 0, encoding
, s
, end
,
4799 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
4803 static enum XML_Error PTRCALL
4804 errorProcessor(XML_Parser parser
,
4807 const char **nextPtr
)
4812 static enum XML_Error
4813 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4814 const char *ptr
, const char *end
,
4817 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4821 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4823 if (!poolAppendChar(pool
, XML_T('\0')))
4824 return XML_ERROR_NO_MEMORY
;
4825 return XML_ERROR_NONE
;
4828 static enum XML_Error
4829 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4830 const char *ptr
, const char *end
,
4833 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4836 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4839 return XML_ERROR_NONE
;
4840 case XML_TOK_INVALID
:
4841 if (enc
== encoding
)
4843 return XML_ERROR_INVALID_TOKEN
;
4844 case XML_TOK_PARTIAL
:
4845 if (enc
== encoding
)
4847 return XML_ERROR_INVALID_TOKEN
;
4848 case XML_TOK_CHAR_REF
:
4850 XML_Char buf
[XML_ENCODE_MAX
];
4852 int n
= XmlCharRefNumber(enc
, ptr
);
4854 if (enc
== encoding
)
4856 return XML_ERROR_BAD_CHAR_REF
;
4859 && n
== 0x20 /* space */
4860 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4862 n
= XmlEncode(n
, (ICHAR
*)buf
);
4864 if (enc
== encoding
)
4866 return XML_ERROR_BAD_CHAR_REF
;
4868 for (i
= 0; i
< n
; i
++) {
4869 if (!poolAppendChar(pool
, buf
[i
]))
4870 return XML_ERROR_NO_MEMORY
;
4874 case XML_TOK_DATA_CHARS
:
4875 if (!poolAppend(pool
, enc
, ptr
, next
))
4876 return XML_ERROR_NO_MEMORY
;
4878 case XML_TOK_TRAILING_CR
:
4879 next
= ptr
+ enc
->minBytesPerChar
;
4881 case XML_TOK_ATTRIBUTE_VALUE_S
:
4882 case XML_TOK_DATA_NEWLINE
:
4883 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4885 if (!poolAppendChar(pool
, 0x20))
4886 return XML_ERROR_NO_MEMORY
;
4888 case XML_TOK_ENTITY_REF
:
4890 const XML_Char
*name
;
4892 char checkEntityDecl
;
4893 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
4894 ptr
+ enc
->minBytesPerChar
,
4895 next
- enc
->minBytesPerChar
);
4897 if (!poolAppendChar(pool
, ch
))
4898 return XML_ERROR_NO_MEMORY
;
4901 name
= poolStoreString(&temp2Pool
, enc
,
4902 ptr
+ enc
->minBytesPerChar
,
4903 next
- enc
->minBytesPerChar
);
4905 return XML_ERROR_NO_MEMORY
;
4906 entity
= (ENTITY
*)lookup(&dtd
->generalEntities
, name
, 0);
4907 poolDiscard(&temp2Pool
);
4908 /* First, determine if a check for an existing declaration is needed;
4909 if yes, check that the entity exists, and that it is internal.
4911 if (pool
== &dtd
->pool
) /* are we called from prolog? */
4914 prologState
.documentEntity
&&
4915 #endif /* XML_DTD */
4917 ? !openInternalEntities
4918 : !dtd
->hasParamEntityRefs
);
4919 else /* if (pool == &tempPool): we are called from content */
4920 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
4921 if (checkEntityDecl
) {
4923 return XML_ERROR_UNDEFINED_ENTITY
;
4924 else if (!entity
->is_internal
)
4925 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4928 /* Cannot report skipped entity here - see comments on
4929 skippedEntityHandler.
4930 if (skippedEntityHandler)
4931 skippedEntityHandler(handlerArg, name, 0);
4933 /* Cannot call the default handler because this would be
4934 out of sync with the call to the startElementHandler.
4935 if ((pool == &tempPool) && defaultHandler)
4936 reportDefault(parser, enc, ptr, next);
4941 if (enc
== encoding
)
4943 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4945 if (entity
->notation
) {
4946 if (enc
== encoding
)
4948 return XML_ERROR_BINARY_ENTITY_REF
;
4950 if (!entity
->textPtr
) {
4951 if (enc
== encoding
)
4953 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
4956 enum XML_Error result
;
4957 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
4958 entity
->open
= XML_TRUE
;
4959 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
4960 (char *)entity
->textPtr
,
4961 (char *)textEnd
, pool
);
4962 entity
->open
= XML_FALSE
;
4969 if (enc
== encoding
)
4971 return XML_ERROR_UNEXPECTED_STATE
;
4978 static enum XML_Error
4979 storeEntityValue(XML_Parser parser
,
4980 const ENCODING
*enc
,
4981 const char *entityTextPtr
,
4982 const char *entityTextEnd
)
4984 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4985 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
4986 enum XML_Error result
= XML_ERROR_NONE
;
4988 int oldInEntityValue
= prologState
.inEntityValue
;
4989 prologState
.inEntityValue
= 1;
4990 #endif /* XML_DTD */
4991 /* never return Null for the value argument in EntityDeclHandler,
4992 since this would indicate an external entity; therefore we
4993 have to make sure that entityValuePool.start is not null */
4994 if (!pool
->blocks
) {
4995 if (!poolGrow(pool
))
4996 return XML_ERROR_NO_MEMORY
;
5001 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
5003 case XML_TOK_PARAM_ENTITY_REF
:
5005 if (isParamEntity
|| enc
!= encoding
) {
5006 const XML_Char
*name
;
5008 name
= poolStoreString(&tempPool
, enc
,
5009 entityTextPtr
+ enc
->minBytesPerChar
,
5010 next
- enc
->minBytesPerChar
);
5012 result
= XML_ERROR_NO_MEMORY
;
5013 goto endEntityValue
;
5015 entity
= (ENTITY
*)lookup(&dtd
->paramEntities
, name
, 0);
5016 poolDiscard(&tempPool
);
5018 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5019 /* cannot report skipped entity here - see comments on
5020 skippedEntityHandler
5021 if (skippedEntityHandler)
5022 skippedEntityHandler(handlerArg, name, 0);
5024 dtd
->keepProcessing
= dtd
->standalone
;
5025 goto endEntityValue
;
5028 if (enc
== encoding
)
5029 eventPtr
= entityTextPtr
;
5030 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
5031 goto endEntityValue
;
5033 if (entity
->systemId
) {
5034 if (externalEntityRefHandler
) {
5035 dtd
->paramEntityRead
= XML_FALSE
;
5036 entity
->open
= XML_TRUE
;
5037 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
5041 entity
->publicId
)) {
5042 entity
->open
= XML_FALSE
;
5043 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
5044 goto endEntityValue
;
5046 entity
->open
= XML_FALSE
;
5047 if (!dtd
->paramEntityRead
)
5048 dtd
->keepProcessing
= dtd
->standalone
;
5051 dtd
->keepProcessing
= dtd
->standalone
;
5054 entity
->open
= XML_TRUE
;
5055 result
= storeEntityValue(parser
,
5057 (char *)entity
->textPtr
,
5058 (char *)(entity
->textPtr
5059 + entity
->textLen
));
5060 entity
->open
= XML_FALSE
;
5062 goto endEntityValue
;
5066 #endif /* XML_DTD */
5067 /* In the internal subset, PE references are not legal
5068 within markup declarations, e.g entity values in this case. */
5069 eventPtr
= entityTextPtr
;
5070 result
= XML_ERROR_PARAM_ENTITY_REF
;
5071 goto endEntityValue
;
5073 result
= XML_ERROR_NONE
;
5074 goto endEntityValue
;
5075 case XML_TOK_ENTITY_REF
:
5076 case XML_TOK_DATA_CHARS
:
5077 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
5078 result
= XML_ERROR_NO_MEMORY
;
5079 goto endEntityValue
;
5082 case XML_TOK_TRAILING_CR
:
5083 next
= entityTextPtr
+ enc
->minBytesPerChar
;
5085 case XML_TOK_DATA_NEWLINE
:
5086 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5087 result
= XML_ERROR_NO_MEMORY
;
5088 goto endEntityValue
;
5090 *(pool
->ptr
)++ = 0xA;
5092 case XML_TOK_CHAR_REF
:
5094 XML_Char buf
[XML_ENCODE_MAX
];
5096 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
5098 if (enc
== encoding
)
5099 eventPtr
= entityTextPtr
;
5100 result
= XML_ERROR_BAD_CHAR_REF
;
5101 goto endEntityValue
;
5103 n
= XmlEncode(n
, (ICHAR
*)buf
);
5105 if (enc
== encoding
)
5106 eventPtr
= entityTextPtr
;
5107 result
= XML_ERROR_BAD_CHAR_REF
;
5108 goto endEntityValue
;
5110 for (i
= 0; i
< n
; i
++) {
5111 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5112 result
= XML_ERROR_NO_MEMORY
;
5113 goto endEntityValue
;
5115 *(pool
->ptr
)++ = buf
[i
];
5119 case XML_TOK_PARTIAL
:
5120 if (enc
== encoding
)
5121 eventPtr
= entityTextPtr
;
5122 result
= XML_ERROR_INVALID_TOKEN
;
5123 goto endEntityValue
;
5124 case XML_TOK_INVALID
:
5125 if (enc
== encoding
)
5127 result
= XML_ERROR_INVALID_TOKEN
;
5128 goto endEntityValue
;
5130 if (enc
== encoding
)
5131 eventPtr
= entityTextPtr
;
5132 result
= XML_ERROR_UNEXPECTED_STATE
;
5133 goto endEntityValue
;
5135 entityTextPtr
= next
;
5139 prologState
.inEntityValue
= oldInEntityValue
;
5140 #endif /* XML_DTD */
5144 static void FASTCALL
5145 normalizeLines(XML_Char
*s
)
5149 if (*s
== XML_T('\0'))
5168 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
5169 const char *start
, const char *end
)
5171 const XML_Char
*target
;
5174 if (!processingInstructionHandler
) {
5176 reportDefault(parser
, enc
, start
, end
);
5179 start
+= enc
->minBytesPerChar
* 2;
5180 tem
= start
+ XmlNameLength(enc
, start
);
5181 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
5184 poolFinish(&tempPool
);
5185 data
= poolStoreString(&tempPool
, enc
,
5187 end
- enc
->minBytesPerChar
*2);
5190 normalizeLines(data
);
5191 processingInstructionHandler(handlerArg
, target
, data
);
5192 poolClear(&tempPool
);
5197 reportComment(XML_Parser parser
, const ENCODING
*enc
,
5198 const char *start
, const char *end
)
5201 if (!commentHandler
) {
5203 reportDefault(parser
, enc
, start
, end
);
5206 data
= poolStoreString(&tempPool
,
5208 start
+ enc
->minBytesPerChar
* 4,
5209 end
- enc
->minBytesPerChar
* 3);
5212 normalizeLines(data
);
5213 commentHandler(handlerArg
, data
);
5214 poolClear(&tempPool
);
5219 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
5220 const char *s
, const char *end
)
5222 if (MUST_CONVERT(enc
, s
)) {
5223 const char **eventPP
;
5224 const char **eventEndPP
;
5225 if (enc
== encoding
) {
5226 eventPP
= &eventPtr
;
5227 eventEndPP
= &eventEndPtr
;
5230 eventPP
= &(openInternalEntities
->internalEventPtr
);
5231 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
5234 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
5235 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
5237 defaultHandler(handlerArg
, dataBuf
, (int)(dataPtr
- (ICHAR
*)dataBuf
));
5242 defaultHandler(handlerArg
, (XML_Char
*)s
, (int)((XML_Char
*)end
- (XML_Char
*)s
));
5247 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
5248 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
5250 DEFAULT_ATTRIBUTE
*att
;
5251 if (value
|| isId
) {
5252 /* The handling of default attributes gets messed up if we have
5253 a default which duplicates a non-default. */
5255 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
5256 if (attId
== type
->defaultAtts
[i
].id
)
5258 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
5259 type
->idAtt
= attId
;
5261 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
5262 if (type
->allocDefaultAtts
== 0) {
5263 type
->allocDefaultAtts
= 8;
5264 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
5265 * sizeof(DEFAULT_ATTRIBUTE
));
5266 if (!type
->defaultAtts
)
5270 DEFAULT_ATTRIBUTE
*temp
;
5271 int count
= type
->allocDefaultAtts
* 2;
5272 temp
= (DEFAULT_ATTRIBUTE
*)
5273 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
5276 type
->allocDefaultAtts
= count
;
5277 type
->defaultAtts
= temp
;
5280 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
5283 att
->isCdata
= isCdata
;
5285 attId
->maybeTokenized
= XML_TRUE
;
5286 type
->nDefaultAtts
+= 1;
5291 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
5293 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5294 const XML_Char
*name
;
5295 for (name
= elementType
->name
; *name
; name
++) {
5296 if (*name
== XML_T(ASCII_COLON
)) {
5299 for (s
= elementType
->name
; s
!= name
; s
++) {
5300 if (!poolAppendChar(&dtd
->pool
, *s
))
5303 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5305 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5309 if (prefix
->name
== poolStart(&dtd
->pool
))
5310 poolFinish(&dtd
->pool
);
5312 poolDiscard(&dtd
->pool
);
5313 elementType
->prefix
= prefix
;
5320 static ATTRIBUTE_ID
*
5321 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
5322 const char *start
, const char *end
)
5324 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5326 const XML_Char
*name
;
5327 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5329 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
5332 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5334 id
= (ATTRIBUTE_ID
*)lookup(&dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
5337 if (id
->name
!= name
)
5338 poolDiscard(&dtd
->pool
);
5340 poolFinish(&dtd
->pool
);
5343 else if (name
[0] == XML_T(ASCII_x
)
5344 && name
[1] == XML_T(ASCII_m
)
5345 && name
[2] == XML_T(ASCII_l
)
5346 && name
[3] == XML_T(ASCII_n
)
5347 && name
[4] == XML_T(ASCII_s
)
5348 && (name
[5] == XML_T('\0') || name
[5] == XML_T(ASCII_COLON
))) {
5349 if (name
[5] == XML_T('\0'))
5350 id
->prefix
= &dtd
->defaultPrefix
;
5352 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
5353 id
->xmlns
= XML_TRUE
;
5357 for (i
= 0; name
[i
]; i
++) {
5358 /* attributes without prefix are *not* in the default namespace */
5359 if (name
[i
] == XML_T(ASCII_COLON
)) {
5361 for (j
= 0; j
< i
; j
++) {
5362 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
5365 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5367 id
->prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&dtd
->pool
),
5369 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
5370 poolFinish(&dtd
->pool
);
5372 poolDiscard(&dtd
->pool
);
5381 #define CONTEXT_SEP XML_T(ASCII_FF)
5383 static const XML_Char
*
5384 getContext(XML_Parser parser
)
5386 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5387 HASH_TABLE_ITER iter
;
5388 XML_Bool needSep
= XML_FALSE
;
5390 if (dtd
->defaultPrefix
.binding
) {
5393 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5395 len
= dtd
->defaultPrefix
.binding
->uriLen
;
5396 if (namespaceSeparator
)
5398 for (i
= 0; i
< len
; i
++)
5399 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
5404 hashTableIterInit(&iter
, &(dtd
->prefixes
));
5409 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
5412 if (!prefix
->binding
)
5414 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5416 for (s
= prefix
->name
; *s
; s
++)
5417 if (!poolAppendChar(&tempPool
, *s
))
5419 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5421 len
= prefix
->binding
->uriLen
;
5422 if (namespaceSeparator
)
5424 for (i
= 0; i
< len
; i
++)
5425 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
5431 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
5434 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
5439 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5441 for (s
= e
->name
; *s
; s
++)
5442 if (!poolAppendChar(&tempPool
, *s
))
5447 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5449 return tempPool
.start
;
5453 setContext(XML_Parser parser
, const XML_Char
*context
)
5455 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5456 const XML_Char
*s
= context
;
5458 while (*context
!= XML_T('\0')) {
5459 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
5461 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5463 e
= (ENTITY
*)lookup(&dtd
->generalEntities
, poolStart(&tempPool
), 0);
5466 if (*s
!= XML_T('\0'))
5469 poolDiscard(&tempPool
);
5471 else if (*s
== XML_T(ASCII_EQUALS
)) {
5473 if (poolLength(&tempPool
) == 0)
5474 prefix
= &dtd
->defaultPrefix
;
5476 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5478 prefix
= (PREFIX
*)lookup(&dtd
->prefixes
, poolStart(&tempPool
),
5482 if (prefix
->name
== poolStart(&tempPool
)) {
5483 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
5487 poolDiscard(&tempPool
);
5489 for (context
= s
+ 1;
5490 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
5492 if (!poolAppendChar(&tempPool
, *context
))
5494 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5496 if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
),
5497 &inheritedBindings
) != XML_ERROR_NONE
)
5499 poolDiscard(&tempPool
);
5500 if (*context
!= XML_T('\0'))
5505 if (!poolAppendChar(&tempPool
, *s
))
5513 static void FASTCALL
5514 normalizePublicId(XML_Char
*publicId
)
5516 XML_Char
*p
= publicId
;
5518 for (s
= publicId
; *s
; s
++) {
5523 if (p
!= publicId
&& p
[-1] != 0x20)
5530 if (p
!= publicId
&& p
[-1] == 0x20)
5536 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
5538 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
5541 poolInit(&(p
->pool
), ms
);
5542 poolInit(&(p
->entityValuePool
), ms
);
5543 hashTableInit(&(p
->generalEntities
), ms
);
5544 hashTableInit(&(p
->elementTypes
), ms
);
5545 hashTableInit(&(p
->attributeIds
), ms
);
5546 hashTableInit(&(p
->prefixes
), ms
);
5548 p
->paramEntityRead
= XML_FALSE
;
5549 hashTableInit(&(p
->paramEntities
), ms
);
5550 #endif /* XML_DTD */
5551 p
->defaultPrefix
.name
= NULL
;
5552 p
->defaultPrefix
.binding
= NULL
;
5554 p
->in_eldecl
= XML_FALSE
;
5555 p
->scaffIndex
= NULL
;
5560 p
->contentStringLen
= 0;
5562 p
->keepProcessing
= XML_TRUE
;
5563 p
->hasParamEntityRefs
= XML_FALSE
;
5564 p
->standalone
= XML_FALSE
;
5569 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
5571 HASH_TABLE_ITER iter
;
5572 hashTableIterInit(&iter
, &(p
->elementTypes
));
5574 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5577 if (e
->allocDefaultAtts
!= 0)
5578 ms
->free_fcn(e
->defaultAtts
);
5580 hashTableClear(&(p
->generalEntities
));
5582 p
->paramEntityRead
= XML_FALSE
;
5583 hashTableClear(&(p
->paramEntities
));
5584 #endif /* XML_DTD */
5585 hashTableClear(&(p
->elementTypes
));
5586 hashTableClear(&(p
->attributeIds
));
5587 hashTableClear(&(p
->prefixes
));
5588 poolClear(&(p
->pool
));
5589 poolClear(&(p
->entityValuePool
));
5590 p
->defaultPrefix
.name
= NULL
;
5591 p
->defaultPrefix
.binding
= NULL
;
5593 p
->in_eldecl
= XML_FALSE
;
5595 ms
->free_fcn(p
->scaffIndex
);
5596 p
->scaffIndex
= NULL
;
5597 ms
->free_fcn(p
->scaffold
);
5603 p
->contentStringLen
= 0;
5605 p
->keepProcessing
= XML_TRUE
;
5606 p
->hasParamEntityRefs
= XML_FALSE
;
5607 p
->standalone
= XML_FALSE
;
5611 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5613 HASH_TABLE_ITER iter
;
5614 hashTableIterInit(&iter
, &(p
->elementTypes
));
5616 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5619 if (e
->allocDefaultAtts
!= 0)
5620 ms
->free_fcn(e
->defaultAtts
);
5622 hashTableDestroy(&(p
->generalEntities
));
5624 hashTableDestroy(&(p
->paramEntities
));
5625 #endif /* XML_DTD */
5626 hashTableDestroy(&(p
->elementTypes
));
5627 hashTableDestroy(&(p
->attributeIds
));
5628 hashTableDestroy(&(p
->prefixes
));
5629 poolDestroy(&(p
->pool
));
5630 poolDestroy(&(p
->entityValuePool
));
5632 ms
->free_fcn(p
->scaffIndex
);
5633 ms
->free_fcn(p
->scaffold
);
5638 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5639 The new DTD has already been initialized.
5642 dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5644 HASH_TABLE_ITER iter
;
5646 /* Copy the prefix table. */
5648 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5650 const XML_Char
*name
;
5651 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5654 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5657 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5661 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5663 /* Copy the attribute id table. */
5667 const XML_Char
*name
;
5668 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5672 /* Remember to allocate the scratch byte before the name. */
5673 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5675 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5679 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
,
5680 sizeof(ATTRIBUTE_ID
));
5683 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5685 newA
->xmlns
= oldA
->xmlns
;
5686 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5687 newA
->prefix
= &newDtd
->defaultPrefix
;
5689 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5690 oldA
->prefix
->name
, 0);
5694 /* Copy the element type table. */
5696 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5701 const XML_Char
*name
;
5702 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5705 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5708 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
,
5709 sizeof(ELEMENT_TYPE
));
5712 if (oldE
->nDefaultAtts
) {
5713 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5714 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5715 if (!newE
->defaultAtts
) {
5721 newE
->idAtt
= (ATTRIBUTE_ID
*)
5722 lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5723 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5725 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
),
5726 oldE
->prefix
->name
, 0);
5727 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5728 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5729 lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5730 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5731 if (oldE
->defaultAtts
[i
].value
) {
5732 newE
->defaultAtts
[i
].value
5733 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5734 if (!newE
->defaultAtts
[i
].value
)
5738 newE
->defaultAtts
[i
].value
= NULL
;
5742 /* Copy the entity tables. */
5743 if (!copyEntityTable(&(newDtd
->generalEntities
),
5745 &(oldDtd
->generalEntities
)))
5749 if (!copyEntityTable(&(newDtd
->paramEntities
),
5751 &(oldDtd
->paramEntities
)))
5753 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5754 #endif /* XML_DTD */
5756 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5757 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5758 newDtd
->standalone
= oldDtd
->standalone
;
5760 /* Don't want deep copying for scaffolding */
5761 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5762 newDtd
->scaffold
= oldDtd
->scaffold
;
5763 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5764 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5765 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5766 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5772 copyEntityTable(HASH_TABLE
*newTable
,
5773 STRING_POOL
*newPool
,
5774 const HASH_TABLE
*oldTable
)
5776 HASH_TABLE_ITER iter
;
5777 const XML_Char
*cachedOldBase
= NULL
;
5778 const XML_Char
*cachedNewBase
= NULL
;
5780 hashTableIterInit(&iter
, oldTable
);
5784 const XML_Char
*name
;
5785 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5788 name
= poolCopyString(newPool
, oldE
->name
);
5791 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
5794 if (oldE
->systemId
) {
5795 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5798 newE
->systemId
= tem
;
5800 if (oldE
->base
== cachedOldBase
)
5801 newE
->base
= cachedNewBase
;
5803 cachedOldBase
= oldE
->base
;
5804 tem
= poolCopyString(newPool
, cachedOldBase
);
5807 cachedNewBase
= newE
->base
= tem
;
5810 if (oldE
->publicId
) {
5811 tem
= poolCopyString(newPool
, oldE
->publicId
);
5814 newE
->publicId
= tem
;
5818 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5822 newE
->textPtr
= tem
;
5823 newE
->textLen
= oldE
->textLen
;
5825 if (oldE
->notation
) {
5826 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5829 newE
->notation
= tem
;
5831 newE
->is_param
= oldE
->is_param
;
5832 newE
->is_internal
= oldE
->is_internal
;
5837 #define INIT_POWER 6
5839 static XML_Bool FASTCALL
5840 keyeq(KEY s1
, KEY s2
)
5842 for (; *s1
== *s2
; s1
++, s2
++)
5848 static unsigned long FASTCALL
5851 unsigned long h
= 0;
5853 h
= CHAR_HASH(h
, *s
++);
5858 lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
5861 if (table
->size
== 0) {
5865 table
->power
= INIT_POWER
;
5866 /* table->size is a power of 2 */
5867 table
->size
= (size_t)1 << INIT_POWER
;
5868 tsize
= table
->size
* sizeof(NAMED
*);
5869 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5874 memset(table
->v
, 0, tsize
);
5875 i
= hash(name
) & ((unsigned long)table
->size
- 1);
5878 unsigned long h
= hash(name
);
5879 unsigned long mask
= (unsigned long)table
->size
- 1;
5880 unsigned char step
= 0;
5882 while (table
->v
[i
]) {
5883 if (keyeq(name
, table
->v
[i
]->name
))
5886 step
= PROBE_STEP(h
, mask
, table
->power
);
5887 i
< step
? (i
+= table
->size
- step
) : (i
-= step
);
5892 /* check for overflow (table is half full) */
5893 if (table
->used
>> (table
->power
- 1)) {
5894 unsigned char newPower
= table
->power
+ 1;
5895 size_t newSize
= (size_t)1 << newPower
;
5896 unsigned long newMask
= (unsigned long)newSize
- 1;
5897 size_t tsize
= newSize
* sizeof(NAMED
*);
5898 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5901 memset(newV
, 0, tsize
);
5902 for (i
= 0; i
< table
->size
; i
++)
5904 unsigned long newHash
= hash(table
->v
[i
]->name
);
5905 size_t j
= newHash
& newMask
;
5909 step
= PROBE_STEP(newHash
, newMask
, newPower
);
5910 j
< step
? (j
+= newSize
- step
) : (j
-= step
);
5912 newV
[j
] = table
->v
[i
];
5914 table
->mem
->free_fcn(table
->v
);
5916 table
->power
= newPower
;
5917 table
->size
= newSize
;
5920 while (table
->v
[i
]) {
5922 step
= PROBE_STEP(h
, newMask
, newPower
);
5923 i
< step
? (i
+= newSize
- step
) : (i
-= step
);
5927 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
5930 memset(table
->v
[i
], 0, createSize
);
5931 table
->v
[i
]->name
= name
;
5936 static void FASTCALL
5937 hashTableClear(HASH_TABLE
*table
)
5940 for (i
= 0; i
< table
->size
; i
++) {
5941 table
->mem
->free_fcn(table
->v
[i
]);
5947 static void FASTCALL
5948 hashTableDestroy(HASH_TABLE
*table
)
5951 for (i
= 0; i
< table
->size
; i
++)
5952 table
->mem
->free_fcn(table
->v
[i
]);
5953 table
->mem
->free_fcn(table
->v
);
5956 static void FASTCALL
5957 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
5966 static void FASTCALL
5967 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
5970 iter
->end
= iter
->p
+ table
->size
;
5973 static NAMED
* FASTCALL
5974 hashTableIterNext(HASH_TABLE_ITER
*iter
)
5976 while (iter
->p
!= iter
->end
) {
5977 NAMED
*tem
= *(iter
->p
)++;
5984 static void FASTCALL
5985 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
5987 pool
->blocks
= NULL
;
5988 pool
->freeBlocks
= NULL
;
5995 static void FASTCALL
5996 poolClear(STRING_POOL
*pool
)
5998 if (!pool
->freeBlocks
)
5999 pool
->freeBlocks
= pool
->blocks
;
6001 BLOCK
*p
= pool
->blocks
;
6003 BLOCK
*tem
= p
->next
;
6004 p
->next
= pool
->freeBlocks
;
6005 pool
->freeBlocks
= p
;
6009 pool
->blocks
= NULL
;
6015 static void FASTCALL
6016 poolDestroy(STRING_POOL
*pool
)
6018 BLOCK
*p
= pool
->blocks
;
6020 BLOCK
*tem
= p
->next
;
6021 pool
->mem
->free_fcn(p
);
6024 p
= pool
->freeBlocks
;
6026 BLOCK
*tem
= p
->next
;
6027 pool
->mem
->free_fcn(p
);
6033 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
6034 const char *ptr
, const char *end
)
6036 if (!pool
->ptr
&& !poolGrow(pool
))
6039 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
6042 if (!poolGrow(pool
))
6048 static const XML_Char
* FASTCALL
6049 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
6052 if (!poolAppendChar(pool
, *s
))
6060 static const XML_Char
*
6061 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
6063 if (!pool
->ptr
&& !poolGrow(pool
))
6065 for (; n
> 0; --n
, s
++) {
6066 if (!poolAppendChar(pool
, *s
))
6074 static const XML_Char
* FASTCALL
6075 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
6078 if (!poolAppendChar(pool
, *s
))
6086 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
6087 const char *ptr
, const char *end
)
6089 if (!poolAppend(pool
, enc
, ptr
, end
))
6091 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
6097 static XML_Bool FASTCALL
6098 poolGrow(STRING_POOL
*pool
)
6100 if (pool
->freeBlocks
) {
6101 if (pool
->start
== 0) {
6102 pool
->blocks
= pool
->freeBlocks
;
6103 pool
->freeBlocks
= pool
->freeBlocks
->next
;
6104 pool
->blocks
->next
= NULL
;
6105 pool
->start
= pool
->blocks
->s
;
6106 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6107 pool
->ptr
= pool
->start
;
6110 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
6111 BLOCK
*tem
= pool
->freeBlocks
->next
;
6112 pool
->freeBlocks
->next
= pool
->blocks
;
6113 pool
->blocks
= pool
->freeBlocks
;
6114 pool
->freeBlocks
= tem
;
6115 memcpy(pool
->blocks
->s
, pool
->start
,
6116 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
6117 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6118 pool
->start
= pool
->blocks
->s
;
6119 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6123 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
6124 int blockSize
= (int)(pool
->end
- pool
->start
)*2;
6125 pool
->blocks
= (BLOCK
*)
6126 pool
->mem
->realloc_fcn(pool
->blocks
,
6128 + blockSize
* sizeof(XML_Char
)));
6129 if (pool
->blocks
== NULL
)
6131 pool
->blocks
->size
= blockSize
;
6132 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6133 pool
->start
= pool
->blocks
->s
;
6134 pool
->end
= pool
->start
+ blockSize
;
6138 int blockSize
= (int)(pool
->end
- pool
->start
);
6139 if (blockSize
< INIT_BLOCK_SIZE
)
6140 blockSize
= INIT_BLOCK_SIZE
;
6143 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
6144 + blockSize
* sizeof(XML_Char
));
6147 tem
->size
= blockSize
;
6148 tem
->next
= pool
->blocks
;
6150 if (pool
->ptr
!= pool
->start
)
6151 memcpy(tem
->s
, pool
->start
,
6152 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
6153 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
6154 pool
->start
= tem
->s
;
6155 pool
->end
= tem
->s
+ blockSize
;
6161 nextScaffoldPart(XML_Parser parser
)
6163 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6164 CONTENT_SCAFFOLD
* me
;
6167 if (!dtd
->scaffIndex
) {
6168 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
6169 if (!dtd
->scaffIndex
)
6171 dtd
->scaffIndex
[0] = 0;
6174 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
6175 CONTENT_SCAFFOLD
*temp
;
6176 if (dtd
->scaffold
) {
6177 temp
= (CONTENT_SCAFFOLD
*)
6178 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
6181 dtd
->scaffSize
*= 2;
6184 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
6185 * sizeof(CONTENT_SCAFFOLD
));
6188 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
6190 dtd
->scaffold
= temp
;
6192 next
= dtd
->scaffCount
++;
6193 me
= &dtd
->scaffold
[next
];
6194 if (dtd
->scaffLevel
) {
6195 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
6196 if (parent
->lastchild
) {
6197 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
6199 if (!parent
->childcnt
)
6200 parent
->firstchild
= next
;
6201 parent
->lastchild
= next
;
6204 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
6209 build_node(XML_Parser parser
,
6212 XML_Content
**contpos
,
6215 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6216 dest
->type
= dtd
->scaffold
[src_node
].type
;
6217 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
6218 if (dest
->type
== XML_CTYPE_NAME
) {
6219 const XML_Char
*src
;
6220 dest
->name
= *strpos
;
6221 src
= dtd
->scaffold
[src_node
].name
;
6223 *(*strpos
)++ = *src
;
6228 dest
->numchildren
= 0;
6229 dest
->children
= NULL
;
6234 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
6235 dest
->children
= *contpos
;
6236 *contpos
+= dest
->numchildren
;
6237 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
6238 i
< dest
->numchildren
;
6239 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
6240 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
6246 static XML_Content
*
6247 build_model (XML_Parser parser
)
6249 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6253 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
6254 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
6256 ret
= (XML_Content
*)MALLOC(allocsize
);
6260 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
6263 build_node(parser
, 0, ret
, &cpos
, &str
);
6267 static ELEMENT_TYPE
*
6268 getElementType(XML_Parser parser
,
6269 const ENCODING
*enc
,
6273 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6274 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
6279 ret
= (ELEMENT_TYPE
*) lookup(&dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
6282 if (ret
->name
!= name
)
6283 poolDiscard(&dtd
->pool
);
6285 poolFinish(&dtd
->pool
);
6286 if (!setElementTypePrefix(parser
, ret
))