1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd 
   2    See the file COPYING for copying permission. 
   6 #include <string.h>                     /* memset(), memcpy() */ 
   8 #include <limits.h>                     /* UINT_MAX */ 
   9 #include <time.h>                       /* time() */ 
  11 #define XML_BUILDING_EXPAT 1 
  13 #ifdef COMPILED_FROM_DSP 
  14 #include "winconfig.h" 
  17 #include "os2config.h" 
  20 #elif defined(__MSDOS__) 
  22 #include "dosconfig.h" 
  25 #elif defined(MACOS_CLASSIC) 
  26 #include "macconfig.h" 
  27 #elif defined(__amigaos__) 
  28 #include "amigaconfig.h" 
  29 #elif defined(__WATCOMC__) 
  30 #include "watcomconfig.h" 
  31 #elif defined(HAVE_EXPAT_CONFIG_H) 
  32 #include "expat_config.h" 
  33 #endif /* ndef COMPILED_FROM_DSP */ 
  39 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX 
  40 #define XmlConvert XmlUtf16Convert 
  41 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding 
  42 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS 
  43 #define XmlEncode XmlUtf16Encode 
  44 /* Using pointer subtraction to convert to integer type. */ 
  45 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1)) 
  46 typedef unsigned short ICHAR
; 
  48 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX 
  49 #define XmlConvert XmlUtf8Convert 
  50 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding 
  51 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS 
  52 #define XmlEncode XmlUtf8Encode 
  53 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8) 
  60 #define XmlInitEncodingNS XmlInitEncoding 
  61 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding 
  62 #undef XmlGetInternalEncodingNS 
  63 #define XmlGetInternalEncodingNS XmlGetInternalEncoding 
  64 #define XmlParseXmlDeclNS XmlParseXmlDecl 
  70 #ifdef XML_UNICODE_WCHAR_T 
  71 #define XML_T(x) (const wchar_t)x 
  72 #define XML_L(x) L ## x 
  74 #define XML_T(x) (const unsigned short)x 
  85 /* Round up n to be a multiple of sz, where sz is a power of 2. */ 
  86 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) 
  88 /* Handle the case where memmove() doesn't exist. */ 
  91 #define memmove(d,s,l) bcopy((s),(d),(l)) 
  93 #error memmove does not exist on this platform, nor is a substitute available 
  94 #endif /* HAVE_BCOPY */ 
  95 #endif /* HAVE_MEMMOVE */ 
 101 typedef const XML_Char 
*KEY
; 
 112   const XML_Memory_Handling_Suite 
*mem
; 
 115 /* Basic character hash algorithm, taken from Python's string hash: 
 116    h = h * 1000003 ^ character, the constant being a prime number. 
 120 #define CHAR_HASH(h, c) \ 
 121   (((h) * 0xF4243) ^ (unsigned short)(c)) 
 123 #define CHAR_HASH(h, c) \ 
 124   (((h) * 0xF4243) ^ (unsigned char)(c)) 
 127 /* For probing (after a collision) we need a step size relative prime 
 128    to the hash table size, which is a power of 2. We use double-hashing, 
 129    since we can calculate a second hash value cheaply by taking those bits 
 130    of the first hash value that were discarded (masked out) when the table 
 131    index was calculated: index = hash & mask, where mask = table->size - 1. 
 132    We limit the maximum step size to table->size / 4 (mask >> 2) and make 
 133    it odd, since odd numbers are always relative prime to a power of 2. 
 135 #define SECOND_HASH(hash, mask, power) \ 
 136   ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2)) 
 137 #define PROBE_STEP(hash, mask, power) \ 
 138   ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) 
 145 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */ 
 146 #define INIT_DATA_BUF_SIZE 1024 
 147 #define INIT_ATTS_SIZE 16 
 148 #define INIT_ATTS_VERSION 0xFFFFFFFF 
 149 #define INIT_BLOCK_SIZE 1024 
 150 #define INIT_BUFFER_SIZE 1024 
 152 #define EXPAND_SPARE 24 
 154 typedef struct binding 
{ 
 155   struct prefix 
*prefix
; 
 156   struct binding 
*nextTagBinding
; 
 157   struct binding 
*prevPrefixBinding
; 
 158   const struct attribute_id 
*attId
; 
 164 typedef struct prefix 
{ 
 165   const XML_Char 
*name
; 
 171   const XML_Char 
*localPart
; 
 172   const XML_Char 
*prefix
; 
 178 /* TAG represents an open element. 
 179    The name of the element is stored in both the document and API 
 180    encodings.  The memory buffer 'buf' is a separately-allocated 
 181    memory area which stores the name.  During the XML_Parse()/ 
 182    XMLParseBuffer() when the element is open, the memory for the 'raw' 
 183    version of the name (in the document encoding) is shared with the 
 184    document buffer.  If the element is open across calls to 
 185    XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to 
 186    contain the 'raw' name as well. 
 188    A parser re-uses these structures, maintaining a list of allocated 
 189    TAG objects in a free list. 
 192   struct tag 
*parent
;           /* parent of this element */ 
 193   const char *rawName
;          /* tagName in the original encoding */ 
 195   TAG_NAME name
;                /* tagName in the API encoding */ 
 196   char *buf
;                    /* buffer for name components */ 
 197   char *bufEnd
;                 /* end of the buffer */ 
 202   const XML_Char 
*name
; 
 203   const XML_Char 
*textPtr
; 
 204   int textLen
;                  /* length in XML_Chars */ 
 205   int processed
;                /* # of processed bytes - when suspended */ 
 206   const XML_Char 
*systemId
; 
 207   const XML_Char 
*base
; 
 208   const XML_Char 
*publicId
; 
 209   const XML_Char 
*notation
; 
 212   XML_Bool is_internal
; /* true if declared in internal subset outside PE */ 
 216   enum XML_Content_Type         type
; 
 217   enum XML_Content_Quant        quant
; 
 218   const XML_Char 
*              name
; 
 225 #define INIT_SCAFFOLD_ELEMENTS 32 
 227 typedef struct block 
{ 
 239   const XML_Memory_Handling_Suite 
*mem
; 
 242 /* The XML_Char before the name is used to determine whether 
 243    an attribute has been specified. */ 
 244 typedef struct attribute_id 
{ 
 247   XML_Bool maybeTokenized
; 
 252   const ATTRIBUTE_ID 
*id
; 
 254   const XML_Char 
*value
; 
 258   unsigned long version
; 
 260   const XML_Char 
*uriName
; 
 264   const XML_Char 
*name
; 
 266   const ATTRIBUTE_ID 
*idAtt
; 
 268   int allocDefaultAtts
; 
 269   DEFAULT_ATTRIBUTE 
*defaultAtts
; 
 273   HASH_TABLE generalEntities
; 
 274   HASH_TABLE elementTypes
; 
 275   HASH_TABLE attributeIds
; 
 278   STRING_POOL entityValuePool
; 
 279   /* false once a parameter entity reference has been skipped */ 
 280   XML_Bool keepProcessing
; 
 281   /* true once an internal or external PE reference has been encountered; 
 282      this includes the reference to an external subset */ 
 283   XML_Bool hasParamEntityRefs
; 
 286   /* indicates if external PE has been read */ 
 287   XML_Bool paramEntityRead
; 
 288   HASH_TABLE paramEntities
; 
 290   PREFIX defaultPrefix
; 
 291   /* === scaffolding for building content model === */ 
 293   CONTENT_SCAFFOLD 
*scaffold
; 
 294   unsigned contentStringLen
; 
 301 typedef struct open_internal_entity 
{ 
 302   const char *internalEventPtr
; 
 303   const char *internalEventEndPtr
; 
 304   struct open_internal_entity 
*next
; 
 307   XML_Bool betweenDecl
; /* WFC: PE Between Declarations */ 
 308 } OPEN_INTERNAL_ENTITY
; 
 310 typedef enum XML_Error PTRCALL 
Processor(XML_Parser parser
, 
 313                                          const char **endPtr
); 
 315 static Processor prologProcessor
; 
 316 static Processor prologInitProcessor
; 
 317 static Processor contentProcessor
; 
 318 static Processor cdataSectionProcessor
; 
 320 static Processor ignoreSectionProcessor
; 
 321 static Processor externalParEntProcessor
; 
 322 static Processor externalParEntInitProcessor
; 
 323 static Processor entityValueProcessor
; 
 324 static Processor entityValueInitProcessor
; 
 326 static Processor epilogProcessor
; 
 327 static Processor errorProcessor
; 
 328 static Processor externalEntityInitProcessor
; 
 329 static Processor externalEntityInitProcessor2
; 
 330 static Processor externalEntityInitProcessor3
; 
 331 static Processor externalEntityContentProcessor
; 
 332 static Processor internalEntityProcessor
; 
 334 static enum XML_Error
 
 335 handleUnknownEncoding(XML_Parser parser
, const XML_Char 
*encodingName
); 
 336 static enum XML_Error
 
 337 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
, 
 338                const char *s
, const char *next
); 
 339 static enum XML_Error
 
 340 initializeEncoding(XML_Parser parser
); 
 341 static enum XML_Error
 
 342 doProlog(XML_Parser parser
, const ENCODING 
*enc
, const char *s
, 
 343          const char *end
, int tok
, const char *next
, const char **nextPtr
, 
 345 static enum XML_Error
 
 346 processInternalEntity(XML_Parser parser
, ENTITY 
*entity
, 
 347                       XML_Bool betweenDecl
); 
 348 static enum XML_Error
 
 349 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING 
*enc
, 
 350           const char *start
, const char *end
, const char **endPtr
, 
 352 static enum XML_Error
 
 353 doCdataSection(XML_Parser parser
, const ENCODING 
*, const char **startPtr
, 
 354                const char *end
, const char **nextPtr
, XML_Bool haveMore
); 
 356 static enum XML_Error
 
 357 doIgnoreSection(XML_Parser parser
, const ENCODING 
*, const char **startPtr
, 
 358                 const char *end
, const char **nextPtr
, XML_Bool haveMore
); 
 361 static enum XML_Error
 
 362 storeAtts(XML_Parser parser
, const ENCODING 
*, const char *s
, 
 363           TAG_NAME 
*tagNamePtr
, BINDING 
**bindingsPtr
); 
 364 static enum XML_Error
 
 365 addBinding(XML_Parser parser
, PREFIX 
*prefix
, const ATTRIBUTE_ID 
*attId
, 
 366            const XML_Char 
*uri
, BINDING 
**bindingsPtr
); 
 368 defineAttribute(ELEMENT_TYPE 
*type
, ATTRIBUTE_ID 
*, XML_Bool isCdata
, 
 369                 XML_Bool isId
, const XML_Char 
*dfltValue
, XML_Parser parser
); 
 370 static enum XML_Error
 
 371 storeAttributeValue(XML_Parser parser
, const ENCODING 
*, XML_Bool isCdata
, 
 372                     const char *, const char *, STRING_POOL 
*); 
 373 static enum XML_Error
 
 374 appendAttributeValue(XML_Parser parser
, const ENCODING 
*, XML_Bool isCdata
, 
 375                      const char *, const char *, STRING_POOL 
*); 
 376 static ATTRIBUTE_ID 
* 
 377 getAttributeId(XML_Parser parser
, const ENCODING 
*enc
, const char *start
, 
 380 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE 
*); 
 381 static enum XML_Error
 
 382 storeEntityValue(XML_Parser parser
, const ENCODING 
*enc
, const char *start
, 
 385 reportProcessingInstruction(XML_Parser parser
, const ENCODING 
*enc
, 
 386                             const char *start
, const char *end
); 
 388 reportComment(XML_Parser parser
, const ENCODING 
*enc
, const char *start
, 
 391 reportDefault(XML_Parser parser
, const ENCODING 
*enc
, const char *start
, 
 394 static const XML_Char 
* getContext(XML_Parser parser
); 
 396 setContext(XML_Parser parser
, const XML_Char 
*context
); 
 398 static void FASTCALL 
normalizePublicId(XML_Char 
*s
); 
 400 static DTD 
* dtdCreate(const XML_Memory_Handling_Suite 
*ms
); 
 401 /* do not call if parentParser != NULL */ 
 402 static void dtdReset(DTD 
*p
, const XML_Memory_Handling_Suite 
*ms
); 
 404 dtdDestroy(DTD 
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite 
*ms
); 
 406 dtdCopy(XML_Parser oldParser
, 
 407         DTD 
*newDtd
, const DTD 
*oldDtd
, const XML_Memory_Handling_Suite 
*ms
); 
 409 copyEntityTable(XML_Parser oldParser
, 
 410                 HASH_TABLE 
*, STRING_POOL 
*, const HASH_TABLE 
*); 
 412 lookup(XML_Parser parser
, HASH_TABLE 
*table
, KEY name
, size_t createSize
); 
 414 hashTableInit(HASH_TABLE 
*, const XML_Memory_Handling_Suite 
*ms
); 
 415 static void FASTCALL 
hashTableClear(HASH_TABLE 
*); 
 416 static void FASTCALL 
hashTableDestroy(HASH_TABLE 
*); 
 418 hashTableIterInit(HASH_TABLE_ITER 
*, const HASH_TABLE 
*); 
 419 static NAMED 
* FASTCALL 
hashTableIterNext(HASH_TABLE_ITER 
*); 
 422 poolInit(STRING_POOL 
*, const XML_Memory_Handling_Suite 
*ms
); 
 423 static void FASTCALL 
poolClear(STRING_POOL 
*); 
 424 static void FASTCALL 
poolDestroy(STRING_POOL 
*); 
 426 poolAppend(STRING_POOL 
*pool
, const ENCODING 
*enc
, 
 427            const char *ptr
, const char *end
); 
 429 poolStoreString(STRING_POOL 
*pool
, const ENCODING 
*enc
, 
 430                 const char *ptr
, const char *end
); 
 431 static XML_Bool FASTCALL 
poolGrow(STRING_POOL 
*pool
); 
 432 static const XML_Char 
* FASTCALL
 
 433 poolCopyString(STRING_POOL 
*pool
, const XML_Char 
*s
); 
 434 static const XML_Char 
* 
 435 poolCopyStringN(STRING_POOL 
*pool
, const XML_Char 
*s
, int n
); 
 436 static const XML_Char 
* FASTCALL
 
 437 poolAppendString(STRING_POOL 
*pool
, const XML_Char 
*s
); 
 439 static int FASTCALL 
nextScaffoldPart(XML_Parser parser
); 
 440 static XML_Content 
* build_model(XML_Parser parser
); 
 441 static ELEMENT_TYPE 
* 
 442 getElementType(XML_Parser parser
, const ENCODING 
*enc
, 
 443                const char *ptr
, const char *end
); 
 445 static unsigned long generate_hash_secret_salt(void); 
 446 static XML_Bool 
startParsing(XML_Parser parser
); 
 449 parserCreate(const XML_Char 
*encodingName
, 
 450              const XML_Memory_Handling_Suite 
*memsuite
, 
 451              const XML_Char 
*nameSep
, 
 455 parserInit(XML_Parser parser
, const XML_Char 
*encodingName
); 
 457 #define poolStart(pool) ((pool)->start) 
 458 #define poolEnd(pool) ((pool)->ptr) 
 459 #define poolLength(pool) ((pool)->ptr - (pool)->start) 
 460 #define poolChop(pool) ((void)--(pool->ptr)) 
 461 #define poolLastChar(pool) (((pool)->ptr)[-1]) 
 462 #define poolDiscard(pool) ((pool)->ptr = (pool)->start) 
 463 #define poolFinish(pool) ((pool)->start = (pool)->ptr) 
 464 #define poolAppendChar(pool, c) \ 
 465   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ 
 467    : ((*((pool)->ptr)++ = c), 1)) 
 469 struct XML_ParserStruct 
{ 
 470   /* The first member must be userData so that the XML_GetUserData 
 475   const XML_Memory_Handling_Suite m_mem
; 
 476   /* first character to be parsed */ 
 477   const char *m_bufferPtr
; 
 478   /* past last character to be parsed */ 
 480   /* allocated end of buffer */ 
 481   const char *m_bufferLim
; 
 482   XML_Index m_parseEndByteIndex
; 
 483   const char *m_parseEndPtr
; 
 485   XML_Char 
*m_dataBufEnd
; 
 486   XML_StartElementHandler m_startElementHandler
; 
 487   XML_EndElementHandler m_endElementHandler
; 
 488   XML_CharacterDataHandler m_characterDataHandler
; 
 489   XML_ProcessingInstructionHandler m_processingInstructionHandler
; 
 490   XML_CommentHandler m_commentHandler
; 
 491   XML_StartCdataSectionHandler m_startCdataSectionHandler
; 
 492   XML_EndCdataSectionHandler m_endCdataSectionHandler
; 
 493   XML_DefaultHandler m_defaultHandler
; 
 494   XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
; 
 495   XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
; 
 496   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
; 
 497   XML_NotationDeclHandler m_notationDeclHandler
; 
 498   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
; 
 499   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
; 
 500   XML_NotStandaloneHandler m_notStandaloneHandler
; 
 501   XML_ExternalEntityRefHandler m_externalEntityRefHandler
; 
 502   XML_Parser m_externalEntityRefHandlerArg
; 
 503   XML_SkippedEntityHandler m_skippedEntityHandler
; 
 504   XML_UnknownEncodingHandler m_unknownEncodingHandler
; 
 505   XML_ElementDeclHandler m_elementDeclHandler
; 
 506   XML_AttlistDeclHandler m_attlistDeclHandler
; 
 507   XML_EntityDeclHandler m_entityDeclHandler
; 
 508   XML_XmlDeclHandler m_xmlDeclHandler
; 
 509   const ENCODING 
*m_encoding
; 
 510   INIT_ENCODING m_initEncoding
; 
 511   const ENCODING 
*m_internalEncoding
; 
 512   const XML_Char 
*m_protocolEncodingName
; 
 514   XML_Bool m_ns_triplets
; 
 515   void *m_unknownEncodingMem
; 
 516   void *m_unknownEncodingData
; 
 517   void *m_unknownEncodingHandlerData
; 
 518   void (XMLCALL 
*m_unknownEncodingRelease
)(void *); 
 519   PROLOG_STATE m_prologState
; 
 520   Processor 
*m_processor
; 
 521   enum XML_Error m_errorCode
; 
 522   const char *m_eventPtr
; 
 523   const char *m_eventEndPtr
; 
 524   const char *m_positionPtr
; 
 525   OPEN_INTERNAL_ENTITY 
*m_openInternalEntities
; 
 526   OPEN_INTERNAL_ENTITY 
*m_freeInternalEntities
; 
 527   XML_Bool m_defaultExpandInternalEntities
; 
 529   ENTITY 
*m_declEntity
; 
 530   const XML_Char 
*m_doctypeName
; 
 531   const XML_Char 
*m_doctypeSysid
; 
 532   const XML_Char 
*m_doctypePubid
; 
 533   const XML_Char 
*m_declAttributeType
; 
 534   const XML_Char 
*m_declNotationName
; 
 535   const XML_Char 
*m_declNotationPublicId
; 
 536   ELEMENT_TYPE 
*m_declElementType
; 
 537   ATTRIBUTE_ID 
*m_declAttributeId
; 
 538   XML_Bool m_declAttributeIsCdata
; 
 539   XML_Bool m_declAttributeIsId
; 
 541   const XML_Char 
*m_curBase
; 
 544   BINDING 
*m_inheritedBindings
; 
 545   BINDING 
*m_freeBindingList
; 
 547   int m_nSpecifiedAtts
; 
 551   unsigned long m_nsAttsVersion
; 
 552   unsigned char m_nsAttsPower
; 
 554   XML_AttrInfo 
*m_attInfo
; 
 557   STRING_POOL m_tempPool
; 
 558   STRING_POOL m_temp2Pool
; 
 559   char *m_groupConnector
; 
 560   unsigned int m_groupSize
; 
 561   XML_Char m_namespaceSeparator
; 
 562   XML_Parser m_parentParser
; 
 563   XML_ParsingStatus m_parsingStatus
; 
 565   XML_Bool m_isParamEntity
; 
 566   XML_Bool m_useForeignDTD
; 
 567   enum XML_ParamEntityParsing m_paramEntityParsing
; 
 569   unsigned long m_hash_secret_salt
; 
 572 #define MALLOC(s) (parser->m_mem.malloc_fcn((s))) 
 573 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s))) 
 574 #define FREE(p) (parser->m_mem.free_fcn((p))) 
 576 #define userData (parser->m_userData) 
 577 #define handlerArg (parser->m_handlerArg) 
 578 #define startElementHandler (parser->m_startElementHandler) 
 579 #define endElementHandler (parser->m_endElementHandler) 
 580 #define characterDataHandler (parser->m_characterDataHandler) 
 581 #define processingInstructionHandler \ 
 582         (parser->m_processingInstructionHandler) 
 583 #define commentHandler (parser->m_commentHandler) 
 584 #define startCdataSectionHandler \ 
 585         (parser->m_startCdataSectionHandler) 
 586 #define endCdataSectionHandler (parser->m_endCdataSectionHandler) 
 587 #define defaultHandler (parser->m_defaultHandler) 
 588 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler) 
 589 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler) 
 590 #define unparsedEntityDeclHandler \ 
 591         (parser->m_unparsedEntityDeclHandler) 
 592 #define notationDeclHandler (parser->m_notationDeclHandler) 
 593 #define startNamespaceDeclHandler \ 
 594         (parser->m_startNamespaceDeclHandler) 
 595 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler) 
 596 #define notStandaloneHandler (parser->m_notStandaloneHandler) 
 597 #define externalEntityRefHandler \ 
 598         (parser->m_externalEntityRefHandler) 
 599 #define externalEntityRefHandlerArg \ 
 600         (parser->m_externalEntityRefHandlerArg) 
 601 #define internalEntityRefHandler \ 
 602         (parser->m_internalEntityRefHandler) 
 603 #define skippedEntityHandler (parser->m_skippedEntityHandler) 
 604 #define unknownEncodingHandler (parser->m_unknownEncodingHandler) 
 605 #define elementDeclHandler (parser->m_elementDeclHandler) 
 606 #define attlistDeclHandler (parser->m_attlistDeclHandler) 
 607 #define entityDeclHandler (parser->m_entityDeclHandler) 
 608 #define xmlDeclHandler (parser->m_xmlDeclHandler) 
 609 #define encoding (parser->m_encoding) 
 610 #define initEncoding (parser->m_initEncoding) 
 611 #define internalEncoding (parser->m_internalEncoding) 
 612 #define unknownEncodingMem (parser->m_unknownEncodingMem) 
 613 #define unknownEncodingData (parser->m_unknownEncodingData) 
 614 #define unknownEncodingHandlerData \ 
 615   (parser->m_unknownEncodingHandlerData) 
 616 #define unknownEncodingRelease (parser->m_unknownEncodingRelease) 
 617 #define protocolEncodingName (parser->m_protocolEncodingName) 
 618 #define ns (parser->m_ns) 
 619 #define ns_triplets (parser->m_ns_triplets) 
 620 #define prologState (parser->m_prologState) 
 621 #define processor (parser->m_processor) 
 622 #define errorCode (parser->m_errorCode) 
 623 #define eventPtr (parser->m_eventPtr) 
 624 #define eventEndPtr (parser->m_eventEndPtr) 
 625 #define positionPtr (parser->m_positionPtr) 
 626 #define position (parser->m_position) 
 627 #define openInternalEntities (parser->m_openInternalEntities) 
 628 #define freeInternalEntities (parser->m_freeInternalEntities) 
 629 #define defaultExpandInternalEntities \ 
 630         (parser->m_defaultExpandInternalEntities) 
 631 #define tagLevel (parser->m_tagLevel) 
 632 #define buffer (parser->m_buffer) 
 633 #define bufferPtr (parser->m_bufferPtr) 
 634 #define bufferEnd (parser->m_bufferEnd) 
 635 #define parseEndByteIndex (parser->m_parseEndByteIndex) 
 636 #define parseEndPtr (parser->m_parseEndPtr) 
 637 #define bufferLim (parser->m_bufferLim) 
 638 #define dataBuf (parser->m_dataBuf) 
 639 #define dataBufEnd (parser->m_dataBufEnd) 
 640 #define _dtd (parser->m_dtd) 
 641 #define curBase (parser->m_curBase) 
 642 #define declEntity (parser->m_declEntity) 
 643 #define doctypeName (parser->m_doctypeName) 
 644 #define doctypeSysid (parser->m_doctypeSysid) 
 645 #define doctypePubid (parser->m_doctypePubid) 
 646 #define declAttributeType (parser->m_declAttributeType) 
 647 #define declNotationName (parser->m_declNotationName) 
 648 #define declNotationPublicId (parser->m_declNotationPublicId) 
 649 #define declElementType (parser->m_declElementType) 
 650 #define declAttributeId (parser->m_declAttributeId) 
 651 #define declAttributeIsCdata (parser->m_declAttributeIsCdata) 
 652 #define declAttributeIsId (parser->m_declAttributeIsId) 
 653 #define freeTagList (parser->m_freeTagList) 
 654 #define freeBindingList (parser->m_freeBindingList) 
 655 #define inheritedBindings (parser->m_inheritedBindings) 
 656 #define tagStack (parser->m_tagStack) 
 657 #define atts (parser->m_atts) 
 658 #define attsSize (parser->m_attsSize) 
 659 #define nSpecifiedAtts (parser->m_nSpecifiedAtts) 
 660 #define idAttIndex (parser->m_idAttIndex) 
 661 #define nsAtts (parser->m_nsAtts) 
 662 #define nsAttsVersion (parser->m_nsAttsVersion) 
 663 #define nsAttsPower (parser->m_nsAttsPower) 
 664 #define attInfo (parser->m_attInfo) 
 665 #define tempPool (parser->m_tempPool) 
 666 #define temp2Pool (parser->m_temp2Pool) 
 667 #define groupConnector (parser->m_groupConnector) 
 668 #define groupSize (parser->m_groupSize) 
 669 #define namespaceSeparator (parser->m_namespaceSeparator) 
 670 #define parentParser (parser->m_parentParser) 
 671 #define ps_parsing (parser->m_parsingStatus.parsing) 
 672 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer) 
 674 #define isParamEntity (parser->m_isParamEntity) 
 675 #define useForeignDTD (parser->m_useForeignDTD) 
 676 #define paramEntityParsing (parser->m_paramEntityParsing) 
 678 #define hash_secret_salt (parser->m_hash_secret_salt) 
 681 XML_ParserCreate(const XML_Char 
*encodingName
) 
 683   return XML_ParserCreate_MM(encodingName
, NULL
, NULL
); 
 687 XML_ParserCreateNS(const XML_Char 
*encodingName
, XML_Char nsSep
) 
 691   return XML_ParserCreate_MM(encodingName
, NULL
, tmp
); 
 694 static const XML_Char implicitContext
[] = { 
 695   ASCII_x
, ASCII_m
, ASCII_l
, ASCII_EQUALS
, ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, 
 696   ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
, ASCII_w
, ASCII_w
, ASCII_w
, 
 697   ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
, ASCII_o
, ASCII_r
, ASCII_g
, 
 698   ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
, ASCII_SLASH
, ASCII_1
, ASCII_9
, 
 699   ASCII_9
, ASCII_8
, ASCII_SLASH
, ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
, 
 700   ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
, ASCII_e
, '\0' 
 704 generate_hash_secret_salt(void) 
 706   unsigned int seed 
= time(NULL
) % UINT_MAX
; 
 711 static XML_Bool  
/* only valid for root parser */ 
 712 startParsing(XML_Parser parser
) 
 714     /* hash functions must be initialized before setContext() is called */ 
 715     if (hash_secret_salt 
== 0) 
 716       hash_secret_salt 
= generate_hash_secret_salt(); 
 718       /* implicit context only set for root parser, since child 
 719          parsers (i.e. external entity parsers) will inherit it 
 721       return setContext(parser
, implicitContext
); 
 727 XML_ParserCreate_MM(const XML_Char 
*encodingName
, 
 728                     const XML_Memory_Handling_Suite 
*memsuite
, 
 729                     const XML_Char 
*nameSep
) 
 731   return parserCreate(encodingName
, memsuite
, nameSep
, NULL
); 
 735 parserCreate(const XML_Char 
*encodingName
, 
 736              const XML_Memory_Handling_Suite 
*memsuite
, 
 737              const XML_Char 
*nameSep
, 
 743     XML_Memory_Handling_Suite 
*mtemp
; 
 744     parser 
= (XML_Parser
) 
 745       memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
)); 
 746     if (parser 
!= NULL
) { 
 747       mtemp 
= (XML_Memory_Handling_Suite 
*)&(parser
->m_mem
); 
 748       mtemp
->malloc_fcn 
= memsuite
->malloc_fcn
; 
 749       mtemp
->realloc_fcn 
= memsuite
->realloc_fcn
; 
 750       mtemp
->free_fcn 
= memsuite
->free_fcn
; 
 754     XML_Memory_Handling_Suite 
*mtemp
; 
 755     parser 
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
)); 
 756     if (parser 
!= NULL
) { 
 757       mtemp 
= (XML_Memory_Handling_Suite 
*)&(parser
->m_mem
); 
 758       mtemp
->malloc_fcn 
= malloc
; 
 759       mtemp
->realloc_fcn 
= realloc
; 
 760       mtemp
->free_fcn 
= free
; 
 770   attsSize 
= INIT_ATTS_SIZE
; 
 771   atts 
= (ATTRIBUTE 
*)MALLOC(attsSize 
* sizeof(ATTRIBUTE
)); 
 777   attInfo 
= (XML_AttrInfo
*)MALLOC(attsSize 
* sizeof(XML_AttrInfo
)); 
 778   if (attInfo 
== NULL
) { 
 784   dataBuf 
= (XML_Char 
*)MALLOC(INIT_DATA_BUF_SIZE 
* sizeof(XML_Char
)); 
 785   if (dataBuf 
== NULL
) { 
 793   dataBufEnd 
= dataBuf 
+ INIT_DATA_BUF_SIZE
; 
 798     _dtd 
= dtdCreate(&parser
->m_mem
); 
 810   freeBindingList 
= NULL
; 
 812   freeInternalEntities 
= NULL
; 
 815   groupConnector 
= NULL
; 
 817   unknownEncodingHandler 
= NULL
; 
 818   unknownEncodingHandlerData 
= NULL
; 
 820   namespaceSeparator 
= ASCII_EXCL
; 
 822   ns_triplets 
= XML_FALSE
; 
 828   poolInit(&tempPool
, &(parser
->m_mem
)); 
 829   poolInit(&temp2Pool
, &(parser
->m_mem
)); 
 830   parserInit(parser
, encodingName
); 
 832   if (encodingName 
&& !protocolEncodingName
) { 
 833     XML_ParserFree(parser
); 
 839     internalEncoding 
= XmlGetInternalEncodingNS(); 
 840     namespaceSeparator 
= *nameSep
; 
 843     internalEncoding 
= XmlGetInternalEncoding(); 
 850 parserInit(XML_Parser parser
, const XML_Char 
*encodingName
) 
 852   processor 
= prologInitProcessor
; 
 853   XmlPrologStateInit(&prologState
); 
 854   protocolEncodingName 
= (encodingName 
!= NULL
 
 855                           ? poolCopyString(&tempPool
, encodingName
) 
 858   XmlInitEncoding(&initEncoding
, &encoding
, 0); 
 861   startElementHandler 
= NULL
; 
 862   endElementHandler 
= NULL
; 
 863   characterDataHandler 
= NULL
; 
 864   processingInstructionHandler 
= NULL
; 
 865   commentHandler 
= NULL
; 
 866   startCdataSectionHandler 
= NULL
; 
 867   endCdataSectionHandler 
= NULL
; 
 868   defaultHandler 
= NULL
; 
 869   startDoctypeDeclHandler 
= NULL
; 
 870   endDoctypeDeclHandler 
= NULL
; 
 871   unparsedEntityDeclHandler 
= NULL
; 
 872   notationDeclHandler 
= NULL
; 
 873   startNamespaceDeclHandler 
= NULL
; 
 874   endNamespaceDeclHandler 
= NULL
; 
 875   notStandaloneHandler 
= NULL
; 
 876   externalEntityRefHandler 
= NULL
; 
 877   externalEntityRefHandlerArg 
= parser
; 
 878   skippedEntityHandler 
= NULL
; 
 879   elementDeclHandler 
= NULL
; 
 880   attlistDeclHandler 
= NULL
; 
 881   entityDeclHandler 
= NULL
; 
 882   xmlDeclHandler 
= NULL
; 
 885   parseEndByteIndex 
= 0; 
 887   declElementType 
= NULL
; 
 888   declAttributeId 
= NULL
; 
 893   declAttributeType 
= NULL
; 
 894   declNotationName 
= NULL
; 
 895   declNotationPublicId 
= NULL
; 
 896   declAttributeIsCdata 
= XML_FALSE
; 
 897   declAttributeIsId 
= XML_FALSE
; 
 898   memset(&position
, 0, sizeof(POSITION
)); 
 899   errorCode 
= XML_ERROR_NONE
; 
 903   openInternalEntities 
= NULL
; 
 904   defaultExpandInternalEntities 
= XML_TRUE
; 
 907   inheritedBindings 
= NULL
; 
 909   unknownEncodingMem 
= NULL
; 
 910   unknownEncodingRelease 
= NULL
; 
 911   unknownEncodingData 
= NULL
; 
 913   ps_parsing 
= XML_INITIALIZED
; 
 915   isParamEntity 
= XML_FALSE
; 
 916   useForeignDTD 
= XML_FALSE
; 
 917   paramEntityParsing 
= XML_PARAM_ENTITY_PARSING_NEVER
; 
 919   hash_secret_salt 
= 0; 
 922 /* moves list of bindings to freeBindingList */ 
 924 moveToFreeBindingList(XML_Parser parser
, BINDING 
*bindings
) 
 927     BINDING 
*b 
= bindings
; 
 928     bindings 
= bindings
->nextTagBinding
; 
 929     b
->nextTagBinding 
= freeBindingList
; 
 935 XML_ParserReset(XML_Parser parser
, const XML_Char 
*encodingName
) 
 938   OPEN_INTERNAL_ENTITY 
*openEntityList
; 
 941   /* move tagStack to freeTagList */ 
 946     tag
->parent 
= freeTagList
; 
 947     moveToFreeBindingList(parser
, tag
->bindings
); 
 948     tag
->bindings 
= NULL
; 
 951   /* move openInternalEntities to freeInternalEntities */ 
 952   openEntityList 
= openInternalEntities
; 
 953   while (openEntityList
) { 
 954     OPEN_INTERNAL_ENTITY 
*openEntity 
= openEntityList
; 
 955     openEntityList 
= openEntity
->next
; 
 956     openEntity
->next 
= freeInternalEntities
; 
 957     freeInternalEntities 
= openEntity
; 
 959   moveToFreeBindingList(parser
, inheritedBindings
); 
 960   FREE(unknownEncodingMem
); 
 961   if (unknownEncodingRelease
) 
 962     unknownEncodingRelease(unknownEncodingData
); 
 963   poolClear(&tempPool
); 
 964   poolClear(&temp2Pool
); 
 965   parserInit(parser
, encodingName
); 
 966   dtdReset(_dtd
, &parser
->m_mem
); 
 970 enum XML_Status XMLCALL
 
 971 XML_SetEncoding(XML_Parser parser
, const XML_Char 
*encodingName
) 
 973   /* Block after XML_Parse()/XML_ParseBuffer() has been called. 
 974      XXX There's no way for the caller to determine which of the 
 975      XXX possible error cases caused the XML_STATUS_ERROR return. 
 977   if (ps_parsing 
== XML_PARSING 
|| ps_parsing 
== XML_SUSPENDED
) 
 978     return XML_STATUS_ERROR
; 
 979   if (encodingName 
== NULL
) 
 980     protocolEncodingName 
= NULL
; 
 982     protocolEncodingName 
= poolCopyString(&tempPool
, encodingName
); 
 983     if (!protocolEncodingName
) 
 984       return XML_STATUS_ERROR
; 
 986   return XML_STATUS_OK
; 
 990 XML_ExternalEntityParserCreate(XML_Parser oldParser
, 
 991                                const XML_Char 
*context
, 
 992                                const XML_Char 
*encodingName
) 
 994   XML_Parser parser 
= oldParser
; 
 997   XML_StartElementHandler oldStartElementHandler 
= startElementHandler
; 
 998   XML_EndElementHandler oldEndElementHandler 
= endElementHandler
; 
 999   XML_CharacterDataHandler oldCharacterDataHandler 
= characterDataHandler
; 
1000   XML_ProcessingInstructionHandler oldProcessingInstructionHandler
 
1001       = processingInstructionHandler
; 
1002   XML_CommentHandler oldCommentHandler 
= commentHandler
; 
1003   XML_StartCdataSectionHandler oldStartCdataSectionHandler
 
1004       = startCdataSectionHandler
; 
1005   XML_EndCdataSectionHandler oldEndCdataSectionHandler
 
1006       = endCdataSectionHandler
; 
1007   XML_DefaultHandler oldDefaultHandler 
= defaultHandler
; 
1008   XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
 
1009       = unparsedEntityDeclHandler
; 
1010   XML_NotationDeclHandler oldNotationDeclHandler 
= notationDeclHandler
; 
1011   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
 
1012       = startNamespaceDeclHandler
; 
1013   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
 
1014       = endNamespaceDeclHandler
; 
1015   XML_NotStandaloneHandler oldNotStandaloneHandler 
= notStandaloneHandler
; 
1016   XML_ExternalEntityRefHandler oldExternalEntityRefHandler
 
1017       = externalEntityRefHandler
; 
1018   XML_SkippedEntityHandler oldSkippedEntityHandler 
= skippedEntityHandler
; 
1019   XML_UnknownEncodingHandler oldUnknownEncodingHandler
 
1020       = unknownEncodingHandler
; 
1021   XML_ElementDeclHandler oldElementDeclHandler 
= elementDeclHandler
; 
1022   XML_AttlistDeclHandler oldAttlistDeclHandler 
= attlistDeclHandler
; 
1023   XML_EntityDeclHandler oldEntityDeclHandler 
= entityDeclHandler
; 
1024   XML_XmlDeclHandler oldXmlDeclHandler 
= xmlDeclHandler
; 
1025   ELEMENT_TYPE 
* oldDeclElementType 
= declElementType
; 
1027   void *oldUserData 
= userData
; 
1028   void *oldHandlerArg 
= handlerArg
; 
1029   XML_Bool oldDefaultExpandInternalEntities 
= defaultExpandInternalEntities
; 
1030   XML_Parser oldExternalEntityRefHandlerArg 
= externalEntityRefHandlerArg
; 
1032   enum XML_ParamEntityParsing oldParamEntityParsing 
= paramEntityParsing
; 
1033   int oldInEntityValue 
= prologState
.inEntityValue
; 
1035   XML_Bool oldns_triplets 
= ns_triplets
; 
1036   /* Note that the new parser shares the same hash secret as the old 
1037      parser, so that dtdCopy and copyEntityTable can lookup values 
1038      from hash tables associated with either parser without us having 
1039      to worry which hash secrets each table has. 
1041   unsigned long oldhash_secret_salt 
= hash_secret_salt
; 
1046 #endif /* XML_DTD */ 
1048   /* Note that the magical uses of the pre-processor to make field 
1049      access look more like C++ require that `parser' be overwritten 
1050      here.  This makes this function more painful to follow than it 
1055     *tmp 
= namespaceSeparator
; 
1056     parser 
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
); 
1059     parser 
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
); 
1065   startElementHandler 
= oldStartElementHandler
; 
1066   endElementHandler 
= oldEndElementHandler
; 
1067   characterDataHandler 
= oldCharacterDataHandler
; 
1068   processingInstructionHandler 
= oldProcessingInstructionHandler
; 
1069   commentHandler 
= oldCommentHandler
; 
1070   startCdataSectionHandler 
= oldStartCdataSectionHandler
; 
1071   endCdataSectionHandler 
= oldEndCdataSectionHandler
; 
1072   defaultHandler 
= oldDefaultHandler
; 
1073   unparsedEntityDeclHandler 
= oldUnparsedEntityDeclHandler
; 
1074   notationDeclHandler 
= oldNotationDeclHandler
; 
1075   startNamespaceDeclHandler 
= oldStartNamespaceDeclHandler
; 
1076   endNamespaceDeclHandler 
= oldEndNamespaceDeclHandler
; 
1077   notStandaloneHandler 
= oldNotStandaloneHandler
; 
1078   externalEntityRefHandler 
= oldExternalEntityRefHandler
; 
1079   skippedEntityHandler 
= oldSkippedEntityHandler
; 
1080   unknownEncodingHandler 
= oldUnknownEncodingHandler
; 
1081   elementDeclHandler 
= oldElementDeclHandler
; 
1082   attlistDeclHandler 
= oldAttlistDeclHandler
; 
1083   entityDeclHandler 
= oldEntityDeclHandler
; 
1084   xmlDeclHandler 
= oldXmlDeclHandler
; 
1085   declElementType 
= oldDeclElementType
; 
1086   userData 
= oldUserData
; 
1087   if (oldUserData 
== oldHandlerArg
) 
1088     handlerArg 
= userData
; 
1090     handlerArg 
= parser
; 
1091   if (oldExternalEntityRefHandlerArg 
!= oldParser
) 
1092     externalEntityRefHandlerArg 
= oldExternalEntityRefHandlerArg
; 
1093   defaultExpandInternalEntities 
= oldDefaultExpandInternalEntities
; 
1094   ns_triplets 
= oldns_triplets
; 
1095   hash_secret_salt 
= oldhash_secret_salt
; 
1096   parentParser 
= oldParser
; 
1098   paramEntityParsing 
= oldParamEntityParsing
; 
1099   prologState
.inEntityValue 
= oldInEntityValue
; 
1101 #endif /* XML_DTD */ 
1102     if (!dtdCopy(oldParser
, _dtd
, oldDtd
, &parser
->m_mem
) 
1103       || !setContext(parser
, context
)) { 
1104       XML_ParserFree(parser
); 
1107     processor 
= externalEntityInitProcessor
; 
1111     /* The DTD instance referenced by _dtd is shared between the document's 
1112        root parser and external PE parsers, therefore one does not need to 
1113        call setContext. In addition, one also *must* not call setContext, 
1114        because this would overwrite existing prefix->binding pointers in 
1115        _dtd with ones that get destroyed with the external PE parser. 
1116        This would leave those prefixes with dangling pointers. 
1118     isParamEntity 
= XML_TRUE
; 
1119     XmlPrologStateInitExternalEntity(&prologState
); 
1120     processor 
= externalParEntInitProcessor
; 
1122 #endif /* XML_DTD */ 
1126 static void FASTCALL
 
1127 destroyBindings(BINDING 
*bindings
, XML_Parser parser
) 
1130     BINDING 
*b 
= bindings
; 
1133     bindings 
= b
->nextTagBinding
; 
1140 XML_ParserFree(XML_Parser parser
) 
1143   OPEN_INTERNAL_ENTITY 
*entityList
; 
1146   /* free tagStack and freeTagList */ 
1150     if (tagList 
== NULL
) { 
1151       if (freeTagList 
== NULL
) 
1153       tagList 
= freeTagList
; 
1157     tagList 
= tagList
->parent
; 
1159     destroyBindings(p
->bindings
, parser
); 
1162   /* free openInternalEntities and freeInternalEntities */ 
1163   entityList 
= openInternalEntities
; 
1165     OPEN_INTERNAL_ENTITY 
*openEntity
; 
1166     if (entityList 
== NULL
) { 
1167       if (freeInternalEntities 
== NULL
) 
1169       entityList 
= freeInternalEntities
; 
1170       freeInternalEntities 
= NULL
; 
1172     openEntity 
= entityList
; 
1173     entityList 
= entityList
->next
; 
1177   destroyBindings(freeBindingList
, parser
); 
1178   destroyBindings(inheritedBindings
, parser
); 
1179   poolDestroy(&tempPool
); 
1180   poolDestroy(&temp2Pool
); 
1182   /* external parameter entity parsers share the DTD structure 
1183      parser->m_dtd with the root parser, so we must not destroy it 
1185   if (!isParamEntity 
&& _dtd
) 
1188 #endif /* XML_DTD */ 
1189     dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
); 
1191 #ifdef XML_ATTR_INFO 
1192   FREE((void *)attInfo
); 
1194   FREE(groupConnector
); 
1198   FREE(unknownEncodingMem
); 
1199   if (unknownEncodingRelease
) 
1200     unknownEncodingRelease(unknownEncodingData
); 
1205 XML_UseParserAsHandlerArg(XML_Parser parser
) 
1207   handlerArg 
= parser
; 
1210 enum XML_Error XMLCALL
 
1211 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
) 
1214   /* block after XML_Parse()/XML_ParseBuffer() has been called */ 
1215   if (ps_parsing 
== XML_PARSING 
|| ps_parsing 
== XML_SUSPENDED
) 
1216     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
; 
1217   useForeignDTD 
= useDTD
; 
1218   return XML_ERROR_NONE
; 
1220   return XML_ERROR_FEATURE_REQUIRES_XML_DTD
; 
1225 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
) 
1227   /* block after XML_Parse()/XML_ParseBuffer() has been called */ 
1228   if (ps_parsing 
== XML_PARSING 
|| ps_parsing 
== XML_SUSPENDED
) 
1230   ns_triplets 
= do_nst 
? XML_TRUE 
: XML_FALSE
; 
1234 XML_SetUserData(XML_Parser parser
, void *p
) 
1236   if (handlerArg 
== userData
) 
1237     handlerArg 
= userData 
= p
; 
1242 enum XML_Status XMLCALL
 
1243 XML_SetBase(XML_Parser parser
, const XML_Char 
*p
) 
1246     p 
= poolCopyString(&_dtd
->pool
, p
); 
1248       return XML_STATUS_ERROR
; 
1253   return XML_STATUS_OK
; 
1256 const XML_Char 
* XMLCALL
 
1257 XML_GetBase(XML_Parser parser
) 
1263 XML_GetSpecifiedAttributeCount(XML_Parser parser
) 
1265   return nSpecifiedAtts
; 
1269 XML_GetIdAttributeIndex(XML_Parser parser
) 
1274 #ifdef XML_ATTR_INFO 
1275 const XML_AttrInfo 
* XMLCALL
 
1276 XML_GetAttributeInfo(XML_Parser parser
) 
1283 XML_SetElementHandler(XML_Parser parser
, 
1284                       XML_StartElementHandler start
, 
1285                       XML_EndElementHandler end
) 
1287   startElementHandler 
= start
; 
1288   endElementHandler 
= end
; 
1292 XML_SetStartElementHandler(XML_Parser parser
, 
1293                            XML_StartElementHandler start
) { 
1294   startElementHandler 
= start
; 
1298 XML_SetEndElementHandler(XML_Parser parser
, 
1299                          XML_EndElementHandler end
) { 
1300   endElementHandler 
= end
; 
1304 XML_SetCharacterDataHandler(XML_Parser parser
, 
1305                             XML_CharacterDataHandler handler
) 
1307   characterDataHandler 
= handler
; 
1311 XML_SetProcessingInstructionHandler(XML_Parser parser
, 
1312                                     XML_ProcessingInstructionHandler handler
) 
1314   processingInstructionHandler 
= handler
; 
1318 XML_SetCommentHandler(XML_Parser parser
, 
1319                       XML_CommentHandler handler
) 
1321   commentHandler 
= handler
; 
1325 XML_SetCdataSectionHandler(XML_Parser parser
, 
1326                            XML_StartCdataSectionHandler start
, 
1327                            XML_EndCdataSectionHandler end
) 
1329   startCdataSectionHandler 
= start
; 
1330   endCdataSectionHandler 
= end
; 
1334 XML_SetStartCdataSectionHandler(XML_Parser parser
, 
1335                                 XML_StartCdataSectionHandler start
) { 
1336   startCdataSectionHandler 
= start
; 
1340 XML_SetEndCdataSectionHandler(XML_Parser parser
, 
1341                               XML_EndCdataSectionHandler end
) { 
1342   endCdataSectionHandler 
= end
; 
1346 XML_SetDefaultHandler(XML_Parser parser
, 
1347                       XML_DefaultHandler handler
) 
1349   defaultHandler 
= handler
; 
1350   defaultExpandInternalEntities 
= XML_FALSE
; 
1354 XML_SetDefaultHandlerExpand(XML_Parser parser
, 
1355                             XML_DefaultHandler handler
) 
1357   defaultHandler 
= handler
; 
1358   defaultExpandInternalEntities 
= XML_TRUE
; 
1362 XML_SetDoctypeDeclHandler(XML_Parser parser
, 
1363                           XML_StartDoctypeDeclHandler start
, 
1364                           XML_EndDoctypeDeclHandler end
) 
1366   startDoctypeDeclHandler 
= start
; 
1367   endDoctypeDeclHandler 
= end
; 
1371 XML_SetStartDoctypeDeclHandler(XML_Parser parser
, 
1372                                XML_StartDoctypeDeclHandler start
) { 
1373   startDoctypeDeclHandler 
= start
; 
1377 XML_SetEndDoctypeDeclHandler(XML_Parser parser
, 
1378                              XML_EndDoctypeDeclHandler end
) { 
1379   endDoctypeDeclHandler 
= end
; 
1383 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
, 
1384                                  XML_UnparsedEntityDeclHandler handler
) 
1386   unparsedEntityDeclHandler 
= handler
; 
1390 XML_SetNotationDeclHandler(XML_Parser parser
, 
1391                            XML_NotationDeclHandler handler
) 
1393   notationDeclHandler 
= handler
; 
1397 XML_SetNamespaceDeclHandler(XML_Parser parser
, 
1398                             XML_StartNamespaceDeclHandler start
, 
1399                             XML_EndNamespaceDeclHandler end
) 
1401   startNamespaceDeclHandler 
= start
; 
1402   endNamespaceDeclHandler 
= end
; 
1406 XML_SetStartNamespaceDeclHandler(XML_Parser parser
, 
1407                                  XML_StartNamespaceDeclHandler start
) { 
1408   startNamespaceDeclHandler 
= start
; 
1412 XML_SetEndNamespaceDeclHandler(XML_Parser parser
, 
1413                                XML_EndNamespaceDeclHandler end
) { 
1414   endNamespaceDeclHandler 
= end
; 
1418 XML_SetNotStandaloneHandler(XML_Parser parser
, 
1419                             XML_NotStandaloneHandler handler
) 
1421   notStandaloneHandler 
= handler
; 
1425 XML_SetExternalEntityRefHandler(XML_Parser parser
, 
1426                                 XML_ExternalEntityRefHandler handler
) 
1428   externalEntityRefHandler 
= handler
; 
1432 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
) 
1435     externalEntityRefHandlerArg 
= (XML_Parser
)arg
; 
1437     externalEntityRefHandlerArg 
= parser
; 
1441 XML_SetSkippedEntityHandler(XML_Parser parser
, 
1442                             XML_SkippedEntityHandler handler
) 
1444   skippedEntityHandler 
= handler
; 
1448 XML_SetUnknownEncodingHandler(XML_Parser parser
, 
1449                               XML_UnknownEncodingHandler handler
, 
1452   unknownEncodingHandler 
= handler
; 
1453   unknownEncodingHandlerData 
= data
; 
1457 XML_SetElementDeclHandler(XML_Parser parser
, 
1458                           XML_ElementDeclHandler eldecl
) 
1460   elementDeclHandler 
= eldecl
; 
1464 XML_SetAttlistDeclHandler(XML_Parser parser
, 
1465                           XML_AttlistDeclHandler attdecl
) 
1467   attlistDeclHandler 
= attdecl
; 
1471 XML_SetEntityDeclHandler(XML_Parser parser
, 
1472                          XML_EntityDeclHandler handler
) 
1474   entityDeclHandler 
= handler
; 
1478 XML_SetXmlDeclHandler(XML_Parser parser
, 
1479                       XML_XmlDeclHandler handler
) { 
1480   xmlDeclHandler 
= handler
; 
1484 XML_SetParamEntityParsing(XML_Parser parser
, 
1485                           enum XML_ParamEntityParsing peParsing
) 
1487   /* block after XML_Parse()/XML_ParseBuffer() has been called */ 
1488   if (ps_parsing 
== XML_PARSING 
|| ps_parsing 
== XML_SUSPENDED
) 
1491   paramEntityParsing 
= peParsing
; 
1494   return peParsing 
== XML_PARAM_ENTITY_PARSING_NEVER
; 
1499 XML_SetHashSalt(XML_Parser parser
, 
1500                 unsigned long hash_salt
) 
1502   /* block after XML_Parse()/XML_ParseBuffer() has been called */ 
1503   if (ps_parsing 
== XML_PARSING 
|| ps_parsing 
== XML_SUSPENDED
) 
1505   hash_secret_salt 
= hash_salt
; 
1509 enum XML_Status XMLCALL
 
1510 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
) 
1512   switch (ps_parsing
) { 
1514     errorCode 
= XML_ERROR_SUSPENDED
; 
1515     return XML_STATUS_ERROR
; 
1517     errorCode 
= XML_ERROR_FINISHED
; 
1518     return XML_STATUS_ERROR
; 
1519   case XML_INITIALIZED
: 
1520     if (parentParser 
== NULL 
&& !startParsing(parser
)) { 
1521       errorCode 
= XML_ERROR_NO_MEMORY
; 
1522       return XML_STATUS_ERROR
; 
1525     ps_parsing 
= XML_PARSING
; 
1529     ps_finalBuffer 
= (XML_Bool
)isFinal
; 
1531       return XML_STATUS_OK
; 
1532     positionPtr 
= bufferPtr
; 
1533     parseEndPtr 
= bufferEnd
; 
1535     /* If data are left over from last buffer, and we now know that these 
1536        data are the final chunk of input, then we have to check them again 
1537        to detect errors based on that fact. 
1539     errorCode 
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
); 
1541     if (errorCode 
== XML_ERROR_NONE
) { 
1542       switch (ps_parsing
) { 
1544         XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
); 
1545         positionPtr 
= bufferPtr
; 
1546         return XML_STATUS_SUSPENDED
; 
1547       case XML_INITIALIZED
: 
1549         ps_parsing 
= XML_FINISHED
; 
1552         return XML_STATUS_OK
; 
1555     eventEndPtr 
= eventPtr
; 
1556     processor 
= errorProcessor
; 
1557     return XML_STATUS_ERROR
; 
1559 #ifndef XML_CONTEXT_BYTES 
1560   else if (bufferPtr 
== bufferEnd
) { 
1563     enum XML_Error result
; 
1564     parseEndByteIndex 
+= len
; 
1566     ps_finalBuffer 
= (XML_Bool
)isFinal
; 
1568     errorCode 
= processor(parser
, s
, parseEndPtr 
= s 
+ len
, &end
); 
1570     if (errorCode 
!= XML_ERROR_NONE
) { 
1571       eventEndPtr 
= eventPtr
; 
1572       processor 
= errorProcessor
; 
1573       return XML_STATUS_ERROR
; 
1576       switch (ps_parsing
) { 
1578         result 
= XML_STATUS_SUSPENDED
; 
1580       case XML_INITIALIZED
: 
1583           ps_parsing 
= XML_FINISHED
; 
1584           return XML_STATUS_OK
; 
1588         result 
= XML_STATUS_OK
; 
1592     XmlUpdatePosition(encoding
, positionPtr
, end
, &position
); 
1593     nLeftOver 
= s 
+ len 
- end
; 
1595       if (buffer 
== NULL 
|| nLeftOver 
> bufferLim 
- buffer
) { 
1596         /* FIXME avoid integer overflow */ 
1598         temp 
= (buffer 
== NULL
 
1599                 ? (char *)MALLOC(len 
* 2) 
1600                 : (char *)REALLOC(buffer
, len 
* 2)); 
1602           errorCode 
= XML_ERROR_NO_MEMORY
; 
1603           eventPtr 
= eventEndPtr 
= NULL
; 
1604           processor 
= errorProcessor
; 
1605           return XML_STATUS_ERROR
; 
1608         bufferLim 
= buffer 
+ len 
* 2; 
1610       memcpy(buffer
, end
, nLeftOver
); 
1613     bufferEnd 
= buffer 
+ nLeftOver
; 
1614     positionPtr 
= bufferPtr
; 
1615     parseEndPtr 
= bufferEnd
; 
1616     eventPtr 
= bufferPtr
; 
1617     eventEndPtr 
= bufferPtr
; 
1620 #endif  /* not defined XML_CONTEXT_BYTES */ 
1622     void *buff 
= XML_GetBuffer(parser
, len
); 
1624       return XML_STATUS_ERROR
; 
1626       memcpy(buff
, s
, len
); 
1627       return XML_ParseBuffer(parser
, len
, isFinal
); 
1632 enum XML_Status XMLCALL
 
1633 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
) 
1636   enum XML_Status result 
= XML_STATUS_OK
; 
1638   switch (ps_parsing
) { 
1640     errorCode 
= XML_ERROR_SUSPENDED
; 
1641     return XML_STATUS_ERROR
; 
1643     errorCode 
= XML_ERROR_FINISHED
; 
1644     return XML_STATUS_ERROR
; 
1645   case XML_INITIALIZED
: 
1646     if (parentParser 
== NULL 
&& !startParsing(parser
)) { 
1647       errorCode 
= XML_ERROR_NO_MEMORY
; 
1648       return XML_STATUS_ERROR
; 
1651     ps_parsing 
= XML_PARSING
; 
1655   positionPtr 
= start
; 
1657   parseEndPtr 
= bufferEnd
; 
1658   parseEndByteIndex 
+= len
; 
1659   ps_finalBuffer 
= (XML_Bool
)isFinal
; 
1661   errorCode 
= processor(parser
, start
, parseEndPtr
, &bufferPtr
); 
1663   if (errorCode 
!= XML_ERROR_NONE
) { 
1664     eventEndPtr 
= eventPtr
; 
1665     processor 
= errorProcessor
; 
1666     return XML_STATUS_ERROR
; 
1669     switch (ps_parsing
) { 
1671       result 
= XML_STATUS_SUSPENDED
; 
1673     case XML_INITIALIZED
: 
1676         ps_parsing 
= XML_FINISHED
; 
1679     default: ;  /* should not happen */ 
1683   XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
); 
1684   positionPtr 
= bufferPtr
; 
1689 XML_GetBuffer(XML_Parser parser
, int len
) 
1691   switch (ps_parsing
) { 
1693     errorCode 
= XML_ERROR_SUSPENDED
; 
1696     errorCode 
= XML_ERROR_FINISHED
; 
1701   if (len 
> bufferLim 
- bufferEnd
) { 
1702     /* FIXME avoid integer overflow */ 
1703     int neededSize 
= len 
+ (int)(bufferEnd 
- bufferPtr
); 
1704 #ifdef XML_CONTEXT_BYTES 
1705     int keep 
= (int)(bufferPtr 
- buffer
); 
1707     if (keep 
> XML_CONTEXT_BYTES
) 
1708       keep 
= XML_CONTEXT_BYTES
; 
1710 #endif  /* defined XML_CONTEXT_BYTES */ 
1711     if (neededSize  
<= bufferLim 
- buffer
) { 
1712 #ifdef XML_CONTEXT_BYTES 
1713       if (keep 
< bufferPtr 
- buffer
) { 
1714         int offset 
= (int)(bufferPtr 
- buffer
) - keep
; 
1715         memmove(buffer
, &buffer
[offset
], bufferEnd 
- bufferPtr 
+ keep
); 
1716         bufferEnd 
-= offset
; 
1717         bufferPtr 
-= offset
; 
1720       memmove(buffer
, bufferPtr
, bufferEnd 
- bufferPtr
); 
1721       bufferEnd 
= buffer 
+ (bufferEnd 
- bufferPtr
); 
1723 #endif  /* not defined XML_CONTEXT_BYTES */ 
1727       int bufferSize 
= (int)(bufferLim 
- bufferPtr
); 
1728       if (bufferSize 
== 0) 
1729         bufferSize 
= INIT_BUFFER_SIZE
; 
1732       } while (bufferSize 
< neededSize
); 
1733       newBuf 
= (char *)MALLOC(bufferSize
); 
1735         errorCode 
= XML_ERROR_NO_MEMORY
; 
1738       bufferLim 
= newBuf 
+ bufferSize
; 
1739 #ifdef XML_CONTEXT_BYTES 
1741         int keep 
= (int)(bufferPtr 
- buffer
); 
1742         if (keep 
> XML_CONTEXT_BYTES
) 
1743           keep 
= XML_CONTEXT_BYTES
; 
1744         memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd 
- bufferPtr 
+ keep
); 
1747         bufferEnd 
= buffer 
+ (bufferEnd 
- bufferPtr
) + keep
; 
1748         bufferPtr 
= buffer 
+ keep
; 
1751         bufferEnd 
= newBuf 
+ (bufferEnd 
- bufferPtr
); 
1752         bufferPtr 
= buffer 
= newBuf
; 
1756         memcpy(newBuf
, bufferPtr
, bufferEnd 
- bufferPtr
); 
1759       bufferEnd 
= newBuf 
+ (bufferEnd 
- bufferPtr
); 
1760       bufferPtr 
= buffer 
= newBuf
; 
1761 #endif  /* not defined XML_CONTEXT_BYTES */ 
1763     eventPtr 
= eventEndPtr 
= NULL
; 
1769 enum XML_Status XMLCALL
 
1770 XML_StopParser(XML_Parser parser
, XML_Bool resumable
) 
1772   switch (ps_parsing
) { 
1775       errorCode 
= XML_ERROR_SUSPENDED
; 
1776       return XML_STATUS_ERROR
; 
1778     ps_parsing 
= XML_FINISHED
; 
1781     errorCode 
= XML_ERROR_FINISHED
; 
1782     return XML_STATUS_ERROR
; 
1786       if (isParamEntity
) { 
1787         errorCode 
= XML_ERROR_SUSPEND_PE
; 
1788         return XML_STATUS_ERROR
; 
1791       ps_parsing 
= XML_SUSPENDED
; 
1794       ps_parsing 
= XML_FINISHED
; 
1796   return XML_STATUS_OK
; 
1799 enum XML_Status XMLCALL
 
1800 XML_ResumeParser(XML_Parser parser
) 
1802   enum XML_Status result 
= XML_STATUS_OK
; 
1804   if (ps_parsing 
!= XML_SUSPENDED
) { 
1805     errorCode 
= XML_ERROR_NOT_SUSPENDED
; 
1806     return XML_STATUS_ERROR
; 
1808   ps_parsing 
= XML_PARSING
; 
1810   errorCode 
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
); 
1812   if (errorCode 
!= XML_ERROR_NONE
) { 
1813     eventEndPtr 
= eventPtr
; 
1814     processor 
= errorProcessor
; 
1815     return XML_STATUS_ERROR
; 
1818     switch (ps_parsing
) { 
1820       result 
= XML_STATUS_SUSPENDED
; 
1822     case XML_INITIALIZED
: 
1824       if (ps_finalBuffer
) { 
1825         ps_parsing 
= XML_FINISHED
; 
1832   XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
); 
1833   positionPtr 
= bufferPtr
; 
1838 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus 
*status
) 
1840   assert(status 
!= NULL
); 
1841   *status 
= parser
->m_parsingStatus
; 
1844 enum XML_Error XMLCALL
 
1845 XML_GetErrorCode(XML_Parser parser
) 
1851 XML_GetCurrentByteIndex(XML_Parser parser
) 
1854     return parseEndByteIndex 
- (parseEndPtr 
- eventPtr
); 
1859 XML_GetCurrentByteCount(XML_Parser parser
) 
1861   if (eventEndPtr 
&& eventPtr
) 
1862     return (int)(eventEndPtr 
- eventPtr
); 
1866 const char * XMLCALL
 
1867 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
) 
1869 #ifdef XML_CONTEXT_BYTES 
1870   if (eventPtr 
&& buffer
) { 
1871     *offset 
= (int)(eventPtr 
- buffer
); 
1872     *size   
= (int)(bufferEnd 
- buffer
); 
1875 #endif /* defined XML_CONTEXT_BYTES */ 
1880 XML_GetCurrentLineNumber(XML_Parser parser
) 
1882   if (eventPtr 
&& eventPtr 
>= positionPtr
) { 
1883     XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
); 
1884     positionPtr 
= eventPtr
; 
1886   return position
.lineNumber 
+ 1; 
1890 XML_GetCurrentColumnNumber(XML_Parser parser
) 
1892   if (eventPtr 
&& eventPtr 
>= positionPtr
) { 
1893     XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
); 
1894     positionPtr 
= eventPtr
; 
1896   return position
.columnNumber
; 
1900 XML_FreeContentModel(XML_Parser parser
, XML_Content 
*model
) 
1906 XML_MemMalloc(XML_Parser parser
, size_t size
) 
1908   return MALLOC(size
); 
1912 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
) 
1914   return REALLOC(ptr
, size
); 
1918 XML_MemFree(XML_Parser parser
, void *ptr
) 
1924 XML_DefaultCurrent(XML_Parser parser
) 
1926   if (defaultHandler
) { 
1927     if (openInternalEntities
) 
1928       reportDefault(parser
, 
1930                     openInternalEntities
->internalEventPtr
, 
1931                     openInternalEntities
->internalEventEndPtr
); 
1933       reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
); 
1937 const XML_LChar 
* XMLCALL
 
1938 XML_ErrorString(enum XML_Error code
) 
1940   static const XML_LChar
* const message
[] = { 
1942     XML_L("out of memory"), 
1943     XML_L("syntax error"), 
1944     XML_L("no element found"), 
1945     XML_L("not well-formed (invalid token)"), 
1946     XML_L("unclosed token"), 
1947     XML_L("partial character"), 
1948     XML_L("mismatched tag"), 
1949     XML_L("duplicate attribute"), 
1950     XML_L("junk after document element"), 
1951     XML_L("illegal parameter entity reference"), 
1952     XML_L("undefined entity"), 
1953     XML_L("recursive entity reference"), 
1954     XML_L("asynchronous entity"), 
1955     XML_L("reference to invalid character number"), 
1956     XML_L("reference to binary entity"), 
1957     XML_L("reference to external entity in attribute"), 
1958     XML_L("XML or text declaration not at start of entity"), 
1959     XML_L("unknown encoding"), 
1960     XML_L("encoding specified in XML declaration is incorrect"), 
1961     XML_L("unclosed CDATA section"), 
1962     XML_L("error in processing external entity reference"), 
1963     XML_L("document is not standalone"), 
1964     XML_L("unexpected parser state - please send a bug report"), 
1965     XML_L("entity declared in parameter entity"), 
1966     XML_L("requested feature requires XML_DTD support in Expat"), 
1967     XML_L("cannot change setting once parsing has begun"), 
1968     XML_L("unbound prefix"), 
1969     XML_L("must not undeclare prefix"), 
1970     XML_L("incomplete markup in parameter entity"), 
1971     XML_L("XML declaration not well-formed"), 
1972     XML_L("text declaration not well-formed"), 
1973     XML_L("illegal character(s) in public id"), 
1974     XML_L("parser suspended"), 
1975     XML_L("parser not suspended"), 
1976     XML_L("parsing aborted"), 
1977     XML_L("parsing finished"), 
1978     XML_L("cannot suspend in external parameter entity"), 
1979     XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"), 
1980     XML_L("reserved prefix (xmlns) must not be declared or undeclared"), 
1981     XML_L("prefix must not be bound to one of the reserved namespace names") 
1983   if (code 
> 0 && code 
< sizeof(message
)/sizeof(message
[0])) 
1984     return message
[code
]; 
1988 const XML_LChar 
* XMLCALL
 
1989 XML_ExpatVersion(void) { 
1991   /* V1 is used to string-ize the version number. However, it would 
1992      string-ize the actual version macro *names* unless we get them 
1993      substituted before being passed to V1. CPP is defined to expand 
1994      a macro, then rescan for more expansions. Thus, we use V2 to expand 
1995      the version macros, then CPP will expand the resulting V1() macro 
1996      with the correct numerals. */ 
1997   /* ### I'm assuming cpp is portable in this respect... */ 
1999 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c) 
2000 #define V2(a,b,c) XML_L("expat_")V1(a,b,c) 
2002   return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
); 
2008 XML_Expat_Version XMLCALL
 
2009 XML_ExpatVersionInfo(void) 
2011   XML_Expat_Version version
; 
2013   version
.major 
= XML_MAJOR_VERSION
; 
2014   version
.minor 
= XML_MINOR_VERSION
; 
2015   version
.micro 
= XML_MICRO_VERSION
; 
2020 const XML_Feature 
* XMLCALL
 
2021 XML_GetFeatureList(void) 
2023   static const XML_Feature features
[] = { 
2024     {XML_FEATURE_SIZEOF_XML_CHAR
,  XML_L("sizeof(XML_Char)"), 
2026     {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"), 
2029     {XML_FEATURE_UNICODE
,          XML_L("XML_UNICODE"), 0}, 
2031 #ifdef XML_UNICODE_WCHAR_T 
2032     {XML_FEATURE_UNICODE_WCHAR_T
,  XML_L("XML_UNICODE_WCHAR_T"), 0}, 
2035     {XML_FEATURE_DTD
,              XML_L("XML_DTD"), 0}, 
2037 #ifdef XML_CONTEXT_BYTES 
2038     {XML_FEATURE_CONTEXT_BYTES
,    XML_L("XML_CONTEXT_BYTES"), 
2042     {XML_FEATURE_MIN_SIZE
,         XML_L("XML_MIN_SIZE"), 0}, 
2045     {XML_FEATURE_NS
,               XML_L("XML_NS"), 0}, 
2047 #ifdef XML_LARGE_SIZE 
2048     {XML_FEATURE_LARGE_SIZE
,       XML_L("XML_LARGE_SIZE"), 0}, 
2050 #ifdef XML_ATTR_INFO 
2051     {XML_FEATURE_ATTR_INFO
,        XML_L("XML_ATTR_INFO"), 0}, 
2053     {XML_FEATURE_END
,              NULL
, 0} 
2059 /* Initially tag->rawName always points into the parse buffer; 
2060    for those TAG instances opened while the current parse buffer was 
2061    processed, and not yet closed, we need to store tag->rawName in a more 
2062    permanent location, since the parse buffer is about to be discarded. 
2065 storeRawNames(XML_Parser parser
) 
2067   TAG 
*tag 
= tagStack
; 
2070     int nameLen 
= sizeof(XML_Char
) * (tag
->name
.strLen 
+ 1); 
2071     char *rawNameBuf 
= tag
->buf 
+ nameLen
; 
2072     /* Stop if already stored.  Since tagStack is a stack, we can stop 
2073        at the first entry that has already been copied; everything 
2074        below it in the stack is already been accounted for in a 
2075        previous call to this function. 
2077     if (tag
->rawName 
== rawNameBuf
) 
2079     /* For re-use purposes we need to ensure that the 
2080        size of tag->buf is a multiple of sizeof(XML_Char). 
2082     bufSize 
= nameLen 
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
)); 
2083     if (bufSize 
> tag
->bufEnd 
- tag
->buf
) { 
2084       char *temp 
= (char *)REALLOC(tag
->buf
, bufSize
); 
2087       /* if tag->name.str points to tag->buf (only when namespace 
2088          processing is off) then we have to update it 
2090       if (tag
->name
.str 
== (XML_Char 
*)tag
->buf
) 
2091         tag
->name
.str 
= (XML_Char 
*)temp
; 
2092       /* if tag->name.localPart is set (when namespace processing is on) 
2093          then update it as well, since it will always point into tag->buf 
2095       if (tag
->name
.localPart
) 
2096         tag
->name
.localPart 
= (XML_Char 
*)temp 
+ (tag
->name
.localPart 
- 
2097                                                   (XML_Char 
*)tag
->buf
); 
2099       tag
->bufEnd 
= temp 
+ bufSize
; 
2100       rawNameBuf 
= temp 
+ nameLen
; 
2102     memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
); 
2103     tag
->rawName 
= rawNameBuf
; 
2109 static enum XML_Error PTRCALL
 
2110 contentProcessor(XML_Parser parser
, 
2113                  const char **endPtr
) 
2115   enum XML_Error result 
= doContent(parser
, 0, encoding
, start
, end
, 
2116                                     endPtr
, (XML_Bool
)!ps_finalBuffer
); 
2117   if (result 
== XML_ERROR_NONE
) { 
2118     if (!storeRawNames(parser
)) 
2119       return XML_ERROR_NO_MEMORY
; 
2124 static enum XML_Error PTRCALL
 
2125 externalEntityInitProcessor(XML_Parser parser
, 
2128                             const char **endPtr
) 
2130   enum XML_Error result 
= initializeEncoding(parser
); 
2131   if (result 
!= XML_ERROR_NONE
) 
2133   processor 
= externalEntityInitProcessor2
; 
2134   return externalEntityInitProcessor2(parser
, start
, end
, endPtr
); 
2137 static enum XML_Error PTRCALL
 
2138 externalEntityInitProcessor2(XML_Parser parser
, 
2141                              const char **endPtr
) 
2143   const char *next 
= start
; /* XmlContentTok doesn't always set the last arg */ 
2144   int tok 
= XmlContentTok(encoding
, start
, end
, &next
); 
2147     /* If we are at the end of the buffer, this would cause the next stage, 
2148        i.e. externalEntityInitProcessor3, to pass control directly to 
2149        doContent (by detecting XML_TOK_NONE) without processing any xml text 
2150        declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. 
2152     if (next 
== end 
&& !ps_finalBuffer
) { 
2154       return XML_ERROR_NONE
; 
2158   case XML_TOK_PARTIAL
: 
2159     if (!ps_finalBuffer
) { 
2161       return XML_ERROR_NONE
; 
2164     return XML_ERROR_UNCLOSED_TOKEN
; 
2165   case XML_TOK_PARTIAL_CHAR
: 
2166     if (!ps_finalBuffer
) { 
2168       return XML_ERROR_NONE
; 
2171     return XML_ERROR_PARTIAL_CHAR
; 
2173   processor 
= externalEntityInitProcessor3
; 
2174   return externalEntityInitProcessor3(parser
, start
, end
, endPtr
); 
2177 static enum XML_Error PTRCALL
 
2178 externalEntityInitProcessor3(XML_Parser parser
, 
2181                              const char **endPtr
) 
2184   const char *next 
= start
; /* XmlContentTok doesn't always set the last arg */ 
2186   tok 
= XmlContentTok(encoding
, start
, end
, &next
); 
2190   case XML_TOK_XML_DECL
: 
2192       enum XML_Error result
; 
2193       result 
= processXmlDecl(parser
, 1, start
, next
); 
2194       if (result 
!= XML_ERROR_NONE
) 
2196       switch (ps_parsing
) { 
2199         return XML_ERROR_NONE
; 
2201         return XML_ERROR_ABORTED
; 
2207   case XML_TOK_PARTIAL
: 
2208     if (!ps_finalBuffer
) { 
2210       return XML_ERROR_NONE
; 
2212     return XML_ERROR_UNCLOSED_TOKEN
; 
2213   case XML_TOK_PARTIAL_CHAR
: 
2214     if (!ps_finalBuffer
) { 
2216       return XML_ERROR_NONE
; 
2218     return XML_ERROR_PARTIAL_CHAR
; 
2220   processor 
= externalEntityContentProcessor
; 
2222   return externalEntityContentProcessor(parser
, start
, end
, endPtr
); 
2225 static enum XML_Error PTRCALL
 
2226 externalEntityContentProcessor(XML_Parser parser
, 
2229                                const char **endPtr
) 
2231   enum XML_Error result 
= doContent(parser
, 1, encoding
, start
, end
, 
2232                                     endPtr
, (XML_Bool
)!ps_finalBuffer
); 
2233   if (result 
== XML_ERROR_NONE
) { 
2234     if (!storeRawNames(parser
)) 
2235       return XML_ERROR_NO_MEMORY
; 
2240 static enum XML_Error
 
2241 doContent(XML_Parser parser
, 
2243           const ENCODING 
*enc
, 
2246           const char **nextPtr
, 
2249   /* save one level of indirection */ 
2250   DTD 
* const dtd 
= _dtd
; 
2252   const char **eventPP
; 
2253   const char **eventEndPP
; 
2254   if (enc 
== encoding
) { 
2255     eventPP 
= &eventPtr
; 
2256     eventEndPP 
= &eventEndPtr
; 
2259     eventPP 
= &(openInternalEntities
->internalEventPtr
); 
2260     eventEndPP 
= &(openInternalEntities
->internalEventEndPtr
); 
2265     const char *next 
= s
; /* XmlContentTok doesn't always set the last arg */ 
2266     int tok 
= XmlContentTok(enc
, s
, end
, &next
); 
2269     case XML_TOK_TRAILING_CR
: 
2272         return XML_ERROR_NONE
; 
2275       if (characterDataHandler
) { 
2277         characterDataHandler(handlerArg
, &c
, 1); 
2279       else if (defaultHandler
) 
2280         reportDefault(parser
, enc
, s
, end
); 
2281       /* We are at the end of the final buffer, should we check for 
2282          XML_SUSPENDED, XML_FINISHED? 
2284       if (startTagLevel 
== 0) 
2285         return XML_ERROR_NO_ELEMENTS
; 
2286       if (tagLevel 
!= startTagLevel
) 
2287         return XML_ERROR_ASYNC_ENTITY
; 
2289       return XML_ERROR_NONE
; 
2293         return XML_ERROR_NONE
; 
2295       if (startTagLevel 
> 0) { 
2296         if (tagLevel 
!= startTagLevel
) 
2297           return XML_ERROR_ASYNC_ENTITY
; 
2299         return XML_ERROR_NONE
; 
2301       return XML_ERROR_NO_ELEMENTS
; 
2302     case XML_TOK_INVALID
: 
2304       return XML_ERROR_INVALID_TOKEN
; 
2305     case XML_TOK_PARTIAL
: 
2308         return XML_ERROR_NONE
; 
2310       return XML_ERROR_UNCLOSED_TOKEN
; 
2311     case XML_TOK_PARTIAL_CHAR
: 
2314         return XML_ERROR_NONE
; 
2316       return XML_ERROR_PARTIAL_CHAR
; 
2317     case XML_TOK_ENTITY_REF
: 
2319         const XML_Char 
*name
; 
2321         XML_Char ch 
= (XML_Char
) XmlPredefinedEntityName(enc
, 
2322                                               s 
+ enc
->minBytesPerChar
, 
2323                                               next 
- enc
->minBytesPerChar
); 
2325           if (characterDataHandler
) 
2326             characterDataHandler(handlerArg
, &ch
, 1); 
2327           else if (defaultHandler
) 
2328             reportDefault(parser
, enc
, s
, next
); 
2331         name 
= poolStoreString(&dtd
->pool
, enc
, 
2332                                 s 
+ enc
->minBytesPerChar
, 
2333                                 next 
- enc
->minBytesPerChar
); 
2335           return XML_ERROR_NO_MEMORY
; 
2336         entity 
= (ENTITY 
*)lookup(parser
, &dtd
->generalEntities
, name
, 0); 
2337         poolDiscard(&dtd
->pool
); 
2338         /* First, determine if a check for an existing declaration is needed; 
2339            if yes, check that the entity exists, and that it is internal, 
2340            otherwise call the skipped entity or default handler. 
2342         if (!dtd
->hasParamEntityRefs 
|| dtd
->standalone
) { 
2344             return XML_ERROR_UNDEFINED_ENTITY
; 
2345           else if (!entity
->is_internal
) 
2346             return XML_ERROR_ENTITY_DECLARED_IN_PE
; 
2349           if (skippedEntityHandler
) 
2350             skippedEntityHandler(handlerArg
, name
, 0); 
2351           else if (defaultHandler
) 
2352             reportDefault(parser
, enc
, s
, next
); 
2356           return XML_ERROR_RECURSIVE_ENTITY_REF
; 
2357         if (entity
->notation
) 
2358           return XML_ERROR_BINARY_ENTITY_REF
; 
2359         if (entity
->textPtr
) { 
2360           enum XML_Error result
; 
2361           if (!defaultExpandInternalEntities
) { 
2362             if (skippedEntityHandler
) 
2363               skippedEntityHandler(handlerArg
, entity
->name
, 0); 
2364             else if (defaultHandler
) 
2365               reportDefault(parser
, enc
, s
, next
); 
2368           result 
= processInternalEntity(parser
, entity
, XML_FALSE
); 
2369           if (result 
!= XML_ERROR_NONE
) 
2372         else if (externalEntityRefHandler
) { 
2373           const XML_Char 
*context
; 
2374           entity
->open 
= XML_TRUE
; 
2375           context 
= getContext(parser
); 
2376           entity
->open 
= XML_FALSE
; 
2378             return XML_ERROR_NO_MEMORY
; 
2379           if (!externalEntityRefHandler(externalEntityRefHandlerArg
, 
2384             return XML_ERROR_EXTERNAL_ENTITY_HANDLING
; 
2385           poolDiscard(&tempPool
); 
2387         else if (defaultHandler
) 
2388           reportDefault(parser
, enc
, s
, next
); 
2391     case XML_TOK_START_TAG_NO_ATTS
: 
2393     case XML_TOK_START_TAG_WITH_ATTS
: 
2396         enum XML_Error result
; 
2400           freeTagList 
= freeTagList
->parent
; 
2403           tag 
= (TAG 
*)MALLOC(sizeof(TAG
)); 
2405             return XML_ERROR_NO_MEMORY
; 
2406           tag
->buf 
= (char *)MALLOC(INIT_TAG_BUF_SIZE
); 
2409             return XML_ERROR_NO_MEMORY
; 
2411           tag
->bufEnd 
= tag
->buf 
+ INIT_TAG_BUF_SIZE
; 
2413         tag
->bindings 
= NULL
; 
2414         tag
->parent 
= tagStack
; 
2416         tag
->name
.localPart 
= NULL
; 
2417         tag
->name
.prefix 
= NULL
; 
2418         tag
->rawName 
= s 
+ enc
->minBytesPerChar
; 
2419         tag
->rawNameLength 
= XmlNameLength(enc
, tag
->rawName
); 
2422           const char *rawNameEnd 
= tag
->rawName 
+ tag
->rawNameLength
; 
2423           const char *fromPtr 
= tag
->rawName
; 
2424           toPtr 
= (XML_Char 
*)tag
->buf
; 
2429                        &fromPtr
, rawNameEnd
, 
2430                        (ICHAR 
**)&toPtr
, (ICHAR 
*)tag
->bufEnd 
- 1); 
2431             convLen 
= (int)(toPtr 
- (XML_Char 
*)tag
->buf
); 
2432             if (fromPtr 
== rawNameEnd
) { 
2433               tag
->name
.strLen 
= convLen
; 
2436             bufSize 
= (int)(tag
->bufEnd 
- tag
->buf
) << 1; 
2438               char *temp 
= (char *)REALLOC(tag
->buf
, bufSize
); 
2440                 return XML_ERROR_NO_MEMORY
; 
2442               tag
->bufEnd 
= temp 
+ bufSize
; 
2443               toPtr 
= (XML_Char 
*)temp 
+ convLen
; 
2447         tag
->name
.str 
= (XML_Char 
*)tag
->buf
; 
2448         *toPtr 
= XML_T('\0'); 
2449         result 
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
)); 
2452         if (startElementHandler
) 
2453           startElementHandler(handlerArg
, tag
->name
.str
, 
2454                               (const XML_Char 
**)atts
); 
2455         else if (defaultHandler
) 
2456           reportDefault(parser
, enc
, s
, next
); 
2457         poolClear(&tempPool
); 
2460     case XML_TOK_EMPTY_ELEMENT_NO_ATTS
: 
2462     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
: 
2464         const char *rawName 
= s 
+ enc
->minBytesPerChar
; 
2465         enum XML_Error result
; 
2466         BINDING 
*bindings 
= NULL
; 
2467         XML_Bool noElmHandlers 
= XML_TRUE
; 
2469         name
.str 
= poolStoreString(&tempPool
, enc
, rawName
, 
2470                                    rawName 
+ XmlNameLength(enc
, rawName
)); 
2472           return XML_ERROR_NO_MEMORY
; 
2473         poolFinish(&tempPool
); 
2474         result 
= storeAtts(parser
, enc
, s
, &name
, &bindings
); 
2477         poolFinish(&tempPool
); 
2478         if (startElementHandler
) { 
2479           startElementHandler(handlerArg
, name
.str
, (const XML_Char 
**)atts
); 
2480           noElmHandlers 
= XML_FALSE
; 
2482         if (endElementHandler
) { 
2483           if (startElementHandler
) 
2484             *eventPP 
= *eventEndPP
; 
2485           endElementHandler(handlerArg
, name
.str
); 
2486           noElmHandlers 
= XML_FALSE
; 
2488         if (noElmHandlers 
&& defaultHandler
) 
2489           reportDefault(parser
, enc
, s
, next
); 
2490         poolClear(&tempPool
); 
2492           BINDING 
*b 
= bindings
; 
2493           if (endNamespaceDeclHandler
) 
2494             endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
); 
2495           bindings 
= bindings
->nextTagBinding
; 
2496           b
->nextTagBinding 
= freeBindingList
; 
2497           freeBindingList 
= b
; 
2498           b
->prefix
->binding 
= b
->prevPrefixBinding
; 
2502         return epilogProcessor(parser
, next
, end
, nextPtr
); 
2504     case XML_TOK_END_TAG
: 
2505       if (tagLevel 
== startTagLevel
) 
2506         return XML_ERROR_ASYNC_ENTITY
; 
2509         const char *rawName
; 
2510         TAG 
*tag 
= tagStack
; 
2511         tagStack 
= tag
->parent
; 
2512         tag
->parent 
= freeTagList
; 
2514         rawName 
= s 
+ enc
->minBytesPerChar
*2; 
2515         len 
= XmlNameLength(enc
, rawName
); 
2516         if (len 
!= tag
->rawNameLength
 
2517             || memcmp(tag
->rawName
, rawName
, len
) != 0) { 
2519           return XML_ERROR_TAG_MISMATCH
; 
2522         if (endElementHandler
) { 
2523           const XML_Char 
*localPart
; 
2524           const XML_Char 
*prefix
; 
2526           localPart 
= tag
->name
.localPart
; 
2527           if (ns 
&& localPart
) { 
2528             /* localPart and prefix may have been overwritten in 
2529                tag->name.str, since this points to the binding->uri 
2530                buffer which gets re-used; so we have to add them again 
2532             uri 
= (XML_Char 
*)tag
->name
.str 
+ tag
->name
.uriLen
; 
2533             /* don't need to check for space - already done in storeAtts() */ 
2534             while (*localPart
) *uri
++ = *localPart
++; 
2535             prefix 
= (XML_Char 
*)tag
->name
.prefix
; 
2536             if (ns_triplets 
&& prefix
) { 
2537               *uri
++ = namespaceSeparator
; 
2538               while (*prefix
) *uri
++ = *prefix
++; 
2542           endElementHandler(handlerArg
, tag
->name
.str
); 
2544         else if (defaultHandler
) 
2545           reportDefault(parser
, enc
, s
, next
); 
2546         while (tag
->bindings
) { 
2547           BINDING 
*b 
= tag
->bindings
; 
2548           if (endNamespaceDeclHandler
) 
2549             endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
); 
2550           tag
->bindings 
= tag
->bindings
->nextTagBinding
; 
2551           b
->nextTagBinding 
= freeBindingList
; 
2552           freeBindingList 
= b
; 
2553           b
->prefix
->binding 
= b
->prevPrefixBinding
; 
2556           return epilogProcessor(parser
, next
, end
, nextPtr
); 
2559     case XML_TOK_CHAR_REF
: 
2561         int n 
= XmlCharRefNumber(enc
, s
); 
2563           return XML_ERROR_BAD_CHAR_REF
; 
2564         if (characterDataHandler
) { 
2565           XML_Char buf
[XML_ENCODE_MAX
]; 
2566           characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR 
*)buf
)); 
2568         else if (defaultHandler
) 
2569           reportDefault(parser
, enc
, s
, next
); 
2572     case XML_TOK_XML_DECL
: 
2573       return XML_ERROR_MISPLACED_XML_PI
; 
2574     case XML_TOK_DATA_NEWLINE
: 
2575       if (characterDataHandler
) { 
2577         characterDataHandler(handlerArg
, &c
, 1); 
2579       else if (defaultHandler
) 
2580         reportDefault(parser
, enc
, s
, next
); 
2582     case XML_TOK_CDATA_SECT_OPEN
: 
2584         enum XML_Error result
; 
2585         if (startCdataSectionHandler
) 
2586           startCdataSectionHandler(handlerArg
); 
2588         /* Suppose you doing a transformation on a document that involves 
2589            changing only the character data.  You set up a defaultHandler 
2590            and a characterDataHandler.  The defaultHandler simply copies 
2591            characters through.  The characterDataHandler does the 
2592            transformation and writes the characters out escaping them as 
2593            necessary.  This case will fail to work if we leave out the 
2594            following two lines (because & and < inside CDATA sections will 
2595            be incorrectly escaped). 
2597            However, now we have a start/endCdataSectionHandler, so it seems 
2598            easier to let the user deal with this. 
2600         else if (characterDataHandler
) 
2601           characterDataHandler(handlerArg
, dataBuf
, 0); 
2603         else if (defaultHandler
) 
2604           reportDefault(parser
, enc
, s
, next
); 
2605         result 
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
); 
2606         if (result 
!= XML_ERROR_NONE
) 
2609           processor 
= cdataSectionProcessor
; 
2614     case XML_TOK_TRAILING_RSQB
: 
2617         return XML_ERROR_NONE
; 
2619       if (characterDataHandler
) { 
2620         if (MUST_CONVERT(enc
, s
)) { 
2621           ICHAR 
*dataPtr 
= (ICHAR 
*)dataBuf
; 
2622           XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR 
*)dataBufEnd
); 
2623           characterDataHandler(handlerArg
, dataBuf
, 
2624                                (int)(dataPtr 
- (ICHAR 
*)dataBuf
)); 
2627           characterDataHandler(handlerArg
, 
2629                                (int)((XML_Char 
*)end 
- (XML_Char 
*)s
)); 
2631       else if (defaultHandler
) 
2632         reportDefault(parser
, enc
, s
, end
); 
2633       /* We are at the end of the final buffer, should we check for 
2634          XML_SUSPENDED, XML_FINISHED? 
2636       if (startTagLevel 
== 0) { 
2638         return XML_ERROR_NO_ELEMENTS
; 
2640       if (tagLevel 
!= startTagLevel
) { 
2642         return XML_ERROR_ASYNC_ENTITY
; 
2645       return XML_ERROR_NONE
; 
2646     case XML_TOK_DATA_CHARS
: 
2648         XML_CharacterDataHandler charDataHandler 
= characterDataHandler
; 
2649         if (charDataHandler
) { 
2650           if (MUST_CONVERT(enc
, s
)) { 
2652               ICHAR 
*dataPtr 
= (ICHAR 
*)dataBuf
; 
2653               XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR 
*)dataBufEnd
); 
2655               charDataHandler(handlerArg
, dataBuf
, 
2656                               (int)(dataPtr 
- (ICHAR 
*)dataBuf
)); 
2663             charDataHandler(handlerArg
, 
2665                             (int)((XML_Char 
*)next 
- (XML_Char 
*)s
)); 
2667         else if (defaultHandler
) 
2668           reportDefault(parser
, enc
, s
, next
); 
2672       if (!reportProcessingInstruction(parser
, enc
, s
, next
)) 
2673         return XML_ERROR_NO_MEMORY
; 
2675     case XML_TOK_COMMENT
: 
2676       if (!reportComment(parser
, enc
, s
, next
)) 
2677         return XML_ERROR_NO_MEMORY
; 
2681         reportDefault(parser
, enc
, s
, next
); 
2684     *eventPP 
= s 
= next
; 
2685     switch (ps_parsing
) { 
2688       return XML_ERROR_NONE
; 
2690       return XML_ERROR_ABORTED
; 
2697 /* Precondition: all arguments must be non-NULL; 
2699    - normalize attributes 
2700    - check attributes for well-formedness 
2701    - generate namespace aware attribute names (URI, prefix) 
2702    - build list of attributes for startElementHandler 
2703    - default attributes 
2704    - process namespace declarations (check and report them) 
2705    - generate namespace aware element name (URI, prefix) 
2707 static enum XML_Error
 
2708 storeAtts(XML_Parser parser
, const ENCODING 
*enc
, 
2709           const char *attStr
, TAG_NAME 
*tagNamePtr
, 
2710           BINDING 
**bindingsPtr
) 
2712   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
2713   ELEMENT_TYPE 
*elementType
; 
2715   const XML_Char 
**appAtts
;   /* the attribute list for the application */ 
2723   const XML_Char 
*localPart
; 
2725   /* lookup the element type name */ 
2726   elementType 
= (ELEMENT_TYPE 
*)lookup(parser
, &dtd
->elementTypes
, tagNamePtr
->str
,0); 
2728     const XML_Char 
*name 
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
); 
2730       return XML_ERROR_NO_MEMORY
; 
2731     elementType 
= (ELEMENT_TYPE 
*)lookup(parser
, &dtd
->elementTypes
, name
, 
2732                                          sizeof(ELEMENT_TYPE
)); 
2734       return XML_ERROR_NO_MEMORY
; 
2735     if (ns 
&& !setElementTypePrefix(parser
, elementType
)) 
2736       return XML_ERROR_NO_MEMORY
; 
2738   nDefaultAtts 
= elementType
->nDefaultAtts
; 
2740   /* get the attributes from the tokenizer */ 
2741   n 
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
); 
2742   if (n 
+ nDefaultAtts 
> attsSize
) { 
2743     int oldAttsSize 
= attsSize
; 
2745 #ifdef XML_ATTR_INFO 
2746     XML_AttrInfo 
*temp2
; 
2748     attsSize 
= n 
+ nDefaultAtts 
+ INIT_ATTS_SIZE
; 
2749     temp 
= (ATTRIBUTE 
*)REALLOC((void *)atts
, attsSize 
* sizeof(ATTRIBUTE
)); 
2751       return XML_ERROR_NO_MEMORY
; 
2753 #ifdef XML_ATTR_INFO 
2754     temp2 
= (XML_AttrInfo 
*)REALLOC((void *)attInfo
, attsSize 
* sizeof(XML_AttrInfo
)); 
2756       return XML_ERROR_NO_MEMORY
; 
2759     if (n 
> oldAttsSize
) 
2760       XmlGetAttributes(enc
, attStr
, n
, atts
); 
2763   appAtts 
= (const XML_Char 
**)atts
; 
2764   for (i 
= 0; i 
< n
; i
++) { 
2765     ATTRIBUTE 
*currAtt 
= &atts
[i
]; 
2766 #ifdef XML_ATTR_INFO 
2767     XML_AttrInfo 
*currAttInfo 
= &attInfo
[i
]; 
2769     /* add the name and value to the attribute list */ 
2770     ATTRIBUTE_ID 
*attId 
= getAttributeId(parser
, enc
, currAtt
->name
, 
2772                                          + XmlNameLength(enc
, currAtt
->name
)); 
2774       return XML_ERROR_NO_MEMORY
; 
2775 #ifdef XML_ATTR_INFO 
2776     currAttInfo
->nameStart 
= parseEndByteIndex 
- (parseEndPtr 
- currAtt
->name
); 
2777     currAttInfo
->nameEnd 
= currAttInfo
->nameStart 
+ 
2778                            XmlNameLength(enc
, currAtt
->name
); 
2779     currAttInfo
->valueStart 
= parseEndByteIndex 
- 
2780                             (parseEndPtr 
- currAtt
->valuePtr
); 
2781     currAttInfo
->valueEnd 
= parseEndByteIndex 
- (parseEndPtr 
- currAtt
->valueEnd
); 
2783     /* Detect duplicate attributes by their QNames. This does not work when 
2784        namespace processing is turned on and different prefixes for the same 
2785        namespace are used. For this case we have a check further down. 
2787     if ((attId
->name
)[-1]) { 
2788       if (enc 
== encoding
) 
2789         eventPtr 
= atts
[i
].name
; 
2790       return XML_ERROR_DUPLICATE_ATTRIBUTE
; 
2792     (attId
->name
)[-1] = 1; 
2793     appAtts
[attIndex
++] = attId
->name
; 
2794     if (!atts
[i
].normalized
) { 
2795       enum XML_Error result
; 
2796       XML_Bool isCdata 
= XML_TRUE
; 
2798       /* figure out whether declared as other than CDATA */ 
2799       if (attId
->maybeTokenized
) { 
2801         for (j 
= 0; j 
< nDefaultAtts
; j
++) { 
2802           if (attId 
== elementType
->defaultAtts
[j
].id
) { 
2803             isCdata 
= elementType
->defaultAtts
[j
].isCdata
; 
2809       /* normalize the attribute value */ 
2810       result 
= storeAttributeValue(parser
, enc
, isCdata
, 
2811                                    atts
[i
].valuePtr
, atts
[i
].valueEnd
, 
2815       appAtts
[attIndex
] = poolStart(&tempPool
); 
2816       poolFinish(&tempPool
); 
2819       /* the value did not need normalizing */ 
2820       appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
, 
2822       if (appAtts
[attIndex
] == 0) 
2823         return XML_ERROR_NO_MEMORY
; 
2824       poolFinish(&tempPool
); 
2826     /* handle prefixed attribute names */ 
2827     if (attId
->prefix
) { 
2829         /* deal with namespace declarations here */ 
2830         enum XML_Error result 
= addBinding(parser
, attId
->prefix
, attId
, 
2831                                            appAtts
[attIndex
], bindingsPtr
); 
2837         /* deal with other prefixed names later */ 
2840         (attId
->name
)[-1] = 2; 
2847   /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ 
2848   nSpecifiedAtts 
= attIndex
; 
2849   if (elementType
->idAtt 
&& (elementType
->idAtt
->name
)[-1]) { 
2850     for (i 
= 0; i 
< attIndex
; i 
+= 2) 
2851       if (appAtts
[i
] == elementType
->idAtt
->name
) { 
2859   /* do attribute defaulting */ 
2860   for (i 
= 0; i 
< nDefaultAtts
; i
++) { 
2861     const DEFAULT_ATTRIBUTE 
*da 
= elementType
->defaultAtts 
+ i
; 
2862     if (!(da
->id
->name
)[-1] && da
->value
) { 
2863       if (da
->id
->prefix
) { 
2864         if (da
->id
->xmlns
) { 
2865           enum XML_Error result 
= addBinding(parser
, da
->id
->prefix
, da
->id
, 
2866                                              da
->value
, bindingsPtr
); 
2871           (da
->id
->name
)[-1] = 2; 
2873           appAtts
[attIndex
++] = da
->id
->name
; 
2874           appAtts
[attIndex
++] = da
->value
; 
2878         (da
->id
->name
)[-1] = 1; 
2879         appAtts
[attIndex
++] = da
->id
->name
; 
2880         appAtts
[attIndex
++] = da
->value
; 
2884   appAtts
[attIndex
] = 0; 
2886   /* expand prefixed attribute names, check for duplicates, 
2887      and clear flags that say whether attributes were specified */ 
2890     int j
;  /* hash table index */ 
2891     unsigned long version 
= nsAttsVersion
; 
2892     int nsAttsSize 
= (int)1 << nsAttsPower
; 
2893     /* size of hash table must be at least 2 * (# of prefixed attributes) */ 
2894     if ((nPrefixes 
<< 1) >> nsAttsPower
) {  /* true for nsAttsPower = 0 */ 
2896       /* hash table size must also be a power of 2 and >= 8 */ 
2897       while (nPrefixes 
>> nsAttsPower
++); 
2898       if (nsAttsPower 
< 3) 
2900       nsAttsSize 
= (int)1 << nsAttsPower
; 
2901       temp 
= (NS_ATT 
*)REALLOC(nsAtts
, nsAttsSize 
* sizeof(NS_ATT
)); 
2903         return XML_ERROR_NO_MEMORY
; 
2905       version 
= 0;  /* force re-initialization of nsAtts hash table */ 
2907     /* using a version flag saves us from initializing nsAtts every time */ 
2908     if (!version
) {  /* initialize version flags when version wraps around */ 
2909       version 
= INIT_ATTS_VERSION
; 
2910       for (j 
= nsAttsSize
; j 
!= 0; ) 
2911         nsAtts
[--j
].version 
= version
; 
2913     nsAttsVersion 
= --version
; 
2915     /* expand prefixed names and check for duplicates */ 
2916     for (; i 
< attIndex
; i 
+= 2) { 
2917       const XML_Char 
*s 
= appAtts
[i
]; 
2918       if (s
[-1] == 2) {  /* prefixed */ 
2921         unsigned long uriHash 
= hash_secret_salt
; 
2922         ((XML_Char 
*)s
)[-1] = 0;  /* clear flag */ 
2923         id 
= (ATTRIBUTE_ID 
*)lookup(parser
, &dtd
->attributeIds
, s
, 0); 
2924         b 
= id
->prefix
->binding
; 
2926           return XML_ERROR_UNBOUND_PREFIX
; 
2928         /* as we expand the name we also calculate its hash value */ 
2929         for (j 
= 0; j 
< b
->uriLen
; j
++) { 
2930           const XML_Char c 
= b
->uri
[j
]; 
2931           if (!poolAppendChar(&tempPool
, c
)) 
2932             return XML_ERROR_NO_MEMORY
; 
2933           uriHash 
= CHAR_HASH(uriHash
, c
); 
2935         while (*s
++ != XML_T(ASCII_COLON
)) 
2937         do {  /* copies null terminator */ 
2938           const XML_Char c 
= *s
; 
2939           if (!poolAppendChar(&tempPool
, *s
)) 
2940             return XML_ERROR_NO_MEMORY
; 
2941           uriHash 
= CHAR_HASH(uriHash
, c
); 
2944         { /* Check hash table for duplicate of expanded name (uriName). 
2945              Derived from code in lookup(parser, HASH_TABLE *table, ...). 
2947           unsigned char step 
= 0; 
2948           unsigned long mask 
= nsAttsSize 
- 1; 
2949           j 
= uriHash 
& mask
;  /* index into hash table */ 
2950           while (nsAtts
[j
].version 
== version
) { 
2951             /* for speed we compare stored hash values first */ 
2952             if (uriHash 
== nsAtts
[j
].hash
) { 
2953               const XML_Char 
*s1 
= poolStart(&tempPool
); 
2954               const XML_Char 
*s2 
= nsAtts
[j
].uriName
; 
2955               /* s1 is null terminated, but not s2 */ 
2956               for (; *s1 
== *s2 
&& *s1 
!= 0; s1
++, s2
++); 
2958                 return XML_ERROR_DUPLICATE_ATTRIBUTE
; 
2961               step 
= PROBE_STEP(uriHash
, mask
, nsAttsPower
); 
2962             j 
< step 
? (j 
+= nsAttsSize 
- step
) : (j 
-= step
); 
2966         if (ns_triplets
) {  /* append namespace separator and prefix */ 
2967           tempPool
.ptr
[-1] = namespaceSeparator
; 
2968           s 
= b
->prefix
->name
; 
2970             if (!poolAppendChar(&tempPool
, *s
)) 
2971               return XML_ERROR_NO_MEMORY
; 
2975         /* store expanded name in attribute list */ 
2976         s 
= poolStart(&tempPool
); 
2977         poolFinish(&tempPool
); 
2980         /* fill empty slot with new version, uriName and hash value */ 
2981         nsAtts
[j
].version 
= version
; 
2982         nsAtts
[j
].hash 
= uriHash
; 
2983         nsAtts
[j
].uriName 
= s
; 
2990       else  /* not prefixed */ 
2991         ((XML_Char 
*)s
)[-1] = 0;  /* clear flag */ 
2994   /* clear flags for the remaining attributes */ 
2995   for (; i 
< attIndex
; i 
+= 2) 
2996     ((XML_Char 
*)(appAtts
[i
]))[-1] = 0; 
2997   for (binding 
= *bindingsPtr
; binding
; binding 
= binding
->nextTagBinding
) 
2998     binding
->attId
->name
[-1] = 0; 
3001     return XML_ERROR_NONE
; 
3003   /* expand the element type name */ 
3004   if (elementType
->prefix
) { 
3005     binding 
= elementType
->prefix
->binding
; 
3007       return XML_ERROR_UNBOUND_PREFIX
; 
3008     localPart 
= tagNamePtr
->str
; 
3009     while (*localPart
++ != XML_T(ASCII_COLON
)) 
3012   else if (dtd
->defaultPrefix
.binding
) { 
3013     binding 
= dtd
->defaultPrefix
.binding
; 
3014     localPart 
= tagNamePtr
->str
; 
3017     return XML_ERROR_NONE
; 
3019   if (ns_triplets 
&& binding
->prefix
->name
) { 
3020     for (; binding
->prefix
->name
[prefixLen
++];) 
3021       ;  /* prefixLen includes null terminator */ 
3023   tagNamePtr
->localPart 
= localPart
; 
3024   tagNamePtr
->uriLen 
= binding
->uriLen
; 
3025   tagNamePtr
->prefix 
= binding
->prefix
->name
; 
3026   tagNamePtr
->prefixLen 
= prefixLen
; 
3027   for (i 
= 0; localPart
[i
++];) 
3028     ;  /* i includes null terminator */ 
3029   n 
= i 
+ binding
->uriLen 
+ prefixLen
; 
3030   if (n 
> binding
->uriAlloc
) { 
3032     uri 
= (XML_Char 
*)MALLOC((n 
+ EXPAND_SPARE
) * sizeof(XML_Char
)); 
3034       return XML_ERROR_NO_MEMORY
; 
3035     binding
->uriAlloc 
= n 
+ EXPAND_SPARE
; 
3036     memcpy(uri
, binding
->uri
, binding
->uriLen 
* sizeof(XML_Char
)); 
3037     for (p 
= tagStack
; p
; p 
= p
->parent
) 
3038       if (p
->name
.str 
== binding
->uri
) 
3043   /* if namespaceSeparator != '\0' then uri includes it already */ 
3044   uri 
= binding
->uri 
+ binding
->uriLen
; 
3045   memcpy(uri
, localPart
, i 
* sizeof(XML_Char
)); 
3046   /* we always have a namespace separator between localPart and prefix */ 
3049     *uri 
= namespaceSeparator
;  /* replace null terminator */ 
3050     memcpy(uri 
+ 1, binding
->prefix
->name
, prefixLen 
* sizeof(XML_Char
)); 
3052   tagNamePtr
->str 
= binding
->uri
; 
3053   return XML_ERROR_NONE
; 
3056 /* addBinding() overwrites the value of prefix->binding without checking. 
3057    Therefore one must keep track of the old value outside of addBinding(). 
3059 static enum XML_Error
 
3060 addBinding(XML_Parser parser
, PREFIX 
*prefix
, const ATTRIBUTE_ID 
*attId
, 
3061            const XML_Char 
*uri
, BINDING 
**bindingsPtr
) 
3063   static const XML_Char xmlNamespace
[] = { 
3064     ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
, 
3065     ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
, 
3066     ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
, 
3067     ASCII_SLASH
, ASCII_1
, ASCII_9
, ASCII_9
, ASCII_8
, ASCII_SLASH
, 
3068     ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
, ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
, 
3071   static const int xmlLen 
= 
3072     (int)sizeof(xmlNamespace
)/sizeof(XML_Char
) - 1; 
3073   static const XML_Char xmlnsNamespace
[] = { 
3074     ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
, 
3075     ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
, 
3076     ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_2
, ASCII_0
, ASCII_0
, 
3077     ASCII_0
, ASCII_SLASH
, ASCII_x
, ASCII_m
, ASCII_l
, ASCII_n
, ASCII_s
, 
3080   static const int xmlnsLen 
= 
3081     (int)sizeof(xmlnsNamespace
)/sizeof(XML_Char
) - 1; 
3083   XML_Bool mustBeXML 
= XML_FALSE
; 
3084   XML_Bool isXML 
= XML_TRUE
; 
3085   XML_Bool isXMLNS 
= XML_TRUE
; 
3090   /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ 
3091   if (*uri 
== XML_T('\0') && prefix
->name
) 
3092     return XML_ERROR_UNDECLARING_PREFIX
; 
3095       && prefix
->name
[0] == XML_T(ASCII_x
) 
3096       && prefix
->name
[1] == XML_T(ASCII_m
) 
3097       && prefix
->name
[2] == XML_T(ASCII_l
)) { 
3099     /* Not allowed to bind xmlns */ 
3100     if (prefix
->name
[3] == XML_T(ASCII_n
) 
3101         && prefix
->name
[4] == XML_T(ASCII_s
) 
3102         && prefix
->name
[5] == XML_T('\0')) 
3103       return XML_ERROR_RESERVED_PREFIX_XMLNS
; 
3105     if (prefix
->name
[3] == XML_T('\0')) 
3106       mustBeXML 
= XML_TRUE
; 
3109   for (len 
= 0; uri
[len
]; len
++) { 
3110     if (isXML 
&& (len 
> xmlLen 
|| uri
[len
] != xmlNamespace
[len
])) 
3113     if (!mustBeXML 
&& isXMLNS
 
3114         && (len 
> xmlnsLen 
|| uri
[len
] != xmlnsNamespace
[len
])) 
3115       isXMLNS 
= XML_FALSE
; 
3117   isXML 
= isXML 
&& len 
== xmlLen
; 
3118   isXMLNS 
= isXMLNS 
&& len 
== xmlnsLen
; 
3120   if (mustBeXML 
!= isXML
) 
3121     return mustBeXML 
? XML_ERROR_RESERVED_PREFIX_XML
 
3122                      : XML_ERROR_RESERVED_NAMESPACE_URI
; 
3125     return XML_ERROR_RESERVED_NAMESPACE_URI
; 
3127   if (namespaceSeparator
) 
3129   if (freeBindingList
) { 
3130     b 
= freeBindingList
; 
3131     if (len 
> b
->uriAlloc
) { 
3132       XML_Char 
*temp 
= (XML_Char 
*)REALLOC(b
->uri
, 
3133                           sizeof(XML_Char
) * (len 
+ EXPAND_SPARE
)); 
3135         return XML_ERROR_NO_MEMORY
; 
3137       b
->uriAlloc 
= len 
+ EXPAND_SPARE
; 
3139     freeBindingList 
= b
->nextTagBinding
; 
3142     b 
= (BINDING 
*)MALLOC(sizeof(BINDING
)); 
3144       return XML_ERROR_NO_MEMORY
; 
3145     b
->uri 
= (XML_Char 
*)MALLOC(sizeof(XML_Char
) * (len 
+ EXPAND_SPARE
)); 
3148       return XML_ERROR_NO_MEMORY
; 
3150     b
->uriAlloc 
= len 
+ EXPAND_SPARE
; 
3153   memcpy(b
->uri
, uri
, len 
* sizeof(XML_Char
)); 
3154   if (namespaceSeparator
) 
3155     b
->uri
[len 
- 1] = namespaceSeparator
; 
3158   b
->prevPrefixBinding 
= prefix
->binding
; 
3159   /* NULL binding when default namespace undeclared */ 
3160   if (*uri 
== XML_T('\0') && prefix 
== &_dtd
->defaultPrefix
) 
3161     prefix
->binding 
= NULL
; 
3163     prefix
->binding 
= b
; 
3164   b
->nextTagBinding 
= *bindingsPtr
; 
3166   /* if attId == NULL then we are not starting a namespace scope */ 
3167   if (attId 
&& startNamespaceDeclHandler
) 
3168     startNamespaceDeclHandler(handlerArg
, prefix
->name
, 
3169                               prefix
->binding 
? uri 
: 0); 
3170   return XML_ERROR_NONE
; 
3173 /* The idea here is to avoid using stack for each CDATA section when 
3174    the whole file is parsed with one call. 
3176 static enum XML_Error PTRCALL
 
3177 cdataSectionProcessor(XML_Parser parser
, 
3180                       const char **endPtr
) 
3182   enum XML_Error result 
= doCdataSection(parser
, encoding
, &start
, end
, 
3183                                          endPtr
, (XML_Bool
)!ps_finalBuffer
); 
3184   if (result 
!= XML_ERROR_NONE
) 
3187     if (parentParser
) {  /* we are parsing an external entity */ 
3188       processor 
= externalEntityContentProcessor
; 
3189       return externalEntityContentProcessor(parser
, start
, end
, endPtr
); 
3192       processor 
= contentProcessor
; 
3193       return contentProcessor(parser
, start
, end
, endPtr
); 
3199 /* startPtr gets set to non-null if the section is closed, and to null if 
3200    the section is not yet closed. 
3202 static enum XML_Error
 
3203 doCdataSection(XML_Parser parser
, 
3204                const ENCODING 
*enc
, 
3205                const char **startPtr
, 
3207                const char **nextPtr
, 
3210   const char *s 
= *startPtr
; 
3211   const char **eventPP
; 
3212   const char **eventEndPP
; 
3213   if (enc 
== encoding
) { 
3214     eventPP 
= &eventPtr
; 
3216     eventEndPP 
= &eventEndPtr
; 
3219     eventPP 
= &(openInternalEntities
->internalEventPtr
); 
3220     eventEndPP 
= &(openInternalEntities
->internalEventEndPtr
); 
3227     int tok 
= XmlCdataSectionTok(enc
, s
, end
, &next
); 
3230     case XML_TOK_CDATA_SECT_CLOSE
: 
3231       if (endCdataSectionHandler
) 
3232         endCdataSectionHandler(handlerArg
); 
3234       /* see comment under XML_TOK_CDATA_SECT_OPEN */ 
3235       else if (characterDataHandler
) 
3236         characterDataHandler(handlerArg
, dataBuf
, 0); 
3238       else if (defaultHandler
) 
3239         reportDefault(parser
, enc
, s
, next
); 
3242       if (ps_parsing 
== XML_FINISHED
) 
3243         return XML_ERROR_ABORTED
; 
3245         return XML_ERROR_NONE
; 
3246     case XML_TOK_DATA_NEWLINE
: 
3247       if (characterDataHandler
) { 
3249         characterDataHandler(handlerArg
, &c
, 1); 
3251       else if (defaultHandler
) 
3252         reportDefault(parser
, enc
, s
, next
); 
3254     case XML_TOK_DATA_CHARS
: 
3256         XML_CharacterDataHandler charDataHandler 
= characterDataHandler
; 
3257         if (charDataHandler
) { 
3258           if (MUST_CONVERT(enc
, s
)) { 
3260               ICHAR 
*dataPtr 
= (ICHAR 
*)dataBuf
; 
3261               XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR 
*)dataBufEnd
); 
3263               charDataHandler(handlerArg
, dataBuf
, 
3264                               (int)(dataPtr 
- (ICHAR 
*)dataBuf
)); 
3271             charDataHandler(handlerArg
, 
3273                             (int)((XML_Char 
*)next 
- (XML_Char 
*)s
)); 
3275         else if (defaultHandler
) 
3276           reportDefault(parser
, enc
, s
, next
); 
3279     case XML_TOK_INVALID
: 
3281       return XML_ERROR_INVALID_TOKEN
; 
3282     case XML_TOK_PARTIAL_CHAR
: 
3285         return XML_ERROR_NONE
; 
3287       return XML_ERROR_PARTIAL_CHAR
; 
3288     case XML_TOK_PARTIAL
: 
3292         return XML_ERROR_NONE
; 
3294       return XML_ERROR_UNCLOSED_CDATA_SECTION
; 
3297       return XML_ERROR_UNEXPECTED_STATE
; 
3300     *eventPP 
= s 
= next
; 
3301     switch (ps_parsing
) { 
3304       return XML_ERROR_NONE
; 
3306       return XML_ERROR_ABORTED
; 
3315 /* The idea here is to avoid using stack for each IGNORE section when 
3316    the whole file is parsed with one call. 
3318 static enum XML_Error PTRCALL
 
3319 ignoreSectionProcessor(XML_Parser parser
, 
3322                        const char **endPtr
) 
3324   enum XML_Error result 
= doIgnoreSection(parser
, encoding
, &start
, end
, 
3325                                           endPtr
, (XML_Bool
)!ps_finalBuffer
); 
3326   if (result 
!= XML_ERROR_NONE
) 
3329     processor 
= prologProcessor
; 
3330     return prologProcessor(parser
, start
, end
, endPtr
); 
3335 /* startPtr gets set to non-null is the section is closed, and to null 
3336    if the section is not yet closed. 
3338 static enum XML_Error
 
3339 doIgnoreSection(XML_Parser parser
, 
3340                 const ENCODING 
*enc
, 
3341                 const char **startPtr
, 
3343                 const char **nextPtr
, 
3348   const char *s 
= *startPtr
; 
3349   const char **eventPP
; 
3350   const char **eventEndPP
; 
3351   if (enc 
== encoding
) { 
3352     eventPP 
= &eventPtr
; 
3354     eventEndPP 
= &eventEndPtr
; 
3357     eventPP 
= &(openInternalEntities
->internalEventPtr
); 
3358     eventEndPP 
= &(openInternalEntities
->internalEventEndPtr
); 
3362   tok 
= XmlIgnoreSectionTok(enc
, s
, end
, &next
); 
3365   case XML_TOK_IGNORE_SECT
: 
3367       reportDefault(parser
, enc
, s
, next
); 
3370     if (ps_parsing 
== XML_FINISHED
) 
3371       return XML_ERROR_ABORTED
; 
3373       return XML_ERROR_NONE
; 
3374   case XML_TOK_INVALID
: 
3376     return XML_ERROR_INVALID_TOKEN
; 
3377   case XML_TOK_PARTIAL_CHAR
: 
3380       return XML_ERROR_NONE
; 
3382     return XML_ERROR_PARTIAL_CHAR
; 
3383   case XML_TOK_PARTIAL
: 
3387       return XML_ERROR_NONE
; 
3389     return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ 
3392     return XML_ERROR_UNEXPECTED_STATE
; 
3397 #endif /* XML_DTD */ 
3399 static enum XML_Error
 
3400 initializeEncoding(XML_Parser parser
) 
3404   char encodingBuf
[128]; 
3405   if (!protocolEncodingName
) 
3409     for (i 
= 0; protocolEncodingName
[i
]; i
++) { 
3410       if (i 
== sizeof(encodingBuf
) - 1 
3411           || (protocolEncodingName
[i
] & ~0x7f) != 0) { 
3412         encodingBuf
[0] = '\0'; 
3415       encodingBuf
[i
] = (char)protocolEncodingName
[i
]; 
3417     encodingBuf
[i
] = '\0'; 
3421   s 
= protocolEncodingName
; 
3423   if ((ns 
? XmlInitEncodingNS 
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
)) 
3424     return XML_ERROR_NONE
; 
3425   return handleUnknownEncoding(parser
, protocolEncodingName
); 
3428 static enum XML_Error
 
3429 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
, 
3430                const char *s
, const char *next
) 
3432   const char *encodingName 
= NULL
; 
3433   const XML_Char 
*storedEncName 
= NULL
; 
3434   const ENCODING 
*newEncoding 
= NULL
; 
3435   const char *version 
= NULL
; 
3436   const char *versionend
; 
3437   const XML_Char 
*storedversion 
= NULL
; 
3438   int standalone 
= -1; 
3441         : XmlParseXmlDecl
)(isGeneralTextEntity
, 
3451     if (isGeneralTextEntity
) 
3452       return XML_ERROR_TEXT_DECL
; 
3454       return XML_ERROR_XML_DECL
; 
3456   if (!isGeneralTextEntity 
&& standalone 
== 1) { 
3457     _dtd
->standalone 
= XML_TRUE
; 
3459     if (paramEntityParsing 
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
) 
3460       paramEntityParsing 
= XML_PARAM_ENTITY_PARSING_NEVER
; 
3461 #endif /* XML_DTD */ 
3463   if (xmlDeclHandler
) { 
3464     if (encodingName 
!= NULL
) { 
3465       storedEncName 
= poolStoreString(&temp2Pool
, 
3469                                       + XmlNameLength(encoding
, encodingName
)); 
3471               return XML_ERROR_NO_MEMORY
; 
3472       poolFinish(&temp2Pool
); 
3475       storedversion 
= poolStoreString(&temp2Pool
, 
3478                                       versionend 
- encoding
->minBytesPerChar
); 
3480         return XML_ERROR_NO_MEMORY
; 
3482     xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
); 
3484   else if (defaultHandler
) 
3485     reportDefault(parser
, encoding
, s
, next
); 
3486   if (protocolEncodingName 
== NULL
) { 
3488       if (newEncoding
->minBytesPerChar 
!= encoding
->minBytesPerChar
) { 
3489         eventPtr 
= encodingName
; 
3490         return XML_ERROR_INCORRECT_ENCODING
; 
3492       encoding 
= newEncoding
; 
3494     else if (encodingName
) { 
3495       enum XML_Error result
; 
3496       if (!storedEncName
) { 
3497         storedEncName 
= poolStoreString( 
3498           &temp2Pool
, encoding
, encodingName
, 
3499           encodingName 
+ XmlNameLength(encoding
, encodingName
)); 
3501           return XML_ERROR_NO_MEMORY
; 
3503       result 
= handleUnknownEncoding(parser
, storedEncName
); 
3504       poolClear(&temp2Pool
); 
3505       if (result 
== XML_ERROR_UNKNOWN_ENCODING
) 
3506         eventPtr 
= encodingName
; 
3511   if (storedEncName 
|| storedversion
) 
3512     poolClear(&temp2Pool
); 
3514   return XML_ERROR_NONE
; 
3517 static enum XML_Error
 
3518 handleUnknownEncoding(XML_Parser parser
, const XML_Char 
*encodingName
) 
3520   if (unknownEncodingHandler
) { 
3523     for (i 
= 0; i 
< 256; i
++) 
3525     info
.convert 
= NULL
; 
3527     info
.release 
= NULL
; 
3528     if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
, 
3531       unknownEncodingMem 
= MALLOC(XmlSizeOfUnknownEncoding()); 
3532       if (!unknownEncodingMem
) { 
3534           info
.release(info
.data
); 
3535         return XML_ERROR_NO_MEMORY
; 
3538              ? XmlInitUnknownEncodingNS
 
3539              : XmlInitUnknownEncoding
)(unknownEncodingMem
, 
3544         unknownEncodingData 
= info
.data
; 
3545         unknownEncodingRelease 
= info
.release
; 
3547         return XML_ERROR_NONE
; 
3550     if (info
.release 
!= NULL
) 
3551       info
.release(info
.data
); 
3553   return XML_ERROR_UNKNOWN_ENCODING
; 
3556 static enum XML_Error PTRCALL
 
3557 prologInitProcessor(XML_Parser parser
, 
3560                     const char **nextPtr
) 
3562   enum XML_Error result 
= initializeEncoding(parser
); 
3563   if (result 
!= XML_ERROR_NONE
) 
3565   processor 
= prologProcessor
; 
3566   return prologProcessor(parser
, s
, end
, nextPtr
); 
3571 static enum XML_Error PTRCALL
 
3572 externalParEntInitProcessor(XML_Parser parser
, 
3575                             const char **nextPtr
) 
3577   enum XML_Error result 
= initializeEncoding(parser
); 
3578   if (result 
!= XML_ERROR_NONE
) 
3581   /* we know now that XML_Parse(Buffer) has been called, 
3582      so we consider the external parameter entity read */ 
3583   _dtd
->paramEntityRead 
= XML_TRUE
; 
3585   if (prologState
.inEntityValue
) { 
3586     processor 
= entityValueInitProcessor
; 
3587     return entityValueInitProcessor(parser
, s
, end
, nextPtr
); 
3590     processor 
= externalParEntProcessor
; 
3591     return externalParEntProcessor(parser
, s
, end
, nextPtr
); 
3595 static enum XML_Error PTRCALL
 
3596 entityValueInitProcessor(XML_Parser parser
, 
3599                          const char **nextPtr
) 
3602   const char *start 
= s
; 
3603   const char *next 
= start
; 
3607     tok 
= XmlPrologTok(encoding
, start
, end
, &next
); 
3610       if (!ps_finalBuffer 
&& tok 
!= XML_TOK_INVALID
) { 
3612         return XML_ERROR_NONE
; 
3615       case XML_TOK_INVALID
: 
3616         return XML_ERROR_INVALID_TOKEN
; 
3617       case XML_TOK_PARTIAL
: 
3618         return XML_ERROR_UNCLOSED_TOKEN
; 
3619       case XML_TOK_PARTIAL_CHAR
: 
3620         return XML_ERROR_PARTIAL_CHAR
; 
3621       case XML_TOK_NONE
:   /* start == end */ 
3625       /* found end of entity value - can store it now */ 
3626       return storeEntityValue(parser
, encoding
, s
, end
); 
3628     else if (tok 
== XML_TOK_XML_DECL
) { 
3629       enum XML_Error result
; 
3630       result 
= processXmlDecl(parser
, 0, start
, next
); 
3631       if (result 
!= XML_ERROR_NONE
) 
3633       switch (ps_parsing
) { 
3636         return XML_ERROR_NONE
; 
3638         return XML_ERROR_ABORTED
; 
3642       /* stop scanning for text declaration - we found one */ 
3643       processor 
= entityValueProcessor
; 
3644       return entityValueProcessor(parser
, next
, end
, nextPtr
); 
3646     /* If we are at the end of the buffer, this would cause XmlPrologTok to 
3647        return XML_TOK_NONE on the next call, which would then cause the 
3648        function to exit with *nextPtr set to s - that is what we want for other 
3649        tokens, but not for the BOM - we would rather like to skip it; 
3650        then, when this routine is entered the next time, XmlPrologTok will 
3651        return XML_TOK_INVALID, since the BOM is still in the buffer 
3653     else if (tok 
== XML_TOK_BOM 
&& next 
== end 
&& !ps_finalBuffer
) { 
3655       return XML_ERROR_NONE
; 
3662 static enum XML_Error PTRCALL
 
3663 externalParEntProcessor(XML_Parser parser
, 
3666                         const char **nextPtr
) 
3668   const char *next 
= s
; 
3671   tok 
= XmlPrologTok(encoding
, s
, end
, &next
); 
3673     if (!ps_finalBuffer 
&& tok 
!= XML_TOK_INVALID
) { 
3675       return XML_ERROR_NONE
; 
3678     case XML_TOK_INVALID
: 
3679       return XML_ERROR_INVALID_TOKEN
; 
3680     case XML_TOK_PARTIAL
: 
3681       return XML_ERROR_UNCLOSED_TOKEN
; 
3682     case XML_TOK_PARTIAL_CHAR
: 
3683       return XML_ERROR_PARTIAL_CHAR
; 
3684     case XML_TOK_NONE
:   /* start == end */ 
3689   /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. 
3690      However, when parsing an external subset, doProlog will not accept a BOM 
3691      as valid, and report a syntax error, so we have to skip the BOM 
3693   else if (tok 
== XML_TOK_BOM
) { 
3695     tok 
= XmlPrologTok(encoding
, s
, end
, &next
); 
3698   processor 
= prologProcessor
; 
3699   return doProlog(parser
, encoding
, s
, end
, tok
, next
, 
3700                   nextPtr
, (XML_Bool
)!ps_finalBuffer
); 
3703 static enum XML_Error PTRCALL
 
3704 entityValueProcessor(XML_Parser parser
, 
3707                      const char **nextPtr
) 
3709   const char *start 
= s
; 
3710   const char *next 
= s
; 
3711   const ENCODING 
*enc 
= encoding
; 
3715     tok 
= XmlPrologTok(enc
, start
, end
, &next
); 
3717       if (!ps_finalBuffer 
&& tok 
!= XML_TOK_INVALID
) { 
3719         return XML_ERROR_NONE
; 
3722       case XML_TOK_INVALID
: 
3723         return XML_ERROR_INVALID_TOKEN
; 
3724       case XML_TOK_PARTIAL
: 
3725         return XML_ERROR_UNCLOSED_TOKEN
; 
3726       case XML_TOK_PARTIAL_CHAR
: 
3727         return XML_ERROR_PARTIAL_CHAR
; 
3728       case XML_TOK_NONE
:   /* start == end */ 
3732       /* found end of entity value - can store it now */ 
3733       return storeEntityValue(parser
, enc
, s
, end
); 
3739 #endif /* XML_DTD */ 
3741 static enum XML_Error PTRCALL
 
3742 prologProcessor(XML_Parser parser
, 
3745                 const char **nextPtr
) 
3747   const char *next 
= s
; 
3748   int tok 
= XmlPrologTok(encoding
, s
, end
, &next
); 
3749   return doProlog(parser
, encoding
, s
, end
, tok
, next
, 
3750                   nextPtr
, (XML_Bool
)!ps_finalBuffer
); 
3753 static enum XML_Error
 
3754 doProlog(XML_Parser parser
, 
3755          const ENCODING 
*enc
, 
3760          const char **nextPtr
, 
3764   static const XML_Char externalSubsetName
[] = { ASCII_HASH 
, '\0' }; 
3765 #endif /* XML_DTD */ 
3766   static const XML_Char atypeCDATA
[] = 
3767       { ASCII_C
, ASCII_D
, ASCII_A
, ASCII_T
, ASCII_A
, '\0' }; 
3768   static const XML_Char atypeID
[] = { ASCII_I
, ASCII_D
, '\0' }; 
3769   static const XML_Char atypeIDREF
[] = 
3770       { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, '\0' }; 
3771   static const XML_Char atypeIDREFS
[] = 
3772       { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, ASCII_S
, '\0' }; 
3773   static const XML_Char atypeENTITY
[] = 
3774       { ASCII_E
, ASCII_N
, ASCII_T
, ASCII_I
, ASCII_T
, ASCII_Y
, '\0' }; 
3775   static const XML_Char atypeENTITIES
[] = { ASCII_E
, ASCII_N
, 
3776       ASCII_T
, ASCII_I
, ASCII_T
, ASCII_I
, ASCII_E
, ASCII_S
, '\0' }; 
3777   static const XML_Char atypeNMTOKEN
[] = { 
3778       ASCII_N
, ASCII_M
, ASCII_T
, ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, '\0' }; 
3779   static const XML_Char atypeNMTOKENS
[] = { ASCII_N
, ASCII_M
, ASCII_T
, 
3780       ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, ASCII_S
, '\0' }; 
3781   static const XML_Char notationPrefix
[] = { ASCII_N
, ASCII_O
, ASCII_T
, 
3782       ASCII_A
, ASCII_T
, ASCII_I
, ASCII_O
, ASCII_N
, ASCII_LPAREN
, '\0' }; 
3783   static const XML_Char enumValueSep
[] = { ASCII_PIPE
, '\0' }; 
3784   static const XML_Char enumValueStart
[] = { ASCII_LPAREN
, '\0' }; 
3786   /* save one level of indirection */ 
3787   DTD 
* const dtd 
= _dtd
; 
3789   const char **eventPP
; 
3790   const char **eventEndPP
; 
3791   enum XML_Content_Quant quant
; 
3793   if (enc 
== encoding
) { 
3794     eventPP 
= &eventPtr
; 
3795     eventEndPP 
= &eventEndPtr
; 
3798     eventPP 
= &(openInternalEntities
->internalEventPtr
); 
3799     eventEndPP 
= &(openInternalEntities
->internalEventEndPtr
); 
3804     XML_Bool handleDefault 
= XML_TRUE
; 
3808       if (haveMore 
&& tok 
!= XML_TOK_INVALID
) { 
3810         return XML_ERROR_NONE
; 
3813       case XML_TOK_INVALID
: 
3815         return XML_ERROR_INVALID_TOKEN
; 
3816       case XML_TOK_PARTIAL
: 
3817         return XML_ERROR_UNCLOSED_TOKEN
; 
3818       case XML_TOK_PARTIAL_CHAR
: 
3819         return XML_ERROR_PARTIAL_CHAR
; 
3820       case -XML_TOK_PROLOG_S
: 
3825         /* for internal PE NOT referenced between declarations */ 
3826         if (enc 
!= encoding 
&& !openInternalEntities
->betweenDecl
) { 
3828           return XML_ERROR_NONE
; 
3830         /* WFC: PE Between Declarations - must check that PE contains 
3831            complete markup, not only for external PEs, but also for 
3832            internal PEs if the reference occurs between declarations. 
3834         if (isParamEntity 
|| enc 
!= encoding
) { 
3835           if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
) 
3837             return XML_ERROR_INCOMPLETE_PE
; 
3839           return XML_ERROR_NONE
; 
3841 #endif /* XML_DTD */ 
3842         return XML_ERROR_NO_ELEMENTS
; 
3849     role 
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
); 
3851     case XML_ROLE_XML_DECL
: 
3853         enum XML_Error result 
= processXmlDecl(parser
, 0, s
, next
); 
3854         if (result 
!= XML_ERROR_NONE
) 
3857         handleDefault 
= XML_FALSE
; 
3860     case XML_ROLE_DOCTYPE_NAME
: 
3861       if (startDoctypeDeclHandler
) { 
3862         doctypeName 
= poolStoreString(&tempPool
, enc
, s
, next
); 
3864           return XML_ERROR_NO_MEMORY
; 
3865         poolFinish(&tempPool
); 
3866         doctypePubid 
= NULL
; 
3867         handleDefault 
= XML_FALSE
; 
3869       doctypeSysid 
= NULL
; /* always initialize to NULL */ 
3871     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
: 
3872       if (startDoctypeDeclHandler
) { 
3873         startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
, 
3876         poolClear(&tempPool
); 
3877         handleDefault 
= XML_FALSE
; 
3881     case XML_ROLE_TEXT_DECL
: 
3883         enum XML_Error result 
= processXmlDecl(parser
, 1, s
, next
); 
3884         if (result 
!= XML_ERROR_NONE
) 
3887         handleDefault 
= XML_FALSE
; 
3890 #endif /* XML_DTD */ 
3891     case XML_ROLE_DOCTYPE_PUBLIC_ID
: 
3893       useForeignDTD 
= XML_FALSE
; 
3894       declEntity 
= (ENTITY 
*)lookup(parser
, 
3895                                     &dtd
->paramEntities
, 
3899         return XML_ERROR_NO_MEMORY
; 
3900 #endif /* XML_DTD */ 
3901       dtd
->hasParamEntityRefs 
= XML_TRUE
; 
3902       if (startDoctypeDeclHandler
) { 
3904         if (!XmlIsPublicId(enc
, s
, next
, eventPP
)) 
3905           return XML_ERROR_PUBLICID
; 
3906         pubId 
= poolStoreString(&tempPool
, enc
, 
3907                                 s 
+ enc
->minBytesPerChar
, 
3908                                 next 
- enc
->minBytesPerChar
); 
3910           return XML_ERROR_NO_MEMORY
; 
3911         normalizePublicId(pubId
); 
3912         poolFinish(&tempPool
); 
3913         doctypePubid 
= pubId
; 
3914         handleDefault 
= XML_FALSE
; 
3915         goto alreadyChecked
; 
3918     case XML_ROLE_ENTITY_PUBLIC_ID
: 
3919       if (!XmlIsPublicId(enc
, s
, next
, eventPP
)) 
3920         return XML_ERROR_PUBLICID
; 
3922       if (dtd
->keepProcessing 
&& declEntity
) { 
3923         XML_Char 
*tem 
= poolStoreString(&dtd
->pool
, 
3925                                         s 
+ enc
->minBytesPerChar
, 
3926                                         next 
- enc
->minBytesPerChar
); 
3928           return XML_ERROR_NO_MEMORY
; 
3929         normalizePublicId(tem
); 
3930         declEntity
->publicId 
= tem
; 
3931         poolFinish(&dtd
->pool
); 
3932         if (entityDeclHandler
) 
3933           handleDefault 
= XML_FALSE
; 
3936     case XML_ROLE_DOCTYPE_CLOSE
: 
3938         startDoctypeDeclHandler(handlerArg
, doctypeName
, 
3939                                 doctypeSysid
, doctypePubid
, 0); 
3940         poolClear(&tempPool
); 
3941         handleDefault 
= XML_FALSE
; 
3943       /* doctypeSysid will be non-NULL in the case of a previous 
3944          XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler 
3945          was not set, indicating an external subset 
3948       if (doctypeSysid 
|| useForeignDTD
) { 
3949         XML_Bool hadParamEntityRefs 
= dtd
->hasParamEntityRefs
; 
3950         dtd
->hasParamEntityRefs 
= XML_TRUE
; 
3951         if (paramEntityParsing 
&& externalEntityRefHandler
) { 
3952           ENTITY 
*entity 
= (ENTITY 
*)lookup(parser
, 
3953                                             &dtd
->paramEntities
, 
3957             return XML_ERROR_NO_MEMORY
; 
3959             entity
->base 
= curBase
; 
3960           dtd
->paramEntityRead 
= XML_FALSE
; 
3961           if (!externalEntityRefHandler(externalEntityRefHandlerArg
, 
3966             return XML_ERROR_EXTERNAL_ENTITY_HANDLING
; 
3967           if (dtd
->paramEntityRead
) { 
3968             if (!dtd
->standalone 
&& 
3969                 notStandaloneHandler 
&& 
3970                 !notStandaloneHandler(handlerArg
)) 
3971               return XML_ERROR_NOT_STANDALONE
; 
3973           /* if we didn't read the foreign DTD then this means that there 
3974              is no external subset and we must reset dtd->hasParamEntityRefs 
3976           else if (!doctypeSysid
) 
3977             dtd
->hasParamEntityRefs 
= hadParamEntityRefs
; 
3978           /* end of DTD - no need to update dtd->keepProcessing */ 
3980         useForeignDTD 
= XML_FALSE
; 
3982 #endif /* XML_DTD */ 
3983       if (endDoctypeDeclHandler
) { 
3984         endDoctypeDeclHandler(handlerArg
); 
3985         handleDefault 
= XML_FALSE
; 
3988     case XML_ROLE_INSTANCE_START
: 
3990       /* if there is no DOCTYPE declaration then now is the 
3991          last chance to read the foreign DTD 
3993       if (useForeignDTD
) { 
3994         XML_Bool hadParamEntityRefs 
= dtd
->hasParamEntityRefs
; 
3995         dtd
->hasParamEntityRefs 
= XML_TRUE
; 
3996         if (paramEntityParsing 
&& externalEntityRefHandler
) { 
3997           ENTITY 
*entity 
= (ENTITY 
*)lookup(parser
, &dtd
->paramEntities
, 
4001             return XML_ERROR_NO_MEMORY
; 
4002           entity
->base 
= curBase
; 
4003           dtd
->paramEntityRead 
= XML_FALSE
; 
4004           if (!externalEntityRefHandler(externalEntityRefHandlerArg
, 
4009             return XML_ERROR_EXTERNAL_ENTITY_HANDLING
; 
4010           if (dtd
->paramEntityRead
) { 
4011             if (!dtd
->standalone 
&& 
4012                 notStandaloneHandler 
&& 
4013                 !notStandaloneHandler(handlerArg
)) 
4014               return XML_ERROR_NOT_STANDALONE
; 
4016           /* if we didn't read the foreign DTD then this means that there 
4017              is no external subset and we must reset dtd->hasParamEntityRefs 
4020             dtd
->hasParamEntityRefs 
= hadParamEntityRefs
; 
4021           /* end of DTD - no need to update dtd->keepProcessing */ 
4024 #endif /* XML_DTD */ 
4025       processor 
= contentProcessor
; 
4026       return contentProcessor(parser
, s
, end
, nextPtr
); 
4027     case XML_ROLE_ATTLIST_ELEMENT_NAME
: 
4028       declElementType 
= getElementType(parser
, enc
, s
, next
); 
4029       if (!declElementType
) 
4030         return XML_ERROR_NO_MEMORY
; 
4031       goto checkAttListDeclHandler
; 
4032     case XML_ROLE_ATTRIBUTE_NAME
: 
4033       declAttributeId 
= getAttributeId(parser
, enc
, s
, next
); 
4034       if (!declAttributeId
) 
4035         return XML_ERROR_NO_MEMORY
; 
4036       declAttributeIsCdata 
= XML_FALSE
; 
4037       declAttributeType 
= NULL
; 
4038       declAttributeIsId 
= XML_FALSE
; 
4039       goto checkAttListDeclHandler
; 
4040     case XML_ROLE_ATTRIBUTE_TYPE_CDATA
: 
4041       declAttributeIsCdata 
= XML_TRUE
; 
4042       declAttributeType 
= atypeCDATA
; 
4043       goto checkAttListDeclHandler
; 
4044     case XML_ROLE_ATTRIBUTE_TYPE_ID
: 
4045       declAttributeIsId 
= XML_TRUE
; 
4046       declAttributeType 
= atypeID
; 
4047       goto checkAttListDeclHandler
; 
4048     case XML_ROLE_ATTRIBUTE_TYPE_IDREF
: 
4049       declAttributeType 
= atypeIDREF
; 
4050       goto checkAttListDeclHandler
; 
4051     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
: 
4052       declAttributeType 
= atypeIDREFS
; 
4053       goto checkAttListDeclHandler
; 
4054     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
: 
4055       declAttributeType 
= atypeENTITY
; 
4056       goto checkAttListDeclHandler
; 
4057     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
: 
4058       declAttributeType 
= atypeENTITIES
; 
4059       goto checkAttListDeclHandler
; 
4060     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
: 
4061       declAttributeType 
= atypeNMTOKEN
; 
4062       goto checkAttListDeclHandler
; 
4063     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
: 
4064       declAttributeType 
= atypeNMTOKENS
; 
4065     checkAttListDeclHandler
: 
4066       if (dtd
->keepProcessing 
&& attlistDeclHandler
) 
4067         handleDefault 
= XML_FALSE
; 
4069     case XML_ROLE_ATTRIBUTE_ENUM_VALUE
: 
4070     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
: 
4071       if (dtd
->keepProcessing 
&& attlistDeclHandler
) { 
4072         const XML_Char 
*prefix
; 
4073         if (declAttributeType
) { 
4074           prefix 
= enumValueSep
; 
4077           prefix 
= (role 
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
 
4081         if (!poolAppendString(&tempPool
, prefix
)) 
4082           return XML_ERROR_NO_MEMORY
; 
4083         if (!poolAppend(&tempPool
, enc
, s
, next
)) 
4084           return XML_ERROR_NO_MEMORY
; 
4085         declAttributeType 
= tempPool
.start
; 
4086         handleDefault 
= XML_FALSE
; 
4089     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
: 
4090     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
: 
4091       if (dtd
->keepProcessing
) { 
4092         if (!defineAttribute(declElementType
, declAttributeId
, 
4093                              declAttributeIsCdata
, declAttributeIsId
, 
4095           return XML_ERROR_NO_MEMORY
; 
4096         if (attlistDeclHandler 
&& declAttributeType
) { 
4097           if (*declAttributeType 
== XML_T(ASCII_LPAREN
) 
4098               || (*declAttributeType 
== XML_T(ASCII_N
) 
4099                   && declAttributeType
[1] == XML_T(ASCII_O
))) { 
4100             /* Enumerated or Notation type */ 
4101             if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
)) 
4102                 || !poolAppendChar(&tempPool
, XML_T('\0'))) 
4103               return XML_ERROR_NO_MEMORY
; 
4104             declAttributeType 
= tempPool
.start
; 
4105             poolFinish(&tempPool
); 
4108           attlistDeclHandler(handlerArg
, declElementType
->name
, 
4109                              declAttributeId
->name
, declAttributeType
, 
4110                              0, role 
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
); 
4111           poolClear(&tempPool
); 
4112           handleDefault 
= XML_FALSE
; 
4116     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
: 
4117     case XML_ROLE_FIXED_ATTRIBUTE_VALUE
: 
4118       if (dtd
->keepProcessing
) { 
4119         const XML_Char 
*attVal
; 
4120         enum XML_Error result 
= 
4121           storeAttributeValue(parser
, enc
, declAttributeIsCdata
, 
4122                               s 
+ enc
->minBytesPerChar
, 
4123                               next 
- enc
->minBytesPerChar
, 
4127         attVal 
= poolStart(&dtd
->pool
); 
4128         poolFinish(&dtd
->pool
); 
4129         /* ID attributes aren't allowed to have a default */ 
4130         if (!defineAttribute(declElementType
, declAttributeId
, 
4131                              declAttributeIsCdata
, XML_FALSE
, attVal
, parser
)) 
4132           return XML_ERROR_NO_MEMORY
; 
4133         if (attlistDeclHandler 
&& declAttributeType
) { 
4134           if (*declAttributeType 
== XML_T(ASCII_LPAREN
) 
4135               || (*declAttributeType 
== XML_T(ASCII_N
) 
4136                   && declAttributeType
[1] == XML_T(ASCII_O
))) { 
4137             /* Enumerated or Notation type */ 
4138             if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
)) 
4139                 || !poolAppendChar(&tempPool
, XML_T('\0'))) 
4140               return XML_ERROR_NO_MEMORY
; 
4141             declAttributeType 
= tempPool
.start
; 
4142             poolFinish(&tempPool
); 
4145           attlistDeclHandler(handlerArg
, declElementType
->name
, 
4146                              declAttributeId
->name
, declAttributeType
, 
4148                              role 
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
); 
4149           poolClear(&tempPool
); 
4150           handleDefault 
= XML_FALSE
; 
4154     case XML_ROLE_ENTITY_VALUE
: 
4155       if (dtd
->keepProcessing
) { 
4156         enum XML_Error result 
= storeEntityValue(parser
, enc
, 
4157                                             s 
+ enc
->minBytesPerChar
, 
4158                                             next 
- enc
->minBytesPerChar
); 
4160           declEntity
->textPtr 
= poolStart(&dtd
->entityValuePool
); 
4161           declEntity
->textLen 
= (int)(poolLength(&dtd
->entityValuePool
)); 
4162           poolFinish(&dtd
->entityValuePool
); 
4163           if (entityDeclHandler
) { 
4165             entityDeclHandler(handlerArg
, 
4167                               declEntity
->is_param
, 
4168                               declEntity
->textPtr
, 
4169                               declEntity
->textLen
, 
4171             handleDefault 
= XML_FALSE
; 
4175           poolDiscard(&dtd
->entityValuePool
); 
4176         if (result 
!= XML_ERROR_NONE
) 
4180     case XML_ROLE_DOCTYPE_SYSTEM_ID
: 
4182       useForeignDTD 
= XML_FALSE
; 
4183 #endif /* XML_DTD */ 
4184       dtd
->hasParamEntityRefs 
= XML_TRUE
; 
4185       if (startDoctypeDeclHandler
) { 
4186         doctypeSysid 
= poolStoreString(&tempPool
, enc
, 
4187                                        s 
+ enc
->minBytesPerChar
, 
4188                                        next 
- enc
->minBytesPerChar
); 
4189         if (doctypeSysid 
== NULL
) 
4190           return XML_ERROR_NO_MEMORY
; 
4191         poolFinish(&tempPool
); 
4192         handleDefault 
= XML_FALSE
; 
4196         /* use externalSubsetName to make doctypeSysid non-NULL 
4197            for the case where no startDoctypeDeclHandler is set */ 
4198         doctypeSysid 
= externalSubsetName
; 
4199 #endif /* XML_DTD */ 
4200       if (!dtd
->standalone
 
4202           && !paramEntityParsing
 
4203 #endif /* XML_DTD */ 
4204           && notStandaloneHandler
 
4205           && !notStandaloneHandler(handlerArg
)) 
4206         return XML_ERROR_NOT_STANDALONE
; 
4211         declEntity 
= (ENTITY 
*)lookup(parser
, 
4212                                       &dtd
->paramEntities
, 
4216           return XML_ERROR_NO_MEMORY
; 
4217         declEntity
->publicId 
= NULL
; 
4220 #endif /* XML_DTD */ 
4221     case XML_ROLE_ENTITY_SYSTEM_ID
: 
4222       if (dtd
->keepProcessing 
&& declEntity
) { 
4223         declEntity
->systemId 
= poolStoreString(&dtd
->pool
, enc
, 
4224                                                s 
+ enc
->minBytesPerChar
, 
4225                                                next 
- enc
->minBytesPerChar
); 
4226         if (!declEntity
->systemId
) 
4227           return XML_ERROR_NO_MEMORY
; 
4228         declEntity
->base 
= curBase
; 
4229         poolFinish(&dtd
->pool
); 
4230         if (entityDeclHandler
) 
4231           handleDefault 
= XML_FALSE
; 
4234     case XML_ROLE_ENTITY_COMPLETE
: 
4235       if (dtd
->keepProcessing 
&& declEntity 
&& entityDeclHandler
) { 
4237         entityDeclHandler(handlerArg
, 
4239                           declEntity
->is_param
, 
4242                           declEntity
->systemId
, 
4243                           declEntity
->publicId
, 
4245         handleDefault 
= XML_FALSE
; 
4248     case XML_ROLE_ENTITY_NOTATION_NAME
: 
4249       if (dtd
->keepProcessing 
&& declEntity
) { 
4250         declEntity
->notation 
= poolStoreString(&dtd
->pool
, enc
, s
, next
); 
4251         if (!declEntity
->notation
) 
4252           return XML_ERROR_NO_MEMORY
; 
4253         poolFinish(&dtd
->pool
); 
4254         if (unparsedEntityDeclHandler
) { 
4256           unparsedEntityDeclHandler(handlerArg
, 
4259                                     declEntity
->systemId
, 
4260                                     declEntity
->publicId
, 
4261                                     declEntity
->notation
); 
4262           handleDefault 
= XML_FALSE
; 
4264         else if (entityDeclHandler
) { 
4266           entityDeclHandler(handlerArg
, 
4270                             declEntity
->systemId
, 
4271                             declEntity
->publicId
, 
4272                             declEntity
->notation
); 
4273           handleDefault 
= XML_FALSE
; 
4277     case XML_ROLE_GENERAL_ENTITY_NAME
: 
4279         if (XmlPredefinedEntityName(enc
, s
, next
)) { 
4283         if (dtd
->keepProcessing
) { 
4284           const XML_Char 
*name 
= poolStoreString(&dtd
->pool
, enc
, s
, next
); 
4286             return XML_ERROR_NO_MEMORY
; 
4287           declEntity 
= (ENTITY 
*)lookup(parser
, &dtd
->generalEntities
, name
, 
4290             return XML_ERROR_NO_MEMORY
; 
4291           if (declEntity
->name 
!= name
) { 
4292             poolDiscard(&dtd
->pool
); 
4296             poolFinish(&dtd
->pool
); 
4297             declEntity
->publicId 
= NULL
; 
4298             declEntity
->is_param 
= XML_FALSE
; 
4299             /* if we have a parent parser or are reading an internal parameter 
4300                entity, then the entity declaration is not considered "internal" 
4302             declEntity
->is_internal 
= !(parentParser 
|| openInternalEntities
); 
4303             if (entityDeclHandler
) 
4304               handleDefault 
= XML_FALSE
; 
4308           poolDiscard(&dtd
->pool
); 
4313     case XML_ROLE_PARAM_ENTITY_NAME
: 
4315       if (dtd
->keepProcessing
) { 
4316         const XML_Char 
*name 
= poolStoreString(&dtd
->pool
, enc
, s
, next
); 
4318           return XML_ERROR_NO_MEMORY
; 
4319         declEntity 
= (ENTITY 
*)lookup(parser
, &dtd
->paramEntities
, 
4320                                            name
, sizeof(ENTITY
)); 
4322           return XML_ERROR_NO_MEMORY
; 
4323         if (declEntity
->name 
!= name
) { 
4324           poolDiscard(&dtd
->pool
); 
4328           poolFinish(&dtd
->pool
); 
4329           declEntity
->publicId 
= NULL
; 
4330           declEntity
->is_param 
= XML_TRUE
; 
4331           /* if we have a parent parser or are reading an internal parameter 
4332              entity, then the entity declaration is not considered "internal" 
4334           declEntity
->is_internal 
= !(parentParser 
|| openInternalEntities
); 
4335           if (entityDeclHandler
) 
4336             handleDefault 
= XML_FALSE
; 
4340         poolDiscard(&dtd
->pool
); 
4343 #else /* not XML_DTD */ 
4345 #endif /* XML_DTD */ 
4347     case XML_ROLE_NOTATION_NAME
: 
4348       declNotationPublicId 
= NULL
; 
4349       declNotationName 
= NULL
; 
4350       if (notationDeclHandler
) { 
4351         declNotationName 
= poolStoreString(&tempPool
, enc
, s
, next
); 
4352         if (!declNotationName
) 
4353           return XML_ERROR_NO_MEMORY
; 
4354         poolFinish(&tempPool
); 
4355         handleDefault 
= XML_FALSE
; 
4358     case XML_ROLE_NOTATION_PUBLIC_ID
: 
4359       if (!XmlIsPublicId(enc
, s
, next
, eventPP
)) 
4360         return XML_ERROR_PUBLICID
; 
4361       if (declNotationName
) {  /* means notationDeclHandler != NULL */ 
4362         XML_Char 
*tem 
= poolStoreString(&tempPool
, 
4364                                         s 
+ enc
->minBytesPerChar
, 
4365                                         next 
- enc
->minBytesPerChar
); 
4367           return XML_ERROR_NO_MEMORY
; 
4368         normalizePublicId(tem
); 
4369         declNotationPublicId 
= tem
; 
4370         poolFinish(&tempPool
); 
4371         handleDefault 
= XML_FALSE
; 
4374     case XML_ROLE_NOTATION_SYSTEM_ID
: 
4375       if (declNotationName 
&& notationDeclHandler
) { 
4376         const XML_Char 
*systemId
 
4377           = poolStoreString(&tempPool
, enc
, 
4378                             s 
+ enc
->minBytesPerChar
, 
4379                             next 
- enc
->minBytesPerChar
); 
4381           return XML_ERROR_NO_MEMORY
; 
4383         notationDeclHandler(handlerArg
, 
4387                             declNotationPublicId
); 
4388         handleDefault 
= XML_FALSE
; 
4390       poolClear(&tempPool
); 
4392     case XML_ROLE_NOTATION_NO_SYSTEM_ID
: 
4393       if (declNotationPublicId 
&& notationDeclHandler
) { 
4395         notationDeclHandler(handlerArg
, 
4399                             declNotationPublicId
); 
4400         handleDefault 
= XML_FALSE
; 
4402       poolClear(&tempPool
); 
4404     case XML_ROLE_ERROR
: 
4406       case XML_TOK_PARAM_ENTITY_REF
: 
4407         /* PE references in internal subset are 
4408            not allowed within declarations. */ 
4409         return XML_ERROR_PARAM_ENTITY_REF
; 
4410       case XML_TOK_XML_DECL
: 
4411         return XML_ERROR_MISPLACED_XML_PI
; 
4413         return XML_ERROR_SYNTAX
; 
4416     case XML_ROLE_IGNORE_SECT
: 
4418         enum XML_Error result
; 
4420           reportDefault(parser
, enc
, s
, next
); 
4421         handleDefault 
= XML_FALSE
; 
4422         result 
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
); 
4423         if (result 
!= XML_ERROR_NONE
) 
4426           processor 
= ignoreSectionProcessor
; 
4431 #endif /* XML_DTD */ 
4432     case XML_ROLE_GROUP_OPEN
: 
4433       if (prologState
.level 
>= groupSize
) { 
4435           char *temp 
= (char *)REALLOC(groupConnector
, groupSize 
*= 2); 
4437             return XML_ERROR_NO_MEMORY
; 
4438           groupConnector 
= temp
; 
4439           if (dtd
->scaffIndex
) { 
4440             int *temp 
= (int *)REALLOC(dtd
->scaffIndex
, 
4441                           groupSize 
* sizeof(int)); 
4443               return XML_ERROR_NO_MEMORY
; 
4444             dtd
->scaffIndex 
= temp
; 
4448           groupConnector 
= (char *)MALLOC(groupSize 
= 32); 
4449           if (!groupConnector
) 
4450             return XML_ERROR_NO_MEMORY
; 
4453       groupConnector
[prologState
.level
] = 0; 
4454       if (dtd
->in_eldecl
) { 
4455         int myindex 
= nextScaffoldPart(parser
); 
4457           return XML_ERROR_NO_MEMORY
; 
4458         dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
; 
4460         dtd
->scaffold
[myindex
].type 
= XML_CTYPE_SEQ
; 
4461         if (elementDeclHandler
) 
4462           handleDefault 
= XML_FALSE
; 
4465     case XML_ROLE_GROUP_SEQUENCE
: 
4466       if (groupConnector
[prologState
.level
] == ASCII_PIPE
) 
4467         return XML_ERROR_SYNTAX
; 
4468       groupConnector
[prologState
.level
] = ASCII_COMMA
; 
4469       if (dtd
->in_eldecl 
&& elementDeclHandler
) 
4470         handleDefault 
= XML_FALSE
; 
4472     case XML_ROLE_GROUP_CHOICE
: 
4473       if (groupConnector
[prologState
.level
] == ASCII_COMMA
) 
4474         return XML_ERROR_SYNTAX
; 
4476           && !groupConnector
[prologState
.level
] 
4477           && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel 
- 1]].type
 
4480         dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel 
- 1]].type
 
4482         if (elementDeclHandler
) 
4483           handleDefault 
= XML_FALSE
; 
4485       groupConnector
[prologState
.level
] = ASCII_PIPE
; 
4487     case XML_ROLE_PARAM_ENTITY_REF
: 
4489     case XML_ROLE_INNER_PARAM_ENTITY_REF
: 
4490       dtd
->hasParamEntityRefs 
= XML_TRUE
; 
4491       if (!paramEntityParsing
) 
4492         dtd
->keepProcessing 
= dtd
->standalone
; 
4494         const XML_Char 
*name
; 
4496         name 
= poolStoreString(&dtd
->pool
, enc
, 
4497                                 s 
+ enc
->minBytesPerChar
, 
4498                                 next 
- enc
->minBytesPerChar
); 
4500           return XML_ERROR_NO_MEMORY
; 
4501         entity 
= (ENTITY 
*)lookup(parser
, &dtd
->paramEntities
, name
, 0); 
4502         poolDiscard(&dtd
->pool
); 
4503         /* first, determine if a check for an existing declaration is needed; 
4504            if yes, check that the entity exists, and that it is internal, 
4505            otherwise call the skipped entity handler 
4507         if (prologState
.documentEntity 
&& 
4509              ? !openInternalEntities
 
4510              : !dtd
->hasParamEntityRefs
)) { 
4512             return XML_ERROR_UNDEFINED_ENTITY
; 
4513           else if (!entity
->is_internal
) 
4514             return XML_ERROR_ENTITY_DECLARED_IN_PE
; 
4517           dtd
->keepProcessing 
= dtd
->standalone
; 
4518           /* cannot report skipped entities in declarations */ 
4519           if ((role 
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) { 
4520             skippedEntityHandler(handlerArg
, name
, 1); 
4521             handleDefault 
= XML_FALSE
; 
4526           return XML_ERROR_RECURSIVE_ENTITY_REF
; 
4527         if (entity
->textPtr
) { 
4528           enum XML_Error result
; 
4529           XML_Bool betweenDecl 
= 
4530             (role 
== XML_ROLE_PARAM_ENTITY_REF 
? XML_TRUE 
: XML_FALSE
); 
4531           result 
= processInternalEntity(parser
, entity
, betweenDecl
); 
4532           if (result 
!= XML_ERROR_NONE
) 
4534           handleDefault 
= XML_FALSE
; 
4537         if (externalEntityRefHandler
) { 
4538           dtd
->paramEntityRead 
= XML_FALSE
; 
4539           entity
->open 
= XML_TRUE
; 
4540           if (!externalEntityRefHandler(externalEntityRefHandlerArg
, 
4544                                         entity
->publicId
)) { 
4545             entity
->open 
= XML_FALSE
; 
4546             return XML_ERROR_EXTERNAL_ENTITY_HANDLING
; 
4548           entity
->open 
= XML_FALSE
; 
4549           handleDefault 
= XML_FALSE
; 
4550           if (!dtd
->paramEntityRead
) { 
4551             dtd
->keepProcessing 
= dtd
->standalone
; 
4556           dtd
->keepProcessing 
= dtd
->standalone
; 
4560 #endif /* XML_DTD */ 
4561       if (!dtd
->standalone 
&& 
4562           notStandaloneHandler 
&& 
4563           !notStandaloneHandler(handlerArg
)) 
4564         return XML_ERROR_NOT_STANDALONE
; 
4567     /* Element declaration stuff */ 
4569     case XML_ROLE_ELEMENT_NAME
: 
4570       if (elementDeclHandler
) { 
4571         declElementType 
= getElementType(parser
, enc
, s
, next
); 
4572         if (!declElementType
) 
4573           return XML_ERROR_NO_MEMORY
; 
4574         dtd
->scaffLevel 
= 0; 
4575         dtd
->scaffCount 
= 0; 
4576         dtd
->in_eldecl 
= XML_TRUE
; 
4577         handleDefault 
= XML_FALSE
; 
4581     case XML_ROLE_CONTENT_ANY
: 
4582     case XML_ROLE_CONTENT_EMPTY
: 
4583       if (dtd
->in_eldecl
) { 
4584         if (elementDeclHandler
) { 
4585           XML_Content 
* content 
= (XML_Content 
*) MALLOC(sizeof(XML_Content
)); 
4587             return XML_ERROR_NO_MEMORY
; 
4588           content
->quant 
= XML_CQUANT_NONE
; 
4589           content
->name 
= NULL
; 
4590           content
->numchildren 
= 0; 
4591           content
->children 
= NULL
; 
4592           content
->type 
= ((role 
== XML_ROLE_CONTENT_ANY
) ? 
4596           elementDeclHandler(handlerArg
, declElementType
->name
, content
); 
4597           handleDefault 
= XML_FALSE
; 
4599         dtd
->in_eldecl 
= XML_FALSE
; 
4603     case XML_ROLE_CONTENT_PCDATA
: 
4604       if (dtd
->in_eldecl
) { 
4605         dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel 
- 1]].type
 
4607         if (elementDeclHandler
) 
4608           handleDefault 
= XML_FALSE
; 
4612     case XML_ROLE_CONTENT_ELEMENT
: 
4613       quant 
= XML_CQUANT_NONE
; 
4614       goto elementContent
; 
4615     case XML_ROLE_CONTENT_ELEMENT_OPT
: 
4616       quant 
= XML_CQUANT_OPT
; 
4617       goto elementContent
; 
4618     case XML_ROLE_CONTENT_ELEMENT_REP
: 
4619       quant 
= XML_CQUANT_REP
; 
4620       goto elementContent
; 
4621     case XML_ROLE_CONTENT_ELEMENT_PLUS
: 
4622       quant 
= XML_CQUANT_PLUS
; 
4624       if (dtd
->in_eldecl
) { 
4626         const XML_Char 
*name
; 
4628         const char *nxt 
= (quant 
== XML_CQUANT_NONE
 
4630                            : next 
- enc
->minBytesPerChar
); 
4631         int myindex 
= nextScaffoldPart(parser
); 
4633           return XML_ERROR_NO_MEMORY
; 
4634         dtd
->scaffold
[myindex
].type 
= XML_CTYPE_NAME
; 
4635         dtd
->scaffold
[myindex
].quant 
= quant
; 
4636         el 
= getElementType(parser
, enc
, s
, nxt
); 
4638           return XML_ERROR_NO_MEMORY
; 
4640         dtd
->scaffold
[myindex
].name 
= name
; 
4642         for (; name
[nameLen
++]; ) 
4644         dtd
->contentStringLen 
+=  nameLen
; 
4645         if (elementDeclHandler
) 
4646           handleDefault 
= XML_FALSE
; 
4650     case XML_ROLE_GROUP_CLOSE
: 
4651       quant 
= XML_CQUANT_NONE
; 
4653     case XML_ROLE_GROUP_CLOSE_OPT
: 
4654       quant 
= XML_CQUANT_OPT
; 
4656     case XML_ROLE_GROUP_CLOSE_REP
: 
4657       quant 
= XML_CQUANT_REP
; 
4659     case XML_ROLE_GROUP_CLOSE_PLUS
: 
4660       quant 
= XML_CQUANT_PLUS
; 
4662       if (dtd
->in_eldecl
) { 
4663         if (elementDeclHandler
) 
4664           handleDefault 
= XML_FALSE
; 
4666         dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant 
= quant
; 
4667         if (dtd
->scaffLevel 
== 0) { 
4668           if (!handleDefault
) { 
4669             XML_Content 
*model 
= build_model(parser
); 
4671               return XML_ERROR_NO_MEMORY
; 
4673             elementDeclHandler(handlerArg
, declElementType
->name
, model
); 
4675           dtd
->in_eldecl 
= XML_FALSE
; 
4676           dtd
->contentStringLen 
= 0; 
4680       /* End element declaration stuff */ 
4683       if (!reportProcessingInstruction(parser
, enc
, s
, next
)) 
4684         return XML_ERROR_NO_MEMORY
; 
4685       handleDefault 
= XML_FALSE
; 
4687     case XML_ROLE_COMMENT
: 
4688       if (!reportComment(parser
, enc
, s
, next
)) 
4689         return XML_ERROR_NO_MEMORY
; 
4690       handleDefault 
= XML_FALSE
; 
4695         handleDefault 
= XML_FALSE
; 
4699     case XML_ROLE_DOCTYPE_NONE
: 
4700       if (startDoctypeDeclHandler
) 
4701         handleDefault 
= XML_FALSE
; 
4703     case XML_ROLE_ENTITY_NONE
: 
4704       if (dtd
->keepProcessing 
&& entityDeclHandler
) 
4705         handleDefault 
= XML_FALSE
; 
4707     case XML_ROLE_NOTATION_NONE
: 
4708       if (notationDeclHandler
) 
4709         handleDefault 
= XML_FALSE
; 
4711     case XML_ROLE_ATTLIST_NONE
: 
4712       if (dtd
->keepProcessing 
&& attlistDeclHandler
) 
4713         handleDefault 
= XML_FALSE
; 
4715     case XML_ROLE_ELEMENT_NONE
: 
4716       if (elementDeclHandler
) 
4717         handleDefault 
= XML_FALSE
; 
4719     } /* end of big switch */ 
4721     if (handleDefault 
&& defaultHandler
) 
4722       reportDefault(parser
, enc
, s
, next
); 
4724     switch (ps_parsing
) { 
4727       return XML_ERROR_NONE
; 
4729       return XML_ERROR_ABORTED
; 
4732       tok 
= XmlPrologTok(enc
, s
, end
, &next
); 
4738 static enum XML_Error PTRCALL
 
4739 epilogProcessor(XML_Parser parser
, 
4742                 const char **nextPtr
) 
4744   processor 
= epilogProcessor
; 
4747     const char *next 
= NULL
; 
4748     int tok 
= XmlPrologTok(encoding
, s
, end
, &next
); 
4751     /* report partial linebreak - it might be the last token */ 
4752     case -XML_TOK_PROLOG_S
: 
4753       if (defaultHandler
) { 
4754         reportDefault(parser
, encoding
, s
, next
); 
4755         if (ps_parsing 
== XML_FINISHED
) 
4756           return XML_ERROR_ABORTED
; 
4759       return XML_ERROR_NONE
; 
4762       return XML_ERROR_NONE
; 
4763     case XML_TOK_PROLOG_S
: 
4765         reportDefault(parser
, encoding
, s
, next
); 
4768       if (!reportProcessingInstruction(parser
, encoding
, s
, next
)) 
4769         return XML_ERROR_NO_MEMORY
; 
4771     case XML_TOK_COMMENT
: 
4772       if (!reportComment(parser
, encoding
, s
, next
)) 
4773         return XML_ERROR_NO_MEMORY
; 
4775     case XML_TOK_INVALID
: 
4777       return XML_ERROR_INVALID_TOKEN
; 
4778     case XML_TOK_PARTIAL
: 
4779       if (!ps_finalBuffer
) { 
4781         return XML_ERROR_NONE
; 
4783       return XML_ERROR_UNCLOSED_TOKEN
; 
4784     case XML_TOK_PARTIAL_CHAR
: 
4785       if (!ps_finalBuffer
) { 
4787         return XML_ERROR_NONE
; 
4789       return XML_ERROR_PARTIAL_CHAR
; 
4791       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
; 
4793     eventPtr 
= s 
= next
; 
4794     switch (ps_parsing
) { 
4797       return XML_ERROR_NONE
; 
4799       return XML_ERROR_ABORTED
; 
4805 static enum XML_Error
 
4806 processInternalEntity(XML_Parser parser
, ENTITY 
*entity
, 
4807                       XML_Bool betweenDecl
) 
4809   const char *textStart
, *textEnd
; 
4811   enum XML_Error result
; 
4812   OPEN_INTERNAL_ENTITY 
*openEntity
; 
4814   if (freeInternalEntities
) { 
4815     openEntity 
= freeInternalEntities
; 
4816     freeInternalEntities 
= openEntity
->next
; 
4819     openEntity 
= (OPEN_INTERNAL_ENTITY 
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
)); 
4821       return XML_ERROR_NO_MEMORY
; 
4823   entity
->open 
= XML_TRUE
; 
4824   entity
->processed 
= 0; 
4825   openEntity
->next 
= openInternalEntities
; 
4826   openInternalEntities 
= openEntity
; 
4827   openEntity
->entity 
= entity
; 
4828   openEntity
->startTagLevel 
= tagLevel
; 
4829   openEntity
->betweenDecl 
= betweenDecl
; 
4830   openEntity
->internalEventPtr 
= NULL
; 
4831   openEntity
->internalEventEndPtr 
= NULL
; 
4832   textStart 
= (char *)entity
->textPtr
; 
4833   textEnd 
= (char *)(entity
->textPtr 
+ entity
->textLen
); 
4836   if (entity
->is_param
) { 
4837     int tok 
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
); 
4838     result 
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
, 
4839                       next
, &next
, XML_FALSE
); 
4842 #endif /* XML_DTD */ 
4843     result 
= doContent(parser
, tagLevel
, internalEncoding
, textStart
, 
4844                        textEnd
, &next
, XML_FALSE
); 
4846   if (result 
== XML_ERROR_NONE
) { 
4847     if (textEnd 
!= next 
&& ps_parsing 
== XML_SUSPENDED
) { 
4848       entity
->processed 
= (int)(next 
- textStart
); 
4849       processor 
= internalEntityProcessor
; 
4852       entity
->open 
= XML_FALSE
; 
4853       openInternalEntities 
= openEntity
->next
; 
4854       /* put openEntity back in list of free instances */ 
4855       openEntity
->next 
= freeInternalEntities
; 
4856       freeInternalEntities 
= openEntity
; 
4862 static enum XML_Error PTRCALL
 
4863 internalEntityProcessor(XML_Parser parser
, 
4866                         const char **nextPtr
) 
4869   const char *textStart
, *textEnd
; 
4871   enum XML_Error result
; 
4872   OPEN_INTERNAL_ENTITY 
*openEntity 
= openInternalEntities
; 
4874     return XML_ERROR_UNEXPECTED_STATE
; 
4876   entity 
= openEntity
->entity
; 
4877   textStart 
= ((char *)entity
->textPtr
) + entity
->processed
; 
4878   textEnd 
= (char *)(entity
->textPtr 
+ entity
->textLen
); 
4881   if (entity
->is_param
) { 
4882     int tok 
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
); 
4883     result 
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
, 
4884                       next
, &next
, XML_FALSE
); 
4887 #endif /* XML_DTD */ 
4888     result 
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
, 
4889                        textStart
, textEnd
, &next
, XML_FALSE
); 
4891   if (result 
!= XML_ERROR_NONE
) 
4893   else if (textEnd 
!= next 
&& ps_parsing 
== XML_SUSPENDED
) { 
4894     entity
->processed 
= (int)(next 
- (char *)entity
->textPtr
); 
4898     entity
->open 
= XML_FALSE
; 
4899     openInternalEntities 
= openEntity
->next
; 
4900     /* put openEntity back in list of free instances */ 
4901     openEntity
->next 
= freeInternalEntities
; 
4902     freeInternalEntities 
= openEntity
; 
4906   if (entity
->is_param
) { 
4908     processor 
= prologProcessor
; 
4909     tok 
= XmlPrologTok(encoding
, s
, end
, &next
); 
4910     return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
, 
4911                     (XML_Bool
)!ps_finalBuffer
); 
4914 #endif /* XML_DTD */ 
4916     processor 
= contentProcessor
; 
4917     /* see externalEntityContentProcessor vs contentProcessor */ 
4918     return doContent(parser
, parentParser 
? 1 : 0, encoding
, s
, end
, 
4919                      nextPtr
, (XML_Bool
)!ps_finalBuffer
); 
4923 static enum XML_Error PTRCALL
 
4924 errorProcessor(XML_Parser parser
, 
4927                const char **nextPtr
) 
4932 static enum XML_Error
 
4933 storeAttributeValue(XML_Parser parser
, const ENCODING 
*enc
, XML_Bool isCdata
, 
4934                     const char *ptr
, const char *end
, 
4937   enum XML_Error result 
= appendAttributeValue(parser
, enc
, isCdata
, ptr
, 
4941   if (!isCdata 
&& poolLength(pool
) && poolLastChar(pool
) == 0x20) 
4943   if (!poolAppendChar(pool
, XML_T('\0'))) 
4944     return XML_ERROR_NO_MEMORY
; 
4945   return XML_ERROR_NONE
; 
4948 static enum XML_Error
 
4949 appendAttributeValue(XML_Parser parser
, const ENCODING 
*enc
, XML_Bool isCdata
, 
4950                      const char *ptr
, const char *end
, 
4953   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
4956     int tok 
= XmlAttributeValueTok(enc
, ptr
, end
, &next
); 
4959       return XML_ERROR_NONE
; 
4960     case XML_TOK_INVALID
: 
4961       if (enc 
== encoding
) 
4963       return XML_ERROR_INVALID_TOKEN
; 
4964     case XML_TOK_PARTIAL
: 
4965       if (enc 
== encoding
) 
4967       return XML_ERROR_INVALID_TOKEN
; 
4968     case XML_TOK_CHAR_REF
: 
4970         XML_Char buf
[XML_ENCODE_MAX
]; 
4972         int n 
= XmlCharRefNumber(enc
, ptr
); 
4974           if (enc 
== encoding
) 
4976           return XML_ERROR_BAD_CHAR_REF
; 
4979             && n 
== 0x20 /* space */ 
4980             && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20)) 
4982         n 
= XmlEncode(n
, (ICHAR 
*)buf
); 
4984           if (enc 
== encoding
) 
4986           return XML_ERROR_BAD_CHAR_REF
; 
4988         for (i 
= 0; i 
< n
; i
++) { 
4989           if (!poolAppendChar(pool
, buf
[i
])) 
4990             return XML_ERROR_NO_MEMORY
; 
4994     case XML_TOK_DATA_CHARS
: 
4995       if (!poolAppend(pool
, enc
, ptr
, next
)) 
4996         return XML_ERROR_NO_MEMORY
; 
4998     case XML_TOK_TRAILING_CR
: 
4999       next 
= ptr 
+ enc
->minBytesPerChar
; 
5001     case XML_TOK_ATTRIBUTE_VALUE_S
: 
5002     case XML_TOK_DATA_NEWLINE
: 
5003       if (!isCdata 
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20)) 
5005       if (!poolAppendChar(pool
, 0x20)) 
5006         return XML_ERROR_NO_MEMORY
; 
5008     case XML_TOK_ENTITY_REF
: 
5010         const XML_Char 
*name
; 
5012         char checkEntityDecl
; 
5013         XML_Char ch 
= (XML_Char
) XmlPredefinedEntityName(enc
, 
5014                                               ptr 
+ enc
->minBytesPerChar
, 
5015                                               next 
- enc
->minBytesPerChar
); 
5017           if (!poolAppendChar(pool
, ch
)) 
5018                 return XML_ERROR_NO_MEMORY
; 
5021         name 
= poolStoreString(&temp2Pool
, enc
, 
5022                                ptr 
+ enc
->minBytesPerChar
, 
5023                                next 
- enc
->minBytesPerChar
); 
5025           return XML_ERROR_NO_MEMORY
; 
5026         entity 
= (ENTITY 
*)lookup(parser
, &dtd
->generalEntities
, name
, 0); 
5027         poolDiscard(&temp2Pool
); 
5028         /* First, determine if a check for an existing declaration is needed; 
5029            if yes, check that the entity exists, and that it is internal. 
5031         if (pool 
== &dtd
->pool
)  /* are we called from prolog? */ 
5034               prologState
.documentEntity 
&& 
5035 #endif /* XML_DTD */ 
5037                ? !openInternalEntities
 
5038                : !dtd
->hasParamEntityRefs
); 
5039         else /* if (pool == &tempPool): we are called from content */ 
5040           checkEntityDecl 
= !dtd
->hasParamEntityRefs 
|| dtd
->standalone
; 
5041         if (checkEntityDecl
) { 
5043             return XML_ERROR_UNDEFINED_ENTITY
; 
5044           else if (!entity
->is_internal
) 
5045             return XML_ERROR_ENTITY_DECLARED_IN_PE
; 
5048           /* Cannot report skipped entity here - see comments on 
5049              skippedEntityHandler. 
5050           if (skippedEntityHandler) 
5051             skippedEntityHandler(handlerArg, name, 0); 
5053           /* Cannot call the default handler because this would be 
5054              out of sync with the call to the startElementHandler. 
5055           if ((pool == &tempPool) && defaultHandler) 
5056             reportDefault(parser, enc, ptr, next); 
5061           if (enc 
== encoding
) 
5063           return XML_ERROR_RECURSIVE_ENTITY_REF
; 
5065         if (entity
->notation
) { 
5066           if (enc 
== encoding
) 
5068           return XML_ERROR_BINARY_ENTITY_REF
; 
5070         if (!entity
->textPtr
) { 
5071           if (enc 
== encoding
) 
5073           return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
; 
5076           enum XML_Error result
; 
5077           const XML_Char 
*textEnd 
= entity
->textPtr 
+ entity
->textLen
; 
5078           entity
->open 
= XML_TRUE
; 
5079           result 
= appendAttributeValue(parser
, internalEncoding
, isCdata
, 
5080                                         (char *)entity
->textPtr
, 
5081                                         (char *)textEnd
, pool
); 
5082           entity
->open 
= XML_FALSE
; 
5089       if (enc 
== encoding
) 
5091       return XML_ERROR_UNEXPECTED_STATE
; 
5098 static enum XML_Error
 
5099 storeEntityValue(XML_Parser parser
, 
5100                  const ENCODING 
*enc
, 
5101                  const char *entityTextPtr
, 
5102                  const char *entityTextEnd
) 
5104   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
5105   STRING_POOL 
*pool 
= &(dtd
->entityValuePool
); 
5106   enum XML_Error result 
= XML_ERROR_NONE
; 
5108   int oldInEntityValue 
= prologState
.inEntityValue
; 
5109   prologState
.inEntityValue 
= 1; 
5110 #endif /* XML_DTD */ 
5111   /* never return Null for the value argument in EntityDeclHandler, 
5112      since this would indicate an external entity; therefore we 
5113      have to make sure that entityValuePool.start is not null */ 
5114   if (!pool
->blocks
) { 
5115     if (!poolGrow(pool
)) 
5116       return XML_ERROR_NO_MEMORY
; 
5121     int tok 
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
); 
5123     case XML_TOK_PARAM_ENTITY_REF
: 
5125       if (isParamEntity 
|| enc 
!= encoding
) { 
5126         const XML_Char 
*name
; 
5128         name 
= poolStoreString(&tempPool
, enc
, 
5129                                entityTextPtr 
+ enc
->minBytesPerChar
, 
5130                                next 
- enc
->minBytesPerChar
); 
5132           result 
= XML_ERROR_NO_MEMORY
; 
5133           goto endEntityValue
; 
5135         entity 
= (ENTITY 
*)lookup(parser
, &dtd
->paramEntities
, name
, 0); 
5136         poolDiscard(&tempPool
); 
5138           /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ 
5139           /* cannot report skipped entity here - see comments on 
5140              skippedEntityHandler 
5141           if (skippedEntityHandler) 
5142             skippedEntityHandler(handlerArg, name, 0); 
5144           dtd
->keepProcessing 
= dtd
->standalone
; 
5145           goto endEntityValue
; 
5148           if (enc 
== encoding
) 
5149             eventPtr 
= entityTextPtr
; 
5150           result 
= XML_ERROR_RECURSIVE_ENTITY_REF
; 
5151           goto endEntityValue
; 
5153         if (entity
->systemId
) { 
5154           if (externalEntityRefHandler
) { 
5155             dtd
->paramEntityRead 
= XML_FALSE
; 
5156             entity
->open 
= XML_TRUE
; 
5157             if (!externalEntityRefHandler(externalEntityRefHandlerArg
, 
5161                                           entity
->publicId
)) { 
5162               entity
->open 
= XML_FALSE
; 
5163               result 
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
; 
5164               goto endEntityValue
; 
5166             entity
->open 
= XML_FALSE
; 
5167             if (!dtd
->paramEntityRead
) 
5168               dtd
->keepProcessing 
= dtd
->standalone
; 
5171             dtd
->keepProcessing 
= dtd
->standalone
; 
5174           entity
->open 
= XML_TRUE
; 
5175           result 
= storeEntityValue(parser
, 
5177                                     (char *)entity
->textPtr
, 
5178                                     (char *)(entity
->textPtr
 
5179                                              + entity
->textLen
)); 
5180           entity
->open 
= XML_FALSE
; 
5182             goto endEntityValue
; 
5186 #endif /* XML_DTD */ 
5187       /* In the internal subset, PE references are not legal 
5188          within markup declarations, e.g entity values in this case. */ 
5189       eventPtr 
= entityTextPtr
; 
5190       result 
= XML_ERROR_PARAM_ENTITY_REF
; 
5191       goto endEntityValue
; 
5193       result 
= XML_ERROR_NONE
; 
5194       goto endEntityValue
; 
5195     case XML_TOK_ENTITY_REF
: 
5196     case XML_TOK_DATA_CHARS
: 
5197       if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) { 
5198         result 
= XML_ERROR_NO_MEMORY
; 
5199         goto endEntityValue
; 
5202     case XML_TOK_TRAILING_CR
: 
5203       next 
= entityTextPtr 
+ enc
->minBytesPerChar
; 
5205     case XML_TOK_DATA_NEWLINE
: 
5206       if (pool
->end 
== pool
->ptr 
&& !poolGrow(pool
)) { 
5207               result 
= XML_ERROR_NO_MEMORY
; 
5208         goto endEntityValue
; 
5210       *(pool
->ptr
)++ = 0xA; 
5212     case XML_TOK_CHAR_REF
: 
5214         XML_Char buf
[XML_ENCODE_MAX
]; 
5216         int n 
= XmlCharRefNumber(enc
, entityTextPtr
); 
5218           if (enc 
== encoding
) 
5219             eventPtr 
= entityTextPtr
; 
5220           result 
= XML_ERROR_BAD_CHAR_REF
; 
5221           goto endEntityValue
; 
5223         n 
= XmlEncode(n
, (ICHAR 
*)buf
); 
5225           if (enc 
== encoding
) 
5226             eventPtr 
= entityTextPtr
; 
5227           result 
= XML_ERROR_BAD_CHAR_REF
; 
5228           goto endEntityValue
; 
5230         for (i 
= 0; i 
< n
; i
++) { 
5231           if (pool
->end 
== pool
->ptr 
&& !poolGrow(pool
)) { 
5232             result 
= XML_ERROR_NO_MEMORY
; 
5233             goto endEntityValue
; 
5235           *(pool
->ptr
)++ = buf
[i
]; 
5239     case XML_TOK_PARTIAL
: 
5240       if (enc 
== encoding
) 
5241         eventPtr 
= entityTextPtr
; 
5242       result 
= XML_ERROR_INVALID_TOKEN
; 
5243       goto endEntityValue
; 
5244     case XML_TOK_INVALID
: 
5245       if (enc 
== encoding
) 
5247       result 
= XML_ERROR_INVALID_TOKEN
; 
5248       goto endEntityValue
; 
5250       if (enc 
== encoding
) 
5251         eventPtr 
= entityTextPtr
; 
5252       result 
= XML_ERROR_UNEXPECTED_STATE
; 
5253       goto endEntityValue
; 
5255     entityTextPtr 
= next
; 
5259   prologState
.inEntityValue 
= oldInEntityValue
; 
5260 #endif /* XML_DTD */ 
5264 static void FASTCALL
 
5265 normalizeLines(XML_Char 
*s
) 
5269     if (*s 
== XML_T('\0')) 
5288 reportProcessingInstruction(XML_Parser parser
, const ENCODING 
*enc
, 
5289                             const char *start
, const char *end
) 
5291   const XML_Char 
*target
; 
5294   if (!processingInstructionHandler
) { 
5296       reportDefault(parser
, enc
, start
, end
); 
5299   start 
+= enc
->minBytesPerChar 
* 2; 
5300   tem 
= start 
+ XmlNameLength(enc
, start
); 
5301   target 
= poolStoreString(&tempPool
, enc
, start
, tem
); 
5304   poolFinish(&tempPool
); 
5305   data 
= poolStoreString(&tempPool
, enc
, 
5307                         end 
- enc
->minBytesPerChar
*2); 
5310   normalizeLines(data
); 
5311   processingInstructionHandler(handlerArg
, target
, data
); 
5312   poolClear(&tempPool
); 
5317 reportComment(XML_Parser parser
, const ENCODING 
*enc
, 
5318               const char *start
, const char *end
) 
5321   if (!commentHandler
) { 
5323       reportDefault(parser
, enc
, start
, end
); 
5326   data 
= poolStoreString(&tempPool
, 
5328                          start 
+ enc
->minBytesPerChar 
* 4, 
5329                          end 
- enc
->minBytesPerChar 
* 3); 
5332   normalizeLines(data
); 
5333   commentHandler(handlerArg
, data
); 
5334   poolClear(&tempPool
); 
5339 reportDefault(XML_Parser parser
, const ENCODING 
*enc
, 
5340               const char *s
, const char *end
) 
5342   if (MUST_CONVERT(enc
, s
)) { 
5343     const char **eventPP
; 
5344     const char **eventEndPP
; 
5345     if (enc 
== encoding
) { 
5346       eventPP 
= &eventPtr
; 
5347       eventEndPP 
= &eventEndPtr
; 
5350       eventPP 
= &(openInternalEntities
->internalEventPtr
); 
5351       eventEndPP 
= &(openInternalEntities
->internalEventEndPtr
); 
5354       ICHAR 
*dataPtr 
= (ICHAR 
*)dataBuf
; 
5355       XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR 
*)dataBufEnd
); 
5357       defaultHandler(handlerArg
, dataBuf
, (int)(dataPtr 
- (ICHAR 
*)dataBuf
)); 
5362     defaultHandler(handlerArg
, (XML_Char 
*)s
, (int)((XML_Char 
*)end 
- (XML_Char 
*)s
)); 
5367 defineAttribute(ELEMENT_TYPE 
*type
, ATTRIBUTE_ID 
*attId
, XML_Bool isCdata
, 
5368                 XML_Bool isId
, const XML_Char 
*value
, XML_Parser parser
) 
5370   DEFAULT_ATTRIBUTE 
*att
; 
5371   if (value 
|| isId
) { 
5372     /* The handling of default attributes gets messed up if we have 
5373        a default which duplicates a non-default. */ 
5375     for (i 
= 0; i 
< type
->nDefaultAtts
; i
++) 
5376       if (attId 
== type
->defaultAtts
[i
].id
) 
5378     if (isId 
&& !type
->idAtt 
&& !attId
->xmlns
) 
5379       type
->idAtt 
= attId
; 
5381   if (type
->nDefaultAtts 
== type
->allocDefaultAtts
) { 
5382     if (type
->allocDefaultAtts 
== 0) { 
5383       type
->allocDefaultAtts 
= 8; 
5384       type
->defaultAtts 
= (DEFAULT_ATTRIBUTE 
*)MALLOC(type
->allocDefaultAtts
 
5385                             * sizeof(DEFAULT_ATTRIBUTE
)); 
5386       if (!type
->defaultAtts
) 
5390       DEFAULT_ATTRIBUTE 
*temp
; 
5391       int count 
= type
->allocDefaultAtts 
* 2; 
5392       temp 
= (DEFAULT_ATTRIBUTE 
*) 
5393         REALLOC(type
->defaultAtts
, (count 
* sizeof(DEFAULT_ATTRIBUTE
))); 
5396       type
->allocDefaultAtts 
= count
; 
5397       type
->defaultAtts 
= temp
; 
5400   att 
= type
->defaultAtts 
+ type
->nDefaultAtts
; 
5403   att
->isCdata 
= isCdata
; 
5405     attId
->maybeTokenized 
= XML_TRUE
; 
5406   type
->nDefaultAtts 
+= 1; 
5411 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE 
*elementType
) 
5413   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
5414   const XML_Char 
*name
; 
5415   for (name 
= elementType
->name
; *name
; name
++) { 
5416     if (*name 
== XML_T(ASCII_COLON
)) { 
5419       for (s 
= elementType
->name
; s 
!= name
; s
++) { 
5420         if (!poolAppendChar(&dtd
->pool
, *s
)) 
5423       if (!poolAppendChar(&dtd
->pool
, XML_T('\0'))) 
5425       prefix 
= (PREFIX 
*)lookup(parser
, &dtd
->prefixes
, poolStart(&dtd
->pool
), 
5429       if (prefix
->name 
== poolStart(&dtd
->pool
)) 
5430         poolFinish(&dtd
->pool
); 
5432         poolDiscard(&dtd
->pool
); 
5433       elementType
->prefix 
= prefix
; 
5440 static ATTRIBUTE_ID 
* 
5441 getAttributeId(XML_Parser parser
, const ENCODING 
*enc
, 
5442                const char *start
, const char *end
) 
5444   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
5446   const XML_Char 
*name
; 
5447   if (!poolAppendChar(&dtd
->pool
, XML_T('\0'))) 
5449   name 
= poolStoreString(&dtd
->pool
, enc
, start
, end
); 
5452   /* skip quotation mark - its storage will be re-used (like in name[-1]) */ 
5454   id 
= (ATTRIBUTE_ID 
*)lookup(parser
, &dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
)); 
5457   if (id
->name 
!= name
) 
5458     poolDiscard(&dtd
->pool
); 
5460     poolFinish(&dtd
->pool
); 
5463     else if (name
[0] == XML_T(ASCII_x
) 
5464         && name
[1] == XML_T(ASCII_m
) 
5465         && name
[2] == XML_T(ASCII_l
) 
5466         && name
[3] == XML_T(ASCII_n
) 
5467         && name
[4] == XML_T(ASCII_s
) 
5468         && (name
[5] == XML_T('\0') || name
[5] == XML_T(ASCII_COLON
))) { 
5469       if (name
[5] == XML_T('\0')) 
5470         id
->prefix 
= &dtd
->defaultPrefix
; 
5472         id
->prefix 
= (PREFIX 
*)lookup(parser
, &dtd
->prefixes
, name 
+ 6, sizeof(PREFIX
)); 
5473       id
->xmlns 
= XML_TRUE
; 
5477       for (i 
= 0; name
[i
]; i
++) { 
5478         /* attributes without prefix are *not* in the default namespace */ 
5479         if (name
[i
] == XML_T(ASCII_COLON
)) { 
5481           for (j 
= 0; j 
< i
; j
++) { 
5482             if (!poolAppendChar(&dtd
->pool
, name
[j
])) 
5485           if (!poolAppendChar(&dtd
->pool
, XML_T('\0'))) 
5487           id
->prefix 
= (PREFIX 
*)lookup(parser
, &dtd
->prefixes
, poolStart(&dtd
->pool
), 
5489           if (id
->prefix
->name 
== poolStart(&dtd
->pool
)) 
5490             poolFinish(&dtd
->pool
); 
5492             poolDiscard(&dtd
->pool
); 
5501 #define CONTEXT_SEP XML_T(ASCII_FF) 
5503 static const XML_Char 
* 
5504 getContext(XML_Parser parser
) 
5506   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
5507   HASH_TABLE_ITER iter
; 
5508   XML_Bool needSep 
= XML_FALSE
; 
5510   if (dtd
->defaultPrefix
.binding
) { 
5513     if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
))) 
5515     len 
= dtd
->defaultPrefix
.binding
->uriLen
; 
5516     if (namespaceSeparator
) 
5518     for (i 
= 0; i 
< len
; i
++) 
5519       if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
])) 
5524   hashTableIterInit(&iter
, &(dtd
->prefixes
)); 
5529     PREFIX 
*prefix 
= (PREFIX 
*)hashTableIterNext(&iter
); 
5532     if (!prefix
->binding
) 
5534     if (needSep 
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
)) 
5536     for (s 
= prefix
->name
; *s
; s
++) 
5537       if (!poolAppendChar(&tempPool
, *s
)) 
5539     if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
))) 
5541     len 
= prefix
->binding
->uriLen
; 
5542     if (namespaceSeparator
) 
5544     for (i 
= 0; i 
< len
; i
++) 
5545       if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
])) 
5551   hashTableIterInit(&iter
, &(dtd
->generalEntities
)); 
5554     ENTITY 
*e 
= (ENTITY 
*)hashTableIterNext(&iter
); 
5559     if (needSep 
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
)) 
5561     for (s 
= e
->name
; *s
; s
++) 
5562       if (!poolAppendChar(&tempPool
, *s
)) 
5567   if (!poolAppendChar(&tempPool
, XML_T('\0'))) 
5569   return tempPool
.start
; 
5573 setContext(XML_Parser parser
, const XML_Char 
*context
) 
5575   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
5576   const XML_Char 
*s 
= context
; 
5578   while (*context 
!= XML_T('\0')) { 
5579     if (*s 
== CONTEXT_SEP 
|| *s 
== XML_T('\0')) { 
5581       if (!poolAppendChar(&tempPool
, XML_T('\0'))) 
5583       e 
= (ENTITY 
*)lookup(parser
, &dtd
->generalEntities
, poolStart(&tempPool
), 0); 
5586       if (*s 
!= XML_T('\0')) 
5589       poolDiscard(&tempPool
); 
5591     else if (*s 
== XML_T(ASCII_EQUALS
)) { 
5593       if (poolLength(&tempPool
) == 0) 
5594         prefix 
= &dtd
->defaultPrefix
; 
5596         if (!poolAppendChar(&tempPool
, XML_T('\0'))) 
5598         prefix 
= (PREFIX 
*)lookup(parser
, &dtd
->prefixes
, poolStart(&tempPool
), 
5602         if (prefix
->name 
== poolStart(&tempPool
)) { 
5603           prefix
->name 
= poolCopyString(&dtd
->pool
, prefix
->name
); 
5607         poolDiscard(&tempPool
); 
5609       for (context 
= s 
+ 1; 
5610            *context 
!= CONTEXT_SEP 
&& *context 
!= XML_T('\0'); 
5612         if (!poolAppendChar(&tempPool
, *context
)) 
5614       if (!poolAppendChar(&tempPool
, XML_T('\0'))) 
5616       if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
), 
5617                      &inheritedBindings
) != XML_ERROR_NONE
) 
5619       poolDiscard(&tempPool
); 
5620       if (*context 
!= XML_T('\0')) 
5625       if (!poolAppendChar(&tempPool
, *s
)) 
5633 static void FASTCALL
 
5634 normalizePublicId(XML_Char 
*publicId
) 
5636   XML_Char 
*p 
= publicId
; 
5638   for (s 
= publicId
; *s
; s
++) { 
5643       if (p 
!= publicId 
&& p
[-1] != 0x20) 
5650   if (p 
!= publicId 
&& p
[-1] == 0x20) 
5656 dtdCreate(const XML_Memory_Handling_Suite 
*ms
) 
5658   DTD 
*p 
= (DTD 
*)ms
->malloc_fcn(sizeof(DTD
)); 
5661   poolInit(&(p
->pool
), ms
); 
5662   poolInit(&(p
->entityValuePool
), ms
); 
5663   hashTableInit(&(p
->generalEntities
), ms
); 
5664   hashTableInit(&(p
->elementTypes
), ms
); 
5665   hashTableInit(&(p
->attributeIds
), ms
); 
5666   hashTableInit(&(p
->prefixes
), ms
); 
5668   p
->paramEntityRead 
= XML_FALSE
; 
5669   hashTableInit(&(p
->paramEntities
), ms
); 
5670 #endif /* XML_DTD */ 
5671   p
->defaultPrefix
.name 
= NULL
; 
5672   p
->defaultPrefix
.binding 
= NULL
; 
5674   p
->in_eldecl 
= XML_FALSE
; 
5675   p
->scaffIndex 
= NULL
; 
5680   p
->contentStringLen 
= 0; 
5682   p
->keepProcessing 
= XML_TRUE
; 
5683   p
->hasParamEntityRefs 
= XML_FALSE
; 
5684   p
->standalone 
= XML_FALSE
; 
5689 dtdReset(DTD 
*p
, const XML_Memory_Handling_Suite 
*ms
) 
5691   HASH_TABLE_ITER iter
; 
5692   hashTableIterInit(&iter
, &(p
->elementTypes
)); 
5694     ELEMENT_TYPE 
*e 
= (ELEMENT_TYPE 
*)hashTableIterNext(&iter
); 
5697     if (e
->allocDefaultAtts 
!= 0) 
5698       ms
->free_fcn(e
->defaultAtts
); 
5700   hashTableClear(&(p
->generalEntities
)); 
5702   p
->paramEntityRead 
= XML_FALSE
; 
5703   hashTableClear(&(p
->paramEntities
)); 
5704 #endif /* XML_DTD */ 
5705   hashTableClear(&(p
->elementTypes
)); 
5706   hashTableClear(&(p
->attributeIds
)); 
5707   hashTableClear(&(p
->prefixes
)); 
5708   poolClear(&(p
->pool
)); 
5709   poolClear(&(p
->entityValuePool
)); 
5710   p
->defaultPrefix
.name 
= NULL
; 
5711   p
->defaultPrefix
.binding 
= NULL
; 
5713   p
->in_eldecl 
= XML_FALSE
; 
5715   ms
->free_fcn(p
->scaffIndex
); 
5716   p
->scaffIndex 
= NULL
; 
5717   ms
->free_fcn(p
->scaffold
); 
5723   p
->contentStringLen 
= 0; 
5725   p
->keepProcessing 
= XML_TRUE
; 
5726   p
->hasParamEntityRefs 
= XML_FALSE
; 
5727   p
->standalone 
= XML_FALSE
; 
5731 dtdDestroy(DTD 
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite 
*ms
) 
5733   HASH_TABLE_ITER iter
; 
5734   hashTableIterInit(&iter
, &(p
->elementTypes
)); 
5736     ELEMENT_TYPE 
*e 
= (ELEMENT_TYPE 
*)hashTableIterNext(&iter
); 
5739     if (e
->allocDefaultAtts 
!= 0) 
5740       ms
->free_fcn(e
->defaultAtts
); 
5742   hashTableDestroy(&(p
->generalEntities
)); 
5744   hashTableDestroy(&(p
->paramEntities
)); 
5745 #endif /* XML_DTD */ 
5746   hashTableDestroy(&(p
->elementTypes
)); 
5747   hashTableDestroy(&(p
->attributeIds
)); 
5748   hashTableDestroy(&(p
->prefixes
)); 
5749   poolDestroy(&(p
->pool
)); 
5750   poolDestroy(&(p
->entityValuePool
)); 
5752     ms
->free_fcn(p
->scaffIndex
); 
5753     ms
->free_fcn(p
->scaffold
); 
5758 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. 
5759    The new DTD has already been initialized. 
5762 dtdCopy(XML_Parser oldParser
, DTD 
*newDtd
, const DTD 
*oldDtd
, const XML_Memory_Handling_Suite 
*ms
) 
5764   HASH_TABLE_ITER iter
; 
5766   /* Copy the prefix table. */ 
5768   hashTableIterInit(&iter
, &(oldDtd
->prefixes
)); 
5770     const XML_Char 
*name
; 
5771     const PREFIX 
*oldP 
= (PREFIX 
*)hashTableIterNext(&iter
); 
5774     name 
= poolCopyString(&(newDtd
->pool
), oldP
->name
); 
5777     if (!lookup(oldParser
, &(newDtd
->prefixes
), name
, sizeof(PREFIX
))) 
5781   hashTableIterInit(&iter
, &(oldDtd
->attributeIds
)); 
5783   /* Copy the attribute id table. */ 
5787     const XML_Char 
*name
; 
5788     const ATTRIBUTE_ID 
*oldA 
= (ATTRIBUTE_ID 
*)hashTableIterNext(&iter
); 
5792     /* Remember to allocate the scratch byte before the name. */ 
5793     if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0'))) 
5795     name 
= poolCopyString(&(newDtd
->pool
), oldA
->name
); 
5799     newA 
= (ATTRIBUTE_ID 
*)lookup(oldParser
, &(newDtd
->attributeIds
), name
, 
5800                                   sizeof(ATTRIBUTE_ID
)); 
5803     newA
->maybeTokenized 
= oldA
->maybeTokenized
; 
5805       newA
->xmlns 
= oldA
->xmlns
; 
5806       if (oldA
->prefix 
== &oldDtd
->defaultPrefix
) 
5807         newA
->prefix 
= &newDtd
->defaultPrefix
; 
5809         newA
->prefix 
= (PREFIX 
*)lookup(oldParser
, &(newDtd
->prefixes
), 
5810                                         oldA
->prefix
->name
, 0); 
5814   /* Copy the element type table. */ 
5816   hashTableIterInit(&iter
, &(oldDtd
->elementTypes
)); 
5821     const XML_Char 
*name
; 
5822     const ELEMENT_TYPE 
*oldE 
= (ELEMENT_TYPE 
*)hashTableIterNext(&iter
); 
5825     name 
= poolCopyString(&(newDtd
->pool
), oldE
->name
); 
5828     newE 
= (ELEMENT_TYPE 
*)lookup(oldParser
, &(newDtd
->elementTypes
), name
, 
5829                                   sizeof(ELEMENT_TYPE
)); 
5832     if (oldE
->nDefaultAtts
) { 
5833       newE
->defaultAtts 
= (DEFAULT_ATTRIBUTE 
*) 
5834           ms
->malloc_fcn(oldE
->nDefaultAtts 
* sizeof(DEFAULT_ATTRIBUTE
)); 
5835       if (!newE
->defaultAtts
) { 
5841       newE
->idAtt 
= (ATTRIBUTE_ID 
*) 
5842           lookup(oldParser
, &(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0); 
5843     newE
->allocDefaultAtts 
= newE
->nDefaultAtts 
= oldE
->nDefaultAtts
; 
5845       newE
->prefix 
= (PREFIX 
*)lookup(oldParser
, &(newDtd
->prefixes
), 
5846                                       oldE
->prefix
->name
, 0); 
5847     for (i 
= 0; i 
< newE
->nDefaultAtts
; i
++) { 
5848       newE
->defaultAtts
[i
].id 
= (ATTRIBUTE_ID 
*) 
5849           lookup(oldParser
, &(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0); 
5850       newE
->defaultAtts
[i
].isCdata 
= oldE
->defaultAtts
[i
].isCdata
; 
5851       if (oldE
->defaultAtts
[i
].value
) { 
5852         newE
->defaultAtts
[i
].value
 
5853             = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
); 
5854         if (!newE
->defaultAtts
[i
].value
) 
5858         newE
->defaultAtts
[i
].value 
= NULL
; 
5862   /* Copy the entity tables. */ 
5863   if (!copyEntityTable(oldParser
, 
5864                        &(newDtd
->generalEntities
), 
5866                        &(oldDtd
->generalEntities
))) 
5870   if (!copyEntityTable(oldParser
, 
5871                        &(newDtd
->paramEntities
), 
5873                        &(oldDtd
->paramEntities
))) 
5875   newDtd
->paramEntityRead 
= oldDtd
->paramEntityRead
; 
5876 #endif /* XML_DTD */ 
5878   newDtd
->keepProcessing 
= oldDtd
->keepProcessing
; 
5879   newDtd
->hasParamEntityRefs 
= oldDtd
->hasParamEntityRefs
; 
5880   newDtd
->standalone 
= oldDtd
->standalone
; 
5882   /* Don't want deep copying for scaffolding */ 
5883   newDtd
->in_eldecl 
= oldDtd
->in_eldecl
; 
5884   newDtd
->scaffold 
= oldDtd
->scaffold
; 
5885   newDtd
->contentStringLen 
= oldDtd
->contentStringLen
; 
5886   newDtd
->scaffSize 
= oldDtd
->scaffSize
; 
5887   newDtd
->scaffLevel 
= oldDtd
->scaffLevel
; 
5888   newDtd
->scaffIndex 
= oldDtd
->scaffIndex
; 
5894 copyEntityTable(XML_Parser oldParser
, 
5895                 HASH_TABLE 
*newTable
, 
5896                 STRING_POOL 
*newPool
, 
5897                 const HASH_TABLE 
*oldTable
) 
5899   HASH_TABLE_ITER iter
; 
5900   const XML_Char 
*cachedOldBase 
= NULL
; 
5901   const XML_Char 
*cachedNewBase 
= NULL
; 
5903   hashTableIterInit(&iter
, oldTable
); 
5907     const XML_Char 
*name
; 
5908     const ENTITY 
*oldE 
= (ENTITY 
*)hashTableIterNext(&iter
); 
5911     name 
= poolCopyString(newPool
, oldE
->name
); 
5914     newE 
= (ENTITY 
*)lookup(oldParser
, newTable
, name
, sizeof(ENTITY
)); 
5917     if (oldE
->systemId
) { 
5918       const XML_Char 
*tem 
= poolCopyString(newPool
, oldE
->systemId
); 
5921       newE
->systemId 
= tem
; 
5923         if (oldE
->base 
== cachedOldBase
) 
5924           newE
->base 
= cachedNewBase
; 
5926           cachedOldBase 
= oldE
->base
; 
5927           tem 
= poolCopyString(newPool
, cachedOldBase
); 
5930           cachedNewBase 
= newE
->base 
= tem
; 
5933       if (oldE
->publicId
) { 
5934         tem 
= poolCopyString(newPool
, oldE
->publicId
); 
5937         newE
->publicId 
= tem
; 
5941       const XML_Char 
*tem 
= poolCopyStringN(newPool
, oldE
->textPtr
, 
5945       newE
->textPtr 
= tem
; 
5946       newE
->textLen 
= oldE
->textLen
; 
5948     if (oldE
->notation
) { 
5949       const XML_Char 
*tem 
= poolCopyString(newPool
, oldE
->notation
); 
5952       newE
->notation 
= tem
; 
5954     newE
->is_param 
= oldE
->is_param
; 
5955     newE
->is_internal 
= oldE
->is_internal
; 
5960 #define INIT_POWER 6 
5962 static XML_Bool FASTCALL
 
5963 keyeq(KEY s1
, KEY s2
) 
5965   for (; *s1 
== *s2
; s1
++, s2
++) 
5971 static unsigned long FASTCALL
 
5972 hash(XML_Parser parser
, KEY s
) 
5974   unsigned long h 
= hash_secret_salt
; 
5976     h 
= CHAR_HASH(h
, *s
++); 
5981 lookup(XML_Parser parser
, HASH_TABLE 
*table
, KEY name
, size_t createSize
) 
5984   if (table
->size 
== 0) { 
5988     table
->power 
= INIT_POWER
; 
5989     /* table->size is a power of 2 */ 
5990     table
->size 
= (size_t)1 << INIT_POWER
; 
5991     tsize 
= table
->size 
* sizeof(NAMED 
*); 
5992     table
->v 
= (NAMED 
**)table
->mem
->malloc_fcn(tsize
); 
5997     memset(table
->v
, 0, tsize
); 
5998     i 
= hash(parser
, name
) & ((unsigned long)table
->size 
- 1); 
6001     unsigned long h 
= hash(parser
, name
); 
6002     unsigned long mask 
= (unsigned long)table
->size 
- 1; 
6003     unsigned char step 
= 0; 
6005     while (table
->v
[i
]) { 
6006       if (keyeq(name
, table
->v
[i
]->name
)) 
6009         step 
= PROBE_STEP(h
, mask
, table
->power
); 
6010       i 
< step 
? (i 
+= table
->size 
- step
) : (i 
-= step
); 
6015     /* check for overflow (table is half full) */ 
6016     if (table
->used 
>> (table
->power 
- 1)) { 
6017       unsigned char newPower 
= table
->power 
+ 1; 
6018       size_t newSize 
= (size_t)1 << newPower
; 
6019       unsigned long newMask 
= (unsigned long)newSize 
- 1; 
6020       size_t tsize 
= newSize 
* sizeof(NAMED 
*); 
6021       NAMED 
**newV 
= (NAMED 
**)table
->mem
->malloc_fcn(tsize
); 
6024       memset(newV
, 0, tsize
); 
6025       for (i 
= 0; i 
< table
->size
; i
++) 
6027           unsigned long newHash 
= hash(parser
, table
->v
[i
]->name
); 
6028           size_t j 
= newHash 
& newMask
; 
6032               step 
= PROBE_STEP(newHash
, newMask
, newPower
); 
6033             j 
< step 
? (j 
+= newSize 
- step
) : (j 
-= step
); 
6035           newV
[j
] = table
->v
[i
]; 
6037       table
->mem
->free_fcn(table
->v
); 
6039       table
->power 
= newPower
; 
6040       table
->size 
= newSize
; 
6043       while (table
->v
[i
]) { 
6045           step 
= PROBE_STEP(h
, newMask
, newPower
); 
6046         i 
< step 
? (i 
+= newSize 
- step
) : (i 
-= step
); 
6050   table
->v
[i
] = (NAMED 
*)table
->mem
->malloc_fcn(createSize
); 
6053   memset(table
->v
[i
], 0, createSize
); 
6054   table
->v
[i
]->name 
= name
; 
6059 static void FASTCALL
 
6060 hashTableClear(HASH_TABLE 
*table
) 
6063   for (i 
= 0; i 
< table
->size
; i
++) { 
6064     table
->mem
->free_fcn(table
->v
[i
]); 
6070 static void FASTCALL
 
6071 hashTableDestroy(HASH_TABLE 
*table
) 
6074   for (i 
= 0; i 
< table
->size
; i
++) 
6075     table
->mem
->free_fcn(table
->v
[i
]); 
6076   table
->mem
->free_fcn(table
->v
); 
6079 static void FASTCALL
 
6080 hashTableInit(HASH_TABLE 
*p
, const XML_Memory_Handling_Suite 
*ms
) 
6089 static void FASTCALL
 
6090 hashTableIterInit(HASH_TABLE_ITER 
*iter
, const HASH_TABLE 
*table
) 
6093   iter
->end 
= iter
->p 
+ table
->size
; 
6096 static NAMED 
* FASTCALL
 
6097 hashTableIterNext(HASH_TABLE_ITER 
*iter
) 
6099   while (iter
->p 
!= iter
->end
) { 
6100     NAMED 
*tem 
= *(iter
->p
)++; 
6107 static void FASTCALL
 
6108 poolInit(STRING_POOL 
*pool
, const XML_Memory_Handling_Suite 
*ms
) 
6110   pool
->blocks 
= NULL
; 
6111   pool
->freeBlocks 
= NULL
; 
6118 static void FASTCALL
 
6119 poolClear(STRING_POOL 
*pool
) 
6121   if (!pool
->freeBlocks
) 
6122     pool
->freeBlocks 
= pool
->blocks
; 
6124     BLOCK 
*p 
= pool
->blocks
; 
6126       BLOCK 
*tem 
= p
->next
; 
6127       p
->next 
= pool
->freeBlocks
; 
6128       pool
->freeBlocks 
= p
; 
6132   pool
->blocks 
= NULL
; 
6138 static void FASTCALL
 
6139 poolDestroy(STRING_POOL 
*pool
) 
6141   BLOCK 
*p 
= pool
->blocks
; 
6143     BLOCK 
*tem 
= p
->next
; 
6144     pool
->mem
->free_fcn(p
); 
6147   p 
= pool
->freeBlocks
; 
6149     BLOCK 
*tem 
= p
->next
; 
6150     pool
->mem
->free_fcn(p
); 
6156 poolAppend(STRING_POOL 
*pool
, const ENCODING 
*enc
, 
6157            const char *ptr
, const char *end
) 
6159   if (!pool
->ptr 
&& !poolGrow(pool
)) 
6162     XmlConvert(enc
, &ptr
, end
, (ICHAR 
**)&(pool
->ptr
), (ICHAR 
*)pool
->end
); 
6165     if (!poolGrow(pool
)) 
6171 static const XML_Char 
* FASTCALL
 
6172 poolCopyString(STRING_POOL 
*pool
, const XML_Char 
*s
) 
6175     if (!poolAppendChar(pool
, *s
)) 
6183 static const XML_Char 
* 
6184 poolCopyStringN(STRING_POOL 
*pool
, const XML_Char 
*s
, int n
) 
6186   if (!pool
->ptr 
&& !poolGrow(pool
)) 
6188   for (; n 
> 0; --n
, s
++) { 
6189     if (!poolAppendChar(pool
, *s
)) 
6197 static const XML_Char 
* FASTCALL
 
6198 poolAppendString(STRING_POOL 
*pool
, const XML_Char 
*s
) 
6201     if (!poolAppendChar(pool
, *s
)) 
6209 poolStoreString(STRING_POOL 
*pool
, const ENCODING 
*enc
, 
6210                 const char *ptr
, const char *end
) 
6212   if (!poolAppend(pool
, enc
, ptr
, end
)) 
6214   if (pool
->ptr 
== pool
->end 
&& !poolGrow(pool
)) 
6220 static XML_Bool FASTCALL
 
6221 poolGrow(STRING_POOL 
*pool
) 
6223   if (pool
->freeBlocks
) { 
6224     if (pool
->start 
== 0) { 
6225       pool
->blocks 
= pool
->freeBlocks
; 
6226       pool
->freeBlocks 
= pool
->freeBlocks
->next
; 
6227       pool
->blocks
->next 
= NULL
; 
6228       pool
->start 
= pool
->blocks
->s
; 
6229       pool
->end 
= pool
->start 
+ pool
->blocks
->size
; 
6230       pool
->ptr 
= pool
->start
; 
6233     if (pool
->end 
- pool
->start 
< pool
->freeBlocks
->size
) { 
6234       BLOCK 
*tem 
= pool
->freeBlocks
->next
; 
6235       pool
->freeBlocks
->next 
= pool
->blocks
; 
6236       pool
->blocks 
= pool
->freeBlocks
; 
6237       pool
->freeBlocks 
= tem
; 
6238       memcpy(pool
->blocks
->s
, pool
->start
, 
6239              (pool
->end 
- pool
->start
) * sizeof(XML_Char
)); 
6240       pool
->ptr 
= pool
->blocks
->s 
+ (pool
->ptr 
- pool
->start
); 
6241       pool
->start 
= pool
->blocks
->s
; 
6242       pool
->end 
= pool
->start 
+ pool
->blocks
->size
; 
6246   if (pool
->blocks 
&& pool
->start 
== pool
->blocks
->s
) { 
6247     int blockSize 
= (int)(pool
->end 
- pool
->start
)*2; 
6248     BLOCK 
*temp 
= (BLOCK 
*) 
6249       pool
->mem
->realloc_fcn(pool
->blocks
, 
6251                               + blockSize 
* sizeof(XML_Char
))); 
6254     pool
->blocks 
= temp
; 
6255     pool
->blocks
->size 
= blockSize
; 
6256     pool
->ptr 
= pool
->blocks
->s 
+ (pool
->ptr 
- pool
->start
); 
6257     pool
->start 
= pool
->blocks
->s
; 
6258     pool
->end 
= pool
->start 
+ blockSize
; 
6262     int blockSize 
= (int)(pool
->end 
- pool
->start
); 
6263     if (blockSize 
< INIT_BLOCK_SIZE
) 
6264       blockSize 
= INIT_BLOCK_SIZE
; 
6267     tem 
= (BLOCK 
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
) 
6268                                         + blockSize 
* sizeof(XML_Char
)); 
6271     tem
->size 
= blockSize
; 
6272     tem
->next 
= pool
->blocks
; 
6274     if (pool
->ptr 
!= pool
->start
) 
6275       memcpy(tem
->s
, pool
->start
, 
6276              (pool
->ptr 
- pool
->start
) * sizeof(XML_Char
)); 
6277     pool
->ptr 
= tem
->s 
+ (pool
->ptr 
- pool
->start
); 
6278     pool
->start 
= tem
->s
; 
6279     pool
->end 
= tem
->s 
+ blockSize
; 
6285 nextScaffoldPart(XML_Parser parser
) 
6287   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
6288   CONTENT_SCAFFOLD 
* me
; 
6291   if (!dtd
->scaffIndex
) { 
6292     dtd
->scaffIndex 
= (int *)MALLOC(groupSize 
* sizeof(int)); 
6293     if (!dtd
->scaffIndex
) 
6295     dtd
->scaffIndex
[0] = 0; 
6298   if (dtd
->scaffCount 
>= dtd
->scaffSize
) { 
6299     CONTENT_SCAFFOLD 
*temp
; 
6300     if (dtd
->scaffold
) { 
6301       temp 
= (CONTENT_SCAFFOLD 
*) 
6302         REALLOC(dtd
->scaffold
, dtd
->scaffSize 
* 2 * sizeof(CONTENT_SCAFFOLD
)); 
6305       dtd
->scaffSize 
*= 2; 
6308       temp 
= (CONTENT_SCAFFOLD 
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
 
6309                                         * sizeof(CONTENT_SCAFFOLD
)); 
6312       dtd
->scaffSize 
= INIT_SCAFFOLD_ELEMENTS
; 
6314     dtd
->scaffold 
= temp
; 
6316   next 
= dtd
->scaffCount
++; 
6317   me 
= &dtd
->scaffold
[next
]; 
6318   if (dtd
->scaffLevel
) { 
6319     CONTENT_SCAFFOLD 
*parent 
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]]; 
6320     if (parent
->lastchild
) { 
6321       dtd
->scaffold
[parent
->lastchild
].nextsib 
= next
; 
6323     if (!parent
->childcnt
) 
6324       parent
->firstchild 
= next
; 
6325     parent
->lastchild 
= next
; 
6328   me
->firstchild 
= me
->lastchild 
= me
->childcnt 
= me
->nextsib 
= 0; 
6333 build_node(XML_Parser parser
, 
6336            XML_Content 
**contpos
, 
6339   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
6340   dest
->type 
= dtd
->scaffold
[src_node
].type
; 
6341   dest
->quant 
= dtd
->scaffold
[src_node
].quant
; 
6342   if (dest
->type 
== XML_CTYPE_NAME
) { 
6343     const XML_Char 
*src
; 
6344     dest
->name 
= *strpos
; 
6345     src 
= dtd
->scaffold
[src_node
].name
; 
6347       *(*strpos
)++ = *src
; 
6352     dest
->numchildren 
= 0; 
6353     dest
->children 
= NULL
; 
6358     dest
->numchildren 
= dtd
->scaffold
[src_node
].childcnt
; 
6359     dest
->children 
= *contpos
; 
6360     *contpos 
+= dest
->numchildren
; 
6361     for (i 
= 0, cn 
= dtd
->scaffold
[src_node
].firstchild
; 
6362          i 
< dest
->numchildren
; 
6363          i
++, cn 
= dtd
->scaffold
[cn
].nextsib
) { 
6364       build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
); 
6370 static XML_Content 
* 
6371 build_model (XML_Parser parser
) 
6373   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
6377   int allocsize 
= (dtd
->scaffCount 
* sizeof(XML_Content
) 
6378                    + (dtd
->contentStringLen 
* sizeof(XML_Char
))); 
6380   ret 
= (XML_Content 
*)MALLOC(allocsize
); 
6384   str 
=  (XML_Char 
*) (&ret
[dtd
->scaffCount
]); 
6387   build_node(parser
, 0, ret
, &cpos
, &str
); 
6391 static ELEMENT_TYPE 
* 
6392 getElementType(XML_Parser parser
, 
6393                const ENCODING 
*enc
, 
6397   DTD 
* const dtd 
= _dtd
;  /* save one level of indirection */ 
6398   const XML_Char 
*name 
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
); 
6403   ret 
= (ELEMENT_TYPE 
*) lookup(parser
, &dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
)); 
6406   if (ret
->name 
!= name
) 
6407     poolDiscard(&dtd
->pool
); 
6409     poolFinish(&dtd
->pool
); 
6410     if (!setElementTypePrefix(parser
, ret
))