2 Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
3 See the file COPYING for copying permission.
6 #include <cmexpat/expatConfig.h>
7 #include <cmexpat/expat.h>
13 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
14 #define XmlConvert XmlUtf16Convert
15 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
16 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
17 #define XmlEncode XmlUtf16Encode
18 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
19 typedef unsigned short ICHAR
;
21 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
22 #define XmlConvert XmlUtf8Convert
23 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
24 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
25 #define XmlEncode XmlUtf8Encode
26 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
33 #define XmlInitEncodingNS XmlInitEncoding
34 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
35 #undef XmlGetInternalEncodingNS
36 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
37 #define XmlParseXmlDeclNS XmlParseXmlDecl
41 #ifdef XML_UNICODE_WCHAR_T
42 #define XML_T(x) L ## x
47 /* Round up n to be a multiple of sz, where sz is a power of 2. */
48 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
53 typedef const XML_Char
*KEY
;
64 XML_Memory_Handling_Suite
*mem
;
72 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
73 #define INIT_DATA_BUF_SIZE 1024
74 #define INIT_ATTS_SIZE 16
75 #define INIT_BLOCK_SIZE 1024
76 #define INIT_BUFFER_SIZE 1024
78 #define EXPAND_SPARE 24
80 typedef struct binding
{
81 struct prefix
*prefix
;
82 struct binding
*nextTagBinding
;
83 struct binding
*prevPrefixBinding
;
84 const struct attribute_id
*attId
;
90 typedef struct prefix
{
97 const XML_Char
*localPart
;
112 const XML_Char
*name
;
113 const XML_Char
*textPtr
;
115 const XML_Char
*systemId
;
116 const XML_Char
*base
;
117 const XML_Char
*publicId
;
118 const XML_Char
*notation
;
124 enum XML_Content_Type type
;
125 enum XML_Content_Quant quant
;
126 const XML_Char
* name
;
133 typedef struct block
{
145 XML_Memory_Handling_Suite
*mem
;
148 /* The XML_Char before the name is used to determine whether
149 an attribute has been specified. */
150 typedef struct attribute_id
{
158 const ATTRIBUTE_ID
*id
;
160 const XML_Char
*value
;
164 const XML_Char
*name
;
166 const ATTRIBUTE_ID
*idAtt
;
168 int allocDefaultAtts
;
169 DEFAULT_ATTRIBUTE
*defaultAtts
;
173 HASH_TABLE generalEntities
;
174 HASH_TABLE elementTypes
;
175 HASH_TABLE attributeIds
;
181 HASH_TABLE paramEntities
;
183 PREFIX defaultPrefix
;
184 /* === scaffolding for building content model === */
186 CONTENT_SCAFFOLD
*scaffold
;
187 unsigned contentStringLen
;
194 typedef struct open_internal_entity
{
195 const char *internalEventPtr
;
196 const char *internalEventEndPtr
;
197 struct open_internal_entity
*next
;
199 } OPEN_INTERNAL_ENTITY
;
201 typedef enum XML_Error
Processor(XML_Parser parser
,
204 const char **endPtr
);
206 static Processor prologProcessor
;
207 static Processor prologInitProcessor
;
208 static Processor contentProcessor
;
209 static Processor cdataSectionProcessor
;
211 static Processor ignoreSectionProcessor
;
213 static Processor epilogProcessor
;
214 static Processor errorProcessor
;
215 static Processor externalEntityInitProcessor
;
216 static Processor externalEntityInitProcessor2
;
217 static Processor externalEntityInitProcessor3
;
218 static Processor externalEntityContentProcessor
;
220 static enum XML_Error
221 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
222 static enum XML_Error
223 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
, const char *, const char *);
224 static enum XML_Error
225 initializeEncoding(XML_Parser parser
);
226 static enum XML_Error
227 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
228 const char *end
, int tok
, const char *next
, const char **nextPtr
);
229 static enum XML_Error
230 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
);
231 static enum XML_Error
232 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
233 const char *start
, const char *end
, const char **endPtr
);
234 static enum XML_Error
235 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
, const char *end
, const char **nextPtr
);
237 static enum XML_Error
238 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
, const char *end
, const char **nextPtr
);
240 static enum XML_Error
storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
241 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
243 int addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
, const XML_Char
*uri
, BINDING
**bindingsPtr
);
246 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*,
247 int isCdata
, int isId
, const XML_Char
*dfltValue
,
250 static enum XML_Error
251 storeAttributeValue(XML_Parser parser
, const ENCODING
*, int isCdata
, const char *, const char *,
253 static enum XML_Error
254 appendAttributeValue(XML_Parser parser
, const ENCODING
*, int isCdata
, const char *, const char *,
256 static ATTRIBUTE_ID
*
257 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
);
258 static int setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
259 static enum XML_Error
260 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
);
262 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
);
264 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
);
266 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
);
268 static const XML_Char
*getContext(XML_Parser parser
);
269 static int setContext(XML_Parser parser
, const XML_Char
*context
);
270 static void normalizePublicId(XML_Char
*s
);
271 static int dtdInit(DTD
*, XML_Parser parser
);
273 static void dtdDestroy(DTD
*, XML_Parser parser
);
275 static int dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, XML_Parser parser
);
277 static int copyEntityTable(HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*,
281 static void dtdSwap(DTD
*, DTD
*);
284 static NAMED
*lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
);
286 static void hashTableInit(HASH_TABLE
*, XML_Memory_Handling_Suite
*ms
);
288 static void hashTableDestroy(HASH_TABLE
*);
289 static void hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
290 static NAMED
*hashTableIterNext(HASH_TABLE_ITER
*);
291 static void poolInit(STRING_POOL
*, XML_Memory_Handling_Suite
*ms
);
292 static void poolClear(STRING_POOL
*);
293 static void poolDestroy(STRING_POOL
*);
294 static XML_Char
*poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
295 const char *ptr
, const char *end
);
296 static XML_Char
*poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
297 const char *ptr
, const char *end
);
299 static int poolGrow(STRING_POOL
*pool
);
301 static int nextScaffoldPart(XML_Parser parser
);
302 static XML_Content
*build_model(XML_Parser parser
);
304 static const XML_Char
*poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
305 static const XML_Char
*poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
306 static const XML_Char
*poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
307 static ELEMENT_TYPE
* getElementType(XML_Parser Paraser
,
312 #define poolStart(pool) ((pool)->start)
313 #define poolEnd(pool) ((pool)->ptr)
314 #define poolLength(pool) ((pool)->ptr - (pool)->start)
315 #define poolChop(pool) ((void)--(pool->ptr))
316 #define poolLastChar(pool) (((pool)->ptr)[-1])
317 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
318 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
319 #define poolAppendChar(pool, c) \
320 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
322 : ((*((pool)->ptr)++ = c), 1))
325 /* The first member must be userData so that the XML_GetUserData macro works. */
329 XML_Memory_Handling_Suite m_mem
;
330 /* first character to be parsed */
331 const char *m_bufferPtr
;
332 /* past last character to be parsed */
334 /* allocated end of buffer */
335 const char *m_bufferLim
;
336 long m_parseEndByteIndex
;
337 const char *m_parseEndPtr
;
339 XML_Char
*m_dataBufEnd
;
340 XML_StartElementHandler m_startElementHandler
;
341 XML_EndElementHandler m_endElementHandler
;
342 XML_CharacterDataHandler m_characterDataHandler
;
343 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
344 XML_CommentHandler m_commentHandler
;
345 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
346 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
347 XML_DefaultHandler m_defaultHandler
;
348 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
349 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
350 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
351 XML_NotationDeclHandler m_notationDeclHandler
;
352 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
353 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
354 XML_NotStandaloneHandler m_notStandaloneHandler
;
355 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
356 void *m_externalEntityRefHandlerArg
;
357 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
358 XML_ElementDeclHandler m_elementDeclHandler
;
359 XML_AttlistDeclHandler m_attlistDeclHandler
;
360 XML_EntityDeclHandler m_entityDeclHandler
;
361 XML_XmlDeclHandler m_xmlDeclHandler
;
362 const ENCODING
*m_encoding
;
363 INIT_ENCODING m_initEncoding
;
364 const ENCODING
*m_internalEncoding
;
365 const XML_Char
*m_protocolEncodingName
;
368 void *m_unknownEncodingMem
;
369 void *m_unknownEncodingData
;
370 void *m_unknownEncodingHandlerData
;
371 void (*m_unknownEncodingRelease
)(void *);
372 PROLOG_STATE m_prologState
;
373 Processor
*m_processor
;
374 enum XML_Error m_errorCode
;
375 const char *m_eventPtr
;
376 const char *m_eventEndPtr
;
377 const char *m_positionPtr
;
378 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
379 int m_defaultExpandInternalEntities
;
381 ENTITY
*m_declEntity
;
382 const XML_Char
*m_doctypeName
;
383 const XML_Char
*m_doctypeSysid
;
384 const XML_Char
*m_doctypePubid
;
385 const XML_Char
*m_declAttributeType
;
386 const XML_Char
*m_declNotationName
;
387 const XML_Char
*m_declNotationPublicId
;
388 ELEMENT_TYPE
*m_declElementType
;
389 ATTRIBUTE_ID
*m_declAttributeId
;
390 char m_declAttributeIsCdata
;
391 char m_declAttributeIsId
;
393 const XML_Char
*m_curBase
;
396 BINDING
*m_inheritedBindings
;
397 BINDING
*m_freeBindingList
;
399 int m_nSpecifiedAtts
;
403 STRING_POOL m_tempPool
;
404 STRING_POOL m_temp2Pool
;
405 char *m_groupConnector
;
406 unsigned m_groupSize
;
407 int m_hadExternalDoctype
;
408 XML_Char m_namespaceSeparator
;
410 enum XML_ParamEntityParsing m_paramEntityParsing
;
411 XML_Parser m_parentParser
;
415 #define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
416 #define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
417 #define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
419 #define userData (((Parser *)parser)->m_userData)
420 #define handlerArg (((Parser *)parser)->m_handlerArg)
421 #define startElementHandler (((Parser *)parser)->m_startElementHandler)
422 #define endElementHandler (((Parser *)parser)->m_endElementHandler)
423 #define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
424 #define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
425 #define commentHandler (((Parser *)parser)->m_commentHandler)
426 #define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
427 #define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
428 #define defaultHandler (((Parser *)parser)->m_defaultHandler)
429 #define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
430 #define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
431 #define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
432 #define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
433 #define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
434 #define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
435 #define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
436 #define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
437 #define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
438 #define internalEntityRefHandler (((Parser *)parser)->m_internalEntityRefHandler)
439 #define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
440 #define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
441 #define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
442 #define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
443 #define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
444 #define encoding (((Parser *)parser)->m_encoding)
445 #define initEncoding (((Parser *)parser)->m_initEncoding)
446 #define internalEncoding (((Parser *)parser)->m_internalEncoding)
447 #define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
448 #define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
449 #define unknownEncodingHandlerData \
450 (((Parser *)parser)->m_unknownEncodingHandlerData)
451 #define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
452 #define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
453 #define ns (((Parser *)parser)->m_ns)
454 #define ns_triplets (((Parser *)parser)->m_ns_triplets)
455 #define prologState (((Parser *)parser)->m_prologState)
456 #define processor (((Parser *)parser)->m_processor)
457 #define errorCode (((Parser *)parser)->m_errorCode)
458 #define eventPtr (((Parser *)parser)->m_eventPtr)
459 #define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
460 #define positionPtr (((Parser *)parser)->m_positionPtr)
461 #define position (((Parser *)parser)->m_position)
462 #define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
463 #define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
464 #define tagLevel (((Parser *)parser)->m_tagLevel)
465 #define buffer (((Parser *)parser)->m_buffer)
466 #define bufferPtr (((Parser *)parser)->m_bufferPtr)
467 #define bufferEnd (((Parser *)parser)->m_bufferEnd)
468 #define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
469 #define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
470 #define bufferLim (((Parser *)parser)->m_bufferLim)
471 #define dataBuf (((Parser *)parser)->m_dataBuf)
472 #define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
473 #define dtd (((Parser *)parser)->m_dtd)
474 #define curBase (((Parser *)parser)->m_curBase)
475 #define declEntity (((Parser *)parser)->m_declEntity)
476 #define doctypeName (((Parser *)parser)->m_doctypeName)
477 #define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
478 #define doctypePubid (((Parser *)parser)->m_doctypePubid)
479 #define declAttributeType (((Parser *)parser)->m_declAttributeType)
480 #define declNotationName (((Parser *)parser)->m_declNotationName)
481 #define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
482 #define declElementType (((Parser *)parser)->m_declElementType)
483 #define declAttributeId (((Parser *)parser)->m_declAttributeId)
484 #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
485 #define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
486 #define freeTagList (((Parser *)parser)->m_freeTagList)
487 #define freeBindingList (((Parser *)parser)->m_freeBindingList)
488 #define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
489 #define tagStack (((Parser *)parser)->m_tagStack)
490 #define atts (((Parser *)parser)->m_atts)
491 #define attsSize (((Parser *)parser)->m_attsSize)
492 #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
493 #define idAttIndex (((Parser *)parser)->m_idAttIndex)
494 #define tempPool (((Parser *)parser)->m_tempPool)
495 #define temp2Pool (((Parser *)parser)->m_temp2Pool)
496 #define groupConnector (((Parser *)parser)->m_groupConnector)
497 #define groupSize (((Parser *)parser)->m_groupSize)
498 #define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
499 #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
501 #define parentParser (((Parser *)parser)->m_parentParser)
502 #define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
505 #ifdef COMPILED_FROM_DSP
506 BOOL WINAPI
DllMain(HINSTANCE h
, DWORD r
, LPVOID p
) {
509 #endif /* def COMPILED_FROM_DSP */
513 Parser
*asParser(XML_Parser parser
)
520 XML_Parser
XML_ParserCreate(const XML_Char
*encodingName
)
522 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
525 XML_Parser
XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
529 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
533 XML_ParserCreate_MM(const XML_Char
*encodingName
,
534 const XML_Memory_Handling_Suite
*memsuite
,
535 const XML_Char
*nameSep
) {
539 const XML_Char implicitContext
[] = {
540 XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
541 XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
542 XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
543 XML_T('.'), XML_T('w'), XML_T('3'),
544 XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
545 XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
546 XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
547 XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
548 XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
554 XML_Memory_Handling_Suite
*mtemp
;
555 parser
= memsuite
->malloc_fcn(sizeof(Parser
));
556 mtemp
= &(((Parser
*) parser
)->m_mem
);
557 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
558 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
559 mtemp
->free_fcn
= memsuite
->free_fcn
;
562 XML_Memory_Handling_Suite
*mtemp
;
563 parser
= malloc(sizeof(Parser
));
564 mtemp
= &(((Parser
*) parser
)->m_mem
);
565 mtemp
->malloc_fcn
= malloc
;
566 mtemp
->realloc_fcn
= realloc
;
567 mtemp
->free_fcn
= free
;
572 processor
= prologInitProcessor
;
573 XmlPrologStateInit(&prologState
);
576 startElementHandler
= 0;
577 endElementHandler
= 0;
578 characterDataHandler
= 0;
579 processingInstructionHandler
= 0;
581 startCdataSectionHandler
= 0;
582 endCdataSectionHandler
= 0;
584 startDoctypeDeclHandler
= 0;
585 endDoctypeDeclHandler
= 0;
586 unparsedEntityDeclHandler
= 0;
587 notationDeclHandler
= 0;
588 startNamespaceDeclHandler
= 0;
589 endNamespaceDeclHandler
= 0;
590 notStandaloneHandler
= 0;
591 externalEntityRefHandler
= 0;
592 externalEntityRefHandlerArg
= parser
;
593 unknownEncodingHandler
= 0;
594 elementDeclHandler
= 0;
595 attlistDeclHandler
= 0;
596 entityDeclHandler
= 0;
601 parseEndByteIndex
= 0;
610 declAttributeType
= 0;
611 declNotationName
= 0;
612 declNotationPublicId
= 0;
613 memset(&position
, 0, sizeof(POSITION
));
614 errorCode
= XML_ERROR_NONE
;
618 openInternalEntities
= 0;
623 inheritedBindings
= 0;
624 attsSize
= INIT_ATTS_SIZE
;
625 atts
= MALLOC(attsSize
* sizeof(ATTRIBUTE
));
627 dataBuf
= MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
630 hadExternalDoctype
= 0;
631 unknownEncodingMem
= 0;
632 unknownEncodingRelease
= 0;
633 unknownEncodingData
= 0;
634 unknownEncodingHandlerData
= 0;
635 namespaceSeparator
= '!';
638 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
642 poolInit(&tempPool
, &(((Parser
*) parser
)->m_mem
));
643 poolInit(&temp2Pool
, &(((Parser
*) parser
)->m_mem
));
644 protocolEncodingName
= encodingName
? poolCopyString(&tempPool
, encodingName
) : 0;
646 if (!dtdInit(&dtd
, parser
) || !atts
|| !dataBuf
647 || (encodingName
&& !protocolEncodingName
)) {
648 XML_ParserFree(parser
);
651 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
654 XmlInitEncodingNS(&initEncoding
, &encoding
, 0);
656 internalEncoding
= XmlGetInternalEncodingNS();
657 namespaceSeparator
= *nameSep
;
659 if (! setContext(parser
, implicitContext
)) {
660 XML_ParserFree(parser
);
665 XmlInitEncoding(&initEncoding
, &encoding
, 0);
666 internalEncoding
= XmlGetInternalEncoding();
670 } /* End XML_ParserCreate_MM */
672 int XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
675 protocolEncodingName
= 0;
677 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
678 if (!protocolEncodingName
)
684 XML_Parser
XML_ExternalEntityParserCreate(XML_Parser oldParser
,
685 const XML_Char
*context
,
686 const XML_Char
*encodingName
)
688 XML_Parser parser
= oldParser
;
690 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
691 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
692 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
693 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
= processingInstructionHandler
;
694 XML_CommentHandler oldCommentHandler
= commentHandler
;
695 XML_StartCdataSectionHandler oldStartCdataSectionHandler
= startCdataSectionHandler
;
696 XML_EndCdataSectionHandler oldEndCdataSectionHandler
= endCdataSectionHandler
;
697 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
698 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
= unparsedEntityDeclHandler
;
699 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
700 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
= startNamespaceDeclHandler
;
701 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
= endNamespaceDeclHandler
;
702 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
703 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
= externalEntityRefHandler
;
704 XML_UnknownEncodingHandler oldUnknownEncodingHandler
= unknownEncodingHandler
;
705 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
706 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
707 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
708 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
709 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
711 void *oldUserData
= userData
;
712 void *oldHandlerArg
= handlerArg
;
713 int oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
714 void *oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
716 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
718 int oldns_triplets
= ns_triplets
;
723 *tmp
= namespaceSeparator
;
724 parser
= XML_ParserCreate_MM(encodingName
, &((Parser
*)parser
)->m_mem
,
728 parser
= XML_ParserCreate_MM(encodingName
, &((Parser
*)parser
)->m_mem
,
735 startElementHandler
= oldStartElementHandler
;
736 endElementHandler
= oldEndElementHandler
;
737 characterDataHandler
= oldCharacterDataHandler
;
738 processingInstructionHandler
= oldProcessingInstructionHandler
;
739 commentHandler
= oldCommentHandler
;
740 startCdataSectionHandler
= oldStartCdataSectionHandler
;
741 endCdataSectionHandler
= oldEndCdataSectionHandler
;
742 defaultHandler
= oldDefaultHandler
;
743 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
744 notationDeclHandler
= oldNotationDeclHandler
;
745 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
746 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
747 notStandaloneHandler
= oldNotStandaloneHandler
;
748 externalEntityRefHandler
= oldExternalEntityRefHandler
;
749 unknownEncodingHandler
= oldUnknownEncodingHandler
;
750 elementDeclHandler
= oldElementDeclHandler
;
751 attlistDeclHandler
= oldAttlistDeclHandler
;
752 entityDeclHandler
= oldEntityDeclHandler
;
753 xmlDeclHandler
= oldXmlDeclHandler
;
754 declElementType
= oldDeclElementType
;
755 userData
= oldUserData
;
756 if (oldUserData
== oldHandlerArg
)
757 handlerArg
= userData
;
760 if (oldExternalEntityRefHandlerArg
!= oldParser
)
761 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
762 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
763 ns_triplets
= oldns_triplets
;
765 paramEntityParsing
= oldParamEntityParsing
;
768 if (!dtdCopy(&dtd
, oldDtd
, parser
) || !setContext(parser
, context
)) {
769 XML_ParserFree(parser
);
772 processor
= externalEntityInitProcessor
;
776 dtdSwap(&dtd
, oldDtd
);
777 parentParser
= oldParser
;
778 XmlPrologStateInitExternalEntity(&prologState
);
780 hadExternalDoctype
= 1;
787 void destroyBindings(BINDING
*bindings
, XML_Parser parser
)
790 BINDING
*b
= bindings
;
793 bindings
= b
->nextTagBinding
;
799 void XML_ParserFree(XML_Parser parser
)
804 if (freeTagList
== 0)
806 tagStack
= freeTagList
;
810 tagStack
= tagStack
->parent
;
812 destroyBindings(p
->bindings
, parser
);
815 destroyBindings(freeBindingList
, parser
);
816 destroyBindings(inheritedBindings
, parser
);
817 poolDestroy(&tempPool
);
818 poolDestroy(&temp2Pool
);
821 if (hadExternalDoctype
)
823 dtdSwap(&dtd
, &((Parser
*)parentParser
)->m_dtd
);
826 dtdDestroy(&dtd
, parser
);
829 FREE(groupConnector
);
833 if (unknownEncodingMem
)
834 FREE(unknownEncodingMem
);
835 if (unknownEncodingRelease
)
836 unknownEncodingRelease(unknownEncodingData
);
840 void XML_UseParserAsHandlerArg(XML_Parser parser
)
846 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
) {
847 ns_triplets
= do_nst
;
850 void XML_SetUserData(XML_Parser parser
, void *p
)
852 if (handlerArg
== userData
)
853 handlerArg
= userData
= p
;
858 int XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
861 p
= poolCopyString(&dtd
.pool
, p
);
871 const XML_Char
*XML_GetBase(XML_Parser parser
)
876 int XML_GetSpecifiedAttributeCount(XML_Parser parser
)
878 return nSpecifiedAtts
;
881 int XML_GetIdAttributeIndex(XML_Parser parser
)
886 void XML_SetElementHandler(XML_Parser parser
,
887 XML_StartElementHandler start
,
888 XML_EndElementHandler end
)
890 startElementHandler
= start
;
891 endElementHandler
= end
;
894 void XML_SetStartElementHandler(XML_Parser parser
,
895 XML_StartElementHandler start
) {
896 startElementHandler
= start
;
899 void XML_SetEndElementHandler(XML_Parser parser
,
900 XML_EndElementHandler end
) {
901 endElementHandler
= end
;
904 void XML_SetCharacterDataHandler(XML_Parser parser
,
905 XML_CharacterDataHandler handler
)
907 characterDataHandler
= handler
;
910 void XML_SetProcessingInstructionHandler(XML_Parser parser
,
911 XML_ProcessingInstructionHandler handler
)
913 processingInstructionHandler
= handler
;
916 void XML_SetCommentHandler(XML_Parser parser
,
917 XML_CommentHandler handler
)
919 commentHandler
= handler
;
922 void XML_SetCdataSectionHandler(XML_Parser parser
,
923 XML_StartCdataSectionHandler start
,
924 XML_EndCdataSectionHandler end
)
926 startCdataSectionHandler
= start
;
927 endCdataSectionHandler
= end
;
930 void XML_SetStartCdataSectionHandler(XML_Parser parser
,
931 XML_StartCdataSectionHandler start
) {
932 startCdataSectionHandler
= start
;
935 void XML_SetEndCdataSectionHandler(XML_Parser parser
,
936 XML_EndCdataSectionHandler end
) {
937 endCdataSectionHandler
= end
;
940 void XML_SetDefaultHandler(XML_Parser parser
,
941 XML_DefaultHandler handler
)
943 defaultHandler
= handler
;
944 defaultExpandInternalEntities
= 0;
947 void XML_SetDefaultHandlerExpand(XML_Parser parser
,
948 XML_DefaultHandler handler
)
950 defaultHandler
= handler
;
951 defaultExpandInternalEntities
= 1;
954 void XML_SetDoctypeDeclHandler(XML_Parser parser
,
955 XML_StartDoctypeDeclHandler start
,
956 XML_EndDoctypeDeclHandler end
)
958 startDoctypeDeclHandler
= start
;
959 endDoctypeDeclHandler
= end
;
962 void XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
963 XML_StartDoctypeDeclHandler start
) {
964 startDoctypeDeclHandler
= start
;
967 void XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
968 XML_EndDoctypeDeclHandler end
) {
969 endDoctypeDeclHandler
= end
;
972 void XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
973 XML_UnparsedEntityDeclHandler handler
)
975 unparsedEntityDeclHandler
= handler
;
978 void XML_SetNotationDeclHandler(XML_Parser parser
,
979 XML_NotationDeclHandler handler
)
981 notationDeclHandler
= handler
;
984 void XML_SetNamespaceDeclHandler(XML_Parser parser
,
985 XML_StartNamespaceDeclHandler start
,
986 XML_EndNamespaceDeclHandler end
)
988 startNamespaceDeclHandler
= start
;
989 endNamespaceDeclHandler
= end
;
992 void XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
993 XML_StartNamespaceDeclHandler start
) {
994 startNamespaceDeclHandler
= start
;
997 void XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
998 XML_EndNamespaceDeclHandler end
) {
999 endNamespaceDeclHandler
= end
;
1003 void XML_SetNotStandaloneHandler(XML_Parser parser
,
1004 XML_NotStandaloneHandler handler
)
1006 notStandaloneHandler
= handler
;
1009 void XML_SetExternalEntityRefHandler(XML_Parser parser
,
1010 XML_ExternalEntityRefHandler handler
)
1012 externalEntityRefHandler
= handler
;
1015 void XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1018 externalEntityRefHandlerArg
= arg
;
1020 externalEntityRefHandlerArg
= parser
;
1023 void XML_SetUnknownEncodingHandler(XML_Parser parser
,
1024 XML_UnknownEncodingHandler handler
,
1027 unknownEncodingHandler
= handler
;
1028 unknownEncodingHandlerData
= data
;
1031 void XML_SetElementDeclHandler(XML_Parser parser
,
1032 XML_ElementDeclHandler eldecl
)
1034 elementDeclHandler
= eldecl
;
1037 void XML_SetAttlistDeclHandler(XML_Parser parser
,
1038 XML_AttlistDeclHandler attdecl
)
1040 attlistDeclHandler
= attdecl
;
1043 void XML_SetEntityDeclHandler(XML_Parser parser
,
1044 XML_EntityDeclHandler handler
)
1046 entityDeclHandler
= handler
;
1049 void XML_SetXmlDeclHandler(XML_Parser parser
,
1050 XML_XmlDeclHandler handler
) {
1051 xmlDeclHandler
= handler
;
1054 int XML_SetParamEntityParsing(XML_Parser parser
,
1055 enum XML_ParamEntityParsing parsing
)
1058 paramEntityParsing
= parsing
;
1061 return parsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1065 int XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1070 positionPtr
= bufferPtr
;
1071 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
= bufferEnd
, 0);
1072 if (errorCode
== XML_ERROR_NONE
)
1074 eventEndPtr
= eventPtr
;
1075 processor
= errorProcessor
;
1078 #ifndef XML_CONTEXT_BYTES
1079 else if (bufferPtr
== bufferEnd
) {
1082 parseEndByteIndex
+= len
;
1085 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, 0);
1086 if (errorCode
== XML_ERROR_NONE
)
1088 eventEndPtr
= eventPtr
;
1089 processor
= errorProcessor
;
1092 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1093 if (errorCode
!= XML_ERROR_NONE
) {
1094 eventEndPtr
= eventPtr
;
1095 processor
= errorProcessor
;
1098 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1099 nLeftOver
= s
+ len
- end
;
1101 if (buffer
== 0 || nLeftOver
> bufferLim
- buffer
) {
1102 /* FIXME avoid integer overflow */
1103 buffer
= buffer
== 0 ? MALLOC(len
* 2) : REALLOC(buffer
, len
* 2);
1104 /* FIXME storage leak if realloc fails */
1106 errorCode
= XML_ERROR_NO_MEMORY
;
1107 eventPtr
= eventEndPtr
= 0;
1108 processor
= errorProcessor
;
1111 bufferLim
= buffer
+ len
* 2;
1113 memcpy(buffer
, end
, nLeftOver
);
1115 bufferEnd
= buffer
+ nLeftOver
;
1119 #endif /* not defined XML_CONTEXT_BYTES */
1121 memcpy(XML_GetBuffer(parser
, len
), s
, len
);
1122 return XML_ParseBuffer(parser
, len
, isFinal
);
1126 int XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1128 const char *start
= bufferPtr
;
1129 positionPtr
= start
;
1131 parseEndByteIndex
+= len
;
1132 errorCode
= processor(parser
, start
, parseEndPtr
= bufferEnd
,
1133 isFinal
? (const char **)0 : &bufferPtr
);
1134 if (errorCode
== XML_ERROR_NONE
) {
1136 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1140 eventEndPtr
= eventPtr
;
1141 processor
= errorProcessor
;
1146 void *XML_GetBuffer(XML_Parser parser
, int len
)
1148 if (len
> bufferLim
- bufferEnd
) {
1149 /* FIXME avoid integer overflow */
1150 int neededSize
= len
+ (bufferEnd
- bufferPtr
);
1151 #ifdef XML_CONTEXT_BYTES
1152 int keep
= bufferPtr
- buffer
;
1154 if (keep
> XML_CONTEXT_BYTES
)
1155 keep
= XML_CONTEXT_BYTES
;
1157 #endif /* defined XML_CONTEXT_BYTES */
1158 if (neededSize
<= bufferLim
- buffer
) {
1159 #ifdef XML_CONTEXT_BYTES
1160 if (keep
< bufferPtr
- buffer
) {
1161 int offset
= (bufferPtr
- buffer
) - keep
;
1162 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1163 bufferEnd
-= offset
;
1164 bufferPtr
-= offset
;
1167 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1168 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1170 #endif /* not defined XML_CONTEXT_BYTES */
1174 int bufferSize
= bufferLim
- bufferPtr
;
1175 if (bufferSize
== 0)
1176 bufferSize
= INIT_BUFFER_SIZE
;
1179 } while (bufferSize
< neededSize
);
1180 newBuf
= MALLOC(bufferSize
);
1182 errorCode
= XML_ERROR_NO_MEMORY
;
1185 bufferLim
= newBuf
+ bufferSize
;
1186 #ifdef XML_CONTEXT_BYTES
1188 int xmKeep
= bufferPtr
- buffer
;
1189 if (xmKeep
> XML_CONTEXT_BYTES
)
1190 xmKeep
= XML_CONTEXT_BYTES
;
1191 memcpy(newBuf
, &bufferPtr
[-xmKeep
], bufferEnd
- bufferPtr
+ xmKeep
);
1194 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + xmKeep
;
1195 bufferPtr
= buffer
+ xmKeep
;
1198 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1199 bufferPtr
= buffer
= newBuf
;
1203 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1206 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1207 bufferPtr
= buffer
= newBuf
;
1208 #endif /* not defined XML_CONTEXT_BYTES */
1214 enum XML_Error
XML_GetErrorCode(XML_Parser parser
)
1219 long XML_GetCurrentByteIndex(XML_Parser parser
)
1222 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1226 int XML_GetCurrentByteCount(XML_Parser parser
)
1228 if (eventEndPtr
&& eventPtr
)
1229 return eventEndPtr
- eventPtr
;
1233 const char * XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1235 #ifdef XML_CONTEXT_BYTES
1236 if (eventPtr
&& buffer
) {
1237 *offset
= eventPtr
- buffer
;
1238 *size
= bufferEnd
- buffer
;
1241 #endif /* defined XML_CONTEXT_BYTES */
1245 int XML_GetCurrentLineNumber(XML_Parser parser
)
1248 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1249 positionPtr
= eventPtr
;
1251 return position
.lineNumber
+ 1;
1254 int XML_GetCurrentColumnNumber(XML_Parser parser
)
1257 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1258 positionPtr
= eventPtr
;
1260 return position
.columnNumber
;
1263 void XML_DefaultCurrent(XML_Parser parser
)
1265 if (defaultHandler
) {
1266 if (openInternalEntities
)
1267 reportDefault(parser
,
1269 openInternalEntities
->internalEventPtr
,
1270 openInternalEntities
->internalEventEndPtr
);
1272 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1276 const XML_LChar
*XML_ErrorString(int code
)
1278 static const XML_LChar
*message
[] = {
1280 XML_T("out of memory"),
1281 XML_T("syntax error"),
1282 XML_T("no element found"),
1283 XML_T("not well-formed (invalid token)"),
1284 XML_T("unclosed token"),
1285 XML_T("unclosed token"),
1286 XML_T("mismatched tag"),
1287 XML_T("duplicate attribute"),
1288 XML_T("junk after document element"),
1289 XML_T("illegal parameter entity reference"),
1290 XML_T("undefined entity"),
1291 XML_T("recursive entity reference"),
1292 XML_T("asynchronous entity"),
1293 XML_T("reference to invalid character number"),
1294 XML_T("reference to binary entity"),
1295 XML_T("reference to external entity in attribute"),
1296 XML_T("xml processing instruction not at start of external entity"),
1297 XML_T("unknown encoding"),
1298 XML_T("encoding specified in XML declaration is incorrect"),
1299 XML_T("unclosed CDATA section"),
1300 XML_T("error in processing external entity reference"),
1301 XML_T("document is not standalone"),
1302 XML_T("unexpected parser state - please send a bug report")
1304 if (code
> 0 && code
< (int)(sizeof(message
)/sizeof(message
[0])))
1305 return message
[code
];
1310 XML_ExpatVersion(void) {
1315 XML_ExpatVersionInfo(void) {
1316 XML_Expat_Version version
;
1318 version
.major
= XML_MAJOR_VERSION
;
1319 version
.minor
= XML_MINOR_VERSION
;
1320 version
.micro
= XML_MICRO_VERSION
;
1326 enum XML_Error
contentProcessor(XML_Parser parser
,
1329 const char **endPtr
)
1331 return doContent(parser
, 0, encoding
, start
, end
, endPtr
);
1335 enum XML_Error
externalEntityInitProcessor(XML_Parser parser
,
1338 const char **endPtr
)
1340 enum XML_Error result
= initializeEncoding(parser
);
1341 if (result
!= XML_ERROR_NONE
)
1343 processor
= externalEntityInitProcessor2
;
1344 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
1348 enum XML_Error
externalEntityInitProcessor2(XML_Parser parser
,
1351 const char **endPtr
)
1354 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1359 case XML_TOK_PARTIAL
:
1362 return XML_ERROR_NONE
;
1365 return XML_ERROR_UNCLOSED_TOKEN
;
1366 case XML_TOK_PARTIAL_CHAR
:
1369 return XML_ERROR_NONE
;
1372 return XML_ERROR_PARTIAL_CHAR
;
1374 processor
= externalEntityInitProcessor3
;
1375 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
1379 enum XML_Error
externalEntityInitProcessor3(XML_Parser parser
,
1382 const char **endPtr
)
1385 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
1387 case XML_TOK_XML_DECL
:
1389 enum XML_Error result
= processXmlDecl(parser
, 1, start
, next
);
1390 if (result
!= XML_ERROR_NONE
)
1395 case XML_TOK_PARTIAL
:
1398 return XML_ERROR_NONE
;
1401 return XML_ERROR_UNCLOSED_TOKEN
;
1402 case XML_TOK_PARTIAL_CHAR
:
1405 return XML_ERROR_NONE
;
1408 return XML_ERROR_PARTIAL_CHAR
;
1410 processor
= externalEntityContentProcessor
;
1412 return doContent(parser
, 1, encoding
, start
, end
, endPtr
);
1416 enum XML_Error
externalEntityContentProcessor(XML_Parser parser
,
1419 const char **endPtr
)
1421 return doContent(parser
, 1, encoding
, start
, end
, endPtr
);
1424 static enum XML_Error
1425 doContent(XML_Parser parser
,
1427 const ENCODING
*enc
,
1430 const char **nextPtr
)
1432 const char **eventPP
;
1433 const char **eventEndPP
;
1434 if (enc
== encoding
) {
1435 eventPP
= &eventPtr
;
1436 eventEndPP
= &eventEndPtr
;
1439 eventPP
= &(openInternalEntities
->internalEventPtr
);
1440 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
1444 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
1445 int tok
= XmlContentTok(enc
, s
, end
, &next
);
1448 case XML_TOK_TRAILING_CR
:
1451 return XML_ERROR_NONE
;
1454 if (characterDataHandler
) {
1456 characterDataHandler(handlerArg
, &c
, 1);
1458 else if (defaultHandler
)
1459 reportDefault(parser
, enc
, s
, end
);
1460 if (startTagLevel
== 0)
1461 return XML_ERROR_NO_ELEMENTS
;
1462 if (tagLevel
!= startTagLevel
)
1463 return XML_ERROR_ASYNC_ENTITY
;
1464 return XML_ERROR_NONE
;
1468 return XML_ERROR_NONE
;
1470 if (startTagLevel
> 0) {
1471 if (tagLevel
!= startTagLevel
)
1472 return XML_ERROR_ASYNC_ENTITY
;
1473 return XML_ERROR_NONE
;
1475 return XML_ERROR_NO_ELEMENTS
;
1476 case XML_TOK_INVALID
:
1478 return XML_ERROR_INVALID_TOKEN
;
1479 case XML_TOK_PARTIAL
:
1482 return XML_ERROR_NONE
;
1484 return XML_ERROR_UNCLOSED_TOKEN
;
1485 case XML_TOK_PARTIAL_CHAR
:
1488 return XML_ERROR_NONE
;
1490 return XML_ERROR_PARTIAL_CHAR
;
1491 case XML_TOK_ENTITY_REF
:
1493 const XML_Char
*name
;
1495 XML_Char ch
= XmlPredefinedEntityName(enc
,
1496 s
+ enc
->minBytesPerChar
,
1497 next
- enc
->minBytesPerChar
);
1499 if (characterDataHandler
)
1500 characterDataHandler(handlerArg
, &ch
, 1);
1501 else if (defaultHandler
)
1502 reportDefault(parser
, enc
, s
, next
);
1505 name
= poolStoreString(&dtd
.pool
, enc
,
1506 s
+ enc
->minBytesPerChar
,
1507 next
- enc
->minBytesPerChar
);
1509 return XML_ERROR_NO_MEMORY
;
1510 entity
= (ENTITY
*)lookup(&dtd
.generalEntities
, name
, 0);
1511 poolDiscard(&dtd
.pool
);
1513 if (dtd
.complete
|| dtd
.standalone
)
1514 return XML_ERROR_UNDEFINED_ENTITY
;
1516 reportDefault(parser
, enc
, s
, next
);
1520 return XML_ERROR_RECURSIVE_ENTITY_REF
;
1521 if (entity
->notation
)
1522 return XML_ERROR_BINARY_ENTITY_REF
;
1524 if (entity
->textPtr
) {
1525 enum XML_Error result
;
1526 OPEN_INTERNAL_ENTITY openEntity
;
1527 if (defaultHandler
&& !defaultExpandInternalEntities
) {
1528 reportDefault(parser
, enc
, s
, next
);
1532 openEntity
.next
= openInternalEntities
;
1533 openInternalEntities
= &openEntity
;
1534 openEntity
.entity
= entity
;
1535 openEntity
.internalEventPtr
= 0;
1536 openEntity
.internalEventEndPtr
= 0;
1537 result
= doContent(parser
,
1540 (char *)entity
->textPtr
,
1541 (char *)(entity
->textPtr
+ entity
->textLen
),
1544 openInternalEntities
= openEntity
.next
;
1548 else if (externalEntityRefHandler
) {
1549 const XML_Char
*context
;
1551 context
= getContext(parser
);
1554 return XML_ERROR_NO_MEMORY
;
1555 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
1560 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
1561 poolDiscard(&tempPool
);
1563 else if (defaultHandler
)
1564 reportDefault(parser
, enc
, s
, next
);
1568 case XML_TOK_START_TAG_WITH_ATTS
:
1569 if (!startElementHandler
) {
1570 enum XML_Error result
= storeAtts(parser
, enc
, s
, 0, 0);
1575 case XML_TOK_START_TAG_NO_ATTS
:
1580 freeTagList
= freeTagList
->parent
;
1583 tag
= MALLOC(sizeof(TAG
));
1585 return XML_ERROR_NO_MEMORY
;
1586 tag
->buf
= MALLOC(INIT_TAG_BUF_SIZE
);
1588 return XML_ERROR_NO_MEMORY
;
1589 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
1592 tag
->parent
= tagStack
;
1594 tag
->name
.localPart
= 0;
1595 tag
->rawName
= s
+ enc
->minBytesPerChar
;
1596 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
1598 /* Need to guarantee that:
1599 tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
1600 if (tag
->rawNameLength
+ (int)(sizeof(XML_Char
) - 1) + (int)sizeof(XML_Char
) > tag
->bufEnd
- tag
->buf
) {
1601 int bufSize
= tag
->rawNameLength
* 4;
1602 bufSize
= ROUND_UP(bufSize
, sizeof(XML_Char
));
1603 tag
->buf
= REALLOC(tag
->buf
, bufSize
);
1605 return XML_ERROR_NO_MEMORY
;
1606 tag
->bufEnd
= tag
->buf
+ bufSize
;
1608 memcpy(tag
->buf
, tag
->rawName
, tag
->rawNameLength
);
1609 tag
->rawName
= tag
->buf
;
1612 if (startElementHandler
) {
1613 enum XML_Error result
;
1616 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
1617 const char *fromPtr
= tag
->rawName
;
1620 toPtr
= (XML_Char
*)(tag
->buf
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
)));
1622 toPtr
= (XML_Char
*)tag
->buf
;
1623 tag
->name
.str
= toPtr
;
1625 &fromPtr
, rawNameEnd
,
1626 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
1627 if (fromPtr
== rawNameEnd
)
1629 bufSize
= (tag
->bufEnd
- tag
->buf
) << 1;
1630 tag
->buf
= REALLOC(tag
->buf
, bufSize
);
1632 return XML_ERROR_NO_MEMORY
;
1633 tag
->bufEnd
= tag
->buf
+ bufSize
;
1635 tag
->rawName
= tag
->buf
;
1637 *toPtr
= XML_T('\0');
1638 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
1641 startElementHandler(handlerArg
, tag
->name
.str
, (const XML_Char
**)atts
);
1642 poolClear(&tempPool
);
1647 reportDefault(parser
, enc
, s
, next
);
1651 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
1652 if (!startElementHandler
) {
1653 enum XML_Error result
= storeAtts(parser
, enc
, s
, 0, 0);
1658 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
1659 if (startElementHandler
|| endElementHandler
) {
1660 const char *rawName
= s
+ enc
->minBytesPerChar
;
1661 enum XML_Error result
;
1662 BINDING
*bindings
= 0;
1664 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
1665 rawName
+ XmlNameLength(enc
, rawName
));
1667 return XML_ERROR_NO_MEMORY
;
1668 poolFinish(&tempPool
);
1669 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
1672 poolFinish(&tempPool
);
1673 if (startElementHandler
)
1674 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
1675 if (endElementHandler
) {
1676 if (startElementHandler
)
1677 *eventPP
= *eventEndPP
;
1678 endElementHandler(handlerArg
, name
.str
);
1680 poolClear(&tempPool
);
1682 BINDING
*b
= bindings
;
1683 if (endNamespaceDeclHandler
)
1684 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
1685 bindings
= bindings
->nextTagBinding
;
1686 b
->nextTagBinding
= freeBindingList
;
1687 freeBindingList
= b
;
1688 b
->prefix
->binding
= b
->prevPrefixBinding
;
1691 else if (defaultHandler
)
1692 reportDefault(parser
, enc
, s
, next
);
1694 return epilogProcessor(parser
, next
, end
, nextPtr
);
1696 case XML_TOK_END_TAG
:
1697 if (tagLevel
== startTagLevel
)
1698 return XML_ERROR_ASYNC_ENTITY
;
1701 const char *rawName
;
1702 TAG
*tag
= tagStack
;
1703 tagStack
= tag
->parent
;
1704 tag
->parent
= freeTagList
;
1706 rawName
= s
+ enc
->minBytesPerChar
*2;
1707 len
= XmlNameLength(enc
, rawName
);
1708 if (len
!= tag
->rawNameLength
1709 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
1711 return XML_ERROR_TAG_MISMATCH
;
1714 if (endElementHandler
&& tag
->name
.str
) {
1715 if (tag
->name
.localPart
) {
1716 XML_Char
*to
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
1717 const XML_Char
*from
= tag
->name
.localPart
;
1718 while ((*to
++ = *from
++) != 0)
1721 endElementHandler(handlerArg
, tag
->name
.str
);
1723 else if (defaultHandler
)
1724 reportDefault(parser
, enc
, s
, next
);
1725 while (tag
->bindings
) {
1726 BINDING
*b
= tag
->bindings
;
1727 if (endNamespaceDeclHandler
)
1728 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
1729 tag
->bindings
= tag
->bindings
->nextTagBinding
;
1730 b
->nextTagBinding
= freeBindingList
;
1731 freeBindingList
= b
;
1732 b
->prefix
->binding
= b
->prevPrefixBinding
;
1735 return epilogProcessor(parser
, next
, end
, nextPtr
);
1738 case XML_TOK_CHAR_REF
:
1740 int n
= XmlCharRefNumber(enc
, s
);
1742 return XML_ERROR_BAD_CHAR_REF
;
1743 if (characterDataHandler
) {
1744 XML_Char buf
[XML_ENCODE_MAX
];
1745 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
1747 else if (defaultHandler
)
1748 reportDefault(parser
, enc
, s
, next
);
1751 case XML_TOK_XML_DECL
:
1752 return XML_ERROR_MISPLACED_XML_PI
;
1753 case XML_TOK_DATA_NEWLINE
:
1754 if (characterDataHandler
) {
1756 characterDataHandler(handlerArg
, &c
, 1);
1758 else if (defaultHandler
)
1759 reportDefault(parser
, enc
, s
, next
);
1761 case XML_TOK_CDATA_SECT_OPEN
:
1763 enum XML_Error result
;
1764 if (startCdataSectionHandler
)
1765 startCdataSectionHandler(handlerArg
);
1767 /* Suppose you doing a transformation on a document that involves
1768 changing only the character data. You set up a defaultHandler
1769 and a characterDataHandler. The defaultHandler simply copies
1770 characters through. The characterDataHandler does the transformation
1771 and writes the characters out escaping them as necessary. This case
1772 will fail to work if we leave out the following two lines (because &
1773 and < inside CDATA sections will be incorrectly escaped).
1775 However, now we have a start/endCdataSectionHandler, so it seems
1776 easier to let the user deal with this. */
1778 else if (characterDataHandler
)
1779 characterDataHandler(handlerArg
, dataBuf
, 0);
1781 else if (defaultHandler
)
1782 reportDefault(parser
, enc
, s
, next
);
1783 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
);
1785 processor
= cdataSectionProcessor
;
1790 case XML_TOK_TRAILING_RSQB
:
1793 return XML_ERROR_NONE
;
1795 if (characterDataHandler
) {
1796 if (MUST_CONVERT(enc
, s
)) {
1797 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
1798 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
1799 characterDataHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
1802 characterDataHandler(handlerArg
,
1804 (XML_Char
*)end
- (XML_Char
*)s
);
1806 else if (defaultHandler
)
1807 reportDefault(parser
, enc
, s
, end
);
1808 if (startTagLevel
== 0) {
1810 return XML_ERROR_NO_ELEMENTS
;
1812 if (tagLevel
!= startTagLevel
) {
1814 return XML_ERROR_ASYNC_ENTITY
;
1816 return XML_ERROR_NONE
;
1817 case XML_TOK_DATA_CHARS
:
1818 if (characterDataHandler
) {
1819 if (MUST_CONVERT(enc
, s
)) {
1821 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
1822 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
1824 characterDataHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
1831 characterDataHandler(handlerArg
,
1833 (XML_Char
*)next
- (XML_Char
*)s
);
1835 else if (defaultHandler
)
1836 reportDefault(parser
, enc
, s
, next
);
1839 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
1840 return XML_ERROR_NO_MEMORY
;
1842 case XML_TOK_COMMENT
:
1843 if (!reportComment(parser
, enc
, s
, next
))
1844 return XML_ERROR_NO_MEMORY
;
1848 reportDefault(parser
, enc
, s
, next
);
1851 *eventPP
= s
= next
;
1856 /* If tagNamePtr is non-null, build a real list of attributes,
1857 otherwise just check the attributes for well-formedness. */
1859 static enum XML_Error
storeAtts(XML_Parser parser
, const ENCODING
*enc
,
1860 const char *attStr
, TAG_NAME
*tagNamePtr
,
1861 BINDING
**bindingsPtr
)
1863 ELEMENT_TYPE
*elementType
= 0;
1864 int nDefaultAtts
= 0;
1865 const XML_Char
**appAtts
; /* the attribute list to pass to the application */
1871 const XML_Char
*localPart
;
1873 /* lookup the element type name */
1875 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
.elementTypes
, tagNamePtr
->str
,0);
1877 tagNamePtr
->str
= poolCopyString(&dtd
.pool
, tagNamePtr
->str
);
1878 if (!tagNamePtr
->str
)
1879 return XML_ERROR_NO_MEMORY
;
1880 elementType
= (ELEMENT_TYPE
*)lookup(&dtd
.elementTypes
, tagNamePtr
->str
, sizeof(ELEMENT_TYPE
));
1882 return XML_ERROR_NO_MEMORY
;
1883 if (ns
&& !setElementTypePrefix(parser
, elementType
))
1884 return XML_ERROR_NO_MEMORY
;
1886 nDefaultAtts
= elementType
->nDefaultAtts
;
1888 /* get the attributes from the tokenizer */
1889 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
1890 if (n
+ nDefaultAtts
> attsSize
) {
1891 int oldAttsSize
= attsSize
;
1892 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
1893 atts
= REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
1895 return XML_ERROR_NO_MEMORY
;
1896 if (n
> oldAttsSize
)
1897 XmlGetAttributes(enc
, attStr
, n
, atts
);
1899 appAtts
= (const XML_Char
**)atts
;
1900 for (i
= 0; i
< n
; i
++) {
1901 /* add the name and value to the attribute list */
1902 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, atts
[i
].name
,
1904 + XmlNameLength(enc
, atts
[i
].name
));
1906 return XML_ERROR_NO_MEMORY
;
1907 /* detect duplicate attributes */
1908 if ((attId
->name
)[-1]) {
1909 if (enc
== encoding
)
1910 eventPtr
= atts
[i
].name
;
1911 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
1913 (attId
->name
)[-1] = 1;
1914 appAtts
[attIndex
++] = attId
->name
;
1915 if (!atts
[i
].normalized
) {
1916 enum XML_Error result
;
1919 /* figure out whether declared as other than CDATA */
1920 if (attId
->maybeTokenized
) {
1922 for (j
= 0; j
< nDefaultAtts
; j
++) {
1923 if (attId
== elementType
->defaultAtts
[j
].id
) {
1924 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
1930 /* normalize the attribute value */
1931 result
= storeAttributeValue(parser
, enc
, isCdata
,
1932 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
1937 appAtts
[attIndex
] = poolStart(&tempPool
);
1938 poolFinish(&tempPool
);
1941 poolDiscard(&tempPool
);
1943 else if (tagNamePtr
) {
1944 /* the value did not need normalizing */
1945 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
, atts
[i
].valueEnd
);
1946 if (appAtts
[attIndex
] == 0)
1947 return XML_ERROR_NO_MEMORY
;
1948 poolFinish(&tempPool
);
1950 /* handle prefixed attribute names */
1951 if (attId
->prefix
&& tagNamePtr
) {
1953 /* deal with namespace declarations here */
1954 if (!addBinding(parser
, attId
->prefix
, attId
, appAtts
[attIndex
], bindingsPtr
))
1955 return XML_ERROR_NO_MEMORY
;
1959 /* deal with other prefixed names later */
1962 (attId
->name
)[-1] = 2;
1970 nSpecifiedAtts
= attIndex
;
1971 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
1972 for (i
= 0; i
< attIndex
; i
+= 2)
1973 if (appAtts
[i
] == elementType
->idAtt
->name
) {
1980 /* do attribute defaulting */
1981 for (j
= 0; j
< nDefaultAtts
; j
++) {
1982 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ j
;
1983 if (!(da
->id
->name
)[-1] && da
->value
) {
1984 if (da
->id
->prefix
) {
1985 if (da
->id
->xmlns
) {
1986 if (!addBinding(parser
, da
->id
->prefix
, da
->id
, da
->value
, bindingsPtr
))
1987 return XML_ERROR_NO_MEMORY
;
1990 (da
->id
->name
)[-1] = 2;
1992 appAtts
[attIndex
++] = da
->id
->name
;
1993 appAtts
[attIndex
++] = da
->value
;
1997 (da
->id
->name
)[-1] = 1;
1998 appAtts
[attIndex
++] = da
->id
->name
;
1999 appAtts
[attIndex
++] = da
->value
;
2003 appAtts
[attIndex
] = 0;
2007 /* expand prefixed attribute names */
2008 for (; i
< attIndex
; i
+= 2) {
2009 if (appAtts
[i
][-1] == 2) {
2011 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2012 id
= (ATTRIBUTE_ID
*)lookup(&dtd
.attributeIds
, appAtts
[i
], 0);
2013 if (id
->prefix
->binding
) {
2015 const BINDING
*b
= id
->prefix
->binding
;
2016 const XML_Char
*s
= appAtts
[i
];
2017 for (j
= 0; j
< b
->uriLen
; j
++) {
2018 if (!poolAppendChar(&tempPool
, b
->uri
[j
]))
2019 return XML_ERROR_NO_MEMORY
;
2024 if (!poolAppendChar(&tempPool
, *s
))
2025 return XML_ERROR_NO_MEMORY
;
2028 tempPool
.ptr
[-1] = namespaceSeparator
;
2029 s
= b
->prefix
->name
;
2031 if (!poolAppendChar(&tempPool
, *s
))
2032 return XML_ERROR_NO_MEMORY
;
2036 appAtts
[i
] = poolStart(&tempPool
);
2037 poolFinish(&tempPool
);
2043 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2046 /* clear the flags that say whether attributes were specified */
2047 for (; i
< attIndex
; i
+= 2)
2048 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2050 return XML_ERROR_NONE
;
2051 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2052 binding
->attId
->name
[-1] = 0;
2053 /* expand the element type name */
2054 if (elementType
->prefix
) {
2055 binding
= elementType
->prefix
->binding
;
2057 return XML_ERROR_NONE
;
2058 localPart
= tagNamePtr
->str
;
2059 while (*localPart
++ != XML_T(':'))
2062 else if (dtd
.defaultPrefix
.binding
) {
2063 binding
= dtd
.defaultPrefix
.binding
;
2064 localPart
= tagNamePtr
->str
;
2067 return XML_ERROR_NONE
;
2068 tagNamePtr
->localPart
= localPart
;
2069 tagNamePtr
->uriLen
= binding
->uriLen
;
2070 for (i
= 0; localPart
[i
++];)
2072 n
= i
+ binding
->uriLen
;
2073 if (n
> binding
->uriAlloc
) {
2075 XML_Char
*uri
= MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
2077 return XML_ERROR_NO_MEMORY
;
2078 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
2079 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
2080 for (p
= tagStack
; p
; p
= p
->parent
)
2081 if (p
->name
.str
== binding
->uri
)
2086 memcpy(binding
->uri
+ binding
->uriLen
, localPart
, i
* sizeof(XML_Char
));
2087 tagNamePtr
->str
= binding
->uri
;
2088 return XML_ERROR_NONE
;
2092 int addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
, const XML_Char
*uri
, BINDING
**bindingsPtr
)
2096 for (len
= 0; uri
[len
]; len
++)
2098 if (namespaceSeparator
)
2100 if (freeBindingList
) {
2101 b
= freeBindingList
;
2102 if (len
> b
->uriAlloc
) {
2103 b
->uri
= REALLOC(b
->uri
, sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2106 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2108 freeBindingList
= b
->nextTagBinding
;
2111 b
= MALLOC(sizeof(BINDING
));
2114 b
->uri
= MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
2119 b
->uriAlloc
= len
+ EXPAND_SPARE
;
2122 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
2123 if (namespaceSeparator
)
2124 b
->uri
[len
- 1] = namespaceSeparator
;
2127 b
->prevPrefixBinding
= prefix
->binding
;
2128 if (*uri
== XML_T('\0') && prefix
== &dtd
.defaultPrefix
)
2129 prefix
->binding
= 0;
2131 prefix
->binding
= b
;
2132 b
->nextTagBinding
= *bindingsPtr
;
2134 if (startNamespaceDeclHandler
)
2135 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
2136 prefix
->binding
? uri
: 0);
2140 /* The idea here is to avoid using stack for each CDATA section when
2141 the whole file is parsed with one call. */
2144 enum XML_Error
cdataSectionProcessor(XML_Parser parser
,
2147 const char **endPtr
)
2149 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
, endPtr
);
2151 processor
= contentProcessor
;
2152 return contentProcessor(parser
, start
, end
, endPtr
);
2157 /* startPtr gets set to non-null is the section is closed, and to null if
2158 the section is not yet closed. */
2161 enum XML_Error
doCdataSection(XML_Parser parser
,
2162 const ENCODING
*enc
,
2163 const char **startPtr
,
2165 const char **nextPtr
)
2167 const char *s
= *startPtr
;
2168 const char **eventPP
;
2169 const char **eventEndPP
;
2170 if (enc
== encoding
) {
2171 eventPP
= &eventPtr
;
2173 eventEndPP
= &eventEndPtr
;
2176 eventPP
= &(openInternalEntities
->internalEventPtr
);
2177 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2183 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
2186 case XML_TOK_CDATA_SECT_CLOSE
:
2187 if (endCdataSectionHandler
)
2188 endCdataSectionHandler(handlerArg
);
2190 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2191 else if (characterDataHandler
)
2192 characterDataHandler(handlerArg
, dataBuf
, 0);
2194 else if (defaultHandler
)
2195 reportDefault(parser
, enc
, s
, next
);
2197 return XML_ERROR_NONE
;
2198 case XML_TOK_DATA_NEWLINE
:
2199 if (characterDataHandler
) {
2201 characterDataHandler(handlerArg
, &c
, 1);
2203 else if (defaultHandler
)
2204 reportDefault(parser
, enc
, s
, next
);
2206 case XML_TOK_DATA_CHARS
:
2207 if (characterDataHandler
) {
2208 if (MUST_CONVERT(enc
, s
)) {
2210 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2211 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2213 characterDataHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
2220 characterDataHandler(handlerArg
,
2222 (XML_Char
*)next
- (XML_Char
*)s
);
2224 else if (defaultHandler
)
2225 reportDefault(parser
, enc
, s
, next
);
2227 case XML_TOK_INVALID
:
2229 return XML_ERROR_INVALID_TOKEN
;
2230 case XML_TOK_PARTIAL_CHAR
:
2233 return XML_ERROR_NONE
;
2235 return XML_ERROR_PARTIAL_CHAR
;
2236 case XML_TOK_PARTIAL
:
2240 return XML_ERROR_NONE
;
2242 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
2245 return XML_ERROR_UNEXPECTED_STATE
;
2247 *eventPP
= s
= next
;
2254 /* The idea here is to avoid using stack for each IGNORE section when
2255 the whole file is parsed with one call. */
2258 enum XML_Error
ignoreSectionProcessor(XML_Parser parser
,
2261 const char **endPtr
)
2263 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
, endPtr
);
2265 processor
= prologProcessor
;
2266 return prologProcessor(parser
, start
, end
, endPtr
);
2271 /* startPtr gets set to non-null is the section is closed, and to null if
2272 the section is not yet closed. */
2275 enum XML_Error
doIgnoreSection(XML_Parser parser
,
2276 const ENCODING
*enc
,
2277 const char **startPtr
,
2279 const char **nextPtr
)
2283 const char *s
= *startPtr
;
2284 const char **eventPP
;
2285 const char **eventEndPP
;
2286 if (enc
== encoding
) {
2287 eventPP
= &eventPtr
;
2289 eventEndPP
= &eventEndPtr
;
2292 eventPP
= &(openInternalEntities
->internalEventPtr
);
2293 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2297 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
2300 case XML_TOK_IGNORE_SECT
:
2302 reportDefault(parser
, enc
, s
, next
);
2304 return XML_ERROR_NONE
;
2305 case XML_TOK_INVALID
:
2307 return XML_ERROR_INVALID_TOKEN
;
2308 case XML_TOK_PARTIAL_CHAR
:
2311 return XML_ERROR_NONE
;
2313 return XML_ERROR_PARTIAL_CHAR
;
2314 case XML_TOK_PARTIAL
:
2318 return XML_ERROR_NONE
;
2320 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2323 return XML_ERROR_UNEXPECTED_STATE
;
2328 #endif /* XML_DTD */
2330 static enum XML_Error
2331 initializeEncoding(XML_Parser parser
)
2335 char encodingBuf
[128];
2336 if (!protocolEncodingName
)
2340 for (i
= 0; protocolEncodingName
[i
]; i
++) {
2341 if (i
== sizeof(encodingBuf
) - 1
2342 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
2343 encodingBuf
[0] = '\0';
2346 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
2348 encodingBuf
[i
] = '\0';
2352 s
= protocolEncodingName
;
2354 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
2355 return XML_ERROR_NONE
;
2356 return handleUnknownEncoding(parser
, protocolEncodingName
);
2359 static enum XML_Error
2360 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
2361 const char *s
, const char *next
)
2363 const char *encodingName
= 0;
2364 const char *storedEncName
= 0;
2365 const ENCODING
*newEncoding
= 0;
2366 const char *version
= 0;
2367 const char *versionend
;
2368 const char *storedversion
= 0;
2369 int standalone
= -1;
2372 : XmlParseXmlDecl
)(isGeneralTextEntity
,
2382 return XML_ERROR_SYNTAX
;
2383 if (!isGeneralTextEntity
&& standalone
== 1) {
2386 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
2387 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
2388 #endif /* XML_DTD */
2390 if (xmlDeclHandler
) {
2392 storedEncName
= poolStoreString(&temp2Pool
,
2396 + XmlNameLength(encoding
, encodingName
));
2397 if (! storedEncName
)
2398 return XML_ERROR_NO_MEMORY
;
2399 poolFinish(&temp2Pool
);
2402 storedversion
= poolStoreString(&temp2Pool
,
2405 versionend
- encoding
->minBytesPerChar
);
2406 if (! storedversion
)
2407 return XML_ERROR_NO_MEMORY
;
2409 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
2411 else if (defaultHandler
)
2412 reportDefault(parser
, encoding
, s
, next
);
2413 if (!protocolEncodingName
) {
2415 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
2416 eventPtr
= encodingName
;
2417 return XML_ERROR_INCORRECT_ENCODING
;
2419 encoding
= newEncoding
;
2421 else if (encodingName
) {
2422 enum XML_Error result
;
2423 if (! storedEncName
) {
2424 storedEncName
= poolStoreString(&temp2Pool
,
2428 + XmlNameLength(encoding
, encodingName
));
2429 if (! storedEncName
)
2430 return XML_ERROR_NO_MEMORY
;
2432 result
= handleUnknownEncoding(parser
, storedEncName
);
2433 poolClear(&tempPool
);
2434 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
2435 eventPtr
= encodingName
;
2440 if (storedEncName
|| storedversion
)
2441 poolClear(&temp2Pool
);
2443 return XML_ERROR_NONE
;
2446 static enum XML_Error
2447 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
2449 if (unknownEncodingHandler
) {
2452 for (i
= 0; i
< 256; i
++)
2457 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
, &info
)) {
2459 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
2460 if (!unknownEncodingMem
) {
2462 info
.release(info
.data
);
2463 return XML_ERROR_NO_MEMORY
;
2466 ? XmlInitUnknownEncodingNS
2467 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
2472 unknownEncodingData
= info
.data
;
2473 unknownEncodingRelease
= info
.release
;
2475 return XML_ERROR_NONE
;
2479 info
.release(info
.data
);
2481 return XML_ERROR_UNKNOWN_ENCODING
;
2484 static enum XML_Error
2485 prologInitProcessor(XML_Parser parser
,
2488 const char **nextPtr
)
2490 enum XML_Error result
= initializeEncoding(parser
);
2491 if (result
!= XML_ERROR_NONE
)
2493 processor
= prologProcessor
;
2494 return prologProcessor(parser
, s
, end
, nextPtr
);
2497 static enum XML_Error
2498 prologProcessor(XML_Parser parser
,
2501 const char **nextPtr
)
2504 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
2505 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
);
2508 static enum XML_Error
2509 doProlog(XML_Parser parser
,
2510 const ENCODING
*enc
,
2515 const char **nextPtr
)
2518 static const XML_Char externalSubsetName
[] = { '#' , '\0' };
2519 #endif /* XML_DTD */
2521 const char **eventPP
;
2522 const char **eventEndPP
;
2523 enum XML_Content_Quant quant
;
2525 if (enc
== encoding
) {
2526 eventPP
= &eventPtr
;
2527 eventEndPP
= &eventEndPtr
;
2530 eventPP
= &(openInternalEntities
->internalEventPtr
);
2531 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2538 if (nextPtr
!= 0 && tok
!= XML_TOK_INVALID
) {
2540 return XML_ERROR_NONE
;
2543 case XML_TOK_INVALID
:
2545 return XML_ERROR_INVALID_TOKEN
;
2546 case XML_TOK_PARTIAL
:
2547 return XML_ERROR_UNCLOSED_TOKEN
;
2548 case XML_TOK_PARTIAL_CHAR
:
2549 return XML_ERROR_PARTIAL_CHAR
;
2552 if (enc
!= encoding
)
2553 return XML_ERROR_NONE
;
2555 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
2557 return XML_ERROR_SYNTAX
;
2558 hadExternalDoctype
= 0;
2559 return XML_ERROR_NONE
;
2561 #endif /* XML_DTD */
2562 return XML_ERROR_NO_ELEMENTS
;
2569 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
2571 case XML_ROLE_XML_DECL
:
2573 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
2574 if (result
!= XML_ERROR_NONE
)
2579 case XML_ROLE_DOCTYPE_NAME
:
2580 if (startDoctypeDeclHandler
) {
2581 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
2583 return XML_ERROR_NO_MEMORY
;
2584 poolFinish(&tempPool
);
2589 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
2590 if (startDoctypeDeclHandler
) {
2591 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
2594 poolClear(&tempPool
);
2598 case XML_ROLE_TEXT_DECL
:
2600 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
2601 if (result
!= XML_ERROR_NONE
)
2606 #endif /* XML_DTD */
2607 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
2608 if (startDoctypeDeclHandler
) {
2609 doctypePubid
= poolStoreString(&tempPool
, enc
, s
+ 1, next
- 1);
2611 return XML_ERROR_NO_MEMORY
;
2612 poolFinish(&tempPool
);
2615 declEntity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
2619 return XML_ERROR_NO_MEMORY
;
2620 #endif /* XML_DTD */
2622 case XML_ROLE_ENTITY_PUBLIC_ID
:
2623 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
2624 return XML_ERROR_SYNTAX
;
2626 XML_Char
*tem
= poolStoreString(&dtd
.pool
,
2628 s
+ enc
->minBytesPerChar
,
2629 next
- enc
->minBytesPerChar
);
2631 return XML_ERROR_NO_MEMORY
;
2632 normalizePublicId(tem
);
2633 declEntity
->publicId
= tem
;
2634 poolFinish(&dtd
.pool
);
2637 case XML_ROLE_DOCTYPE_CLOSE
:
2639 startDoctypeDeclHandler(handlerArg
, doctypeName
,
2640 doctypeSysid
, doctypePubid
, 0);
2641 poolClear(&tempPool
);
2643 if (dtd
.complete
&& hadExternalDoctype
) {
2646 if (paramEntityParsing
&& externalEntityRefHandler
) {
2647 ENTITY
*entity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
2650 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2655 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2657 #endif /* XML_DTD */
2660 && notStandaloneHandler
2661 && !notStandaloneHandler(handlerArg
))
2662 return XML_ERROR_NOT_STANDALONE
;
2664 if (endDoctypeDeclHandler
)
2665 endDoctypeDeclHandler(handlerArg
);
2667 case XML_ROLE_INSTANCE_START
:
2668 processor
= contentProcessor
;
2669 return contentProcessor(parser
, s
, end
, nextPtr
);
2670 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
2671 declElementType
= getElementType(parser
, enc
, s
, next
);
2672 if (!declElementType
)
2673 return XML_ERROR_NO_MEMORY
;
2675 case XML_ROLE_ATTRIBUTE_NAME
:
2676 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
2677 if (!declAttributeId
)
2678 return XML_ERROR_NO_MEMORY
;
2679 declAttributeIsCdata
= 0;
2680 declAttributeType
= 0;
2681 declAttributeIsId
= 0;
2683 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
2684 declAttributeIsCdata
= 1;
2685 declAttributeType
= "CDATA";
2687 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
2688 declAttributeIsId
= 1;
2689 declAttributeType
= "ID";
2691 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
2692 declAttributeType
= "IDREF";
2694 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
2695 declAttributeType
= "IDREFS";
2697 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
2698 declAttributeType
= "ENTITY";
2700 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
2701 declAttributeType
= "ENTITIES";
2703 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
2704 declAttributeType
= "NMTOKEN";
2706 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
2707 declAttributeType
= "NMTOKENS";
2710 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
2711 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
2712 if (attlistDeclHandler
)
2715 if (declAttributeType
) {
2719 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
2723 if (! poolAppendString(&tempPool
, prefix
))
2724 return XML_ERROR_NO_MEMORY
;
2725 if (! poolAppend(&tempPool
, enc
, s
, next
))
2726 return XML_ERROR_NO_MEMORY
;
2727 declAttributeType
= tempPool
.start
;
2730 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
2731 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
2733 && !defineAttribute(declElementType
, declAttributeId
,
2734 declAttributeIsCdata
, declAttributeIsId
, 0,
2736 return XML_ERROR_NO_MEMORY
;
2737 if (attlistDeclHandler
&& declAttributeType
) {
2738 if (*declAttributeType
== '('
2739 || (*declAttributeType
== 'N' && declAttributeType
[1] == 'O')) {
2740 /* Enumerated or Notation type */
2741 if (! poolAppendChar(&tempPool
, ')')
2742 || ! poolAppendChar(&tempPool
, '\0'))
2743 return XML_ERROR_NO_MEMORY
;
2744 declAttributeType
= tempPool
.start
;
2745 poolFinish(&tempPool
);
2748 attlistDeclHandler(handlerArg
, declElementType
->name
,
2749 declAttributeId
->name
, declAttributeType
,
2750 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
2751 poolClear(&tempPool
);
2754 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
2755 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
2757 const XML_Char
*attVal
;
2758 enum XML_Error result
2759 = storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
2760 s
+ enc
->minBytesPerChar
,
2761 next
- enc
->minBytesPerChar
,
2765 attVal
= poolStart(&dtd
.pool
);
2766 poolFinish(&dtd
.pool
);
2768 /* ID attributes aren't allowed to have a default */
2769 && !defineAttribute(declElementType
, declAttributeId
, declAttributeIsCdata
, 0, attVal
, parser
))
2770 return XML_ERROR_NO_MEMORY
;
2771 if (attlistDeclHandler
&& declAttributeType
) {
2772 if (*declAttributeType
== '('
2773 || (*declAttributeType
== 'N' && declAttributeType
[1] == 'O')) {
2774 /* Enumerated or Notation type */
2775 if (! poolAppendChar(&tempPool
, ')')
2776 || ! poolAppendChar(&tempPool
, '\0'))
2777 return XML_ERROR_NO_MEMORY
;
2778 declAttributeType
= tempPool
.start
;
2779 poolFinish(&tempPool
);
2782 attlistDeclHandler(handlerArg
, declElementType
->name
,
2783 declAttributeId
->name
, declAttributeType
,
2785 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
2786 poolClear(&tempPool
);
2790 case XML_ROLE_ENTITY_VALUE
:
2792 enum XML_Error result
= storeEntityValue(parser
, enc
,
2793 s
+ enc
->minBytesPerChar
,
2794 next
- enc
->minBytesPerChar
);
2796 declEntity
->textPtr
= poolStart(&dtd
.pool
);
2797 declEntity
->textLen
= poolLength(&dtd
.pool
);
2798 poolFinish(&dtd
.pool
);
2799 if (entityDeclHandler
) {
2801 entityDeclHandler(handlerArg
,
2803 declEntity
->is_param
,
2804 declEntity
->textPtr
,
2805 declEntity
->textLen
,
2810 poolDiscard(&dtd
.pool
);
2811 if (result
!= XML_ERROR_NONE
)
2815 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
2816 if (startDoctypeDeclHandler
) {
2817 doctypeSysid
= poolStoreString(&tempPool
, enc
, s
+ 1, next
- 1);
2819 return XML_ERROR_NO_MEMORY
;
2820 poolFinish(&tempPool
);
2824 && !paramEntityParsing
2825 #endif /* XML_DTD */
2826 && notStandaloneHandler
2827 && !notStandaloneHandler(handlerArg
))
2828 return XML_ERROR_NOT_STANDALONE
;
2829 hadExternalDoctype
= 1;
2834 declEntity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
2837 declEntity
->publicId
= 0;
2839 return XML_ERROR_NO_MEMORY
;
2842 #endif /* XML_DTD */
2843 case XML_ROLE_ENTITY_SYSTEM_ID
:
2845 declEntity
->systemId
= poolStoreString(&dtd
.pool
, enc
,
2846 s
+ enc
->minBytesPerChar
,
2847 next
- enc
->minBytesPerChar
);
2848 if (!declEntity
->systemId
)
2849 return XML_ERROR_NO_MEMORY
;
2850 declEntity
->base
= curBase
;
2851 poolFinish(&dtd
.pool
);
2854 case XML_ROLE_ENTITY_COMPLETE
:
2855 if (declEntity
&& entityDeclHandler
) {
2857 entityDeclHandler(handlerArg
,
2861 declEntity
->systemId
,
2862 declEntity
->publicId
,
2866 case XML_ROLE_ENTITY_NOTATION_NAME
:
2868 declEntity
->notation
= poolStoreString(&dtd
.pool
, enc
, s
, next
);
2869 if (!declEntity
->notation
)
2870 return XML_ERROR_NO_MEMORY
;
2871 poolFinish(&dtd
.pool
);
2872 if (unparsedEntityDeclHandler
) {
2874 unparsedEntityDeclHandler(handlerArg
,
2877 declEntity
->systemId
,
2878 declEntity
->publicId
,
2879 declEntity
->notation
);
2881 else if (entityDeclHandler
) {
2883 entityDeclHandler(handlerArg
,
2887 declEntity
->systemId
,
2888 declEntity
->publicId
,
2889 declEntity
->notation
);
2893 case XML_ROLE_GENERAL_ENTITY_NAME
:
2895 const XML_Char
*name
;
2896 if (XmlPredefinedEntityName(enc
, s
, next
)) {
2900 name
= poolStoreString(&dtd
.pool
, enc
, s
, next
);
2902 return XML_ERROR_NO_MEMORY
;
2904 declEntity
= (ENTITY
*)lookup(&dtd
.generalEntities
, name
, sizeof(ENTITY
));
2906 return XML_ERROR_NO_MEMORY
;
2907 if (declEntity
->name
!= name
) {
2908 poolDiscard(&dtd
.pool
);
2912 poolFinish(&dtd
.pool
);
2913 declEntity
->publicId
= 0;
2914 declEntity
->is_param
= 0;
2918 poolDiscard(&dtd
.pool
);
2923 case XML_ROLE_PARAM_ENTITY_NAME
:
2926 const XML_Char
*name
= poolStoreString(&dtd
.pool
, enc
, s
, next
);
2928 return XML_ERROR_NO_MEMORY
;
2929 declEntity
= (ENTITY
*)lookup(&dtd
.paramEntities
,
2930 name
, sizeof(ENTITY
));
2932 return XML_ERROR_NO_MEMORY
;
2933 if (declEntity
->name
!= name
) {
2934 poolDiscard(&dtd
.pool
);
2938 poolFinish(&dtd
.pool
);
2939 declEntity
->publicId
= 0;
2940 declEntity
->is_param
= 1;
2943 #else /* not XML_DTD */
2945 #endif /* not XML_DTD */
2947 case XML_ROLE_NOTATION_NAME
:
2948 declNotationPublicId
= 0;
2949 declNotationName
= 0;
2950 if (notationDeclHandler
) {
2951 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
2952 if (!declNotationName
)
2953 return XML_ERROR_NO_MEMORY
;
2954 poolFinish(&tempPool
);
2957 case XML_ROLE_NOTATION_PUBLIC_ID
:
2958 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
2959 return XML_ERROR_SYNTAX
;
2960 if (declNotationName
) {
2961 XML_Char
*tem
= poolStoreString(&tempPool
,
2963 s
+ enc
->minBytesPerChar
,
2964 next
- enc
->minBytesPerChar
);
2966 return XML_ERROR_NO_MEMORY
;
2967 normalizePublicId(tem
);
2968 declNotationPublicId
= tem
;
2969 poolFinish(&tempPool
);
2972 case XML_ROLE_NOTATION_SYSTEM_ID
:
2973 if (declNotationName
&& notationDeclHandler
) {
2974 const XML_Char
*systemId
2975 = poolStoreString(&tempPool
, enc
,
2976 s
+ enc
->minBytesPerChar
,
2977 next
- enc
->minBytesPerChar
);
2979 return XML_ERROR_NO_MEMORY
;
2981 notationDeclHandler(handlerArg
,
2985 declNotationPublicId
);
2987 poolClear(&tempPool
);
2989 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
2990 if (declNotationPublicId
&& notationDeclHandler
) {
2992 notationDeclHandler(handlerArg
,
2996 declNotationPublicId
);
2998 poolClear(&tempPool
);
3000 case XML_ROLE_ERROR
:
3002 case XML_TOK_PARAM_ENTITY_REF
:
3003 return XML_ERROR_PARAM_ENTITY_REF
;
3004 case XML_TOK_XML_DECL
:
3005 return XML_ERROR_MISPLACED_XML_PI
;
3007 return XML_ERROR_SYNTAX
;
3010 case XML_ROLE_IGNORE_SECT
:
3012 enum XML_Error result
;
3014 reportDefault(parser
, enc
, s
, next
);
3015 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
);
3017 processor
= ignoreSectionProcessor
;
3022 #endif /* XML_DTD */
3023 case XML_ROLE_GROUP_OPEN
:
3024 if (prologState
.level
>= groupSize
) {
3026 groupConnector
= REALLOC(groupConnector
, groupSize
*= 2);
3028 dtd
.scaffIndex
= REALLOC(dtd
.scaffIndex
, groupSize
* sizeof(int));
3031 groupConnector
= MALLOC(groupSize
= 32);
3032 if (!groupConnector
)
3033 return XML_ERROR_NO_MEMORY
;
3035 groupConnector
[prologState
.level
] = 0;
3036 if (dtd
.in_eldecl
) {
3037 int myindex
= nextScaffoldPart(parser
);
3039 return XML_ERROR_NO_MEMORY
;
3040 dtd
.scaffIndex
[dtd
.scaffLevel
] = myindex
;
3042 dtd
.scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
3045 case XML_ROLE_GROUP_SEQUENCE
:
3046 if (groupConnector
[prologState
.level
] == '|')
3047 return XML_ERROR_SYNTAX
;
3048 groupConnector
[prologState
.level
] = ',';
3050 case XML_ROLE_GROUP_CHOICE
:
3051 if (groupConnector
[prologState
.level
] == ',')
3052 return XML_ERROR_SYNTAX
;
3054 && ! groupConnector
[prologState
.level
]
3055 && dtd
.scaffold
[dtd
.scaffIndex
[dtd
.scaffLevel
- 1]].type
!= XML_CTYPE_MIXED
3057 dtd
.scaffold
[dtd
.scaffIndex
[dtd
.scaffLevel
- 1]].type
= XML_CTYPE_CHOICE
;
3059 groupConnector
[prologState
.level
] = '|';
3061 case XML_ROLE_PARAM_ENTITY_REF
:
3063 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
3064 if (paramEntityParsing
3065 && (dtd
.complete
|| role
== XML_ROLE_INNER_PARAM_ENTITY_REF
)) {
3066 const XML_Char
*name
;
3068 name
= poolStoreString(&dtd
.pool
, enc
,
3069 s
+ enc
->minBytesPerChar
,
3070 next
- enc
->minBytesPerChar
);
3072 return XML_ERROR_NO_MEMORY
;
3073 entity
= (ENTITY
*)lookup(&dtd
.paramEntities
, name
, 0);
3074 poolDiscard(&dtd
.pool
);
3076 /* FIXME what to do if !dtd.complete? */
3077 return XML_ERROR_UNDEFINED_ENTITY
;
3080 return XML_ERROR_RECURSIVE_ENTITY_REF
;
3081 if (entity
->textPtr
) {
3082 enum XML_Error result
;
3083 result
= processInternalParamEntity(parser
, entity
);
3084 if (result
!= XML_ERROR_NONE
)
3088 if (role
== XML_ROLE_INNER_PARAM_ENTITY_REF
)
3089 return XML_ERROR_PARAM_ENTITY_REF
;
3090 if (externalEntityRefHandler
) {
3093 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3097 entity
->publicId
)) {
3099 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3106 #endif /* XML_DTD */
3108 && notStandaloneHandler
3109 && !notStandaloneHandler(handlerArg
))
3110 return XML_ERROR_NOT_STANDALONE
;
3113 reportDefault(parser
, enc
, s
, next
);
3116 /* Element declaration stuff */
3118 case XML_ROLE_ELEMENT_NAME
:
3119 if (elementDeclHandler
) {
3120 declElementType
= getElementType(parser
, enc
, s
, next
);
3121 if (! declElementType
)
3122 return XML_ERROR_NO_MEMORY
;
3129 case XML_ROLE_CONTENT_ANY
:
3130 case XML_ROLE_CONTENT_EMPTY
:
3131 if (dtd
.in_eldecl
) {
3132 if (elementDeclHandler
) {
3133 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
3135 return XML_ERROR_NO_MEMORY
;
3136 content
->quant
= XML_CQUANT_NONE
;
3138 content
->numchildren
= 0;
3139 content
->children
= 0;
3140 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
3144 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
3150 case XML_ROLE_CONTENT_PCDATA
:
3151 if (dtd
.in_eldecl
) {
3152 dtd
.scaffold
[dtd
.scaffIndex
[dtd
.scaffLevel
- 1]].type
= XML_CTYPE_MIXED
;
3156 case XML_ROLE_CONTENT_ELEMENT
:
3157 quant
= XML_CQUANT_NONE
;
3158 goto elementContent
;
3159 case XML_ROLE_CONTENT_ELEMENT_OPT
:
3160 quant
= XML_CQUANT_OPT
;
3161 goto elementContent
;
3162 case XML_ROLE_CONTENT_ELEMENT_REP
:
3163 quant
= XML_CQUANT_REP
;
3164 goto elementContent
;
3165 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
3166 quant
= XML_CQUANT_PLUS
;
3171 const char *nxt
= quant
== XML_CQUANT_NONE
? next
: next
- 1;
3172 int myindex
= nextScaffoldPart(parser
);
3174 return XML_ERROR_NO_MEMORY
;
3175 dtd
.scaffold
[myindex
].type
= XML_CTYPE_NAME
;
3176 dtd
.scaffold
[myindex
].quant
= quant
;
3177 el
= getElementType(parser
, enc
, s
, nxt
);
3179 return XML_ERROR_NO_MEMORY
;
3180 dtd
.scaffold
[myindex
].name
= el
->name
;
3181 dtd
.contentStringLen
+= nxt
- s
+ 1;
3185 case XML_ROLE_GROUP_CLOSE
:
3186 quant
= XML_CQUANT_NONE
;
3188 case XML_ROLE_GROUP_CLOSE_OPT
:
3189 quant
= XML_CQUANT_OPT
;
3191 case XML_ROLE_GROUP_CLOSE_REP
:
3192 quant
= XML_CQUANT_REP
;
3194 case XML_ROLE_GROUP_CLOSE_PLUS
:
3195 quant
= XML_CQUANT_PLUS
;
3197 if (dtd
.in_eldecl
) {
3199 dtd
.scaffold
[dtd
.scaffIndex
[dtd
.scaffLevel
]].quant
= quant
;
3200 if (dtd
.scaffLevel
== 0) {
3201 if (elementDeclHandler
) {
3202 XML_Content
*model
= build_model(parser
);
3204 return XML_ERROR_NO_MEMORY
;
3206 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
3209 dtd
.contentStringLen
= 0;
3213 /* End element declaration stuff */
3218 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
3219 return XML_ERROR_NO_MEMORY
;
3221 case XML_TOK_COMMENT
:
3222 if (!reportComment(parser
, enc
, s
, next
))
3223 return XML_ERROR_NO_MEMORY
;
3228 if (defaultHandler
) {
3231 case XML_TOK_COMMENT
:
3233 case XML_TOK_XML_DECL
:
3235 case XML_TOK_IGNORE_SECT
:
3236 #endif /* XML_DTD */
3237 case XML_TOK_PARAM_ENTITY_REF
:
3241 if (role
!= XML_ROLE_IGNORE_SECT
)
3242 #endif /* XML_DTD */
3243 reportDefault(parser
, enc
, s
, next
);
3247 tok
= XmlPrologTok(enc
, s
, end
, &next
);
3253 enum XML_Error
epilogProcessor(XML_Parser parser
,
3256 const char **nextPtr
)
3258 processor
= epilogProcessor
;
3262 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3265 case -XML_TOK_PROLOG_S
:
3266 if (defaultHandler
) {
3268 reportDefault(parser
, encoding
, s
, end
);
3274 return XML_ERROR_NONE
;
3275 case XML_TOK_PROLOG_S
:
3277 reportDefault(parser
, encoding
, s
, next
);
3280 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
3281 return XML_ERROR_NO_MEMORY
;
3283 case XML_TOK_COMMENT
:
3284 if (!reportComment(parser
, encoding
, s
, next
))
3285 return XML_ERROR_NO_MEMORY
;
3287 case XML_TOK_INVALID
:
3289 return XML_ERROR_INVALID_TOKEN
;
3290 case XML_TOK_PARTIAL
:
3293 return XML_ERROR_NONE
;
3295 return XML_ERROR_UNCLOSED_TOKEN
;
3296 case XML_TOK_PARTIAL_CHAR
:
3299 return XML_ERROR_NONE
;
3301 return XML_ERROR_PARTIAL_CHAR
;
3303 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
3305 eventPtr
= s
= next
;
3311 static enum XML_Error
3312 processInternalParamEntity(XML_Parser parser
, ENTITY
*entity
)
3314 const char *s
, *end
, *next
;
3316 enum XML_Error result
;
3317 OPEN_INTERNAL_ENTITY openEntity
;
3319 openEntity
.next
= openInternalEntities
;
3320 openInternalEntities
= &openEntity
;
3321 openEntity
.entity
= entity
;
3322 openEntity
.internalEventPtr
= 0;
3323 openEntity
.internalEventEndPtr
= 0;
3324 s
= (char *)entity
->textPtr
;
3325 end
= (char *)(entity
->textPtr
+ entity
->textLen
);
3326 tok
= XmlPrologTok(internalEncoding
, s
, end
, &next
);
3327 result
= doProlog(parser
, internalEncoding
, s
, end
, tok
, next
, 0);
3329 openInternalEntities
= openEntity
.next
;
3333 #endif /* XML_DTD */
3336 enum XML_Error
errorProcessor(XML_Parser parser
,
3339 const char **nextPtr
)
3343 cmExpatUnused(nextPtr
);
3347 static enum XML_Error
3348 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, int isCdata
,
3349 const char *ptr
, const char *end
,
3352 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
, end
, pool
);
3355 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
3357 if (!poolAppendChar(pool
, XML_T('\0')))
3358 return XML_ERROR_NO_MEMORY
;
3359 return XML_ERROR_NONE
;
3362 static enum XML_Error
3363 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, int isCdata
,
3364 const char *ptr
, const char *end
,
3369 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
3372 return XML_ERROR_NONE
;
3373 case XML_TOK_INVALID
:
3374 if (enc
== encoding
)
3376 return XML_ERROR_INVALID_TOKEN
;
3377 case XML_TOK_PARTIAL
:
3378 if (enc
== encoding
)
3380 return XML_ERROR_INVALID_TOKEN
;
3381 case XML_TOK_CHAR_REF
:
3383 XML_Char buf
[XML_ENCODE_MAX
];
3385 int n
= XmlCharRefNumber(enc
, ptr
);
3387 if (enc
== encoding
)
3389 return XML_ERROR_BAD_CHAR_REF
;
3392 && n
== 0x20 /* space */
3393 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
3395 n
= XmlEncode(n
, (ICHAR
*)buf
);
3397 if (enc
== encoding
)
3399 return XML_ERROR_BAD_CHAR_REF
;
3401 for (i
= 0; i
< n
; i
++) {
3402 if (!poolAppendChar(pool
, buf
[i
]))
3403 return XML_ERROR_NO_MEMORY
;
3407 case XML_TOK_DATA_CHARS
:
3408 if (!poolAppend(pool
, enc
, ptr
, next
))
3409 return XML_ERROR_NO_MEMORY
;
3411 case XML_TOK_TRAILING_CR
:
3412 next
= ptr
+ enc
->minBytesPerChar
;
3414 case XML_TOK_ATTRIBUTE_VALUE_S
:
3415 case XML_TOK_DATA_NEWLINE
:
3416 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
3418 if (!poolAppendChar(pool
, 0x20))
3419 return XML_ERROR_NO_MEMORY
;
3421 case XML_TOK_ENTITY_REF
:
3423 const XML_Char
*name
;
3425 XML_Char ch
= XmlPredefinedEntityName(enc
,
3426 ptr
+ enc
->minBytesPerChar
,
3427 next
- enc
->minBytesPerChar
);
3429 if (!poolAppendChar(pool
, ch
))
3430 return XML_ERROR_NO_MEMORY
;
3433 name
= poolStoreString(&temp2Pool
, enc
,
3434 ptr
+ enc
->minBytesPerChar
,
3435 next
- enc
->minBytesPerChar
);
3437 return XML_ERROR_NO_MEMORY
;
3438 entity
= (ENTITY
*)lookup(&dtd
.generalEntities
, name
, 0);
3439 poolDiscard(&temp2Pool
);
3442 if (enc
== encoding
)
3444 return XML_ERROR_UNDEFINED_ENTITY
;
3447 else if (entity
->open
) {
3448 if (enc
== encoding
)
3450 return XML_ERROR_RECURSIVE_ENTITY_REF
;
3452 else if (entity
->notation
) {
3453 if (enc
== encoding
)
3455 return XML_ERROR_BINARY_ENTITY_REF
;
3457 else if (!entity
->textPtr
) {
3458 if (enc
== encoding
)
3460 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
3463 enum XML_Error result
;
3464 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
3466 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
, (char *)entity
->textPtr
, (char *)textEnd
, pool
);
3474 if (enc
== encoding
)
3476 return XML_ERROR_UNEXPECTED_STATE
;
3484 enum XML_Error
storeEntityValue(XML_Parser parser
,
3485 const ENCODING
*enc
,
3486 const char *entityTextPtr
,
3487 const char *entityTextEnd
)
3489 STRING_POOL
*pool
= &(dtd
.pool
);
3492 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
3494 case XML_TOK_PARAM_ENTITY_REF
:
3496 if (parentParser
|| enc
!= encoding
) {
3497 enum XML_Error result
;
3498 const XML_Char
*name
;
3500 name
= poolStoreString(&tempPool
, enc
,
3501 entityTextPtr
+ enc
->minBytesPerChar
,
3502 next
- enc
->minBytesPerChar
);
3504 return XML_ERROR_NO_MEMORY
;
3505 entity
= (ENTITY
*)lookup(&dtd
.paramEntities
, name
, 0);
3506 poolDiscard(&tempPool
);
3508 if (enc
== encoding
)
3509 eventPtr
= entityTextPtr
;
3510 return XML_ERROR_UNDEFINED_ENTITY
;
3513 if (enc
== encoding
)
3514 eventPtr
= entityTextPtr
;
3515 return XML_ERROR_RECURSIVE_ENTITY_REF
;
3517 if (entity
->systemId
) {
3518 if (enc
== encoding
)
3519 eventPtr
= entityTextPtr
;
3520 return XML_ERROR_PARAM_ENTITY_REF
;
3523 result
= storeEntityValue(parser
,
3525 (char *)entity
->textPtr
,
3526 (char *)(entity
->textPtr
+ entity
->textLen
));
3532 #endif /* XML_DTD */
3533 eventPtr
= entityTextPtr
;
3534 return XML_ERROR_SYNTAX
;
3536 return XML_ERROR_NONE
;
3537 case XML_TOK_ENTITY_REF
:
3538 case XML_TOK_DATA_CHARS
:
3539 if (!poolAppend(pool
, enc
, entityTextPtr
, next
))
3540 return XML_ERROR_NO_MEMORY
;
3542 case XML_TOK_TRAILING_CR
:
3543 next
= entityTextPtr
+ enc
->minBytesPerChar
;
3545 case XML_TOK_DATA_NEWLINE
:
3546 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
))
3547 return XML_ERROR_NO_MEMORY
;
3548 *(pool
->ptr
)++ = 0xA;
3550 case XML_TOK_CHAR_REF
:
3552 XML_Char buf
[XML_ENCODE_MAX
];
3554 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
3556 if (enc
== encoding
)
3557 eventPtr
= entityTextPtr
;
3558 return XML_ERROR_BAD_CHAR_REF
;
3560 n
= XmlEncode(n
, (ICHAR
*)buf
);
3562 if (enc
== encoding
)
3563 eventPtr
= entityTextPtr
;
3564 return XML_ERROR_BAD_CHAR_REF
;
3566 for (i
= 0; i
< n
; i
++) {
3567 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
))
3568 return XML_ERROR_NO_MEMORY
;
3569 *(pool
->ptr
)++ = buf
[i
];
3573 case XML_TOK_PARTIAL
:
3574 if (enc
== encoding
)
3575 eventPtr
= entityTextPtr
;
3576 return XML_ERROR_INVALID_TOKEN
;
3577 case XML_TOK_INVALID
:
3578 if (enc
== encoding
)
3580 return XML_ERROR_INVALID_TOKEN
;
3582 if (enc
== encoding
)
3583 eventPtr
= entityTextPtr
;
3584 return XML_ERROR_UNEXPECTED_STATE
;
3586 entityTextPtr
= next
;
3592 normalizeLines(XML_Char
*s
)
3596 if (*s
== XML_T('\0'))
3615 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
)
3617 const XML_Char
*target
;
3620 if (!processingInstructionHandler
) {
3622 reportDefault(parser
, enc
, start
, end
);
3625 start
+= enc
->minBytesPerChar
* 2;
3626 tem
= start
+ XmlNameLength(enc
, start
);
3627 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
3630 poolFinish(&tempPool
);
3631 data
= poolStoreString(&tempPool
, enc
,
3633 end
- enc
->minBytesPerChar
*2);
3636 normalizeLines(data
);
3637 processingInstructionHandler(handlerArg
, target
, data
);
3638 poolClear(&tempPool
);
3643 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
)
3646 if (!commentHandler
) {
3648 reportDefault(parser
, enc
, start
, end
);
3651 data
= poolStoreString(&tempPool
,
3653 start
+ enc
->minBytesPerChar
* 4,
3654 end
- enc
->minBytesPerChar
* 3);
3657 normalizeLines(data
);
3658 commentHandler(handlerArg
, data
);
3659 poolClear(&tempPool
);
3664 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *s
, const char *end
)
3666 if (MUST_CONVERT(enc
, s
)) {
3667 const char **eventPP
;
3668 const char **eventEndPP
;
3669 if (enc
== encoding
) {
3670 eventPP
= &eventPtr
;
3671 eventEndPP
= &eventEndPtr
;
3674 eventPP
= &(openInternalEntities
->internalEventPtr
);
3675 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3678 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3679 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3681 defaultHandler(handlerArg
, dataBuf
, dataPtr
- (ICHAR
*)dataBuf
);
3686 defaultHandler(handlerArg
, (XML_Char
*)s
, (XML_Char
*)end
- (XML_Char
*)s
);
3691 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, int isCdata
,
3692 int isId
, const XML_Char
*value
, XML_Parser parser
)
3694 DEFAULT_ATTRIBUTE
*att
;
3695 if (value
|| isId
) {
3696 /* The handling of default attributes gets messed up if we have
3697 a default which duplicates a non-default. */
3699 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
3700 if (attId
== type
->defaultAtts
[i
].id
)
3702 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
3703 type
->idAtt
= attId
;
3705 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
3706 if (type
->allocDefaultAtts
== 0) {
3707 type
->allocDefaultAtts
= 8;
3708 type
->defaultAtts
= MALLOC(type
->allocDefaultAtts
*sizeof(DEFAULT_ATTRIBUTE
));
3711 type
->allocDefaultAtts
*= 2;
3712 type
->defaultAtts
= REALLOC(type
->defaultAtts
,
3713 type
->allocDefaultAtts
*sizeof(DEFAULT_ATTRIBUTE
));
3715 if (!type
->defaultAtts
)
3718 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
3721 att
->isCdata
= isCdata
;
3723 attId
->maybeTokenized
= 1;
3724 type
->nDefaultAtts
+= 1;
3728 static int setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
3730 const XML_Char
*name
;
3731 for (name
= elementType
->name
; *name
; name
++) {
3732 if (*name
== XML_T(':')) {
3735 for (s
= elementType
->name
; s
!= name
; s
++) {
3736 if (!poolAppendChar(&dtd
.pool
, *s
))
3739 if (!poolAppendChar(&dtd
.pool
, XML_T('\0')))
3741 prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, poolStart(&dtd
.pool
), sizeof(PREFIX
));
3744 if (prefix
->name
== poolStart(&dtd
.pool
))
3745 poolFinish(&dtd
.pool
);
3747 poolDiscard(&dtd
.pool
);
3748 elementType
->prefix
= prefix
;
3755 static ATTRIBUTE_ID
*
3756 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
, const char *end
)
3759 const XML_Char
*name
;
3760 if (!poolAppendChar(&dtd
.pool
, XML_T('\0')))
3762 name
= poolStoreString(&dtd
.pool
, enc
, start
, end
);
3766 id
= (ATTRIBUTE_ID
*)lookup(&dtd
.attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
3769 if (id
->name
!= name
)
3770 poolDiscard(&dtd
.pool
);
3772 poolFinish(&dtd
.pool
);
3775 else if (name
[0] == 'x'
3780 && (name
[5] == XML_T('\0') || name
[5] == XML_T(':'))) {
3781 if (name
[5] == '\0')
3782 id
->prefix
= &dtd
.defaultPrefix
;
3784 id
->prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, name
+ 6, sizeof(PREFIX
));
3789 for (i
= 0; name
[i
]; i
++) {
3790 if (name
[i
] == XML_T(':')) {
3792 for (j
= 0; j
< i
; j
++) {
3793 if (!poolAppendChar(&dtd
.pool
, name
[j
]))
3796 if (!poolAppendChar(&dtd
.pool
, XML_T('\0')))
3798 id
->prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, poolStart(&dtd
.pool
), sizeof(PREFIX
));
3799 if (id
->prefix
->name
== poolStart(&dtd
.pool
))
3800 poolFinish(&dtd
.pool
);
3802 poolDiscard(&dtd
.pool
);
3811 #define CONTEXT_SEP XML_T('\f')
3814 const XML_Char
*getContext(XML_Parser parser
)
3816 HASH_TABLE_ITER iter
;
3819 if (dtd
.defaultPrefix
.binding
) {
3822 if (!poolAppendChar(&tempPool
, XML_T('=')))
3824 len
= dtd
.defaultPrefix
.binding
->uriLen
;
3825 if (namespaceSeparator
!= XML_T('\0'))
3827 for (i
= 0; i
< len
; i
++)
3828 if (!poolAppendChar(&tempPool
, dtd
.defaultPrefix
.binding
->uri
[i
]))
3833 hashTableIterInit(&iter
, &(dtd
.prefixes
));
3838 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
3841 if (!prefix
->binding
)
3843 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
3845 for (s
= prefix
->name
; *s
; s
++)
3846 if (!poolAppendChar(&tempPool
, *s
))
3848 if (!poolAppendChar(&tempPool
, XML_T('=')))
3850 len
= prefix
->binding
->uriLen
;
3851 if (namespaceSeparator
!= XML_T('\0'))
3853 for (i
= 0; i
< len
; i
++)
3854 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
3860 hashTableIterInit(&iter
, &(dtd
.generalEntities
));
3863 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
3868 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
3870 for (s
= e
->name
; *s
; s
++)
3871 if (!poolAppendChar(&tempPool
, *s
))
3876 if (!poolAppendChar(&tempPool
, XML_T('\0')))
3878 return tempPool
.start
;
3882 int setContext(XML_Parser parser
, const XML_Char
*context
)
3884 const XML_Char
*s
= context
;
3886 while (*context
!= XML_T('\0')) {
3887 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
3889 if (!poolAppendChar(&tempPool
, XML_T('\0')))
3891 e
= (ENTITY
*)lookup(&dtd
.generalEntities
, poolStart(&tempPool
), 0);
3894 if (*s
!= XML_T('\0'))
3897 poolDiscard(&tempPool
);
3899 else if (*s
== '=') {
3901 if (poolLength(&tempPool
) == 0)
3902 prefix
= &dtd
.defaultPrefix
;
3904 if (!poolAppendChar(&tempPool
, XML_T('\0')))
3906 prefix
= (PREFIX
*)lookup(&dtd
.prefixes
, poolStart(&tempPool
), sizeof(PREFIX
));
3909 if (prefix
->name
== poolStart(&tempPool
)) {
3910 prefix
->name
= poolCopyString(&dtd
.pool
, prefix
->name
);
3914 poolDiscard(&tempPool
);
3916 for (context
= s
+ 1; *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0'); context
++)
3917 if (!poolAppendChar(&tempPool
, *context
))
3919 if (!poolAppendChar(&tempPool
, XML_T('\0')))
3921 if (!addBinding(parser
, prefix
, 0, poolStart(&tempPool
), &inheritedBindings
))
3923 poolDiscard(&tempPool
);
3924 if (*context
!= XML_T('\0'))
3929 if (!poolAppendChar(&tempPool
, *s
))
3939 void normalizePublicId(XML_Char
*publicId
)
3941 XML_Char
*p
= publicId
;
3943 for (s
= publicId
; *s
; s
++) {
3948 if (p
!= publicId
&& p
[-1] != 0x20)
3955 if (p
!= publicId
&& p
[-1] == 0x20)
3960 static int dtdInit(DTD
*p
, XML_Parser parser
)
3962 XML_Memory_Handling_Suite
*ms
= &((Parser
*) parser
)->m_mem
;
3963 poolInit(&(p
->pool
), ms
);
3964 hashTableInit(&(p
->generalEntities
), ms
);
3965 hashTableInit(&(p
->elementTypes
), ms
);
3966 hashTableInit(&(p
->attributeIds
), ms
);
3967 hashTableInit(&(p
->prefixes
), ms
);
3971 hashTableInit(&(p
->paramEntities
), ms
);
3972 #endif /* XML_DTD */
3973 p
->defaultPrefix
.name
= 0;
3974 p
->defaultPrefix
.binding
= 0;
3980 p
->contentStringLen
= 0;
3989 static void dtdSwap(DTD
*p1
, DTD
*p2
)
3992 memcpy(&tem
, p1
, sizeof(DTD
));
3993 memcpy(p1
, p2
, sizeof(DTD
));
3994 memcpy(p2
, &tem
, sizeof(DTD
));
3997 #endif /* XML_DTD */
3999 static void dtdDestroy(DTD
*p
, XML_Parser parser
)
4001 HASH_TABLE_ITER iter
;
4002 hashTableIterInit(&iter
, &(p
->elementTypes
));
4004 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
4007 if (e
->allocDefaultAtts
!= 0)
4008 FREE(e
->defaultAtts
);
4010 hashTableDestroy(&(p
->generalEntities
));
4012 hashTableDestroy(&(p
->paramEntities
));
4013 #endif /* XML_DTD */
4014 hashTableDestroy(&(p
->elementTypes
));
4015 hashTableDestroy(&(p
->attributeIds
));
4016 hashTableDestroy(&(p
->prefixes
));
4017 poolDestroy(&(p
->pool
));
4019 FREE(p
->scaffIndex
);
4024 /* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.
4025 The new DTD has already been initialized. */
4027 static int dtdCopy(DTD
*newDtd
, const DTD
*oldDtd
, XML_Parser parser
)
4029 HASH_TABLE_ITER iter
;
4031 /* Copy the prefix table. */
4033 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
4035 const XML_Char
*name
;
4036 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
4039 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
4042 if (!lookup(&(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
4046 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
4048 /* Copy the attribute id table. */
4052 const XML_Char
*name
;
4053 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
4057 /* Remember to allocate the scratch byte before the name. */
4058 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
4060 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
4064 newA
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), name
, sizeof(ATTRIBUTE_ID
));
4067 newA
->maybeTokenized
= oldA
->maybeTokenized
;
4069 newA
->xmlns
= oldA
->xmlns
;
4070 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
4071 newA
->prefix
= &newDtd
->defaultPrefix
;
4073 newA
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
), oldA
->prefix
->name
, 0);
4077 /* Copy the element type table. */
4079 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
4084 const XML_Char
*name
;
4085 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
4088 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
4091 newE
= (ELEMENT_TYPE
*)lookup(&(newDtd
->elementTypes
), name
, sizeof(ELEMENT_TYPE
));
4094 if (oldE
->nDefaultAtts
) {
4095 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
4096 if (!newE
->defaultAtts
)
4100 newE
->idAtt
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
4101 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
4103 newE
->prefix
= (PREFIX
*)lookup(&(newDtd
->prefixes
), oldE
->prefix
->name
, 0);
4104 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
4105 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)lookup(&(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
4106 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
4107 if (oldE
->defaultAtts
[i
].value
) {
4108 newE
->defaultAtts
[i
].value
= poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
4109 if (!newE
->defaultAtts
[i
].value
)
4113 newE
->defaultAtts
[i
].value
= 0;
4117 /* Copy the entity tables. */
4118 if (!copyEntityTable(&(newDtd
->generalEntities
),
4120 &(oldDtd
->generalEntities
), parser
))
4124 if (!copyEntityTable(&(newDtd
->paramEntities
),
4126 &(oldDtd
->paramEntities
), parser
))
4128 #endif /* XML_DTD */
4130 newDtd
->complete
= oldDtd
->complete
;
4131 newDtd
->standalone
= oldDtd
->standalone
;
4133 /* Don't want deep copying for scaffolding */
4134 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
4135 newDtd
->scaffold
= oldDtd
->scaffold
;
4136 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
4137 newDtd
->scaffSize
= oldDtd
->scaffSize
;
4138 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
4139 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
4144 static int copyEntityTable(HASH_TABLE
*newTable
,
4145 STRING_POOL
*newPool
,
4146 const HASH_TABLE
*oldTable
,
4149 HASH_TABLE_ITER iter
;
4150 const XML_Char
*cachedOldBase
= 0;
4151 const XML_Char
*cachedNewBase
= 0;
4152 cmExpatUnused(parser
);
4154 hashTableIterInit(&iter
, oldTable
);
4158 const XML_Char
*name
;
4159 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
4162 name
= poolCopyString(newPool
, oldE
->name
);
4165 newE
= (ENTITY
*)lookup(newTable
, name
, sizeof(ENTITY
));
4168 if (oldE
->systemId
) {
4169 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
4172 newE
->systemId
= tem
;
4174 if (oldE
->base
== cachedOldBase
)
4175 newE
->base
= cachedNewBase
;
4177 cachedOldBase
= oldE
->base
;
4178 tem
= poolCopyString(newPool
, cachedOldBase
);
4181 cachedNewBase
= newE
->base
= tem
;
4186 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
, oldE
->textLen
);
4189 newE
->textPtr
= tem
;
4190 newE
->textLen
= oldE
->textLen
;
4192 if (oldE
->notation
) {
4193 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
4196 newE
->notation
= tem
;
4202 #define INIT_SIZE 64
4205 int keyeq(KEY s1
, KEY s2
)
4207 for (; *s1
== *s2
; s1
++, s2
++)
4214 unsigned long hash(KEY s
)
4216 unsigned long h
= 0;
4218 h
= (h
<< 5) + h
+ (unsigned char)*s
++;
4223 NAMED
*lookup(HASH_TABLE
*table
, KEY name
, size_t createSize
)
4226 if (table
->size
== 0) {
4231 tsize
= INIT_SIZE
* sizeof(NAMED
*);
4232 table
->v
= table
->mem
->malloc_fcn(tsize
);
4235 memset(table
->v
, 0, tsize
);
4236 table
->size
= INIT_SIZE
;
4237 table
->usedLim
= INIT_SIZE
/ 2;
4238 i
= hash(name
) & (table
->size
- 1);
4241 unsigned long h
= hash(name
);
4242 for (i
= h
& (table
->size
- 1);
4244 i
== 0 ? i
= table
->size
- 1 : --i
) {
4245 if (keyeq(name
, table
->v
[i
]->name
))
4250 if (table
->used
== table
->usedLim
) {
4251 /* check for overflow */
4252 size_t newSize
= table
->size
* 2;
4253 size_t tsize
= newSize
* sizeof(NAMED
*);
4254 NAMED
**newV
= table
->mem
->malloc_fcn(tsize
);
4257 memset(newV
, 0, tsize
);
4258 for (i
= 0; i
< table
->size
; i
++)
4261 for (j
= hash(table
->v
[i
]->name
) & (newSize
- 1);
4263 j
== 0 ? j
= newSize
- 1 : --j
)
4265 newV
[j
] = table
->v
[i
];
4267 table
->mem
->free_fcn(table
->v
);
4269 table
->size
= newSize
;
4270 table
->usedLim
= newSize
/2;
4271 for (i
= h
& (table
->size
- 1);
4273 i
== 0 ? i
= table
->size
- 1 : --i
)
4277 table
->v
[i
] = table
->mem
->malloc_fcn(createSize
);
4280 memset(table
->v
[i
], 0, createSize
);
4281 table
->v
[i
]->name
= name
;
4287 void hashTableDestroy(HASH_TABLE
*table
)
4290 for (i
= 0; i
< table
->size
; i
++) {
4291 NAMED
*p
= table
->v
[i
];
4293 table
->mem
->free_fcn(p
);
4296 table
->mem
->free_fcn(table
->v
);
4300 void hashTableInit(HASH_TABLE
*p
, XML_Memory_Handling_Suite
*ms
)
4310 void hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
4313 iter
->end
= iter
->p
+ table
->size
;
4317 NAMED
*hashTableIterNext(HASH_TABLE_ITER
*iter
)
4319 while (iter
->p
!= iter
->end
) {
4320 NAMED
*tem
= *(iter
->p
)++;
4329 void poolInit(STRING_POOL
*pool
, XML_Memory_Handling_Suite
*ms
)
4332 pool
->freeBlocks
= 0;
4340 void poolClear(STRING_POOL
*pool
)
4342 if (!pool
->freeBlocks
)
4343 pool
->freeBlocks
= pool
->blocks
;
4345 BLOCK
*p
= pool
->blocks
;
4347 BLOCK
*tem
= p
->next
;
4348 p
->next
= pool
->freeBlocks
;
4349 pool
->freeBlocks
= p
;
4360 void poolDestroy(STRING_POOL
*pool
)
4362 BLOCK
*p
= pool
->blocks
;
4364 BLOCK
*tem
= p
->next
;
4365 pool
->mem
->free_fcn(p
);
4369 p
= pool
->freeBlocks
;
4371 BLOCK
*tem
= p
->next
;
4372 pool
->mem
->free_fcn(p
);
4375 pool
->freeBlocks
= 0;
4382 XML_Char
*poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
4383 const char *ptr
, const char *end
)
4385 if (!pool
->ptr
&& !poolGrow(pool
))
4388 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
4391 if (!poolGrow(pool
))
4397 static const XML_Char
*poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
4400 if (!poolAppendChar(pool
, *s
))
4408 static const XML_Char
*poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
4410 if (!pool
->ptr
&& !poolGrow(pool
))
4412 for (; n
> 0; --n
, s
++) {
4413 if (!poolAppendChar(pool
, *s
))
4423 const XML_Char
*poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
4426 if (!poolAppendChar(pool
, *s
))
4431 } /* End poolAppendString */
4434 XML_Char
*poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
4435 const char *ptr
, const char *end
)
4437 if (!poolAppend(pool
, enc
, ptr
, end
))
4439 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
4446 int poolGrow(STRING_POOL
*pool
)
4448 if (pool
->freeBlocks
) {
4449 if (pool
->start
== 0) {
4450 pool
->blocks
= pool
->freeBlocks
;
4451 pool
->freeBlocks
= pool
->freeBlocks
->next
;
4452 pool
->blocks
->next
= 0;
4453 pool
->start
= pool
->blocks
->s
;
4454 pool
->end
= pool
->start
+ pool
->blocks
->size
;
4455 pool
->ptr
= pool
->start
;
4458 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
4459 BLOCK
*tem
= pool
->freeBlocks
->next
;
4460 pool
->freeBlocks
->next
= pool
->blocks
;
4461 pool
->blocks
= pool
->freeBlocks
;
4462 pool
->freeBlocks
= tem
;
4463 memcpy(pool
->blocks
->s
, pool
->start
, (pool
->end
- pool
->start
) * sizeof(XML_Char
));
4464 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
4465 pool
->start
= pool
->blocks
->s
;
4466 pool
->end
= pool
->start
+ pool
->blocks
->size
;
4470 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
4471 int blockSize
= (pool
->end
- pool
->start
)*2;
4472 pool
->blocks
= pool
->mem
->realloc_fcn(pool
->blocks
, offsetof(BLOCK
, s
) + blockSize
* sizeof(XML_Char
));
4475 pool
->blocks
->size
= blockSize
;
4476 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
4477 pool
->start
= pool
->blocks
->s
;
4478 pool
->end
= pool
->start
+ blockSize
;
4482 int blockSize
= pool
->end
- pool
->start
;
4483 if (blockSize
< INIT_BLOCK_SIZE
)
4484 blockSize
= INIT_BLOCK_SIZE
;
4487 tem
= pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
) + blockSize
* sizeof(XML_Char
));
4490 tem
->size
= blockSize
;
4491 tem
->next
= pool
->blocks
;
4493 if (pool
->ptr
!= pool
->start
)
4494 memcpy(tem
->s
, pool
->start
, (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
4495 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
4496 pool
->start
= tem
->s
;
4497 pool
->end
= tem
->s
+ blockSize
;
4503 nextScaffoldPart(XML_Parser parser
)
4505 CONTENT_SCAFFOLD
* me
;
4508 if (! dtd
.scaffIndex
) {
4509 dtd
.scaffIndex
= MALLOC(groupSize
* sizeof(int));
4510 if (! dtd
.scaffIndex
)
4512 dtd
.scaffIndex
[0] = 0;
4515 if (dtd
.scaffCount
>= dtd
.scaffSize
) {
4518 dtd
.scaffold
= (CONTENT_SCAFFOLD
*) REALLOC(dtd
.scaffold
,
4519 dtd
.scaffSize
* sizeof(CONTENT_SCAFFOLD
));
4523 dtd
.scaffold
= (CONTENT_SCAFFOLD
*) MALLOC(dtd
.scaffSize
* sizeof(CONTENT_SCAFFOLD
));
4528 next
= dtd
.scaffCount
++;
4529 me
= &dtd
.scaffold
[next
];
4530 if (dtd
.scaffLevel
) {
4531 CONTENT_SCAFFOLD
*parent
= &dtd
.scaffold
[dtd
.scaffIndex
[dtd
.scaffLevel
- 1]];
4532 if (parent
->lastchild
) {
4533 dtd
.scaffold
[parent
->lastchild
].nextsib
= next
;
4535 if (! parent
->childcnt
)
4536 parent
->firstchild
= next
;
4537 parent
->lastchild
= next
;
4540 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
4542 } /* End nextScaffoldPart */
4545 build_node (XML_Parser parser
,
4548 XML_Content
**contpos
,
4551 dest
->type
= dtd
.scaffold
[src_node
].type
;
4552 dest
->quant
= dtd
.scaffold
[src_node
].quant
;
4553 if (dest
->type
== XML_CTYPE_NAME
) {
4555 dest
->name
= *strpos
;
4556 src
= dtd
.scaffold
[src_node
].name
;
4558 *(*strpos
)++ = *src
;
4563 dest
->numchildren
= 0;
4569 dest
->numchildren
= dtd
.scaffold
[src_node
].childcnt
;
4570 dest
->children
= *contpos
;
4571 *contpos
+= dest
->numchildren
;
4572 for (i
= 0, cn
= dtd
.scaffold
[src_node
].firstchild
;
4573 i
< dest
->numchildren
;
4574 i
++, cn
= dtd
.scaffold
[cn
].nextsib
) {
4575 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
4579 } /* End build_node */
4581 static XML_Content
*
4582 build_model (XML_Parser parser
)
4587 int allocsize
= dtd
.scaffCount
* sizeof(XML_Content
) + dtd
.contentStringLen
;
4589 ret
= MALLOC(allocsize
);
4593 str
= (char *) (&ret
[dtd
.scaffCount
]);
4596 build_node(parser
, 0, ret
, &cpos
, &str
);
4598 } /* End build_model */
4600 static ELEMENT_TYPE
*
4601 getElementType(XML_Parser parser
,
4602 const ENCODING
*enc
,
4606 const XML_Char
*name
= poolStoreString(&dtd
.pool
, enc
, ptr
, end
);
4611 ret
= (ELEMENT_TYPE
*) lookup(&dtd
.elementTypes
, name
, sizeof(ELEMENT_TYPE
));
4614 if (ret
->name
!= name
)
4615 poolDiscard(&dtd
.pool
);
4617 poolFinish(&dtd
.pool
);
4618 if (!setElementTypePrefix(parser
, ret
))
4622 } /* End getElementType */