home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / xwphescr.zip / XWPH0208.ZIP / src / helpers / xmlparse.c < prev    next >
C/C++ Source or Header  |  2002-04-13  |  224KB  |  6,312 lines

  1.  
  2. /*
  3.  *@@sourcefile xmlparse.c:
  4.  *      contains the API of the expat XML parser 1.95.2, as released on
  5.  *      http://sourceforge.net/projects/expat/ on July 26, 2001.
  6.  *
  7.  *      V1.95.1 was ported to and integrated with the xwphelpers
  8.  *      for V0.9.9 (2001-02-10) [umoeller]. V1.95.2 was re-ported
  9.  *      with V0.9.14 (2001-08-09) [umoeller].
  10.  *
  11.  *      See xml.c for a general introduction to @XML support in the
  12.  *      xwphelpers.
  13.  *
  14.  *      Expat is a library, written in C, for parsing XML @documents. It's
  15.  *      the underlying XML parser for the open source Mozilla project,
  16.  *      perl's XML::Parser, and other open-source XML parsers.
  17.  *
  18.  *      Expat was written by James Clark, who also wrote groff (an nroff
  19.  *      look-alike), Jade (an implemention of ISO's DSSSL stylesheet
  20.  *      language for SGML), XP (a Java XML parser package), XT (a Java
  21.  *      XSL engine). He was also the technical lead on the XML Working
  22.  *      Group at W3 that produced the XML specification.
  23.  *
  24.  *      Most of this documentation is the original documentation
  25.  *      that comes with expat as an HTML file. I (umoeller)
  26.  *      have integrated the docs into the sources and added a
  27.  *      couple of remarks while trying to implement parsers.
  28.  *
  29.  *      See XML_ParserCreate for instructions how to parse XML.
  30.  *
  31.  *      Note that expat is a non-validating XML processor. Validation
  32.  *      is supported by the top layer of xwphelpers XML support. See
  33.  *      xml.c.
  34.  *
  35.  *@@added V0.9.9 (2001-02-10) [umoeller]
  36.  *@@header "expat\expat.h"
  37.  */
  38.  
  39. /*
  40.  *      Copyright (C) 2001 Ulrich Möller.
  41.  *      Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
  42.  *                                     and Clark Cooper.
  43.  *
  44.  *      Permission is hereby granted, free of charge, to any person obtaining
  45.  *      a copy of this software and associated documentation files (the
  46.  *      "Software"), to deal in the Software without restriction, including
  47.  *      without limitation the rights to use, copy, modify, merge, publish,
  48.  *      distribute, sublicense, and/or sell copies of the Software, and to
  49.  *      permit persons to whom the Software is furnished to do so, subject to
  50.  *      the following conditions:
  51.  *
  52.  *      The above copyright notice and this permission notice shall be included
  53.  *      in all copies or substantial portions of the Software.
  54.  *
  55.  *      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  56.  *      EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  57.  *      MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  58.  *      IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  59.  *      CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  60.  *      TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  61.  *      SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  62.  */
  63.  
  64. /*
  65.  *@@category: Helpers\XML\expat
  66.  *      expat XML parser. See xmlparse.c.
  67.  */
  68.  
  69. #include "setup.h"
  70.  
  71. #pragma info(norea, nogen)
  72.         // disable "statement unreachable" and "missing break statement"
  73.         // this code generates those options HEAVILY
  74.  
  75.  
  76. /* #ifdef COMPILED_FROM_DSP
  77.  * #  include "winconfig.h"
  78.  * #  define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
  79.  * #  include "expat.h"
  80.  * #  undef XMLPARSEAPI
  81.  * #else
  82.  * #include <config.h> */
  83.  
  84. #ifdef __declspec
  85. #define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
  86. #endif
  87.  
  88. #include "expat\expat.h"
  89.  
  90. #ifdef __declspec
  91. #undef XMLPARSEAPI
  92. #endif
  93. // #endif /* ndef COMPILED_FROM_DSP */
  94.  
  95. #include <stddef.h>
  96. #include <string.h>
  97.  
  98. #ifdef XML_UNICODE
  99. #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
  100. #define XmlConvert XmlUtf16Convert
  101. #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
  102. #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
  103. #define XmlEncode XmlUtf16Encode
  104. #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
  105. typedef unsigned short ICHAR;
  106.  
  107. #else
  108. #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
  109. #define XmlConvert XmlUtf8Convert
  110. #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
  111. #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
  112. #define XmlEncode XmlUtf8Encode
  113. #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
  114. typedef char ICHAR;
  115.  
  116. #endif
  117.  
  118.  
  119. #ifndef XML_NS
  120.  
  121. #define XmlInitEncodingNS XmlInitEncoding
  122. #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
  123. #undef XmlGetInternalEncodingNS
  124. #define XmlGetInternalEncodingNS XmlGetInternalEncoding
  125. #define XmlParseXmlDeclNS XmlParseXmlDecl
  126.  
  127. #endif
  128.  
  129. #ifdef XML_UNICODE_WCHAR_T
  130. #define XML_T(x) L ## x
  131. #else
  132. #define XML_T(x) x
  133. #endif
  134.  
  135. /* Round up n to be a multiple of sz, where sz is a power of 2. */
  136. #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
  137.  
  138. #include "expat\xmltok.h"
  139. #include "expat\xmlrole.h"
  140.  
  141. typedef const XML_Char *KEY;
  142.  
  143. typedef struct
  144. {
  145.     KEY name;
  146. }
  147. NAMED;
  148.  
  149. typedef struct
  150. {
  151.     NAMED **v;
  152.     size_t size;
  153.     size_t used;
  154.     size_t usedLim;
  155.     XML_Memory_Handling_Suite *mem;
  156. }
  157. HASH_TABLE;
  158.  
  159. typedef struct
  160. {
  161.     NAMED **p;
  162.     NAMED **end;
  163. }
  164. HASH_TABLE_ITER;
  165.  
  166. #define INIT_TAG_BUF_SIZE 32    /* must be a multiple of sizeof(XML_Char) */
  167. #define INIT_DATA_BUF_SIZE 1024
  168. #define INIT_ATTS_SIZE 16
  169. #define INIT_BLOCK_SIZE 1024
  170. #define INIT_BUFFER_SIZE 1024
  171.  
  172. #define EXPAND_SPARE 24
  173.  
  174. typedef struct binding
  175. {
  176.     struct prefix *prefix;
  177.     struct binding *nextTagBinding;
  178.     struct binding *prevPrefixBinding;
  179.     const struct attribute_id *attId;
  180.     XML_Char *uri;
  181.     int uriLen;
  182.     int uriAlloc;
  183. }
  184. BINDING;
  185.  
  186. typedef struct prefix
  187. {
  188.     const XML_Char *name;
  189.     BINDING *binding;
  190. }
  191. PREFIX;
  192.  
  193. typedef struct
  194. {
  195.     const XML_Char *str;
  196.     const XML_Char *localPart;
  197.     int uriLen;
  198. }
  199. TAG_NAME;
  200.  
  201. typedef struct tag
  202. {
  203.     struct tag *parent;
  204.     const char *rawName;
  205.     int rawNameLength;
  206.     TAG_NAME name;
  207.     char *buf;
  208.     char *bufEnd;
  209.     BINDING *bindings;
  210. }
  211. TAG;
  212.  
  213. typedef struct
  214. {
  215.     const XML_Char *name;
  216.     const XML_Char *textPtr;
  217.     int textLen;
  218.     const XML_Char *systemId;
  219.     const XML_Char *base;
  220.     const XML_Char *publicId;
  221.     const XML_Char *notation;
  222.     char open;
  223.     char is_param;
  224. }
  225. ENTITY;
  226.  
  227. typedef struct
  228. {
  229.     enum XML_Content_Type type;
  230.     enum XML_Content_Quant quant;
  231.     const XML_Char *name;
  232.     int firstchild;
  233.     int lastchild;
  234.     int childcnt;
  235.     int nextsib;
  236. }
  237. CONTENT_SCAFFOLD;
  238.  
  239. typedef struct block
  240. {
  241.     struct block *next;
  242.     int size;
  243.     XML_Char s[1];
  244. }
  245. BLOCK;
  246.  
  247. typedef struct
  248. {
  249.     BLOCK *blocks;
  250.     BLOCK *freeBlocks;
  251.     const XML_Char *end;
  252.     XML_Char *ptr;
  253.     XML_Char *start;
  254.     XML_Memory_Handling_Suite *mem;
  255. }
  256. STRING_POOL;
  257.  
  258. /* The XML_Char before the name is used to determine whether
  259.  * an attribute has been specified. */
  260. typedef struct attribute_id
  261. {
  262.     XML_Char *name;
  263.     PREFIX *prefix;
  264.     char maybeTokenized;
  265.     char xmlns;
  266. }
  267. ATTRIBUTE_ID;
  268.  
  269. typedef struct
  270. {
  271.     const ATTRIBUTE_ID *id;
  272.     char isCdata;
  273.     const XML_Char *value;
  274. }
  275. DEFAULT_ATTRIBUTE;
  276.  
  277. typedef struct
  278. {
  279.     const XML_Char *name;
  280.     PREFIX *prefix;
  281.     const ATTRIBUTE_ID *idAtt;
  282.     int nDefaultAtts;
  283.     int allocDefaultAtts;
  284.     DEFAULT_ATTRIBUTE *defaultAtts;
  285. }
  286. ELEMENT_TYPE;
  287.  
  288. typedef struct
  289. {
  290.     HASH_TABLE generalEntities;
  291.     HASH_TABLE elementTypes;
  292.     HASH_TABLE attributeIds;
  293.     HASH_TABLE prefixes;
  294.     STRING_POOL pool;
  295.     int complete;
  296.     int standalone;
  297. #ifdef XML_DTD
  298.     HASH_TABLE paramEntities;
  299. #endif                          /* XML_DTD */
  300.     PREFIX defaultPrefix;
  301.     /* === scaffolding for building content model === */
  302.     int in_eldecl;
  303.     CONTENT_SCAFFOLD *scaffold;
  304.     unsigned contentStringLen;
  305.     unsigned scaffSize;
  306.     unsigned scaffCount;
  307.     int scaffLevel;
  308.     int *scaffIndex;
  309. }
  310. DTD;
  311.  
  312. typedef struct open_internal_entity
  313. {
  314.     const char *internalEventPtr;
  315.     const char *internalEventEndPtr;
  316.     struct open_internal_entity *next;
  317.     ENTITY *entity;
  318. }
  319. OPEN_INTERNAL_ENTITY;
  320.  
  321. typedef XMLERROR Processor(XML_Parser parser,
  322.                            const char *start,
  323.                            const char *end,
  324.                            const char **endPtr);
  325.  
  326. static Processor prologProcessor;
  327. static Processor prologInitProcessor;
  328. static Processor contentProcessor;
  329. static Processor cdataSectionProcessor;
  330.  
  331. #ifdef XML_DTD
  332. static Processor ignoreSectionProcessor;
  333.  
  334. #endif /* XML_DTD */
  335. static Processor epilogProcessor;
  336. static Processor errorProcessor;
  337. static Processor externalEntityInitProcessor;
  338. static Processor externalEntityInitProcessor2;
  339. static Processor externalEntityInitProcessor3;
  340. static Processor externalEntityContentProcessor;
  341.  
  342. static XMLERROR
  343.  handleUnknownEncoding(XML_Parser parser, const XML_Char * encodingName);
  344. static XMLERROR
  345.  processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
  346. static XMLERROR
  347.  initializeEncoding(XML_Parser parser);
  348. static XMLERROR
  349.  doProlog(XML_Parser parser, const ENCODING * enc, const char *s,
  350.           const char *end, int tok, const char *next, const char **nextPtr);
  351. static XMLERROR
  352.  processInternalParamEntity(XML_Parser parser, ENTITY * entity);
  353. static XMLERROR
  354.  doContent(XML_Parser parser, int startTagLevel, const ENCODING * enc,
  355.            const char *start, const char *end, const char **endPtr);
  356. static XMLERROR
  357.  doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
  358.  
  359. #ifdef XML_DTD
  360. static XMLERROR
  361.  doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
  362.  
  363. #endif /* XML_DTD */
  364. static XMLERROR storeAtts(XML_Parser parser, const ENCODING *, const char *s,
  365.                           TAG_NAME * tagNamePtr, BINDING ** bindingsPtr);
  366. static
  367. int addBinding(XML_Parser parser, PREFIX * prefix, const ATTRIBUTE_ID * attId, const XML_Char * uri, BINDING ** bindingsPtr);
  368.  
  369. static int
  370.  defineAttribute(ELEMENT_TYPE * type, ATTRIBUTE_ID *,
  371.                  int isCdata, int isId, const XML_Char * dfltValue,
  372.                  XML_Parser parser);
  373.  
  374. static XMLERROR
  375.  storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
  376.                      STRING_POOL *);
  377. static XMLERROR
  378.  appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
  379.                       STRING_POOL *);
  380. static ATTRIBUTE_ID *
  381.  getAttributeId(XML_Parser parser, const ENCODING * enc, const char *start, const char *end);
  382. static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
  383. static XMLERROR
  384.  storeEntityValue(XML_Parser parser, const ENCODING * enc, const char *start, const char *end);
  385. static int
  386.  reportProcessingInstruction(XML_Parser parser, const ENCODING * enc, const char *start, const char *end);
  387. static int
  388.  reportComment(XML_Parser parser, const ENCODING * enc, const char *start, const char *end);
  389. static void
  390.  reportDefault(XML_Parser parser, const ENCODING * enc, const char *start, const char *end);
  391.  
  392. static const XML_Char *getContext(XML_Parser parser);
  393. static int setContext(XML_Parser parser, const XML_Char * context);
  394. static void normalizePublicId(XML_Char * s);
  395. static int dtdInit(DTD *, XML_Parser parser);
  396.  
  397. static void dtdDestroy(DTD *, XML_Parser parser);
  398.  
  399. static int dtdCopy(DTD * newDtd, const DTD * oldDtd, XML_Parser parser);
  400.  
  401. static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *,
  402.                            XML_Parser parser);
  403.  
  404. #ifdef XML_DTD
  405. static void dtdSwap(DTD *, DTD *);
  406.  
  407. #endif /* XML_DTD */
  408.  
  409. static NAMED *lookup(HASH_TABLE * table, KEY name, size_t createSize);
  410.  
  411. static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite * ms);
  412.  
  413. static void hashTableDestroy(HASH_TABLE *);
  414. static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
  415. static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
  416. static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite * ms);
  417. static void poolClear(STRING_POOL *);
  418. static void poolDestroy(STRING_POOL *);
  419. static XML_Char *poolAppend(STRING_POOL *pool,
  420.                             const ENCODING *enc,
  421.                             const char *ptr,
  422.                             const char *end,
  423.                             unsigned long *pulOfs); // V0.9.14 (2001-08-09) [umoeller]
  424. static XML_Char *poolStoreString(STRING_POOL *pool,
  425.                                  const ENCODING *enc,
  426.                                  const char *ptr,
  427.                                  const char *end,
  428.                                  unsigned long *pulOfs); // V0.9.14 (2001-08-09) [umoeller]
  429.  
  430. static int poolGrow(STRING_POOL * pool);
  431.  
  432. static int nextScaffoldPart(XML_Parser parser);
  433. static XMLCONTENT *build_model(XML_Parser parser);
  434.  
  435. static const XML_Char *poolCopyString(STRING_POOL * pool, const XML_Char * s);
  436. static const XML_Char *poolCopyStringN(STRING_POOL * pool, const XML_Char * s, int n);
  437. static const XML_Char *poolAppendString(STRING_POOL * pool, const XML_Char * s);
  438. static ELEMENT_TYPE *getElementType(XML_Parser Paraser,
  439.                                     const ENCODING * enc,
  440.                                     const char *ptr,
  441.                                     const char *end);
  442.  
  443. #define poolStart(pool) ((pool)->start)
  444. #define poolEnd(pool) ((pool)->ptr)
  445. #define poolLength(pool) ((pool)->ptr - (pool)->start)
  446. #define poolChop(pool) ((void)--(pool->ptr))
  447. #define poolLastChar(pool) (((pool)->ptr)[-1])
  448. #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
  449. #define poolFinish(pool) ((pool)->start = (pool)->ptr)
  450. #define poolAppendChar(pool, c) \
  451.   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
  452.    ? 0 \
  453.    : ((*((pool)->ptr)++ = c), 1))
  454.  
  455. typedef struct
  456. {
  457.     /* The first member must be userData so that the XML_GetUserData macro works. */
  458.     void *m_userData;
  459.     void *m_handlerArg;
  460.     char *m_buffer;
  461.     XML_Memory_Handling_Suite m_mem;
  462.     /* first character to be parsed */
  463.     const char *m_bufferPtr;
  464.     /* past last character to be parsed */
  465.     char *m_bufferEnd;
  466.     /* allocated end of buffer */
  467.     const char *m_bufferLim;
  468.     long m_parseEndByteIndex;
  469.     const char *m_parseEndPtr;
  470.     XML_Char *m_dataBuf;
  471.     XML_Char *m_dataBufEnd;
  472.     XML_StartElementHandler m_startElementHandler;
  473.     XML_EndElementHandler m_endElementHandler;
  474.     XML_CharacterDataHandler m_characterDataHandler;
  475.     XML_ProcessingInstructionHandler m_processingInstructionHandler;
  476.     XML_CommentHandler m_commentHandler;
  477.     XML_StartCdataSectionHandler m_startCdataSectionHandler;
  478.     XML_EndCdataSectionHandler m_endCdataSectionHandler;
  479.     XML_DefaultHandler m_defaultHandler;
  480.     XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
  481.     XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
  482.     XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
  483.     XML_NotationDeclHandler m_notationDeclHandler;
  484.     XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
  485.     XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
  486.     XML_NotStandaloneHandler m_notStandaloneHandler;
  487.     XML_ExternalEntityRefHandler m_externalEntityRefHandler;
  488.     void *m_externalEntityRefHandlerArg;
  489.     XML_UnknownEncodingHandler m_unknownEncodingHandler;
  490.     XML_ElementDeclHandler m_elementDeclHandler;
  491.     XML_AttlistDeclHandler m_attlistDeclHandler;
  492.     XML_EntityDeclHandler m_entityDeclHandler;
  493.     XML_XmlDeclHandler m_xmlDeclHandler;
  494.     const ENCODING *m_encoding;
  495.     INIT_ENCODING m_initEncoding;
  496.     const ENCODING *m_internalEncoding;
  497.     const XML_Char *m_protocolEncodingName;
  498.     int m_ns;
  499.     int m_ns_triplets;
  500.     void *m_unknownEncodingMem;
  501.     void *m_unknownEncodingData;
  502.     void *m_unknownEncodingHandlerData;
  503.     void (*m_unknownEncodingRelease) (void *);
  504.     PROLOG_STATE m_prologState;
  505.     Processor *m_processor;
  506.     XMLERROR m_errorCode;
  507.     const char *m_eventPtr;
  508.     const char *m_eventEndPtr;
  509.     const char *m_positionPtr;
  510.     OPEN_INTERNAL_ENTITY *m_openInternalEntities;
  511.     int m_defaultExpandInternalEntities;
  512.     int m_tagLevel;
  513.     ENTITY *m_declEntity;
  514.     const XML_Char *m_doctypeName;
  515.     const XML_Char *m_doctypeSysid;
  516.     const XML_Char *m_doctypePubid;
  517.     const XML_Char *m_declAttributeType;
  518.     const XML_Char *m_declNotationName;
  519.     const XML_Char *m_declNotationPublicId;
  520.     ELEMENT_TYPE *m_declElementType;
  521.     ATTRIBUTE_ID *m_declAttributeId;
  522.     char m_declAttributeIsCdata;
  523.     char m_declAttributeIsId;
  524.     DTD m_dtd;
  525.     const XML_Char *m_curBase;
  526.     TAG *m_tagStack;
  527.     TAG *m_freeTagList;
  528.     BINDING *m_inheritedBindings;
  529.     BINDING *m_freeBindingList;
  530.     int m_attsSize;
  531.     int m_nSpecifiedAtts;
  532.     int m_idAttIndex;
  533.     ATTRIBUTE *m_atts;
  534.     POSITION m_position;
  535.     STRING_POOL m_tempPool;
  536.     STRING_POOL m_temp2Pool;
  537.     char *m_groupConnector;
  538.     unsigned m_groupSize;
  539.     int m_hadExternalDoctype;
  540.     XML_Char m_namespaceSeparator;
  541. #ifdef XML_DTD
  542.     enum XML_ParamEntityParsing m_paramEntityParsing;
  543.     XML_Parser m_parentParser;
  544. #endif
  545. }
  546. Parser;
  547.  
  548. #define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
  549. #define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
  550. #define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
  551.  
  552. #define userData (((Parser *)parser)->m_userData)
  553. #define handlerArg (((Parser *)parser)->m_handlerArg)
  554. #define startElementHandler (((Parser *)parser)->m_startElementHandler)
  555. #define endElementHandler (((Parser *)parser)->m_endElementHandler)
  556. #define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
  557. #define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
  558. #define commentHandler (((Parser *)parser)->m_commentHandler)
  559. #define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
  560. #define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
  561. #define defaultHandler (((Parser *)parser)->m_defaultHandler)
  562. #define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
  563. #define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
  564. #define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
  565. #define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
  566. #define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
  567. #define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
  568. #define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
  569. #define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
  570. #define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
  571. #define internalEntityRefHandler (((Parser *)parser)->m_internalEntityRefHandler)
  572. #define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
  573. #define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
  574. #define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
  575. #define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
  576. #define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
  577. #define encoding (((Parser *)parser)->m_encoding)
  578. #define initEncoding (((Parser *)parser)->m_initEncoding)
  579. #define internalEncoding (((Parser *)parser)->m_internalEncoding)
  580. #define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
  581. #define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
  582. #define unknownEncodingHandlerData \
  583.   (((Parser *)parser)->m_unknownEncodingHandlerData)
  584. #define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
  585. #define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
  586. #define ns (((Parser *)parser)->m_ns)
  587. #define ns_triplets (((Parser *)parser)->m_ns_triplets)
  588. #define prologState (((Parser *)parser)->m_prologState)
  589. #define processor (((Parser *)parser)->m_processor)
  590. #define errorCode (((Parser *)parser)->m_errorCode)
  591. #define eventPtr (((Parser *)parser)->m_eventPtr)
  592. #define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
  593. #define positionPtr (((Parser *)parser)->m_positionPtr)
  594. #define position (((Parser *)parser)->m_position)
  595. #define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
  596. #define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
  597. #define tagLevel (((Parser *)parser)->m_tagLevel)
  598. #define buffer (((Parser *)parser)->m_buffer)
  599. #define bufferPtr (((Parser *)parser)->m_bufferPtr)
  600. #define bufferEnd (((Parser *)parser)->m_bufferEnd)
  601. #define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
  602. #define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
  603. #define bufferLim (((Parser *)parser)->m_bufferLim)
  604. #define dataBuf (((Parser *)parser)->m_dataBuf)
  605. #define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
  606. #define dtd (((Parser *)parser)->m_dtd)
  607. #define curBase (((Parser *)parser)->m_curBase)
  608. #define declEntity (((Parser *)parser)->m_declEntity)
  609. #define doctypeName (((Parser *)parser)->m_doctypeName)
  610. #define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
  611. #define doctypePubid (((Parser *)parser)->m_doctypePubid)
  612. #define declAttributeType (((Parser *)parser)->m_declAttributeType)
  613. #define declNotationName (((Parser *)parser)->m_declNotationName)
  614. #define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
  615. #define declElementType (((Parser *)parser)->m_declElementType)
  616. #define declAttributeId (((Parser *)parser)->m_declAttributeId)
  617. #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
  618. #define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
  619. #define freeTagList (((Parser *)parser)->m_freeTagList)
  620. #define freeBindingList (((Parser *)parser)->m_freeBindingList)
  621. #define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
  622. #define tagStack (((Parser *)parser)->m_tagStack)
  623. #define atts (((Parser *)parser)->m_atts)
  624. #define attsSize (((Parser *)parser)->m_attsSize)
  625. #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
  626. #define idAttIndex (((Parser *)parser)->m_idAttIndex)
  627. #define tempPool (((Parser *)parser)->m_tempPool)
  628. #define temp2Pool (((Parser *)parser)->m_temp2Pool)
  629. #define groupConnector (((Parser *)parser)->m_groupConnector)
  630. #define groupSize (((Parser *)parser)->m_groupSize)
  631. #define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
  632. #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
  633. #ifdef XML_DTD
  634. #define parentParser (((Parser *)parser)->m_parentParser)
  635. #define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
  636. #endif /* XML_DTD */
  637.  
  638. #ifdef COMPILED_FROM_DSP
  639. BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p)
  640. {
  641.     return TRUE;
  642. }
  643. #endif /* def COMPILED_FROM_DSP */
  644.  
  645. #ifdef _MSC_VER
  646. #ifdef _DEBUG
  647. Parser *asParser(XML_Parser parser)
  648. {
  649.     return parser;
  650. }
  651. #endif
  652. #endif
  653.  
  654. /*
  655.  *@@ XML_ParserCreate:
  656.  *      constructs a new parser. If encoding is non-null, it specifies
  657.  *      a character encoding to use for the document (see below).
  658.  *      This overrides the document encoding declaration.
  659.  *
  660.  *      Expat is a stream-oriented parser. You register callback (or
  661.  *      handler) functions with the parser and then start feeding it
  662.  *      the document. As the parser recognizes parts of the document,
  663.  *      it will call the appropriate handler for that part (if you've
  664.  *      registered one). The document is fed to the parser in pieces,
  665.  *      so you can start parsing before you have all the document.
  666.  *      This also allows you to parse really huge documents that won't
  667.  *      fit into memory.
  668.  *
  669.  *      Expat can be intimidating due to the many kinds of handlers
  670.  *      and options you can set. But you only need to learn four
  671.  *      functions in order to do 90% of what you'll want to do with it:
  672.  *
  673.  *      -- XML_ParserCreate: Create a new parser object.
  674.  *
  675.  *      -- XML_SetElementHandler: Set handlers for start and end tags.
  676.  *
  677.  *      -- XML_SetCharacterDataHandler: Set handler for text.
  678.  *
  679.  *      -- XML_Parse: Pass a buffer full of document to the parser.
  680.  *
  681.  *      So the first step in parsing an XML document with expat is
  682.  *      to create a parser object. There are three functions in the
  683.  *      expat API for creating a parser object. However, only two of
  684.  *      these (XML_ParserCreate and XML_ParserCreateNS) can be used
  685.  *      for constructing a parser for a top-level document. The object
  686.  *      returned by these functions is an opaque pointer (i.e. expat.h
  687.  *      declares it as void*) to data with further internal structure.
  688.  *      In order to free the memory associated with this object you
  689.  *      must call XML_ParserFree. Note that if you have provided
  690.  *      any user data that gets stored in the parser, then your
  691.  *      application is responsible for freeing it prior to calling
  692.  *      XML_ParserFree.
  693.  *
  694.  *      The objects returned by the parser creation functions are
  695.  *      good for parsing only one XML document or external parsed
  696.  *      entity. If your application needs to parse many XML documents,
  697.  *      then it needs to create a parser object for each one. The
  698.  *      best way to deal with this is to create a higher level object
  699.  *      that contains all the default initialization you want for
  700.  *      your parser objects.
  701.  *
  702.  *      Walking through a document hierarchy with a stream oriented
  703.  *      parser will require a good stack mechanism in order to keep
  704.  *      track of current context. For instance, to answer the simple
  705.  *      question, "What element does this text belong to?" requires
  706.  *      a stack, since the parser may have descended into other
  707.  *      elements that are children of the current one and has
  708.  *      encountered this text on the way out.
  709.  *
  710.  *      The things you're likely to want to keep on a stack are the
  711.  *      currently opened element and its attributes. You push this
  712.  *      information onto the stack in the start handler and you pop
  713.  *      it off in the end handler.
  714.  *
  715.  *      For some tasks, it is sufficient to just keep information on
  716.  *      what the depth of the stack is (or would be if you had one).
  717.  *      The outline program shown above presents one example. Another
  718.  *      such task would be skipping over a complete element. When you
  719.  *      see the start tag for the element you want to skip, you set a
  720.  *      skip flag and record the depth at which the element started.
  721.  *      When the end tag handler encounters the same depth, the
  722.  *      skipped element has ended and the flag may be cleared. If you
  723.  *      follow the convention that the root element starts at 1, then
  724.  *      you can use the same variable for skip flag and skip depth.
  725.  *
  726.  *      <B>Namespace Processing</B>
  727.  *
  728.  *      When the parser is created using the XML_ParserCreateNS,
  729.  *      function, expat performs namespace processing. See that
  730.  *      function for details.
  731.  *
  732.  *      <B>Character Encodings</B>
  733.  *
  734.  *      While XML is based on Unicode, and every XML processor is
  735.  *      required to recognized UTF-8 and UTF-16 (1 and 2 byte
  736.  *      encodings of Unicode), other @encodings may be declared in
  737.  *      XML documents or entities. For the main document, an XML
  738.  *      declaration may contain an encoding declaration in its
  739.  *      @text_declaration. See @encodings for additional
  740.  *      information.
  741.  *
  742.  *      With expat, you may also specify an encoding at the time
  743.  *      of creating a parser. This is useful when the encoding
  744.  *      information may come from a source outside the document
  745.  *      itself (like a higher level protocol).
  746.  *
  747.  *      See XML_SetUnknownEncodingHandler for encodings directly
  748.  *      supported by expat and for how to handle other encodings.
  749.  *
  750.  *      One pitfall that novice expat users are likely to fall into is
  751.  *      that although expat may accept input in various encodings, the
  752.  *      strings that it passes to the handlers are always encoded in
  753.  *      UTF-8. Your application is responsible for any translation of
  754.  *      these strings into other encodings.
  755.  *
  756.  *      <B>Handling External Entity References</B>
  757.  *
  758.  *      Expat does not read or parse @external_entities directly. Note that
  759.  *      any external @DTD is a special case of an external entity. For how to
  760.  *      handle external entities, see XML_SetExternalEntityRefHandler.
  761.  *
  762.  *      <B>Parsing Parameter Entities</B>
  763.  *
  764.  *      In order to parse @parameter_entities, before starting the parse,
  765.  *      you must call XML_SetParamEntityParsing.
  766.  */
  767.  
  768. XML_Parser XML_ParserCreate(const XML_Char * encodingName)
  769. {
  770.     return XML_ParserCreate_MM(encodingName, NULL, NULL);
  771. }
  772.  
  773. /*
  774.  *@@ XML_ParserCreateNS:
  775.  *      constructs a new parser that has namespace processing
  776.  *      in effect. Namespace expanded element names and attribute
  777.  *      names are returned as a concatenation of the namespace URI,
  778.  *      sep, and the local part of the name. This means that you
  779.  *      should pick a character for sep that can't be part of a
  780.  *      legal URI.
  781.  *
  782.  *      Under namespace processing, expat consumes xmlns and xmlns:...
  783.  *      attributes, which declare namespaces for the scope of the
  784.  *      element in which they occur. This means that your start
  785.  *      handler will not see these attributes. Your application can
  786.  *      still be informed of these declarations by setting namespace
  787.  *      declaration handlers with XML_SetNamespaceDeclHandler.
  788.  *
  789.  *      Element type and attribute names that belong to a given
  790.  *      namespace are passed to the appropriate handler in expanded
  791.  *      form. By default this expanded form is a concatenation of the
  792.  *      namespace URI, the separator character (which is the 2nd
  793.  *      argument to XML_ParserCreateNS), and the local name (i.e.
  794.  *      the part after the colon). Names with undeclared prefixes
  795.  *      are passed through to the handlers unchanged, with the prefix
  796.  *      and colon still attached. Unprefixed attribute names are never
  797.  *      expanded, and unprefixed element names are only expanded when
  798.  *      they are in the scope of a default namespace.
  799.  *
  800.  *      However if XML_SetReturnNSTriplet has been called with a
  801.  *      non-zero do_nst parameter, then the expanded form for names
  802.  *      with an explicit prefix is a concatenation of: URI, separator,
  803.  *      local name, separator, prefix.
  804.  *
  805.  *      You can set handlers for the start of a namespace declaration
  806.  *      and for the end of a scope of a declaration with the
  807.  *      XML_SetNamespaceDeclHandler function. The
  808.  *      StartNamespaceDeclHandler is called prior to the start
  809.  *      tag handler and the EndNamespaceDeclHandler is called before
  810.  *      the corresponding end tag that ends the namespace's scope.
  811.  *      The namespace start handler gets passed the prefix and URI
  812.  *      for the namespace. For a default namespace declaration
  813.  *      (xmlns='...'), the prefix will be null. The URI will be null
  814.  *      for the case where the default namespace is being unset. The
  815.  *      namespace end handler just gets the prefix for the closing
  816.  *      scope.
  817.  *
  818.  *      These handlers are called for each declaration. So if, for
  819.  *      instance, a start tag had three namespace declarations, then
  820.  *      the StartNamespaceDeclHandler would be called three times
  821.  *      before the start tag handler is called, once for each
  822.  *      declaration.
  823.  *
  824.  *      The namespace.c example demonstrates the use of these
  825.  *      features. Like outline.c, it produces an outline, but in
  826.  *      addition it annotates when a namespace scope starts and
  827.  *      when it ends. This example also demonstrates use of
  828.  *      application user data.
  829.  */
  830.  
  831. XML_Parser XML_ParserCreateNS(const XML_Char * encodingName,
  832.                               XML_Char nsSep)
  833. {
  834.     XML_Char tmp[2];
  835.  
  836.     *tmp = nsSep;
  837.     return XML_ParserCreate_MM(encodingName, NULL, tmp);
  838. }
  839.  
  840. /*
  841.  *@@ XML_ParserCreate_MM:
  842.  *      constructs a new parser using the suite of memory handling
  843.  *      functions specified in ms. If ms is NULL, then use the
  844.  *      standard set of memory management functions. If sep is
  845.  *      non-NULL, then namespace processing is enabled in the
  846.  *      created parser and the character pointed at by sep is
  847.  *      used as the separator between the namespace URI and the
  848.  *      local part of the name.
  849.  */
  850.  
  851. XML_Parser XML_ParserCreate_MM(const XML_Char * encodingName,
  852.                                const XML_Memory_Handling_Suite * memsuite,
  853.                                const XML_Char * nameSep)
  854. {
  855.  
  856.     XML_Parser parser;
  857.     static
  858.     const XML_Char implicitContext[] =
  859.     {
  860.         XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
  861.         XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
  862.         XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
  863.         XML_T('.'), XML_T('w'), XML_T('3'),
  864.         XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
  865.         XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
  866.         XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
  867.         XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
  868.         XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
  869.         XML_T('\0')
  870.     };
  871.  
  872.  
  873.     if (memsuite)
  874.     {
  875.         XML_Memory_Handling_Suite *mtemp;
  876.  
  877.         parser = memsuite->malloc_fcn(sizeof(Parser));
  878.         mtemp = &(((Parser *) parser)->m_mem);
  879.         mtemp->malloc_fcn = memsuite->malloc_fcn;
  880.         mtemp->realloc_fcn = memsuite->realloc_fcn;
  881.         mtemp->free_fcn = memsuite->free_fcn;
  882.     }
  883.     else
  884.     {
  885.         XML_Memory_Handling_Suite *mtemp;
  886.  
  887.         parser = malloc(sizeof(Parser));
  888.         mtemp = &(((Parser *) parser)->m_mem);
  889.         mtemp->malloc_fcn = malloc;
  890.         mtemp->realloc_fcn = realloc;
  891.         mtemp->free_fcn = free;
  892.     }
  893.  
  894.     if (!parser)
  895.         return parser;
  896.     processor = prologInitProcessor;
  897.     XmlPrologStateInit(&prologState);
  898.     userData = 0;
  899.     handlerArg = 0;
  900.     startElementHandler = 0;
  901.     endElementHandler = 0;
  902.     characterDataHandler = 0;
  903.     processingInstructionHandler = 0;
  904.     commentHandler = 0;
  905.     startCdataSectionHandler = 0;
  906.     endCdataSectionHandler = 0;
  907.     defaultHandler = 0;
  908.     startDoctypeDeclHandler = 0;
  909.     endDoctypeDeclHandler = 0;
  910.     unparsedEntityDeclHandler = 0;
  911.     notationDeclHandler = 0;
  912.     startNamespaceDeclHandler = 0;
  913.     endNamespaceDeclHandler = 0;
  914.     notStandaloneHandler = 0;
  915.     externalEntityRefHandler = 0;
  916.     externalEntityRefHandlerArg = parser;
  917.     unknownEncodingHandler = 0;
  918.     elementDeclHandler = 0;
  919.     attlistDeclHandler = 0;
  920.     entityDeclHandler = 0;
  921.     xmlDeclHandler = 0;
  922.     buffer = 0;
  923.     bufferPtr = 0;
  924.     bufferEnd = 0;
  925.     parseEndByteIndex = 0;
  926.     parseEndPtr = 0;
  927.     bufferLim = 0;
  928.     declElementType = 0;
  929.     declAttributeId = 0;
  930.     declEntity = 0;
  931.     doctypeName = 0;
  932.     doctypeSysid = 0;
  933.     doctypePubid = 0;
  934.     declAttributeType = 0;
  935.     declNotationName = 0;
  936.     declNotationPublicId = 0;
  937.     memset(&position, 0, sizeof(POSITION));
  938.     errorCode = ERROR_EXPAT_NONE;
  939.     eventPtr = 0;
  940.     eventEndPtr = 0;
  941.     positionPtr = 0;
  942.     openInternalEntities = 0;
  943.     tagLevel = 0;
  944.     tagStack = 0;
  945.     freeTagList = 0;
  946.     freeBindingList = 0;
  947.     inheritedBindings = 0;
  948.     attsSize = INIT_ATTS_SIZE;
  949.     atts = (ATTRIBUTE*)MALLOC(attsSize * sizeof(ATTRIBUTE));
  950.     nSpecifiedAtts = 0;
  951.     dataBuf = (XML_Char*)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
  952.     groupSize = 0;
  953.     groupConnector = 0;
  954.     hadExternalDoctype = 0;
  955.     unknownEncodingMem = 0;
  956.     unknownEncodingRelease = 0;
  957.     unknownEncodingData = 0;
  958.     unknownEncodingHandlerData = 0;
  959.     namespaceSeparator = '!';
  960. #ifdef XML_DTD
  961.     parentParser = 0;
  962.     paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
  963. #endif
  964.     ns = 0;
  965.     ns_triplets = 0;
  966.     poolInit(&tempPool, &(((Parser *) parser)->m_mem));
  967.     poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
  968.     protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
  969.     curBase = 0;
  970.     if (!dtdInit(&dtd, parser) || !atts || !dataBuf
  971.         || (encodingName && !protocolEncodingName))
  972.     {
  973.         XML_ParserFree(parser);
  974.         return 0;
  975.     }
  976.     dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
  977.  
  978.     if (nameSep)
  979.     {
  980.         XmlInitEncodingNS(&initEncoding, &encoding, 0);
  981.         ns = 1;
  982.         internalEncoding = XmlGetInternalEncodingNS();
  983.         namespaceSeparator = *nameSep;
  984.  
  985.         if (!setContext(parser, implicitContext))
  986.         {
  987.             XML_ParserFree(parser);
  988.             return 0;
  989.         }
  990.     }
  991.     else
  992.     {
  993.         XmlInitEncoding(&initEncoding, &encoding, 0);
  994.         internalEncoding = XmlGetInternalEncoding();
  995.     }
  996.  
  997.     return parser;
  998. }                               /* End XML_ParserCreate_MM */
  999.  
  1000. /*
  1001.  *@@ XML_SetEncoding:
  1002.  *      sets the encoding to be used by the parser. It is
  1003.  *      equivalent to passing a non-null encoding argument
  1004.  *      to the parser creation functions. It must not be
  1005.  *      called after XML_Parser or XML_ParseBuffer have
  1006.  *      been called on the given parser.
  1007.  */
  1008.  
  1009. int XML_SetEncoding(XML_Parser parser,
  1010.                     const XML_Char * encodingName)
  1011. {
  1012.     if (!encodingName)
  1013.         protocolEncodingName = 0;
  1014.     else
  1015.     {
  1016.         protocolEncodingName = poolCopyString(&tempPool, encodingName);
  1017.         if (!protocolEncodingName)
  1018.             return 0;
  1019.     }
  1020.     return 1;
  1021. }
  1022.  
  1023. /*
  1024.  *@@ XML_ExternalEntityParserCreate:
  1025.  *      constructs a new XML_Parser object for parsing an external
  1026.  *      general entity. Context is the context argument passed in a
  1027.  *      call to a ExternalEntityRefHandler. Other state information
  1028.  *      such as handlers, user data, namespace processing is
  1029.  *      inherited from the parser passed as the 1st argument. So you
  1030.  *      shouldn't need to call any of the behavior changing
  1031.  *      functions on this parser (unless you want it to act
  1032.  *      differently than the parent parser.)
  1033.  */
  1034.  
  1035. XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
  1036.                                           const XML_Char * context,
  1037.                                           const XML_Char * encodingName)
  1038. {
  1039.     XML_Parser parser = oldParser;
  1040.     DTD *oldDtd = &dtd;
  1041.     XML_StartElementHandler oldStartElementHandler = startElementHandler;
  1042.     XML_EndElementHandler oldEndElementHandler = endElementHandler;
  1043.     XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
  1044.     XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
  1045.     XML_CommentHandler oldCommentHandler = commentHandler;
  1046.     XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
  1047.     XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
  1048.     XML_DefaultHandler oldDefaultHandler = defaultHandler;
  1049.     XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
  1050.     XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
  1051.     XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
  1052.     XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
  1053.     XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
  1054.     XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
  1055.     XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
  1056.     XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
  1057.     XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
  1058.     XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
  1059.     XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
  1060.     ELEMENT_TYPE *oldDeclElementType = declElementType;
  1061.  
  1062.     void *oldUserData = userData;
  1063.     void *oldHandlerArg = handlerArg;
  1064.     int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
  1065.     void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
  1066.  
  1067. #ifdef XML_DTD
  1068.     enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
  1069.  
  1070. #endif
  1071.     int oldns_triplets = ns_triplets;
  1072.  
  1073.     if (ns)
  1074.     {
  1075.         XML_Char tmp[2];
  1076.  
  1077.         *tmp = namespaceSeparator;
  1078.         parser = XML_ParserCreate_MM(encodingName, &((Parser *) parser)->m_mem,
  1079.                                      tmp);
  1080.     }
  1081.     else
  1082.     {
  1083.         parser = XML_ParserCreate_MM(encodingName, &((Parser *) parser)->m_mem,
  1084.                                      NULL);
  1085.     }
  1086.  
  1087.     if (!parser)
  1088.         return 0;
  1089.  
  1090.     startElementHandler = oldStartElementHandler;
  1091.     endElementHandler = oldEndElementHandler;
  1092.     characterDataHandler = oldCharacterDataHandler;
  1093.     processingInstructionHandler = oldProcessingInstructionHandler;
  1094.     commentHandler = oldCommentHandler;
  1095.     startCdataSectionHandler = oldStartCdataSectionHandler;
  1096.     endCdataSectionHandler = oldEndCdataSectionHandler;
  1097.     defaultHandler = oldDefaultHandler;
  1098.     unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
  1099.     notationDeclHandler = oldNotationDeclHandler;
  1100.     startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
  1101.     endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
  1102.     notStandaloneHandler = oldNotStandaloneHandler;
  1103.     externalEntityRefHandler = oldExternalEntityRefHandler;
  1104.     unknownEncodingHandler = oldUnknownEncodingHandler;
  1105.     elementDeclHandler = oldElementDeclHandler;
  1106.     attlistDeclHandler = oldAttlistDeclHandler;
  1107.     entityDeclHandler = oldEntityDeclHandler;
  1108.     xmlDeclHandler = oldXmlDeclHandler;
  1109.     declElementType = oldDeclElementType;
  1110.     userData = oldUserData;
  1111.     if (oldUserData == oldHandlerArg)
  1112.         handlerArg = userData;
  1113.     else
  1114.         handlerArg = parser;
  1115.     if (oldExternalEntityRefHandlerArg != oldParser)
  1116.         externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
  1117.     defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
  1118.     ns_triplets = oldns_triplets;
  1119. #ifdef XML_DTD
  1120.     paramEntityParsing = oldParamEntityParsing;
  1121.     if (context)
  1122.     {
  1123. #endif /* XML_DTD */
  1124.         if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context))
  1125.         {
  1126.             XML_ParserFree(parser);
  1127.             return 0;
  1128.         }
  1129.         processor = externalEntityInitProcessor;
  1130. #ifdef XML_DTD
  1131.     }
  1132.     else
  1133.     {
  1134.         dtdSwap(&dtd, oldDtd);
  1135.         parentParser = oldParser;
  1136.         XmlPrologStateInitExternalEntity(&prologState);
  1137.         dtd.complete = 1;
  1138.         hadExternalDoctype = 1;
  1139.     }
  1140. #endif /* XML_DTD */
  1141.     return parser;
  1142. }
  1143.  
  1144. static void destroyBindings(BINDING * bindings,
  1145.                             XML_Parser parser)
  1146. {
  1147.     for (;;)
  1148.     {
  1149.         BINDING *b = bindings;
  1150.  
  1151.         if (!b)
  1152.             break;
  1153.         bindings = b->nextTagBinding;
  1154.         FREE(b->uri);
  1155.         FREE(b);
  1156.     }
  1157. }
  1158.  
  1159. /*
  1160.  *@@ XML_ParserFree:
  1161.  *      free memory used by the parser. Your application is
  1162.  *      responsible for freeing any memory associated
  1163.  *      with UserData.
  1164.  */
  1165.  
  1166. void XML_ParserFree(XML_Parser parser)
  1167. {
  1168.     for (;;)
  1169.     {
  1170.         TAG *p;
  1171.  
  1172.         if (tagStack == 0)
  1173.         {
  1174.             if (freeTagList == 0)
  1175.                 break;
  1176.             tagStack = freeTagList;
  1177.             freeTagList = 0;
  1178.         }
  1179.         p = tagStack;
  1180.         tagStack = tagStack->parent;
  1181.         FREE(p->buf);
  1182.         destroyBindings(p->bindings, parser);
  1183.         FREE(p);
  1184.     }
  1185.     destroyBindings(freeBindingList, parser);
  1186.     destroyBindings(inheritedBindings, parser);
  1187.     poolDestroy(&tempPool);
  1188.     poolDestroy(&temp2Pool);
  1189. #ifdef XML_DTD
  1190.     if (parentParser)
  1191.     {
  1192.         if (hadExternalDoctype)
  1193.             dtd.complete = 0;
  1194.         dtdSwap(&dtd, &((Parser *) parentParser)->m_dtd);
  1195.     }
  1196. #endif /* XML_DTD */
  1197.     dtdDestroy(&dtd, parser);
  1198.     FREE((void *)atts);
  1199.     if (groupConnector)
  1200.         FREE(groupConnector);
  1201.     if (buffer)
  1202.         FREE(buffer);
  1203.     FREE(dataBuf);
  1204.     if (unknownEncodingMem)
  1205.         FREE(unknownEncodingMem);
  1206.     if (unknownEncodingRelease)
  1207.         unknownEncodingRelease(unknownEncodingData);
  1208.     FREE(parser);
  1209. }
  1210.  
  1211. /*
  1212.  *@@ XML_UseParserAsHandlerArg:
  1213.  *      after this is called, handlers receive the parser in the
  1214.  *      userData argument (see XML_SetUserData). The userData
  1215.  *      information can still be obtained using the XML_GetUserData
  1216.  *      function.
  1217.  */
  1218.  
  1219. void XML_UseParserAsHandlerArg(XML_Parser parser)
  1220. {
  1221.     handlerArg = parser;
  1222. }
  1223.  
  1224. /*
  1225.  *@@ XML_SetReturnNSTriplet:
  1226.  *      this function only has an effect when using a parser
  1227.  *      created with XML_ParserCreateNS, i.e. when namespace
  1228.  *      processing is in effect. The do_nst sets whether or
  1229.  *      not prefixes are returned with names qualified with
  1230.  *      a namespace prefix. If this function is called with
  1231.  *      do_nst non-zero, then afterwards namespace qualified
  1232.  *      names (that is qualified with a prefix as opposed to
  1233.  *      belonging to a default namespace) are returned as a
  1234.  *      triplet with the three parts separated by the namespace
  1235.  *      separator specified when the parser was created. The
  1236.  *      order of returned parts is URI, local name, and prefix.
  1237.  *
  1238.  *      If do_nst is zero, then namespaces are reported in
  1239.  *      the default manner, URI then local_name separated by
  1240.  *      the namespace separator.
  1241.  */
  1242.  
  1243. void XML_SetReturnNSTriplet(XML_Parser parser,
  1244.                             int do_nst)
  1245. {
  1246.     ns_triplets = do_nst;
  1247. }
  1248.  
  1249. /*
  1250.  *@@ XML_SetUserData:
  1251.  *      sets the user data pointer that gets passed to handlers.
  1252.  *
  1253.  *      It overwrites any previous value for this pointer. Note that
  1254.  *      the application is responsible for freeing the memory
  1255.  *      associated with userData when it is finished with the parser.
  1256.  *      So if you call this when there's already a pointer there, and
  1257.  *      you haven't freed the memory associated with it, then you've
  1258.  *      probably just leaked memory.
  1259.  *
  1260.  *      Also see XML_UseParserAsHandlerArg.
  1261.  */
  1262.  
  1263. void XML_SetUserData(XML_Parser parser,
  1264.                      void *p)
  1265. {
  1266.     if (handlerArg == userData)
  1267.         handlerArg = userData = p;
  1268.     else
  1269.         userData = p;
  1270. }
  1271.  
  1272. /*
  1273.  *@@ XML_SetBase:
  1274.  *      set the base to be used for resolving relative URIs in
  1275.  *      system identifiers. The return value is 0 if there's no
  1276.  *      memory to store base, otherwise it's non-zero.
  1277.  */
  1278.  
  1279. int XML_SetBase(XML_Parser parser,
  1280.                 const XML_Char * p)
  1281. {
  1282.     if (p)
  1283.     {
  1284.         p = poolCopyString(&dtd.pool, p);
  1285.         if (!p)
  1286.             return 0;
  1287.         curBase = p;
  1288.     }
  1289.     else
  1290.         curBase = 0;
  1291.     return 1;
  1292. }
  1293.  
  1294. /*
  1295.  *@@ XML_GetBase:
  1296.  *      returns the base for resolving relative URIs.
  1297.  *      See XML_SetBase.
  1298.  */
  1299.  
  1300. const XML_Char *XML_GetBase(XML_Parser parser)
  1301. {
  1302.     return curBase;
  1303. }
  1304.  
  1305. /*
  1306.  *@@ XML_GetSpecifiedAttributeCount:
  1307.  *      when attributes are reported to the start handler in the
  1308.  *      atts vector, attributes that were explicitly set in the
  1309.  *      element occur before any attributes that receive their
  1310.  *      value from default information in an ATTLIST declaration.
  1311.  *      This function returns the number of attributes that were
  1312.  *      explicitly set times two, thus giving the offset in the
  1313.  *      atts array passed to the start tag handler of the first
  1314.  *      attribute set due to defaults. It supplies information
  1315.  *      for the last call to a start handler. If called inside a
  1316.  *      start handler, then that means the current call.
  1317.  */
  1318.  
  1319. int XML_GetSpecifiedAttributeCount(XML_Parser parser)
  1320. {
  1321.     return nSpecifiedAtts;
  1322. }
  1323.  
  1324. /*
  1325.  *@@ XML_GetIdAttributeIndex:
  1326.  *      returns the index of the ID attribute passed in the atts
  1327.  *      array in the last call to XML_StartElementHandler, or -1
  1328.  *      if there is no ID attribute. If called inside a start
  1329.  *      handler, then that means the current call.
  1330.  */
  1331.  
  1332. int XML_GetIdAttributeIndex(XML_Parser parser)
  1333. {
  1334.     return idAttIndex;
  1335. }
  1336.  
  1337. /*
  1338.  *@@ XML_SetElementHandler:
  1339.  *      sets handlers for start and end tags with one call.
  1340.  *
  1341.  *      See XML_SetStartElementHandler and XML_SetEndElementHandler
  1342.  *      for details.
  1343.  */
  1344.  
  1345. void XML_SetElementHandler(XML_Parser parser,
  1346.                            XML_StartElementHandler start,
  1347.                            XML_EndElementHandler end)
  1348. {
  1349.     startElementHandler = start;
  1350.     endElementHandler = end;
  1351. }
  1352.  
  1353. /*
  1354.  *@@ XML_SetStartElementHandler:
  1355.  *      sets handler for start (and empty) tags.
  1356.  *
  1357.  *      This handler must have the following prototype:
  1358.  *
  1359.  +          void EXPATENTRY StartElementHandler(void *pUserData,
  1360.  +                                              const XML_Char *name,
  1361.  +                                              const XML_Char **atts);
  1362.  +
  1363.  *      "data" is the user data pointer set with XML_SetUserData.
  1364.  *
  1365.  *      "name" is the element name.
  1366.  *
  1367.  *      Attributes are passed to the start handler as a pointer
  1368.  *      to a vector of char pointers. Each attribute seen in a
  1369.  *      start (or empty) tag occupies 2 consecutive places in
  1370.  *      this vector: the attribute name followed by the attribute
  1371.  *      value. These pairs are terminated by a null pointer.
  1372.  *
  1373.  *      Note that an empty tag generates a call to both start
  1374.  *      and end handlers (in that order).
  1375.  *
  1376.  *      Although handlers are typically set prior to parsing and left
  1377.  *      alone, an application may choose to set or change the handler
  1378.  *      for a parsing event while the parse is in progress. For
  1379.  *      instance, your application may choose to ignore all text not
  1380.  *      descended from a para element. One way it could do this is to
  1381.  *      set the character handler when a para start tag is seen, and
  1382.  *      unset it for the corresponding end tag.
  1383.  *
  1384.  *      A handler may be unset by providing a NULL pointer to the
  1385.  *      appropriate handler setter. None of the handler setting
  1386.  *      functions have a return value.
  1387.  *
  1388.  *      Your handlers will be receiving strings in arrays of type
  1389.  *      XML_Char. This type is defined in expat.h as char* and
  1390.  *      contains bytes encoding UTF-8. Note that you'll receive them
  1391.  *      in this form independent of the original encoding of the
  1392.  *      document.
  1393.  */
  1394.  
  1395. void XML_SetStartElementHandler(XML_Parser parser,
  1396.                                 XML_StartElementHandler start)
  1397. {
  1398.     startElementHandler = start;
  1399. }
  1400.  
  1401. /*
  1402.  *@@ XML_SetEndElementHandler:
  1403.  *      sets handler for end (and empty) tags. As noted above, an
  1404.  *      empty tag generates a call to both start and end handlers.
  1405.  *
  1406.  *      Handler prototype:
  1407.  +
  1408.  +          void EXPATENTRY EndElementHandler(void *pUserData,
  1409.  +                                            const XML_Char *name);
  1410.  */
  1411.  
  1412. void XML_SetEndElementHandler(XML_Parser parser,
  1413.                               XML_EndElementHandler end)
  1414. {
  1415.     endElementHandler = end;
  1416. }
  1417.  
  1418. /*
  1419.  *@@ XML_SetCharacterDataHandler:
  1420.  *      sets a character data (text, @content) handler.
  1421.  *
  1422.  *      Handler prototype:
  1423.  *
  1424.  +          void EXPATENTRY CharacterDataHandler(void *pUserData,
  1425.  +                                               const XML_Char *s,
  1426.  +                                               int len);
  1427.  +
  1428.  *      The string your handler receives is NOT zero terminated.
  1429.  *      You have to use the length argument to deal with the end
  1430.  *      of the string. A single block of contiguous text free of
  1431.  *      markup may still result in a sequence of calls to this
  1432.  *      handler. In other words, if you're searching for a pattern
  1433.  *      in the text, it may be split across calls to this handler.
  1434.  */
  1435.  
  1436. void XML_SetCharacterDataHandler(XML_Parser parser,
  1437.                                  XML_CharacterDataHandler handler)
  1438. {
  1439.     characterDataHandler = handler;
  1440. }
  1441.  
  1442. /*
  1443.  *@@ XML_SetProcessingInstructionHandler:
  1444.  *      sets a handler for processing instructions.
  1445.  *
  1446.  *      Handler prototype:
  1447.  *
  1448.  +          void EXPATENTRY ProcessingInstructionHandler(void *pUserData,
  1449.  +                                                       const XML_Char *target,
  1450.  +                                                       const XML_Char *data);
  1451.  +
  1452.  *      The target is the first word in the processing instruction. The data
  1453.  *      is the rest of the characters in it after skipping all
  1454.  *      whitespace after the initial word.
  1455.  */
  1456.  
  1457. void XML_SetProcessingInstructionHandler(XML_Parser parser,
  1458.                                      XML_ProcessingInstructionHandler handler)
  1459. {
  1460.     processingInstructionHandler = handler;
  1461. }
  1462.  
  1463. /*
  1464.  *@@ XML_SetCommentHandler:
  1465.  *      sets a handler for comments. The data is all text inside
  1466.  *      the comment delimiters.
  1467.  *
  1468.  *      Handler prototype:
  1469.  *
  1470.  +          void EXPATENTRY CommentHandler(void *pUserData,
  1471.  +                                         const XML_Char *data);
  1472.  *
  1473.  */
  1474.  
  1475. void XML_SetCommentHandler(XML_Parser parser,
  1476.                            XML_CommentHandler handler)
  1477. {
  1478.     commentHandler = handler;
  1479. }
  1480.  
  1481. /*
  1482.  *@@ XML_SetCdataSectionHandler:
  1483.  *      combination of XML_SetStartCdataSectionHandler and
  1484.  *      XML_SetEndCdataSectionHandler in one call.
  1485.  */
  1486.  
  1487. void XML_SetCdataSectionHandler(XML_Parser parser,
  1488.                                 XML_StartCdataSectionHandler start,
  1489.                                 XML_EndCdataSectionHandler end)
  1490. {
  1491.     startCdataSectionHandler = start;
  1492.     endCdataSectionHandler = end;
  1493. }
  1494.  
  1495. /*
  1496.  *@@ XML_SetCdataSectionHandler:
  1497.  *      sets a handler that gets called at the beginning of a CDATA
  1498.  *      section.
  1499.  *
  1500.  *      Handler prototype:
  1501.  *
  1502.  +          void EXPATENTRY StartCdataSectionHandler(void *pUserData);
  1503.  *
  1504.  */
  1505.  
  1506. void XML_SetStartCdataSectionHandler(XML_Parser parser,
  1507.                                      XML_StartCdataSectionHandler start)
  1508. {
  1509.     startCdataSectionHandler = start;
  1510. }
  1511.  
  1512. /*
  1513.  *@@ XML_SetCdataSectionHandler:
  1514.  *      sets a handler that gets called at the end of a CDATA
  1515.  *      section.
  1516.  *
  1517.  *      Handler prototype:
  1518.  *
  1519.  *          void EXPATENTRY EndCdataSectionHandler(void *pUserData);
  1520.  */
  1521.  
  1522. void XML_SetEndCdataSectionHandler(XML_Parser parser,
  1523.                                    XML_EndCdataSectionHandler end)
  1524. {
  1525.     endCdataSectionHandler = end;
  1526. }
  1527.  
  1528. /*
  1529.  *@@ XML_SetDefaultHandler:
  1530.  *      sets a handler for any characters in the document for
  1531.  *      which there is no applicable handler.
  1532.  *
  1533.  *      This includes both data for which no handlers can be set
  1534.  *      (like some kinds of DTD declarations) and data which could
  1535.  *      be reported but for which there has no handler supplied.
  1536.  *
  1537.  *      Handler prototype:
  1538.  +
  1539.  +          void EXPATENTRY DefaultHandler(void *pUserData,
  1540.  +                                         const XML_Char *s,
  1541.  +                                         int len);
  1542.  *
  1543.  *      The characters are passed exactly as they were in the XML
  1544.  *      document except that they will be encoded in UTF-8.  Line
  1545.  *      boundaries are not normalized.
  1546.  *
  1547.  *      Note that a byte order mark character is not passed to the
  1548.  *      default handler.
  1549.  *
  1550.  *      Note that a contiguous piece of data that is destined to
  1551.  *      be reported to the default handler may actually be reported
  1552.  *      over several calls to the handler.
  1553.  *
  1554.  *      Setting the handler with this call has the side effect of
  1555.  *      turning off expansion of references to internally defined
  1556.  *      general entities. Instead these references are passed to
  1557.  *      the default handler. To avoid that, use XML_SetDefaultHandlerExpand.
  1558.  */
  1559.  
  1560. void XML_SetDefaultHandler(XML_Parser parser,
  1561.                            XML_DefaultHandler handler)
  1562. {
  1563.     defaultHandler = handler;
  1564.     defaultExpandInternalEntities = 0;
  1565. }
  1566.  
  1567. /*
  1568.  *@@ XML_SetDefaultHandlerExpand:
  1569.  *      this sets a default handler, but doesn't affect expansion of
  1570.  *      internal entity references.
  1571.  *
  1572.  *      See XML_SetDefaultHandler.
  1573.  */
  1574.  
  1575. void XML_SetDefaultHandlerExpand(XML_Parser parser,
  1576.                                  XML_DefaultHandler handler)
  1577. {
  1578.     defaultHandler = handler;
  1579.     defaultExpandInternalEntities = 1;
  1580. }
  1581.  
  1582. /*
  1583.  *@@ XML_SetDoctypeDeclHandler:
  1584.  *      combination of XML_SetStartDoctypeDeclHandler and
  1585.  *      XML_SetEndDoctypeDeclHandler.
  1586.  */
  1587.  
  1588. void XML_SetDoctypeDeclHandler(XML_Parser parser,
  1589.                                XML_StartDoctypeDeclHandler start,
  1590.                                XML_EndDoctypeDeclHandler end)
  1591. {
  1592.     startDoctypeDeclHandler = start;
  1593.     endDoctypeDeclHandler = end;
  1594. }
  1595.  
  1596. /*
  1597.  *@@ XML_SetStartDoctypeDeclHandler:
  1598.  *      sets a handler that is called at the start of a DOCTYPE
  1599.  *      declaration, before any external or internal subset is
  1600.  *      parsed.
  1601.  *
  1602.  *      Handler prototype:
  1603.  *
  1604.  +          void EXPATENTRY StartDoctypeDeclHandler(void *pUserData,
  1605.  +                                                  const XML_Char *pcszDoctypeName,
  1606.  +                                                  const XML_Char *pcszSysid,
  1607.  +                                                  const XML_Char *pcszPubid,
  1608.  +                                                  int fHasInternalSubset);
  1609.  *
  1610.  *      Both pcszSysid and pcszPubid may be NULL. "fHasInternalSubset"
  1611.  *      will be non-zero if the DOCTYPE declaration has an internal subset.
  1612.  */
  1613.  
  1614. void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
  1615.                                     XML_StartDoctypeDeclHandler start)
  1616. {
  1617.     startDoctypeDeclHandler = start;
  1618. }
  1619.  
  1620. /*
  1621.  *@@ XML_SetEndDoctypeDeclHandler:
  1622.  *      sets a handler that is called at the end of a DOCTYPE
  1623.  *      declaration, after parsing any external subset.
  1624.  *
  1625.  *      Handler prototype:
  1626.  *
  1627.  +          void EXPATENTRY EndDoctypeDeclHandler(void *pUserData);
  1628.  *
  1629.  */
  1630.  
  1631. void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
  1632.                                   XML_EndDoctypeDeclHandler end)
  1633. {
  1634.     endDoctypeDeclHandler = end;
  1635. }
  1636.  
  1637. /*
  1638.  *@@ XML_SetUnparsedEntityDeclHandler:
  1639.  *      sets a handler that receives declarations of unparsed
  1640.  *      entities. These are entity declarations that have a
  1641.  *      notation (NDATA) field:
  1642.  *
  1643.  +           <!ENTITY logo SYSTEM "images/logo.gif" NDATA gif>
  1644.  *
  1645.  *      This handler is obsolete and is provided for backwards
  1646.  *      compatibility. Use instead XML_SetEntityDeclHandler.
  1647.  */
  1648.  
  1649. void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
  1650.                                       XML_UnparsedEntityDeclHandler handler)
  1651. {
  1652.     unparsedEntityDeclHandler = handler;
  1653. }
  1654.  
  1655. /*
  1656.  *@@ XML_SetNotationDeclHandler:
  1657.  *      sets a handler that receives notation declarations.
  1658.  *
  1659.  *      Handler prototype:
  1660.  +
  1661.  +      void EXPATENTRY NotationDeclHandler(void *pUserData,
  1662.  +                                          const XML_Char *pcszNotationName,
  1663.  +                                          const XML_Char *pcszBase,
  1664.  +                                          const XML_Char *pcszSystemId,
  1665.  +                                          const XML_Char *pcszPublicId);
  1666.  +
  1667.  */
  1668.  
  1669. void XML_SetNotationDeclHandler(XML_Parser parser,
  1670.                                 XML_NotationDeclHandler handler)
  1671. {
  1672.     notationDeclHandler = handler;
  1673. }
  1674.  
  1675. /*
  1676.  *@@ XML_SetNamespaceDeclHandler:
  1677.  *      combination of XML_SetEndNamespaceDeclHandler and
  1678.  *      XML_SetEndNamespaceDeclHandler.
  1679.  */
  1680.  
  1681. void XML_SetNamespaceDeclHandler(XML_Parser parser,
  1682.                                  XML_StartNamespaceDeclHandler start,
  1683.                                  XML_EndNamespaceDeclHandler end)
  1684. {
  1685.     startNamespaceDeclHandler = start;
  1686.     endNamespaceDeclHandler = end;
  1687. }
  1688.  
  1689. /*
  1690.  *@@ XML_SetStartNamespaceDeclHandler:
  1691.  *      sets a handler to be called when a namespace is declared.
  1692.  *      Namespace declarations occur inside start tags. But the
  1693.  *      namespace declaration start handler is called before the
  1694.  *      start tag handler for each namespace declared in that start
  1695.  *      tag.
  1696.  *
  1697.  *      Handler prototype:
  1698.  *
  1699.  +      void EXPATENTRY StartNamespaceDeclHandler(void *pUserData,
  1700.  +                                                const XML_Char *prefix,
  1701.  +                                                const XML_Char *uri);
  1702.  +
  1703.  */
  1704.  
  1705. void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
  1706.                                       XML_StartNamespaceDeclHandler start)
  1707. {
  1708.     startNamespaceDeclHandler = start;
  1709. }
  1710.  
  1711. /*
  1712.  *@@ XML_SetEndNamespaceDeclHandler:
  1713.  *      sets a handler to be called when leaving the scope of a
  1714.  *      namespace declaration. This will be called, for each
  1715.  *      namespace declaration, after the handler for the end tag
  1716.  *      of the element in which the namespace was declared.
  1717.  *
  1718.  *      Handler prototype:
  1719.  +
  1720.  +      void EXPATENTRY EndNamespaceDeclHandler(void *pUserData,
  1721.  +                                              const XML_Char *prefix);
  1722.  */
  1723.  
  1724. void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
  1725.                                     XML_EndNamespaceDeclHandler end)
  1726. {
  1727.     endNamespaceDeclHandler = end;
  1728. }
  1729.  
  1730.  
  1731. /*
  1732.  *@@ XML_SetNotStandaloneHandler:
  1733.  *      sets a handler that is called if the document is not
  1734.  *      "standalone". This happens when there is an external
  1735.  *      subset or a reference to a parameter entity, but does
  1736.  *      not have standalone set to "yes" in an XML declaration.
  1737.  *      If this handler returns 0, then the parser will throw an
  1738.  *      ERROR_EXPAT_NOT_STANDALONE error.
  1739.  *
  1740.  *      Handler prototype:
  1741.  *
  1742.  +          int EXPATENTRY NotStandaloneHandler(void *pUserData);
  1743.  */
  1744.  
  1745. void XML_SetNotStandaloneHandler(XML_Parser parser,
  1746.                                  XML_NotStandaloneHandler handler)
  1747. {
  1748.     notStandaloneHandler = handler;
  1749. }
  1750.  
  1751. /*
  1752.  *@@ XML_SetExternalEntityRefHandler:
  1753.  *      sets a handler for references to @external_entities.
  1754.  *
  1755.  *      This handler is also called for processing an external DTD
  1756.  *      subset if parameter entity parsing is in effect.
  1757.  *      (See XML_SetParamEntityParsing.)
  1758.  *
  1759.  *      Warning: If you have set no ExternalEntityRefHandler, then
  1760.  *      external entity references are silently ignored. Otherwise,
  1761.  *      they trigger a call to your handler with the information
  1762.  *      needed to read and parse the external entity.
  1763.  *
  1764.  *      Handler prototype:
  1765.  +
  1766.  +      int EXPATENTRY ExternalEntityRefHandler(void *pUser,
  1767.  +                                              XML_Parser parser,
  1768.  +                                              const XML_Char *pcszContext,
  1769.  +                                              const XML_Char *pcszBase,
  1770.  +                                              const XML_Char *pcszSystemId,
  1771.  +                                              const XML_Char *pcszPublicId);
  1772.  +
  1773.  *      The pcszContext argument specifies the parsing context in the
  1774.  *      format expected by the context argument to
  1775.  *      XML_ExternalEntityParserCreate; pcszContext is valid only until
  1776.  *      the handler returns, so if the referenced entity is to be
  1777.  *      parsed later, it must be copied.
  1778.  *
  1779.  *      The pcszBase parameter is the base to use for relative system
  1780.  *      identifiers. It is set by XML_SetBase and may be null.
  1781.  *
  1782.  *      The pcszPublicId parameter is the public id given in the entity
  1783.  *      declaration and may be null.
  1784.  *
  1785.  *      The pcszSystemId is the system identifier specified in the
  1786.  *      entity declaration and is never null.
  1787.  *
  1788.  *      There are a couple of ways in which this handler differs
  1789.  *      from others. First, this handler returns an integer. A
  1790.  *      non-zero value should be returned for successful handling
  1791.  *      of the external entity reference. Returning a zero indicates
  1792.  *      failure, and causes the calling parser to return an
  1793.  *      ERROR_EXPAT_EXTERNAL_ENTITY_HANDLING error.
  1794.  *
  1795.  *      Second, instead of having pUserData as its first argument,
  1796.  *      it receives the parser that encountered the entity reference.
  1797.  *      This, along with the context parameter, may be used as
  1798.  *      arguments to a call to XML_ExternalEntityParserCreate.
  1799.  *      Using the returned parser, the body of the external entity
  1800.  *      can be recursively parsed.
  1801.  *
  1802.  *      Since this handler may be called recursively, it should not
  1803.  *      be saving information into global or static variables.
  1804.  *
  1805.  *      Your handler isn't actually responsible for parsing the entity,
  1806.  *      but it is responsible for creating a subsidiary parser with
  1807.  *      XML_ExternalEntityParserCreate that will do the job. That returns
  1808.  *      an instance of XML_Parser that has handlers and other data
  1809.  *      structures initialized from the parent parser. You may then use
  1810.  *      XML_Parse or XML_ParseBuffer calls against that parser. Since
  1811.  *      external entities may refer to other external entities, your
  1812.  *      handler should be prepared to be called recursively.
  1813.  *
  1814.  *@@changed V0.9.14 (2001-08-09) [umoeller]: changed prototype to contain user data
  1815.  */
  1816.  
  1817. void XML_SetExternalEntityRefHandler(XML_Parser parser,
  1818.                                      XML_ExternalEntityRefHandler handler)
  1819. {
  1820.     externalEntityRefHandler = handler;
  1821. }
  1822.  
  1823. void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
  1824. {
  1825.     if (arg)
  1826.         externalEntityRefHandlerArg = arg;
  1827.     else
  1828.         externalEntityRefHandlerArg = parser;
  1829. }
  1830.  
  1831. /*
  1832.  *@@ XML_SetUnknownEncodingHandler:
  1833.  *      sets a handler to deal with @encodings other than the
  1834.  *      built-in set.
  1835.  *
  1836.  *      There are four built-in encodings in expat:
  1837.  *
  1838.  *      --   UTF-8: 8-bit encoding of Unicode.
  1839.  *
  1840.  *      --   UTF-16: 16-bit encoding of Unicode.
  1841.  *
  1842.  *      --   ISO-8859-1: that's "latin 1".
  1843.  *
  1844.  *      --   US-ASCII
  1845.  *
  1846.  *      Anything else discovered in an encoding declaration or in
  1847.  *      the protocol encoding specified in the parser constructor
  1848.  *      triggers a call to the UnknownEncodingHandler.
  1849.  *
  1850.  *      Handler prototype:
  1851.  *
  1852.  +          int EXPATENTRY UnknownEncodingHandler(void *encodingHandlerData,
  1853.  +                                                const XML_Char *name,
  1854.  +                                                XML_Encoding *info);
  1855.  +
  1856.  *      The encodingHandlerData argument is that which was passed as the
  1857.  *      second argument to XML_SetUnknownEncodingHandler.
  1858.  *
  1859.  *      The name argument gives the name of the encoding as specified in
  1860.  *      the encoding declaration.
  1861.  *
  1862.  *      If the callback can provide information about the encoding,
  1863.  *      it must fill in the XML_Encoding structure, and return 1.
  1864.  *      Otherwise it must return 0.
  1865.  *      If info does not describe a suitable encoding,
  1866.  *      then the parser will return an XML_UNKNOWN_ENCODING error.
  1867.  *
  1868.  *      See _XML_Encoding for more details about that structure and
  1869.  *      what to do with it, and restrictions imposed by expat.
  1870.  *
  1871.  */
  1872.  
  1873. void XML_SetUnknownEncodingHandler(XML_Parser parser,
  1874.                                    XML_UnknownEncodingHandler handler,
  1875.                                    void *data)
  1876. {
  1877.     unknownEncodingHandler = handler;
  1878.     unknownEncodingHandlerData = data;
  1879. }
  1880.  
  1881. /*
  1882.  *@@ XML_SetElementDeclHandler:
  1883.  *      sets a handler for an @element_declaration in a @DTD. The
  1884.  *      handler gets called with the name of the element in
  1885.  *      the declaration and a pointer to a structure that contains
  1886.  *      the element model. It is the application's responsibility
  1887.  *      to free this data structure.
  1888.  *
  1889.  *      This handler must have the following prototype:
  1890.  *
  1891.  +          void EXPATENTRY ElementDeclHandler(void *pUserData,
  1892.  +                                             const XML_Char *name,
  1893.  +                                             XMLCONTENT *model);
  1894.  *
  1895.  *      See _XMLCONTENT for details.
  1896.  */
  1897.  
  1898. void XML_SetElementDeclHandler(XML_Parser parser,
  1899.                                XML_ElementDeclHandler eldecl)
  1900. {
  1901.     elementDeclHandler = eldecl;
  1902. }
  1903.  
  1904. /*
  1905.  *@@ XML_SetAttlistDeclHandler:
  1906.  *      sets a handler for an @attribute_declaration in the @DTD.
  1907.  *
  1908.  *      This handler must have the following prototype:
  1909.  *
  1910.  +          void EXPATENTRY AttlistDeclHandler(void *pUserData,
  1911.  +                                             const XML_Char *pcszElementName,
  1912.  +                                             const XML_Char *pcszAttribName,
  1913.  +                                             const XML_Char *pcszAttribType,
  1914.  +                                             const XML_Char *pcszDefault,
  1915.  +                                             int fIsRequired);
  1916.  *
  1917.  *      This handler is called for each attribute. So a single attlist
  1918.  *      declaration with multiple attributes declared will generate
  1919.  *      multiple calls to this handler.
  1920.  *
  1921.  *      --  pcszElementName is the name of the  element for which the
  1922.  *          attribute is being declared.
  1923.  *
  1924.  *      --  pcszAttribName has the attribute name being declared.
  1925.  *
  1926.  *      --  pcszAttribType is the attribute type.
  1927.  *          It is the string representing the type in the declaration
  1928.  *          with whitespace removed.
  1929.  *
  1930.  *      --  pcszDefault holds the default value. It will be
  1931.  *          NULL in the case of "#IMPLIED" or "#REQUIRED" attributes.
  1932.  *          You can distinguish these two cases by checking the
  1933.  *          fIsRequired parameter, which will be true in the case of
  1934.  *          "#REQUIRED" attributes. Attributes which are "#FIXED"
  1935.  *          will have also have a TRUE fIsRequired, but they will have
  1936.  *          the non-NULL fixed value in the pcszDefault parameter.
  1937.  */
  1938.  
  1939. void XML_SetAttlistDeclHandler(XML_Parser parser,
  1940.                                XML_AttlistDeclHandler attdecl)
  1941. {
  1942.     attlistDeclHandler = attdecl;
  1943. }
  1944.  
  1945. /*
  1946.  *@@ XML_SetEntityDeclHandler:
  1947.  *      sets a handler that will be called for all entity declarations.
  1948.  *
  1949.  *      Handler prototype:
  1950.  *
  1951.  +          void EXPATENTRY EntityDeclHandler(void *pUserData,
  1952.  +                                            const XML_Char *pcszEntityName,
  1953.  +                                            int fIsParameterEntity,
  1954.  +                                            const XML_Char *pcszValue,
  1955.  +                                            int iValueLength,
  1956.  +                                            const XML_Char *pcszBase,
  1957.  +                                            const XML_Char *pcszSystemId,
  1958.  +                                            const XML_Char *pcszPublicId,
  1959.  +                                            const XML_Char *pcszNotationName);
  1960.  +
  1961.  *      The fIsParameterEntity argument will be non-zero in the case
  1962.  *      of parameter entities and zero otherwise.
  1963.  *
  1964.  *      For internal entities (<!ENTITY foo "bar">), pcszValue will be
  1965.  *      non-NULL and pcszSystemId, pcszPublicId, and pcszNotationName
  1966.  *      will all be NULL. The value string is not NULL terminated; the
  1967.  *      lengthis provided in the iValueLength parameter. Do not use
  1968.  *      iValueLength to test for internal entities, since it is legal
  1969.  *      to have zero-length values. Instead check for whether or not
  1970.  *      pcszValue is NULL.
  1971.  *
  1972.  *      The pcszNotationName argument will have a non-NULL value only
  1973.  *      for unparsed entity declarations.
  1974.  */
  1975.  
  1976. void XML_SetEntityDeclHandler(XML_Parser parser,
  1977.                               XML_EntityDeclHandler handler)
  1978. {
  1979.     entityDeclHandler = handler;
  1980. }
  1981.  
  1982. /*
  1983.  *@@ XML_SetXmlDeclHandler:
  1984.  *      sets a handler that is called for XML declarations and also
  1985.  *      for text declarations discovered in external entities.
  1986.  *
  1987.  *      Handler prototype:
  1988.  *
  1989.  +          void EXPATENTRY XmlDeclHandler(void *pUserData,
  1990.  +                                         const XML_Char *pcszVersion,
  1991.  +                                         const XML_Char *pcszEncoding,
  1992.  +                                         int standalone);
  1993.  *
  1994.  *      The way to distinguish is that the version parameter will
  1995.  *      be NULL for text declarations. The encoding parameter may
  1996.  *      be NULL for an XML declaration. The standalone argument will
  1997.  *      contain -1, 0, or 1 indicating respectively that there was no
  1998.  *      standalone parameter in the declaration, that it was given
  1999.  *      as no, or that it was given as yes.
  2000.  */
  2001.  
  2002. void XML_SetXmlDeclHandler(XML_Parser parser,
  2003.                            XML_XmlDeclHandler handler)
  2004. {
  2005.     xmlDeclHandler = handler;
  2006. }
  2007.  
  2008. /*
  2009.  *@@ XML_SetParamEntityParsing:
  2010.  *      this enables parsing of @parameter_entities, including the
  2011.  *      external parameter entity that is the external @DTD subset,
  2012.  *      according to code.
  2013.  *
  2014.  *      If parsing of parameter entities is enabled, then references
  2015.  *      to external parameter entities (including the external DTD
  2016.  *      subset) will be passed to the handler set with
  2017.  *      XML_SetExternalEntityRefHandler. The context passed will be 0.
  2018.  *
  2019.  *      Unlike external general entities, external parameter entities
  2020.  *      can only be parsed synchronously. If the external parameter
  2021.  *      entity is to be parsed, it must be parsed during the call to
  2022.  *      the external entity ref handler: the complete sequence of
  2023.  *      XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
  2024.  *      XML_ParserFree calls must be made during this call.
  2025.  *
  2026.  *      After XML_ExternalEntityParserCreate has been called to create
  2027.  *      the parser for the external parameter entity (context must be 0
  2028.  *      for this call), it is illegal to make any calls on the old parser
  2029.  *      until XML_ParserFree has been called on the newly created parser.
  2030.  *      If the library has been compiled without support for parameter
  2031.  *      entity parsing (ie without XML_DTD being defined), then
  2032.  *      XML_SetParamEntityParsing will return 0 if parsing of parameter
  2033.  *      entities is requested; otherwise it will return non-zero.
  2034.  *
  2035.  *      NOTE: The xwphelpers implementation #defines XML_DTD in
  2036.  *      include\expat\expat_setup.h, which is included in all expat
  2037.  *      files.
  2038.  *
  2039.  *      The choices for code are:
  2040.  *
  2041.  *      --  XML_PARAM_ENTITY_PARSING_NEVER:
  2042.  *          Don't parse parameter entities or the external subset.
  2043.  *          This is the only choice if XML_DTD is not defined.
  2044.  *
  2045.  *      --  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE:
  2046.  *          Parse parameter entities and the external subset unless
  2047.  *          standalone was set to "yes" in the XML declaration.
  2048.  *
  2049.  *      --  XML_PARAM_ENTITY_PARSING_ALWAYS
  2050.  *          Always parse parameter entities and the external subset.
  2051.  *
  2052.  *      In order to read an external DTD, you also have to set an
  2053.  *      external entity reference handler (XML_SetExternalEntityRefHandler).
  2054.  */
  2055.  
  2056. int XML_SetParamEntityParsing(XML_Parser parser,
  2057.                               enum XML_ParamEntityParsing parsing)
  2058. {
  2059. #ifdef XML_DTD
  2060.     paramEntityParsing = parsing;
  2061.     return 1;
  2062. #else
  2063.     return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
  2064. #endif
  2065. }
  2066.  
  2067. /*
  2068.  *@@ XML_Parse:
  2069.  *      parses some more of the document.
  2070.  *
  2071.  *      The string s is a buffer containing part (or perhaps all)
  2072.  *      of the document. The number of bytes of s that are part
  2073.  *      of the document is indicated by len. This means that s
  2074.  *      doesn't have to be null terminated. It also means that
  2075.  *      if len is larger than the number of bytes in the block
  2076.  *      of memory that s points at, then a memory fault is
  2077.  *      likely. The isFinal parameter informs the parser that
  2078.  *      this is the last piece of the document. Frequently, the
  2079.  *      last piece is empty (i.e. len is zero.)
  2080.  *
  2081.  *      If a parse error occurred, it returns 0. Otherwise it
  2082.  *      returns a non-zero value.
  2083.  */
  2084.  
  2085. int XML_Parse(XML_Parser parser,
  2086.               const char *s,
  2087.               int len,
  2088.               int isFinal)
  2089. {
  2090.     if (len == 0)
  2091.     {
  2092.         if (!isFinal)
  2093.             return 1;
  2094.         positionPtr = bufferPtr;
  2095.         errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
  2096.         if (errorCode == ERROR_EXPAT_NONE)
  2097.             return 1;
  2098.         eventEndPtr = eventPtr;
  2099.         processor = errorProcessor;
  2100.         return 0;
  2101.     }
  2102. #ifndef XML_CONTEXT_BYTES
  2103.     else if (bufferPtr == bufferEnd)
  2104.     {
  2105.         const char *end;
  2106.         int nLeftOver;
  2107.  
  2108.         parseEndByteIndex += len;
  2109.         positionPtr = s;
  2110.         if (isFinal)
  2111.         {
  2112.             errorCode = processor(parser, s, parseEndPtr = s + len, 0);
  2113.             if (errorCode == ERROR_EXPAT_NONE)
  2114.                 return 1;
  2115.             eventEndPtr = eventPtr;
  2116.             processor = errorProcessor;
  2117.             return 0;
  2118.         }
  2119.         errorCode = processor(parser, s, parseEndPtr = s + len, &end);
  2120.         if (errorCode != ERROR_EXPAT_NONE)
  2121.         {
  2122.             eventEndPtr = eventPtr;
  2123.             processor = errorProcessor;
  2124.             return 0;
  2125.         }
  2126.         XmlUpdatePosition(encoding, positionPtr, end, &position);
  2127.         nLeftOver = s + len - end;
  2128.         if (nLeftOver)
  2129.         {
  2130.             if (buffer == 0 || nLeftOver > bufferLim - buffer)
  2131.             {
  2132.                 /* FIXME avoid integer overflow */
  2133.                 buffer = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
  2134.                 /* FIXME storage leak if realloc fails */
  2135.                 if (!buffer)
  2136.                 {
  2137.                     errorCode = ERROR_EXPAT_NO_MEMORY;
  2138.                     eventPtr = eventEndPtr = 0;
  2139.                     processor = errorProcessor;
  2140.                     return 0;
  2141.                 }
  2142.                 bufferLim = buffer + len * 2;
  2143.             }
  2144.             memcpy(buffer, end, nLeftOver);
  2145.             bufferPtr = buffer;
  2146.             bufferEnd = buffer + nLeftOver;
  2147.         }
  2148.         return 1;
  2149.     }
  2150. #endif /* not defined XML_CONTEXT_BYTES */
  2151.     else
  2152.     {
  2153.         memcpy(XML_GetBuffer(parser, len), s, len);
  2154.         return XML_ParseBuffer(parser, len, isFinal);
  2155.     }
  2156. }
  2157.  
  2158. /*
  2159.  *@@ XML_ParseBuffer:
  2160.  *      this is just like XML_Parse, except in this case expat
  2161.  *      provides the buffer. By obtaining the buffer from expat
  2162.  *      with the XML_GetBuffer function, the application can
  2163.  *      avoid double copying of the input.
  2164.  */
  2165.  
  2166. int XML_ParseBuffer(XML_Parser parser,
  2167.                     int len,
  2168.                     int isFinal)
  2169. {
  2170.     const char *start = bufferPtr;
  2171.  
  2172.     positionPtr = start;
  2173.     bufferEnd += len;
  2174.     parseEndByteIndex += len;
  2175.     errorCode = processor(parser, start, parseEndPtr = bufferEnd,
  2176.                           isFinal ? (const char **)0 : &bufferPtr);
  2177.     if (errorCode == ERROR_EXPAT_NONE)
  2178.     {
  2179.         if (!isFinal)
  2180.             XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
  2181.         return 1;
  2182.     }
  2183.     else
  2184.     {
  2185.         eventEndPtr = eventPtr;
  2186.         processor = errorProcessor;
  2187.         return 0;
  2188.     }
  2189. }
  2190.  
  2191. /*
  2192.  *@@ XML_GetBuffer:
  2193.  *      obtains a buffer of size len to read a piece of the
  2194.  *      document into. A NULL value is returned if expat can't
  2195.  *      allocate enough memory for this buffer. This has to be
  2196.  *      called prior to every call to XML_ParseBuffer.
  2197.  *
  2198.  *      A typical use would look like this:
  2199.  *
  2200.  +      for (;;)
  2201.  +      {
  2202.  +          int bytes_read;
  2203.  +          void *buff = XML_GetBuffer(p, BUFF_SIZE);
  2204.  +          if (buff == NULL)
  2205.  +              // handle error
  2206.  +
  2207.  +          bytes_read = read(docfd, buff, BUFF_SIZE);
  2208.  +          if (bytes_read < 0)
  2209.  +              // handle error
  2210.  +
  2211.  +          if (!XML_ParseBuffer(p, bytes_read, bytes_read == 0))
  2212.  +              // handle parse error
  2213.  +
  2214.  +          if (bytes_read == 0)
  2215.  +              break;
  2216.  +      }
  2217.  *
  2218.  */
  2219.  
  2220. void *XML_GetBuffer(XML_Parser parser,
  2221.                     int len)
  2222. {
  2223.     if (len > bufferLim - bufferEnd)
  2224.     {
  2225.         /* FIXME avoid integer overflow */
  2226.         int neededSize = len + (bufferEnd - bufferPtr);
  2227.  
  2228. #ifdef XML_CONTEXT_BYTES
  2229.         int keep = bufferPtr - buffer;
  2230.  
  2231.         if (keep > XML_CONTEXT_BYTES)
  2232.             keep = XML_CONTEXT_BYTES;
  2233.         neededSize += keep;
  2234. #endif /* defined XML_CONTEXT_BYTES */
  2235.         if (neededSize <= bufferLim - buffer)
  2236.         {
  2237. #ifdef XML_CONTEXT_BYTES
  2238.             if (keep < bufferPtr - buffer)
  2239.             {
  2240.                 int offset = (bufferPtr - buffer) - keep;
  2241.  
  2242.                 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
  2243.                 bufferEnd -= offset;
  2244.                 bufferPtr -= offset;
  2245.             }
  2246. #else
  2247.             memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
  2248.             bufferEnd = buffer + (bufferEnd - bufferPtr);
  2249.             bufferPtr = buffer;
  2250. #endif /* not defined XML_CONTEXT_BYTES */
  2251.         }
  2252.         else
  2253.         {
  2254.             char *newBuf;
  2255.             int bufferSize = bufferLim - bufferPtr;
  2256.  
  2257.             if (bufferSize == 0)
  2258.                 bufferSize = INIT_BUFFER_SIZE;
  2259.             do
  2260.             {
  2261.                 bufferSize *= 2;
  2262.             }
  2263.             while (bufferSize < neededSize);
  2264.             newBuf = (char*)MALLOC(bufferSize);
  2265.             if (newBuf == 0)
  2266.             {
  2267.                 errorCode = ERROR_EXPAT_NO_MEMORY;
  2268.                 return 0;
  2269.             }
  2270.             bufferLim = newBuf + bufferSize;
  2271. #ifdef XML_CONTEXT_BYTES
  2272.             if (bufferPtr)
  2273.             {
  2274.                 int keep = bufferPtr - buffer;
  2275.  
  2276.                 if (keep > XML_CONTEXT_BYTES)
  2277.                     keep = XML_CONTEXT_BYTES;
  2278.                 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
  2279.                 FREE(buffer);
  2280.                 buffer = newBuf;
  2281.                 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
  2282.                 bufferPtr = buffer + keep;
  2283.             }
  2284.             else
  2285.             {
  2286.                 bufferEnd = newBuf + (bufferEnd - bufferPtr);
  2287.                 bufferPtr = buffer = newBuf;
  2288.             }
  2289. #else
  2290.             if (bufferPtr)
  2291.             {
  2292.                 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
  2293.                 FREE(buffer);
  2294.             }
  2295.             bufferEnd = newBuf + (bufferEnd - bufferPtr);
  2296.             bufferPtr = buffer = newBuf;
  2297. #endif /* not defined XML_CONTEXT_BYTES */
  2298.         }
  2299.     }
  2300.     return bufferEnd;
  2301. }
  2302.  
  2303. /*
  2304.  *@@ XML_GetErrorCode:
  2305.  *      returns what type of error has occurred.
  2306.  *
  2307.  *      To be called when the parse functions return 0 (i.e. a
  2308.  *      parse error has ocurred), although the position reporting
  2309.  *      functions are useful outside of errors. The position reported
  2310.  *      is the byte position (in the original document or entity
  2311.  *      encoding) of the first of the sequence of characters that
  2312.  *      generated the current event (or the error that caused the
  2313.  *      parse functions to return 0.)
  2314.  *
  2315.  *      The position reporting functions are accurate only outside
  2316.  *      of the DTD. In other words, they usually return bogus
  2317.  *      information when called from within a DTD declaration handler.
  2318.  */
  2319.  
  2320. XMLERROR XML_GetErrorCode(XML_Parser parser)
  2321. {
  2322.     return errorCode;
  2323. }
  2324.  
  2325. /*
  2326.  *@@ XML_GetCurrentByteIndex:
  2327.  *      returns the byte offset of the position.
  2328.  *
  2329.  *      To be called on parser errors. See XML_GetErrorCode.
  2330.  */
  2331.  
  2332. long XML_GetCurrentByteIndex(XML_Parser parser)
  2333. {
  2334.     if (eventPtr)
  2335.         return parseEndByteIndex - (parseEndPtr - eventPtr);
  2336.     return -1;
  2337. }
  2338.  
  2339. /*
  2340.  *@@ XML_GetCurrentByteCount:
  2341.  *      return the number of bytes in the current event. Returns
  2342.  *      0 if the event is inside a reference to an internal entity.
  2343.  *
  2344.  *      To be called on parser errors. See XML_GetErrorCode.
  2345.  */
  2346.  
  2347. int XML_GetCurrentByteCount(XML_Parser parser)
  2348. {
  2349.     if (eventEndPtr && eventPtr)
  2350.         return eventEndPtr - eventPtr;
  2351.     return 0;
  2352. }
  2353.  
  2354. /*
  2355.  *@@ XML_GetInputContext:
  2356.  *      returns the parser's input buffer, sets the integer pointed
  2357.  *      at by offset to the offset within this buffer of the current
  2358.  *      parse position, and set the integer pointed at by size to the
  2359.  *      size of the returned buffer.
  2360.  *
  2361.  *      This should only be called from within a handler during an
  2362.  *      active parse and the returned buffer should only be referred
  2363.  *      to from within the handler that made the call. This input
  2364.  *      buffer contains the untranslated bytes of the input.
  2365.  *
  2366.  *      Only a limited amount of context is kept, so if the event
  2367.  *      triggering a call spans over a very large amount of input,
  2368.  *      the actual parse position may be before the beginning of the buffer.
  2369.  */
  2370.  
  2371. const char *XML_GetInputContext(XML_Parser parser,
  2372.                                 int *offset,
  2373.                                 int *size)
  2374. {
  2375. #ifdef XML_CONTEXT_BYTES
  2376.     if (eventPtr && buffer)
  2377.     {
  2378.         *offset = eventPtr - buffer;
  2379.         *size = bufferEnd - buffer;
  2380.         return buffer;
  2381.     }
  2382. #endif /* defined XML_CONTEXT_BYTES */
  2383.     return (char *)0;
  2384. }
  2385.  
  2386. /*
  2387.  *@@ XML_GetCurrentLineNumber:
  2388.  *      returns the line number of the position.
  2389.  *
  2390.  *      Can be called on parser errors. See XML_GetErrorCode.
  2391.  */
  2392.  
  2393. int XML_GetCurrentLineNumber(XML_Parser parser)
  2394. {
  2395.     if (eventPtr)
  2396.     {
  2397.         XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
  2398.         positionPtr = eventPtr;
  2399.     }
  2400.     return position.lineNumber + 1;
  2401. }
  2402.  
  2403. /*
  2404.  *@@ XML_GetCurrentColumnNumber:
  2405.  *      returns the offset, from the beginning of the current
  2406.  *      line, of the position.
  2407.  *
  2408.  *      Can be called on parser errors. See XML_GetErrorCode.
  2409.  */
  2410.  
  2411. int XML_GetCurrentColumnNumber(XML_Parser parser)
  2412. {
  2413.     if (eventPtr)
  2414.     {
  2415.         XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
  2416.         positionPtr = eventPtr;
  2417.     }
  2418.     return position.columnNumber;
  2419. }
  2420.  
  2421. /*
  2422.  *@@ XML_DefaultCurrent:
  2423.  *      not in the expat docs.
  2424.  */
  2425.  
  2426. void XML_DefaultCurrent(XML_Parser parser)
  2427. {
  2428.     if (defaultHandler)
  2429.     {
  2430.         if (openInternalEntities)
  2431.             reportDefault(parser,
  2432.                           internalEncoding,
  2433.                           openInternalEntities->internalEventPtr,
  2434.                           openInternalEntities->internalEventEndPtr);
  2435.         else
  2436.             reportDefault(parser, encoding, eventPtr, eventEndPtr);
  2437.     }
  2438. }
  2439.  
  2440. const XML_LChar *XML_ErrorString(int code)
  2441. {
  2442.     static const XML_LChar *message[] =
  2443.     {
  2444.         0,
  2445.         XML_T("out of memory"),
  2446.         XML_T("syntax error"),
  2447.         XML_T("no element found"),
  2448.         XML_T("not well-formed (invalid token)"),
  2449.         XML_T("unclosed token"),
  2450.         XML_T("unclosed token"),
  2451.         XML_T("mismatched tag"),
  2452.         XML_T("duplicate attribute"),
  2453.         XML_T("junk after document element"),
  2454.         XML_T("illegal parameter entity reference"),
  2455.         XML_T("undefined entity"),
  2456.         XML_T("recursive entity reference"),
  2457.         XML_T("asynchronous entity"),
  2458.         XML_T("reference to invalid character number"),
  2459.         XML_T("reference to binary entity"),
  2460.         XML_T("reference to external entity in attribute"),
  2461.         XML_T("xml processing instruction not at start of external entity"),
  2462.         XML_T("unknown encoding"),
  2463.         XML_T("encoding specified in XML declaration is incorrect"),
  2464.         XML_T("unclosed CDATA section"),
  2465.         XML_T("error in processing external entity reference"),
  2466.         XML_T("document is not standalone"),
  2467.         XML_T("unexpected parser state - please send a bug report")
  2468.     };
  2469.  
  2470.     if (code > 0 && code < sizeof(message) / sizeof(message[0]))
  2471.         return message[code];
  2472.     return 0;
  2473. }
  2474.  
  2475. /* const XML_LChar *
  2476.  * XML_ExpatVersion(void) {
  2477.  * return VERSION;
  2478.  * }
  2479.  *
  2480.  * XML_Expat_Version
  2481.  * XML_ExpatVersionInfo(void) {
  2482.  * XML_Expat_Version version;
  2483.  *
  2484.  * version.major = XML_MAJOR_VERSION;
  2485.  * version.minor = XML_MINOR_VERSION;
  2486.  * version.micro = XML_MICRO_VERSION;
  2487.  *
  2488.  * return version;
  2489.  * } */
  2490.  
  2491. static XMLERROR contentProcessor(XML_Parser parser,
  2492.                                  const char *start,
  2493.                                  const char *end,
  2494.                                  const char **endPtr)
  2495. {
  2496.     return doContent(parser, 0, encoding, start, end, endPtr);
  2497. }
  2498.  
  2499. static XMLERROR externalEntityInitProcessor(XML_Parser parser,
  2500.                                             const char *start,
  2501.                                             const char *end,
  2502.                                             const char **endPtr)
  2503. {
  2504.     XMLERROR result = initializeEncoding(parser);
  2505.  
  2506.     if (result != ERROR_EXPAT_NONE)
  2507.         return result;
  2508.     processor = externalEntityInitProcessor2;
  2509.     return externalEntityInitProcessor2(parser, start, end, endPtr);
  2510. }
  2511.  
  2512. static XMLERROR externalEntityInitProcessor2(XML_Parser parser,
  2513.                                              const char *start,
  2514.                                              const char *end,
  2515.                                              const char **endPtr)
  2516. {
  2517.     const char *next;
  2518.     int tok = XmlContentTok(encoding, start, end, &next);
  2519.  
  2520.     switch (tok)
  2521.     {
  2522.         case XML_TOK_BOM:
  2523.             start = next;
  2524.             break;
  2525.         case XML_TOK_PARTIAL:
  2526.             if (endPtr)
  2527.             {
  2528.                 *endPtr = start;
  2529.                 return ERROR_EXPAT_NONE;
  2530.             }
  2531.             eventPtr = start;
  2532.             return ERROR_EXPAT_UNCLOSED_TOKEN;
  2533.         case XML_TOK_PARTIAL_CHAR:
  2534.             if (endPtr)
  2535.             {
  2536.                 *endPtr = start;
  2537.                 return ERROR_EXPAT_NONE;
  2538.             }
  2539.             eventPtr = start;
  2540.             return ERROR_EXPAT_PARTIAL_CHAR;
  2541.     }
  2542.     processor = externalEntityInitProcessor3;
  2543.     return externalEntityInitProcessor3(parser, start, end, endPtr);
  2544. }
  2545.  
  2546. static XMLERROR externalEntityInitProcessor3(XML_Parser parser,
  2547.                                              const char *start,
  2548.                                              const char *end,
  2549.                                              const char **endPtr)
  2550. {
  2551.     const char *next;
  2552.     int tok = XmlContentTok(encoding, start, end, &next);
  2553.  
  2554.     switch (tok)
  2555.     {
  2556.         case XML_TOK_XML_DECL:
  2557.             {
  2558.                 XMLERROR result = processXmlDecl(parser, 1, start, next);
  2559.  
  2560.                 if (result != ERROR_EXPAT_NONE)
  2561.                     return result;
  2562.                 start = next;
  2563.             }
  2564.             break;
  2565.         case XML_TOK_PARTIAL:
  2566.             if (endPtr)
  2567.             {
  2568.                 *endPtr = start;
  2569.                 return ERROR_EXPAT_NONE;
  2570.             }
  2571.             eventPtr = start;
  2572.             return ERROR_EXPAT_UNCLOSED_TOKEN;
  2573.         case XML_TOK_PARTIAL_CHAR:
  2574.             if (endPtr)
  2575.             {
  2576.                 *endPtr = start;
  2577.                 return ERROR_EXPAT_NONE;
  2578.             }
  2579.             eventPtr = start;
  2580.             return ERROR_EXPAT_PARTIAL_CHAR;
  2581.     }
  2582.     processor = externalEntityContentProcessor;
  2583.     tagLevel = 1;
  2584.     return doContent(parser, 1, encoding, start, end, endPtr);
  2585. }
  2586.  
  2587. static XMLERROR externalEntityContentProcessor(XML_Parser parser,
  2588.                                                const char *start,
  2589.                                                const char *end,
  2590.                                                const char **endPtr)
  2591. {
  2592.     return doContent(parser, 1, encoding, start, end, endPtr);
  2593. }
  2594.  
  2595. /*
  2596.  *@@ doContent:
  2597.  *
  2598.  *@@changed V0.9.14 (2001-08-09) [umoeller]: fixed ERROR_EXPAT_UNDEFINED_ENTITY with callback-defined encodings
  2599.  */
  2600.  
  2601. static XMLERROR doContent(XML_Parser parser,
  2602.                           int startTagLevel,
  2603.                           const ENCODING * enc,
  2604.                           const char *s,
  2605.                           const char *end,
  2606.                           const char **nextPtr)
  2607. {
  2608.     const char **eventPP;
  2609.     const char **eventEndPP;
  2610.  
  2611.     if (enc == encoding)
  2612.     {
  2613.         eventPP = &eventPtr;
  2614.         eventEndPP = &eventEndPtr;
  2615.     }
  2616.     else
  2617.     {
  2618.         eventPP = &(openInternalEntities->internalEventPtr);
  2619.         eventEndPP = &(openInternalEntities->internalEventEndPtr);
  2620.     }
  2621.     *eventPP = s;
  2622.     for (;;)
  2623.     {
  2624.         const char *next = s;   /* XmlContentTok doesn't always set the last arg */
  2625.         int tok = XmlContentTok(enc, s, end, &next);
  2626.  
  2627.         *eventEndPP = next;
  2628.         switch (tok)
  2629.         {
  2630.             case XML_TOK_TRAILING_CR:
  2631.                 if (nextPtr)
  2632.                 {
  2633.                     *nextPtr = s;
  2634.                     return ERROR_EXPAT_NONE;
  2635.                 }
  2636.                 *eventEndPP = end;
  2637.                 if (characterDataHandler)
  2638.                 {
  2639.                     XML_Char c = 0xA;
  2640.  
  2641.                     characterDataHandler(handlerArg, &c, 1);
  2642.                 }
  2643.                 else if (defaultHandler)
  2644.                     reportDefault(parser, enc, s, end);
  2645.                 if (startTagLevel == 0)
  2646.                     return ERROR_EXPAT_NO_ELEMENTS;
  2647.                 if (tagLevel != startTagLevel)
  2648.                     return ERROR_EXPAT_ASYNC_ENTITY;
  2649.                 return ERROR_EXPAT_NONE;
  2650.             case XML_TOK_NONE:
  2651.                 if (nextPtr)
  2652.                 {
  2653.                     *nextPtr = s;
  2654.                     return ERROR_EXPAT_NONE;
  2655.                 }
  2656.                 if (startTagLevel > 0)
  2657.                 {
  2658.                     if (tagLevel != startTagLevel)
  2659.                         return ERROR_EXPAT_ASYNC_ENTITY;
  2660.                     return ERROR_EXPAT_NONE;
  2661.                 }
  2662.                 return ERROR_EXPAT_NO_ELEMENTS;
  2663.             case XML_TOK_INVALID:
  2664.                 *eventPP = next;
  2665.                 return ERROR_EXPAT_INVALID_TOKEN;
  2666.             case XML_TOK_PARTIAL:
  2667.                 if (nextPtr)
  2668.                 {
  2669.                     *nextPtr = s;
  2670.                     return ERROR_EXPAT_NONE;
  2671.                 }
  2672.                 return ERROR_EXPAT_UNCLOSED_TOKEN;
  2673.             case XML_TOK_PARTIAL_CHAR:
  2674.                 if (nextPtr)
  2675.                 {
  2676.                     *nextPtr = s;
  2677.                     return ERROR_EXPAT_NONE;
  2678.                 }
  2679.                 return ERROR_EXPAT_PARTIAL_CHAR;
  2680.             case XML_TOK_ENTITY_REF:
  2681.                 {
  2682.                     const XML_Char *name;
  2683.                     ENTITY *entity;
  2684.                     unsigned long ulOfs; // V0.9.14 (2001-08-09) [umoeller]
  2685.                     XML_Char ch = XmlPredefinedEntityName(enc,
  2686.                                                           s + enc->minBytesPerChar,
  2687.                                                           next - enc->minBytesPerChar);
  2688.  
  2689.                     if (ch)
  2690.                     {
  2691.                         if (characterDataHandler)
  2692.                             characterDataHandler(handlerArg, &ch, 1);
  2693.                         else if (defaultHandler)
  2694.                             reportDefault(parser, enc, s, next);
  2695.                         break;
  2696.                     }
  2697.                     name = poolStoreString(&dtd.pool,
  2698.                                            enc,
  2699.                                            s + enc->minBytesPerChar,
  2700.                                            next - enc->minBytesPerChar,
  2701.                                            &ulOfs);
  2702.                     if (!name)
  2703.                         return ERROR_EXPAT_NO_MEMORY;
  2704.                     entity = (ENTITY*)lookup(&dtd.generalEntities,
  2705.                                              name + ulOfs,  // V0.9.14 (2001-08-09) [umoeller]
  2706.                                              0);
  2707.                     poolDiscard(&dtd.pool);
  2708.                     if (!entity)
  2709.                     {
  2710.                         if (dtd.complete || dtd.standalone)
  2711.                             return ERROR_EXPAT_UNDEFINED_ENTITY;
  2712.                         if (defaultHandler)
  2713.                             reportDefault(parser, enc, s, next);
  2714.                         break;
  2715.                     }
  2716.                     if (entity->open)
  2717.                         return ERROR_EXPAT_RECURSIVE_ENTITY_REF;
  2718.                     if (entity->notation)
  2719.                         return ERROR_EXPAT_BINARY_ENTITY_REF;
  2720.                     if (entity)
  2721.                     {
  2722.                         if (entity->textPtr)
  2723.                         {
  2724.                             XMLERROR result;
  2725.                             OPEN_INTERNAL_ENTITY openEntity;
  2726.  
  2727.                             if (defaultHandler && !defaultExpandInternalEntities)
  2728.                             {
  2729.                                 reportDefault(parser, enc, s, next);
  2730.                                 break;
  2731.                             }
  2732.                             entity->open = 1;
  2733.                             openEntity.next = openInternalEntities;
  2734.                             openInternalEntities = &openEntity;
  2735.                             openEntity.entity = entity;
  2736.                             openEntity.internalEventPtr = 0;
  2737.                             openEntity.internalEventEndPtr = 0;
  2738.                             result = doContent(parser,
  2739.                                                tagLevel,
  2740.                                                internalEncoding,
  2741.                                                (char *)entity->textPtr,
  2742.                                   (char *)(entity->textPtr + entity->textLen),
  2743.                                                0);
  2744.                             entity->open = 0;
  2745.                             openInternalEntities = openEntity.next;
  2746.                             if (result)
  2747.                                 return result;
  2748.                         }
  2749.                         else if (externalEntityRefHandler)
  2750.                         {
  2751.                             const XML_Char *context;
  2752.  
  2753.                             entity->open = 1;
  2754.                             context = getContext(parser);
  2755.                             entity->open = 0;
  2756.                             if (!context)
  2757.                                 return ERROR_EXPAT_NO_MEMORY;
  2758.                             if (!externalEntityRefHandler(handlerArg,   // V0.9.14 (2001-08-09) [umoeller]
  2759.                                                           externalEntityRefHandlerArg,
  2760.                                                           context,
  2761.                                                           entity->base,
  2762.                                                           entity->systemId,
  2763.                                                           entity->publicId))
  2764.                                 return ERROR_EXPAT_EXTERNAL_ENTITY_HANDLING;
  2765.                             poolDiscard(&tempPool);
  2766.                         }
  2767.                         else if (defaultHandler)
  2768.                             reportDefault(parser, enc, s, next);
  2769.                     }
  2770.                     break;
  2771.                 }
  2772.             case XML_TOK_START_TAG_WITH_ATTS:
  2773.                 if (!startElementHandler)
  2774.                 {
  2775.                     XMLERROR result = storeAtts(parser, enc, s, 0, 0);
  2776.  
  2777.                     if (result)
  2778.                         return result;
  2779.                 }
  2780.                 /* fall through */
  2781.             case XML_TOK_START_TAG_NO_ATTS:
  2782.                 {
  2783.                     TAG *tag;
  2784.  
  2785.                     if (freeTagList)
  2786.                     {
  2787.                         tag = freeTagList;
  2788.                         freeTagList = freeTagList->parent;
  2789.                     }
  2790.                     else
  2791.                     {
  2792.                         tag = (TAG*)MALLOC(sizeof(TAG));
  2793.                         if (!tag)
  2794.                             return ERROR_EXPAT_NO_MEMORY;
  2795.                         tag->buf = (char*)MALLOC(INIT_TAG_BUF_SIZE);
  2796.                         if (!tag->buf)
  2797.                             return ERROR_EXPAT_NO_MEMORY;
  2798.                         tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
  2799.                     }
  2800.                     tag->bindings = 0;
  2801.                     tag->parent = tagStack;
  2802.                     tagStack = tag;
  2803.                     tag->name.localPart = 0;
  2804.                     tag->rawName = s + enc->minBytesPerChar;
  2805.                     tag->rawNameLength = XmlNameLength(enc, tag->rawName);
  2806.                     if (nextPtr)
  2807.                     {
  2808.                         /* Need to guarantee that:
  2809.                          * tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
  2810.                         if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf)
  2811.                         {
  2812.                             int bufSize = tag->rawNameLength * 4;
  2813.  
  2814.                             bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
  2815.                             tag->buf = (char*)REALLOC(tag->buf, bufSize);
  2816.                             if (!tag->buf)
  2817.                                 return ERROR_EXPAT_NO_MEMORY;
  2818.                             tag->bufEnd = tag->buf + bufSize;
  2819.                         }
  2820.                         memcpy(tag->buf, tag->rawName, tag->rawNameLength);
  2821.                         tag->rawName = tag->buf;
  2822.                     }
  2823.                     ++tagLevel;
  2824.                     if (startElementHandler)
  2825.                     {
  2826.                         XMLERROR result;
  2827.                         XML_Char *toPtr;
  2828.  
  2829.                         for (;;)
  2830.                         {
  2831.                             const char *rawNameEnd = tag->rawName + tag->rawNameLength;
  2832.                             const char *fromPtr = tag->rawName;
  2833.                             int bufSize;
  2834.  
  2835.                             if (nextPtr)
  2836.                                 toPtr = (XML_Char *) (tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
  2837.                             else
  2838.                                 toPtr = (XML_Char *) tag->buf;
  2839.                             tag->name.str = toPtr;
  2840.                             XmlConvert(enc,
  2841.                                        &fromPtr, rawNameEnd,
  2842.                                (ICHAR **) & toPtr, (ICHAR *) tag->bufEnd - 1);
  2843.                             if (fromPtr == rawNameEnd)
  2844.                                 break;
  2845.                             bufSize = (tag->bufEnd - tag->buf) << 1;
  2846.                             tag->buf = (char*)REALLOC(tag->buf, bufSize);
  2847.                             if (!tag->buf)
  2848.                                 return ERROR_EXPAT_NO_MEMORY;
  2849.                             tag->bufEnd = tag->buf + bufSize;
  2850.                             if (nextPtr)
  2851.                                 tag->rawName = tag->buf;
  2852.                         }
  2853.                         *toPtr = XML_T('\0');
  2854.                         result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
  2855.                         if (result)
  2856.                             return result;
  2857.                         startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
  2858.                         poolClear(&tempPool);
  2859.                     }
  2860.                     else
  2861.                     {
  2862.                         tag->name.str = 0;
  2863.                         if (defaultHandler)
  2864.                             reportDefault(parser, enc, s, next);
  2865.                     }
  2866.                     break;
  2867.                 }
  2868.             case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
  2869.                 if (!startElementHandler)
  2870.                 {
  2871.                     XMLERROR result = storeAtts(parser, enc, s, 0, 0);
  2872.  
  2873.                     if (result)
  2874.                         return result;
  2875.                 }
  2876.                 /* fall through */
  2877.             case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
  2878.                 if (startElementHandler || endElementHandler)
  2879.                 {
  2880.                     const char *rawName = s + enc->minBytesPerChar;
  2881.                     XMLERROR result;
  2882.                     BINDING *bindings = 0;
  2883.                     TAG_NAME name;
  2884.  
  2885.                     name.str = poolStoreString(&tempPool,
  2886.                                                enc,
  2887.                                                rawName,
  2888.                                                rawName + XmlNameLength(enc, rawName),
  2889.                                                NULL);
  2890.                     if (!name.str)
  2891.                         return ERROR_EXPAT_NO_MEMORY;
  2892.                     poolFinish(&tempPool);
  2893.                     result = storeAtts(parser, enc, s, &name, &bindings);
  2894.                     if (result)
  2895.                         return result;
  2896.                     poolFinish(&tempPool);
  2897.                     if (startElementHandler)
  2898.                         startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
  2899.                     if (endElementHandler)
  2900.                     {
  2901.                         if (startElementHandler)
  2902.                             *eventPP = *eventEndPP;
  2903.                         endElementHandler(handlerArg, name.str);
  2904.                     }
  2905.                     poolClear(&tempPool);
  2906.                     while (bindings)
  2907.                     {
  2908.                         BINDING *b = bindings;
  2909.  
  2910.                         if (endNamespaceDeclHandler)
  2911.                             endNamespaceDeclHandler(handlerArg, b->prefix->name);
  2912.                         bindings = bindings->nextTagBinding;
  2913.                         b->nextTagBinding = freeBindingList;
  2914.                         freeBindingList = b;
  2915.                         b->prefix->binding = b->prevPrefixBinding;
  2916.                     }
  2917.                 }
  2918.                 else if (defaultHandler)
  2919.                     reportDefault(parser, enc, s, next);
  2920.                 if (tagLevel == 0)
  2921.                     return epilogProcessor(parser, next, end, nextPtr);
  2922.                 break;
  2923.             case XML_TOK_END_TAG:
  2924.                 if (tagLevel == startTagLevel)
  2925.                     return ERROR_EXPAT_ASYNC_ENTITY;
  2926.                 else
  2927.                 {
  2928.                     int len;
  2929.                     const char *rawName;
  2930.                     TAG *tag = tagStack;
  2931.  
  2932.                     tagStack = tag->parent;
  2933.                     tag->parent = freeTagList;
  2934.                     freeTagList = tag;
  2935.                     rawName = s + enc->minBytesPerChar * 2;
  2936.                     len = XmlNameLength(enc, rawName);
  2937.                     if (len != tag->rawNameLength
  2938.                         || memcmp(tag->rawName, rawName, len) != 0)
  2939.                     {
  2940.                         *eventPP = rawName;
  2941.                         return ERROR_EXPAT_TAG_MISMATCH;
  2942.                     }
  2943.                     --tagLevel;
  2944.                     if (endElementHandler && tag->name.str)
  2945.                     {
  2946.                         if (tag->name.localPart)
  2947.                         {
  2948.                             XML_Char *to = (XML_Char *) tag->name.str + tag->name.uriLen;
  2949.                             const XML_Char *from = tag->name.localPart;
  2950.  
  2951.                             while ((*to++ = *from++) != 0)
  2952.                                 ;
  2953.                         }
  2954.                         endElementHandler(handlerArg, tag->name.str);
  2955.                     }
  2956.                     else if (defaultHandler)
  2957.                         reportDefault(parser, enc, s, next);
  2958.                     while (tag->bindings)
  2959.                     {
  2960.                         BINDING *b = tag->bindings;
  2961.  
  2962.                         if (endNamespaceDeclHandler)
  2963.                             endNamespaceDeclHandler(handlerArg, b->prefix->name);
  2964.                         tag->bindings = tag->bindings->nextTagBinding;
  2965.                         b->nextTagBinding = freeBindingList;
  2966.                         freeBindingList = b;
  2967.                         b->prefix->binding = b->prevPrefixBinding;
  2968.                     }
  2969.                     if (tagLevel == 0)
  2970.                         return epilogProcessor(parser, next, end, nextPtr);
  2971.                 }
  2972.                 break;
  2973.             case XML_TOK_CHAR_REF:
  2974.                 {
  2975.                     int n = XmlCharRefNumber(enc, s);
  2976.  
  2977.                     if (n < 0)
  2978.                         return ERROR_EXPAT_BAD_CHAR_REF;
  2979.                     if (characterDataHandler)
  2980.                     {
  2981.                         XML_Char buf[XML_ENCODE_MAX];
  2982.  
  2983.                         characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *) buf));
  2984.                     }
  2985.                     else if (defaultHandler)
  2986.                         reportDefault(parser, enc, s, next);
  2987.                 }
  2988.                 break;
  2989.             case XML_TOK_XML_DECL:
  2990.                 return ERROR_EXPAT_MISPLACED_XML_PI;
  2991.             case XML_TOK_DATA_NEWLINE:
  2992.                 if (characterDataHandler)
  2993.                 {
  2994.                     XML_Char c = 0xA;
  2995.  
  2996.                     characterDataHandler(handlerArg, &c, 1);
  2997.                 }
  2998.                 else if (defaultHandler)
  2999.                     reportDefault(parser, enc, s, next);
  3000.                 break;
  3001.             case XML_TOK_CDATA_SECT_OPEN:
  3002.                 {
  3003.                     XMLERROR result;
  3004.  
  3005.                     if (startCdataSectionHandler)
  3006.                         startCdataSectionHandler(handlerArg);
  3007. #if 0
  3008.                     /* Suppose you doing a transformation on a document that involves
  3009.                      * changing only the character data.  You set up a defaultHandler
  3010.                      * and a characterDataHandler.  The defaultHandler simply copies
  3011.                      * characters through.  The characterDataHandler does the transformation
  3012.                      * and writes the characters out escaping them as necessary.  This case
  3013.                      * will fail to work if we leave out the following two lines (because &
  3014.                      * and < inside CDATA sections will be incorrectly escaped).
  3015.                      *
  3016.                      * However, now we have a start/endCdataSectionHandler, so it seems
  3017.                      * easier to let the user deal with this. */
  3018.  
  3019.                     else if (characterDataHandler)
  3020.                         characterDataHandler(handlerArg, dataBuf, 0);
  3021. #endif
  3022.                     else if (defaultHandler)
  3023.                         reportDefault(parser, enc, s, next);
  3024.                     result = doCdataSection(parser, enc, &next, end, nextPtr);
  3025.                     if (!next)
  3026.                     {
  3027.                         processor = cdataSectionProcessor;
  3028.                         return result;
  3029.                     }
  3030.                 }
  3031.                 break;
  3032.             case XML_TOK_TRAILING_RSQB:
  3033.                 if (nextPtr)
  3034.                 {
  3035.                     *nextPtr = s;
  3036.                     return ERROR_EXPAT_NONE;
  3037.                 }
  3038.                 if (characterDataHandler)
  3039.                 {
  3040.                     if (MUST_CONVERT(enc, s))
  3041.                     {
  3042.                         ICHAR *dataPtr = (ICHAR *) dataBuf;
  3043.  
  3044.                         XmlConvert(enc, &s, end, &dataPtr, (ICHAR *) dataBufEnd);
  3045.                         characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *) dataBuf);
  3046.                     }
  3047.                     else
  3048.                         characterDataHandler(handlerArg,
  3049.                                              (XML_Char *) s,
  3050.                                            (XML_Char *) end - (XML_Char *) s);
  3051.                 }
  3052.                 else if (defaultHandler)
  3053.                     reportDefault(parser, enc, s, end);
  3054.                 if (startTagLevel == 0)
  3055.                 {
  3056.                     *eventPP = end;
  3057.                     return ERROR_EXPAT_NO_ELEMENTS;
  3058.                 }
  3059.                 if (tagLevel != startTagLevel)
  3060.                 {
  3061.                     *eventPP = end;
  3062.                     return ERROR_EXPAT_ASYNC_ENTITY;
  3063.                 }
  3064.                 return ERROR_EXPAT_NONE;
  3065.             case XML_TOK_DATA_CHARS:
  3066.                 if (characterDataHandler)
  3067.                 {
  3068.                     if (MUST_CONVERT(enc, s))
  3069.                     {
  3070.                         for (;;)
  3071.                         {
  3072.                             ICHAR *dataPtr = (ICHAR *) dataBuf;
  3073.  
  3074.                             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *) dataBufEnd);
  3075.                             *eventEndPP = s;
  3076.                             characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *) dataBuf);
  3077.                             if (s == next)
  3078.                                 break;
  3079.                             *eventPP = s;
  3080.                         }
  3081.                     }
  3082.                     else
  3083.                         characterDataHandler(handlerArg,
  3084.                                              (XML_Char *) s,
  3085.                                           (XML_Char *) next - (XML_Char *) s);
  3086.                 }
  3087.                 else if (defaultHandler)
  3088.                     reportDefault(parser, enc, s, next);
  3089.                 break;
  3090.             case XML_TOK_PI:
  3091.                 if (!reportProcessingInstruction(parser, enc, s, next))
  3092.                     return ERROR_EXPAT_NO_MEMORY;
  3093.                 break;
  3094.             case XML_TOK_COMMENT:
  3095.                 if (!reportComment(parser, enc, s, next))
  3096.                     return ERROR_EXPAT_NO_MEMORY;
  3097.                 break;
  3098.             default:
  3099.                 if (defaultHandler)
  3100.                     reportDefault(parser, enc, s, next);
  3101.                 break;
  3102.         }
  3103.         *eventPP = s = next;
  3104.     }
  3105.     /* not reached */
  3106. }
  3107.  
  3108. /* If tagNamePtr is non-null, build a real list of attributes,
  3109.  * otherwise just check the attributes for well-formedness. */
  3110.  
  3111. static XMLERROR storeAtts(XML_Parser parser,
  3112.                           const ENCODING * enc,
  3113.                           const char *attStr,
  3114.                           TAG_NAME * tagNamePtr,
  3115.                           BINDING ** bindingsPtr)
  3116. {
  3117.     ELEMENT_TYPE *elementType = 0;
  3118.     int nDefaultAtts = 0;
  3119.     const XML_Char **appAtts;   /* the attribute list to pass to the application */
  3120.     int attIndex = 0;
  3121.     int i;
  3122.     int n;
  3123.     int nPrefixes = 0;
  3124.     BINDING *binding;
  3125.     const XML_Char *localPart;
  3126.  
  3127.     /* lookup the element type name */
  3128.     if (tagNamePtr)
  3129.     {
  3130.         elementType = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, tagNamePtr->str, 0);
  3131.         if (!elementType)
  3132.         {
  3133.             tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
  3134.             if (!tagNamePtr->str)
  3135.                 return ERROR_EXPAT_NO_MEMORY;
  3136.             elementType = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
  3137.             if (!elementType)
  3138.                 return ERROR_EXPAT_NO_MEMORY;
  3139.             if (ns && !setElementTypePrefix(parser, elementType))
  3140.                 return ERROR_EXPAT_NO_MEMORY;
  3141.         }
  3142.         nDefaultAtts = elementType->nDefaultAtts;
  3143.     }
  3144.     /* get the attributes from the tokenizer */
  3145.     n = XmlGetAttributes(enc, attStr, attsSize, atts);
  3146.     if (n + nDefaultAtts > attsSize)
  3147.     {
  3148.         int oldAttsSize = attsSize;
  3149.  
  3150.         attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
  3151.         atts = (ATTRIBUTE*)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
  3152.         if (!atts)
  3153.             return ERROR_EXPAT_NO_MEMORY;
  3154.         if (n > oldAttsSize)
  3155.             XmlGetAttributes(enc, attStr, n, atts);
  3156.     }
  3157.     appAtts = (const XML_Char **)atts;
  3158.     for (i = 0; i < n; i++)
  3159.     {
  3160.         /* add the name and value to the attribute list */
  3161.         ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
  3162.                                              atts[i].name
  3163.                                           + XmlNameLength(enc, atts[i].name));
  3164.  
  3165.         if (!attId)
  3166.             return ERROR_EXPAT_NO_MEMORY;
  3167.         /* detect duplicate attributes */
  3168.         if ((attId->name)[-1])
  3169.         {
  3170.             if (enc == encoding)
  3171.                 eventPtr = atts[i].name;
  3172.             return ERROR_EXPAT_DUPLICATE_ATTRIBUTE;
  3173.         }
  3174.         (attId->name)[-1] = 1;
  3175.         appAtts[attIndex++] = attId->name;
  3176.         if (!atts[i].normalized)
  3177.         {
  3178.             XMLERROR result;
  3179.             int isCdata = 1;
  3180.  
  3181.             /* figure out whether declared as other than CDATA */
  3182.             if (attId->maybeTokenized)
  3183.             {
  3184.                 int j;
  3185.  
  3186.                 for (j = 0; j < nDefaultAtts; j++)
  3187.                 {
  3188.                     if (attId == elementType->defaultAtts[j].id)
  3189.                     {
  3190.                         isCdata = elementType->defaultAtts[j].isCdata;
  3191.                         break;
  3192.                     }
  3193.                 }
  3194.             }
  3195.  
  3196.             /* normalize the attribute value */
  3197.             result = storeAttributeValue(parser, enc, isCdata,
  3198.                                          atts[i].valuePtr, atts[i].valueEnd,
  3199.                                          &tempPool);
  3200.             if (result)
  3201.                 return result;
  3202.             if (tagNamePtr)
  3203.             {
  3204.                 appAtts[attIndex] = poolStart(&tempPool);
  3205.                 poolFinish(&tempPool);
  3206.             }
  3207.             else
  3208.                 poolDiscard(&tempPool);
  3209.         }
  3210.         else if (tagNamePtr)
  3211.         {
  3212.             /* the value did not need normalizing */
  3213.             appAtts[attIndex] = poolStoreString(&tempPool,
  3214.                                                 enc,
  3215.                                                 atts[i].valuePtr,
  3216.                                                 atts[i].valueEnd,
  3217.                                                 NULL);
  3218.             if (appAtts[attIndex] == 0)
  3219.                 return ERROR_EXPAT_NO_MEMORY;
  3220.             poolFinish(&tempPool);
  3221.         }
  3222.         /* handle prefixed attribute names */
  3223.         if (attId->prefix && tagNamePtr)
  3224.         {
  3225.             if (attId->xmlns)
  3226.             {
  3227.                 /* deal with namespace declarations here */
  3228.                 if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
  3229.                     return ERROR_EXPAT_NO_MEMORY;
  3230.                 --attIndex;
  3231.             }
  3232.             else
  3233.             {
  3234.                 /* deal with other prefixed names later */
  3235.                 attIndex++;
  3236.                 nPrefixes++;
  3237.                 (attId->name)[-1] = 2;
  3238.             }
  3239.         }
  3240.         else
  3241.             attIndex++;
  3242.     }
  3243.     if (tagNamePtr)
  3244.     {
  3245.         int j;
  3246.  
  3247.         nSpecifiedAtts = attIndex;
  3248.         if (elementType->idAtt && (elementType->idAtt->name)[-1])
  3249.         {
  3250.             for (i = 0; i < attIndex; i += 2)
  3251.                 if (appAtts[i] == elementType->idAtt->name)
  3252.                 {
  3253.                     idAttIndex = i;
  3254.                     break;
  3255.                 }
  3256.         }
  3257.         else
  3258.             idAttIndex = -1;
  3259.         /* do attribute defaulting */
  3260.         for (j = 0; j < nDefaultAtts; j++)
  3261.         {
  3262.             const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
  3263.  
  3264.             if (!(da->id->name)[-1] && da->value)
  3265.             {
  3266.                 if (da->id->prefix)
  3267.                 {
  3268.                     if (da->id->xmlns)
  3269.                     {
  3270.                         if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
  3271.                             return ERROR_EXPAT_NO_MEMORY;
  3272.                     }
  3273.                     else
  3274.                     {
  3275.                         (da->id->name)[-1] = 2;
  3276.                         nPrefixes++;
  3277.                         appAtts[attIndex++] = da->id->name;
  3278.                         appAtts[attIndex++] = da->value;
  3279.                     }
  3280.                 }
  3281.                 else
  3282.                 {
  3283.                     (da->id->name)[-1] = 1;
  3284.                     appAtts[attIndex++] = da->id->name;
  3285.                     appAtts[attIndex++] = da->value;
  3286.                 }
  3287.             }
  3288.         }
  3289.         appAtts[attIndex] = 0;
  3290.     }
  3291.     i = 0;
  3292.     if (nPrefixes)
  3293.     {
  3294.         /* expand prefixed attribute names */
  3295.         for (; i < attIndex; i += 2)
  3296.         {
  3297.             if (appAtts[i][-1] == 2)
  3298.             {
  3299.                 ATTRIBUTE_ID *id;
  3300.  
  3301.                 ((XML_Char *) (appAtts[i]))[-1] = 0;
  3302.                 id = (ATTRIBUTE_ID *) lookup(&dtd.attributeIds, appAtts[i], 0);
  3303.                 if (id->prefix->binding)
  3304.                 {
  3305.                     int j;
  3306.                     const BINDING *b = id->prefix->binding;
  3307.                     const XML_Char *s = appAtts[i];
  3308.  
  3309.                     for (j = 0; j < b->uriLen; j++)
  3310.                     {
  3311.                         if (!poolAppendChar(&tempPool, b->uri[j]))
  3312.                             return ERROR_EXPAT_NO_MEMORY;
  3313.                     }
  3314.                     while (*s++ != ':')
  3315.                         ;
  3316.                     do
  3317.                     {
  3318.                         if (!poolAppendChar(&tempPool, *s))
  3319.                             return ERROR_EXPAT_NO_MEMORY;
  3320.                     }
  3321.                     while (*s++);
  3322.                     if (ns_triplets)
  3323.                     {
  3324.                         tempPool.ptr[-1] = namespaceSeparator;
  3325.                         s = b->prefix->name;
  3326.                         do
  3327.                         {
  3328.                             if (!poolAppendChar(&tempPool, *s))
  3329.                                 return ERROR_EXPAT_NO_MEMORY;
  3330.                         }
  3331.                         while (*s++);
  3332.                     }
  3333.  
  3334.                     appAtts[i] = poolStart(&tempPool);
  3335.                     poolFinish(&tempPool);
  3336.                 }
  3337.                 if (!--nPrefixes)
  3338.                     break;
  3339.             }
  3340.             else
  3341.                 ((XML_Char *) (appAtts[i]))[-1] = 0;
  3342.         }
  3343.     }
  3344.     /* clear the flags that say whether attributes were specified */
  3345.     for (; i < attIndex; i += 2)
  3346.         ((XML_Char *) (appAtts[i]))[-1] = 0;
  3347.     if (!tagNamePtr)
  3348.         return ERROR_EXPAT_NONE;
  3349.     for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
  3350.         binding->attId->name[-1] = 0;
  3351.     /* expand the element type name */
  3352.     if (elementType->prefix)
  3353.     {
  3354.         binding = elementType->prefix->binding;
  3355.         if (!binding)
  3356.             return ERROR_EXPAT_NONE;
  3357.         localPart = tagNamePtr->str;
  3358.         while (*localPart++ != XML_T(':'))
  3359.             ;
  3360.     }
  3361.     else if (dtd.defaultPrefix.binding)
  3362.     {
  3363.         binding = dtd.defaultPrefix.binding;
  3364.         localPart = tagNamePtr->str;
  3365.     }
  3366.     else
  3367.         return ERROR_EXPAT_NONE;
  3368.     tagNamePtr->localPart = localPart;
  3369.     tagNamePtr->uriLen = binding->uriLen;
  3370.     for (i = 0; localPart[i++];)
  3371.         ;
  3372.     n = i + binding->uriLen;
  3373.     if (n > binding->uriAlloc)
  3374.     {
  3375.         TAG *p;
  3376.         XML_Char *uri = (XML_Char*)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
  3377.  
  3378.         if (!uri)
  3379.             return ERROR_EXPAT_NO_MEMORY;
  3380.         binding->uriAlloc = n + EXPAND_SPARE;
  3381.         memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
  3382.         for (p = tagStack; p; p = p->parent)
  3383.             if (p->name.str == binding->uri)
  3384.                 p->name.str = uri;
  3385.         FREE(binding->uri);
  3386.         binding->uri = uri;
  3387.     }
  3388.     memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
  3389.     tagNamePtr->str = binding->uri;
  3390.     return ERROR_EXPAT_NONE;
  3391. }
  3392.  
  3393. static int addBinding(XML_Parser parser,
  3394.                       PREFIX * prefix,
  3395.                       const ATTRIBUTE_ID * attId,
  3396.                       const XML_Char * uri,
  3397.                       BINDING ** bindingsPtr)
  3398. {
  3399.     BINDING *b;
  3400.     int len;
  3401.  
  3402.     for (len = 0; uri[len]; len++)
  3403.         ;
  3404.     if (namespaceSeparator)
  3405.         len++;
  3406.     if (freeBindingList)
  3407.     {
  3408.         b = freeBindingList;
  3409.         if (len > b->uriAlloc)
  3410.         {
  3411.             b->uri = (XML_Char*)REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
  3412.             if (!b->uri)
  3413.                 return 0;
  3414.             b->uriAlloc = len + EXPAND_SPARE;
  3415.         }
  3416.         freeBindingList = b->nextTagBinding;
  3417.     }
  3418.     else
  3419.     {
  3420.         b = (BINDING*)MALLOC(sizeof(BINDING));
  3421.         if (!b)
  3422.             return 0;
  3423.         b->uri = (XML_Char*)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
  3424.         if (!b->uri)
  3425.         {
  3426.             FREE(b);
  3427.             return 0;
  3428.         }
  3429.         b->uriAlloc = len + EXPAND_SPARE;
  3430.     }
  3431.     b->uriLen = len;
  3432.     memcpy(b->uri, uri, len * sizeof(XML_Char));
  3433.     if (namespaceSeparator)
  3434.         b->uri[len - 1] = namespaceSeparator;
  3435.     b->prefix = prefix;
  3436.     b->attId = attId;
  3437.     b->prevPrefixBinding = prefix->binding;
  3438.     if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
  3439.         prefix->binding = 0;
  3440.     else
  3441.         prefix->binding = b;
  3442.     b->nextTagBinding = *bindingsPtr;
  3443.     *bindingsPtr = b;
  3444.     if (startNamespaceDeclHandler)
  3445.         startNamespaceDeclHandler(handlerArg, prefix->name,
  3446.                                   prefix->binding ? uri : 0);
  3447.     return 1;
  3448. }
  3449.  
  3450. /* The idea here is to avoid using stack for each CDATA section when
  3451.  * the whole file is parsed with one call. */
  3452.  
  3453. static XMLERROR cdataSectionProcessor(XML_Parser parser,
  3454.                                       const char *start,
  3455.                                       const char *end,
  3456.                                       const char **endPtr)
  3457. {
  3458.     XMLERROR result = doCdataSection(parser, encoding, &start, end, endPtr);
  3459.  
  3460.     if (start)
  3461.     {
  3462.         processor = contentProcessor;
  3463.         return contentProcessor(parser, start, end, endPtr);
  3464.     }
  3465.     return result;
  3466. }
  3467.  
  3468. /* startPtr gets set to non-null is the section is closed, and to null if
  3469.  * the section is not yet closed. */
  3470.  
  3471. static XMLERROR doCdataSection(XML_Parser parser,
  3472.                                const ENCODING * enc,
  3473.                                const char **startPtr,
  3474.                                const char *end,
  3475.                                const char **nextPtr)
  3476. {
  3477.     const char *s = *startPtr;
  3478.     const char **eventPP;
  3479.     const char **eventEndPP;
  3480.  
  3481.     if (enc == encoding)
  3482.     {
  3483.         eventPP = &eventPtr;
  3484.         *eventPP = s;
  3485.         eventEndPP = &eventEndPtr;
  3486.     }
  3487.     else
  3488.     {
  3489.         eventPP = &(openInternalEntities->internalEventPtr);
  3490.         eventEndPP = &(openInternalEntities->internalEventEndPtr);
  3491.     }
  3492.     *eventPP = s;
  3493.     *startPtr = 0;
  3494.     for (;;)
  3495.     {
  3496.         const char *next;
  3497.         int tok = XmlCdataSectionTok(enc, s, end, &next);
  3498.  
  3499.         *eventEndPP = next;
  3500.         switch (tok)
  3501.         {
  3502.             case XML_TOK_CDATA_SECT_CLOSE:
  3503.                 if (endCdataSectionHandler)
  3504.                     endCdataSectionHandler(handlerArg);
  3505. #if 0
  3506.                 /* see comment under XML_TOK_CDATA_SECT_OPEN */
  3507.                 else if (characterDataHandler)
  3508.                     characterDataHandler(handlerArg, dataBuf, 0);
  3509. #endif
  3510.                 else if (defaultHandler)
  3511.                     reportDefault(parser, enc, s, next);
  3512.                 *startPtr = next;
  3513.                 return ERROR_EXPAT_NONE;
  3514.             case XML_TOK_DATA_NEWLINE:
  3515.                 if (characterDataHandler)
  3516.                 {
  3517.                     XML_Char c = 0xA;
  3518.  
  3519.                     characterDataHandler(handlerArg, &c, 1);
  3520.                 }
  3521.                 else if (defaultHandler)
  3522.                     reportDefault(parser, enc, s, next);
  3523.                 break;
  3524.             case XML_TOK_DATA_CHARS:
  3525.                 if (characterDataHandler)
  3526.                 {
  3527.                     if (MUST_CONVERT(enc, s))
  3528.                     {
  3529.                         for (;;)
  3530.                         {
  3531.                             ICHAR *dataPtr = (ICHAR *) dataBuf;
  3532.  
  3533.                             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *) dataBufEnd);
  3534.                             *eventEndPP = next;
  3535.                             characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *) dataBuf);
  3536.                             if (s == next)
  3537.                                 break;
  3538.                             *eventPP = s;
  3539.                         }
  3540.                     }
  3541.                     else
  3542.                         characterDataHandler(handlerArg,
  3543.                                              (XML_Char *) s,
  3544.                                           (XML_Char *) next - (XML_Char *) s);
  3545.                 }
  3546.                 else if (defaultHandler)
  3547.                     reportDefault(parser, enc, s, next);
  3548.                 break;
  3549.             case XML_TOK_INVALID:
  3550.                 *eventPP = next;
  3551.                 return ERROR_EXPAT_INVALID_TOKEN;
  3552.             case XML_TOK_PARTIAL_CHAR:
  3553.                 if (nextPtr)
  3554.                 {
  3555.                     *nextPtr = s;
  3556.                     return ERROR_EXPAT_NONE;
  3557.                 }
  3558.                 return ERROR_EXPAT_PARTIAL_CHAR;
  3559.             case XML_TOK_PARTIAL:
  3560.             case XML_TOK_NONE:
  3561.                 if (nextPtr)
  3562.                 {
  3563.                     *nextPtr = s;
  3564.                     return ERROR_EXPAT_NONE;
  3565.                 }
  3566.                 return ERROR_EXPAT_UNCLOSED_CDATA_SECTION;
  3567.             default:
  3568.                 *eventPP = next;
  3569.                 return ERROR_EXPAT_UNEXPECTED_STATE;
  3570.         }
  3571.         *eventPP = s = next;
  3572.     }
  3573.     /* not reached */
  3574. }
  3575.  
  3576. #ifdef XML_DTD
  3577.  
  3578. /* The idea here is to avoid using stack for each IGNORE section when
  3579.  * the whole file is parsed with one call. */
  3580.  
  3581. static XMLERROR ignoreSectionProcessor(XML_Parser parser,
  3582.                                        const char *start,
  3583.                                        const char *end,
  3584.                                        const char **endPtr)
  3585. {
  3586.     XMLERROR result = doIgnoreSection(parser, encoding, &start, end, endPtr);
  3587.  
  3588.     if (start)
  3589.     {
  3590.         processor = prologProcessor;
  3591.         return prologProcessor(parser, start, end, endPtr);
  3592.     }
  3593.     return result;
  3594. }
  3595.  
  3596. /* startPtr gets set to non-null is the section is closed, and to null if
  3597.  * the section is not yet closed. */
  3598.  
  3599. static XMLERROR doIgnoreSection(XML_Parser parser,
  3600.                                 const ENCODING * enc,
  3601.                                 const char **startPtr,
  3602.                                 const char *end,
  3603.                                 const char **nextPtr)
  3604. {
  3605.     const char *next;
  3606.     int tok;
  3607.     const char *s = *startPtr;
  3608.     const char **eventPP;
  3609.     const char **eventEndPP;
  3610.  
  3611.     if (enc == encoding)
  3612.     {
  3613.         eventPP = &eventPtr;
  3614.         *eventPP = s;
  3615.         eventEndPP = &eventEndPtr;
  3616.     }
  3617.     else
  3618.     {
  3619.         eventPP = &(openInternalEntities->internalEventPtr);
  3620.         eventEndPP = &(openInternalEntities->internalEventEndPtr);
  3621.     }
  3622.     *eventPP = s;
  3623.     *startPtr = 0;
  3624.     tok = XmlIgnoreSectionTok(enc, s, end, &next);
  3625.     *eventEndPP = next;
  3626.     switch (tok)
  3627.     {
  3628.         case XML_TOK_IGNORE_SECT:
  3629.             if (defaultHandler)
  3630.                 reportDefault(parser, enc, s, next);
  3631.             *startPtr = next;
  3632.             return ERROR_EXPAT_NONE;
  3633.         case XML_TOK_INVALID:
  3634.             *eventPP = next;
  3635.             return ERROR_EXPAT_INVALID_TOKEN;
  3636.         case XML_TOK_PARTIAL_CHAR:
  3637.             if (nextPtr)
  3638.             {
  3639.                 *nextPtr = s;
  3640.                 return ERROR_EXPAT_NONE;
  3641.             }
  3642.             return ERROR_EXPAT_PARTIAL_CHAR;
  3643.         case XML_TOK_PARTIAL:
  3644.         case XML_TOK_NONE:
  3645.             if (nextPtr)
  3646.             {
  3647.                 *nextPtr = s;
  3648.                 return ERROR_EXPAT_NONE;
  3649.             }
  3650.             return ERROR_EXPAT_SYNTAX;  /* ERROR_EXPAT_UNCLOSED_IGNORE_SECTION */
  3651.         default:
  3652.             *eventPP = next;
  3653.             return ERROR_EXPAT_UNEXPECTED_STATE;
  3654.     }
  3655.     /* not reached */
  3656. }
  3657.  
  3658. #endif /* XML_DTD */
  3659.  
  3660. static XMLERROR initializeEncoding(XML_Parser parser)
  3661. {
  3662.     const char *s;
  3663.  
  3664. #ifdef XML_UNICODE
  3665.     char encodingBuf[128];
  3666.  
  3667.     if (!protocolEncodingName)
  3668.         s = 0;
  3669.     else
  3670.     {
  3671.         int i;
  3672.  
  3673.         for (i = 0; protocolEncodingName[i]; i++)
  3674.         {
  3675.             if (i == sizeof(encodingBuf) - 1
  3676.                 || (protocolEncodingName[i] & ~0x7f) != 0)
  3677.             {
  3678.                 encodingBuf[0] = '\0';
  3679.                 break;
  3680.             }
  3681.             encodingBuf[i] = (char)protocolEncodingName[i];
  3682.         }
  3683.         encodingBuf[i] = '\0';
  3684.         s = encodingBuf;
  3685.     }
  3686. #else
  3687.     s = protocolEncodingName;
  3688. #endif
  3689.     if ((ns ? XmlInitEncodingNS : XmlInitEncoding) (&initEncoding, &encoding, s))
  3690.         return ERROR_EXPAT_NONE;
  3691.     return handleUnknownEncoding(parser, protocolEncodingName);
  3692. }
  3693.  
  3694. static XMLERROR  processXmlDecl(XML_Parser parser,
  3695.                                 int isGeneralTextEntity,
  3696.                                 const char *s,
  3697.                                 const char *next)
  3698. {
  3699.     const char *encodingName = 0;
  3700.     const char *storedEncName = 0;
  3701.     const ENCODING *newEncoding = 0;
  3702.     const char *version = 0;
  3703.     const char *versionend;
  3704.     const char *storedversion = 0;
  3705.     int standalone = -1;
  3706.  
  3707.     if (!(ns
  3708.           ? XmlParseXmlDeclNS
  3709.           : XmlParseXmlDecl) (isGeneralTextEntity,
  3710.                               encoding,
  3711.                               s,
  3712.                               next,
  3713.                               &eventPtr,
  3714.                               &version,
  3715.                               &versionend,
  3716.                               &encodingName,
  3717.                               &newEncoding,
  3718.                               &standalone))
  3719.         return ERROR_EXPAT_SYNTAX;
  3720.     if (!isGeneralTextEntity && standalone == 1)
  3721.     {
  3722.         dtd.standalone = 1;
  3723. #ifdef XML_DTD
  3724.         if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
  3725.             paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
  3726. #endif /* XML_DTD */
  3727.     }
  3728.     if (xmlDeclHandler)
  3729.     {
  3730.         if (encodingName)
  3731.         {
  3732.             storedEncName = poolStoreString(&temp2Pool,
  3733.                                             encoding,
  3734.                                             encodingName,
  3735.                                             encodingName
  3736.                                             + XmlNameLength(encoding, encodingName),
  3737.                                             NULL);
  3738.             if (!storedEncName)
  3739.                 return ERROR_EXPAT_NO_MEMORY;
  3740.             poolFinish(&temp2Pool);
  3741.         }
  3742.         if (version)
  3743.         {
  3744.             storedversion = poolStoreString(&temp2Pool,
  3745.                                             encoding,
  3746.                                             version,
  3747.                                             versionend - encoding->minBytesPerChar,
  3748.                                             NULL);
  3749.             if (!storedversion)
  3750.                 return ERROR_EXPAT_NO_MEMORY;
  3751.         }
  3752.         xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
  3753.     }
  3754.     else if (defaultHandler)
  3755.         reportDefault(parser, encoding, s, next);
  3756.     if (!protocolEncodingName)
  3757.     {
  3758.         if (newEncoding)
  3759.         {
  3760.             if (newEncoding->minBytesPerChar != encoding->minBytesPerChar)
  3761.             {
  3762.                 eventPtr = encodingName;
  3763.                 return ERROR_EXPAT_INCORRECT_ENCODING;
  3764.             }
  3765.             encoding = newEncoding;
  3766.         }
  3767.         else if (encodingName)
  3768.         {
  3769.             XMLERROR result;
  3770.  
  3771.             if (!storedEncName)
  3772.             {
  3773.                 storedEncName = poolStoreString(&temp2Pool,
  3774.                                                 encoding,
  3775.                                                 encodingName,
  3776.                                                 encodingName
  3777.                                                 + XmlNameLength(encoding, encodingName),
  3778.                                                 NULL);
  3779.                 if (!storedEncName)
  3780.                     return ERROR_EXPAT_NO_MEMORY;
  3781.             }
  3782.             result = handleUnknownEncoding(parser, storedEncName);
  3783.             poolClear(&tempPool);
  3784.             if (result == ERROR_EXPAT_UNKNOWN_ENCODING)
  3785.                 eventPtr = encodingName;
  3786.             return result;
  3787.         }
  3788.     }
  3789.  
  3790.     if (storedEncName || storedversion)
  3791.         poolClear(&temp2Pool);
  3792.  
  3793.     return ERROR_EXPAT_NONE;
  3794. }
  3795.  
  3796. static XMLERROR  handleUnknownEncoding(XML_Parser parser,
  3797.                                        const XML_Char * encodingName)
  3798. {
  3799.     if (unknownEncodingHandler)
  3800.     {
  3801.         XML_Encoding info;
  3802.         int i;
  3803.  
  3804.         for (i = 0; i < 256; i++)
  3805.             info.map[i] = -1;
  3806.         info.convert = 0;
  3807.         info.data = 0;
  3808.         info.release = 0;
  3809.         if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info))
  3810.         {
  3811.             ENCODING *enc;
  3812.  
  3813.             unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
  3814.             if (!unknownEncodingMem)
  3815.             {
  3816.                 if (info.release)
  3817.                     info.release(info.data);
  3818.                 return ERROR_EXPAT_NO_MEMORY;
  3819.             }
  3820.             enc = (ns
  3821.                    ? XmlInitUnknownEncodingNS
  3822.                    : XmlInitUnknownEncoding) (unknownEncodingMem,
  3823.                                               info.map,
  3824.                                               info.convert,
  3825.                                               info.data);
  3826.             if (enc)
  3827.             {
  3828.                 unknownEncodingData = info.data;
  3829.                 unknownEncodingRelease = (void(*)(void*))info.release;
  3830.                 encoding = enc;
  3831.                 return ERROR_EXPAT_NONE;
  3832.             }
  3833.         }
  3834.         if (info.release)
  3835.             info.release(info.data);
  3836.     }
  3837.     return ERROR_EXPAT_UNKNOWN_ENCODING;
  3838. }
  3839.  
  3840. static XMLERROR prologInitProcessor(XML_Parser parser,
  3841.                                     const char *s,
  3842.                                     const char *end,
  3843.                                     const char **nextPtr)
  3844. {
  3845.     XMLERROR result = initializeEncoding(parser);
  3846.  
  3847.     if (result != ERROR_EXPAT_NONE)
  3848.         return result;
  3849.     processor = prologProcessor;
  3850.     return prologProcessor(parser, s, end, nextPtr);
  3851. }
  3852.  
  3853. static XMLERROR prologProcessor(XML_Parser parser,
  3854.                                 const char *s,
  3855.                                 const char *end,
  3856.                                 const char **nextPtr)
  3857. {
  3858.     const char *next;
  3859.     int tok = XmlPrologTok(encoding, s, end, &next);
  3860.  
  3861.     return doProlog(parser, encoding, s, end, tok, next, nextPtr);
  3862. }
  3863.  
  3864. static XMLERROR doProlog(XML_Parser parser,
  3865.                          const ENCODING * enc,
  3866.                          const char *s,
  3867.                          const char *end,
  3868.                          int tok,
  3869.                          const char *next,
  3870.                          const char **nextPtr)
  3871. {
  3872. #ifdef XML_DTD
  3873.     static const XML_Char externalSubsetName[] =
  3874.     {'#', '\0'};
  3875.  
  3876. #endif /* XML_DTD */
  3877.  
  3878.     const char **eventPP;
  3879.     const char **eventEndPP;
  3880.     enum XML_Content_Quant quant;
  3881.  
  3882.     if (enc == encoding)
  3883.     {
  3884.         eventPP = &eventPtr;
  3885.         eventEndPP = &eventEndPtr;
  3886.     }
  3887.     else
  3888.     {
  3889.         eventPP = &(openInternalEntities->internalEventPtr);
  3890.         eventEndPP = &(openInternalEntities->internalEventEndPtr);
  3891.     }
  3892.     for (;;)
  3893.     {
  3894.         int role;
  3895.  
  3896.         *eventPP = s;
  3897.         *eventEndPP = next;
  3898.         if (tok <= 0)
  3899.         {
  3900.             if (nextPtr != 0 && tok != XML_TOK_INVALID)
  3901.             {
  3902.                 *nextPtr = s;
  3903.                 return ERROR_EXPAT_NONE;
  3904.             }
  3905.             switch (tok)
  3906.             {
  3907.                 case XML_TOK_INVALID:
  3908.                     *eventPP = next;
  3909.                     return ERROR_EXPAT_INVALID_TOKEN;
  3910.                 case XML_TOK_PARTIAL:
  3911.                     return ERROR_EXPAT_UNCLOSED_TOKEN;
  3912.                 case XML_TOK_PARTIAL_CHAR:
  3913.                     return ERROR_EXPAT_PARTIAL_CHAR;
  3914.                 case XML_TOK_NONE:
  3915. #ifdef XML_DTD
  3916.                     if (enc != encoding)
  3917.                         return ERROR_EXPAT_NONE;
  3918.                     if (parentParser)
  3919.                     {
  3920.                         if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
  3921.                             == XML_ROLE_ERROR)
  3922.                             return ERROR_EXPAT_SYNTAX;
  3923.                         hadExternalDoctype = 0;
  3924.                         return ERROR_EXPAT_NONE;
  3925.                     }
  3926. #endif /* XML_DTD */
  3927.                     return ERROR_EXPAT_NO_ELEMENTS;
  3928.                 default:
  3929.                     tok = -tok;
  3930.                     next = end;
  3931.                     break;
  3932.             }
  3933.         }
  3934.         role = XmlTokenRole(&prologState, tok, s, next, enc);
  3935.         switch (role)
  3936.         {
  3937.             case XML_ROLE_XML_DECL:
  3938.                 {
  3939.                     XMLERROR result = processXmlDecl(parser, 0, s, next);
  3940.  
  3941.                     if (result != ERROR_EXPAT_NONE)
  3942.                         return result;
  3943.                     enc = encoding;
  3944.                 }
  3945.                 break;
  3946.             case XML_ROLE_DOCTYPE_NAME:
  3947.                 if (startDoctypeDeclHandler)
  3948.                 {
  3949.                     doctypeName = poolStoreString(&tempPool, enc, s, next, NULL);
  3950.                     if (!doctypeName)
  3951.                         return ERROR_EXPAT_NO_MEMORY;
  3952.                     poolFinish(&tempPool);
  3953.                     doctypeSysid = 0;
  3954.                     doctypePubid = 0;
  3955.                 }
  3956.                 break;
  3957.             case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
  3958.                 if (startDoctypeDeclHandler)
  3959.                 {
  3960.                     startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
  3961.                                             doctypePubid, 1);
  3962.                     doctypeName = 0;
  3963.                     poolClear(&tempPool);
  3964.                 }
  3965.                 break;
  3966. #ifdef XML_DTD
  3967.             case XML_ROLE_TEXT_DECL:
  3968.                 {
  3969.                     XMLERROR result = processXmlDecl(parser, 1, s, next);
  3970.  
  3971.                     if (result != ERROR_EXPAT_NONE)
  3972.                         return result;
  3973.                     enc = encoding;
  3974.                 }
  3975.                 break;
  3976. #endif /* XML_DTD */
  3977.             case XML_ROLE_DOCTYPE_PUBLIC_ID:
  3978.                 if (startDoctypeDeclHandler)
  3979.                 {
  3980.                     doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1, NULL);
  3981.                     if (!doctypePubid)
  3982.                         return ERROR_EXPAT_NO_MEMORY;
  3983.                     poolFinish(&tempPool);
  3984.                 }
  3985. #ifdef XML_DTD
  3986.                 declEntity = (ENTITY *) lookup(&dtd.paramEntities,
  3987.                                                externalSubsetName,
  3988.                                                sizeof(ENTITY));
  3989.                 if (!declEntity)
  3990.                     return ERROR_EXPAT_NO_MEMORY;
  3991. #endif /* XML_DTD */
  3992.                 /* fall through */
  3993.             case XML_ROLE_ENTITY_PUBLIC_ID:
  3994.                 if (!XmlIsPublicId(enc, s, next, eventPP))
  3995.                     return ERROR_EXPAT_SYNTAX;
  3996.                 if (declEntity)
  3997.                 {
  3998.                     XML_Char *tem = poolStoreString(&dtd.pool,
  3999.                                                     enc,
  4000.                                                     s + enc->minBytesPerChar,
  4001.                                                     next - enc->minBytesPerChar,
  4002.                                                     NULL);
  4003.  
  4004.                     if (!tem)
  4005.                         return ERROR_EXPAT_NO_MEMORY;
  4006.                     normalizePublicId(tem);
  4007.                     declEntity->publicId = tem;
  4008.                     poolFinish(&dtd.pool);
  4009.                 }
  4010.                 break;
  4011.             case XML_ROLE_DOCTYPE_CLOSE:
  4012.                 if (doctypeName)
  4013.                 {
  4014.                     startDoctypeDeclHandler(handlerArg, doctypeName,
  4015.                                             doctypeSysid, doctypePubid, 0);
  4016.                     poolClear(&tempPool);
  4017.                 }
  4018.                 if (dtd.complete && hadExternalDoctype)
  4019.                 {
  4020.                     dtd.complete = 0;
  4021. #ifdef XML_DTD
  4022.                     if (paramEntityParsing && externalEntityRefHandler)
  4023.                     {
  4024.                         ENTITY *entity = (ENTITY *) lookup(&dtd.paramEntities,
  4025.                                                            externalSubsetName,
  4026.                                                            0);
  4027.  
  4028.                         if (!externalEntityRefHandler(handlerArg,   // V0.9.14 (2001-08-09) [umoeller]
  4029.                                                       externalEntityRefHandlerArg,
  4030.                                                       0,
  4031.                                                       entity->base,
  4032.                                                       entity->systemId,
  4033.                                                       entity->publicId))
  4034.                             return ERROR_EXPAT_EXTERNAL_ENTITY_HANDLING;
  4035.                     }
  4036. #endif /* XML_DTD */
  4037.                     if (!dtd.complete
  4038.                         && !dtd.standalone
  4039.                         && notStandaloneHandler
  4040.                         && !notStandaloneHandler(handlerArg))
  4041.                         return ERROR_EXPAT_NOT_STANDALONE;
  4042.                 }
  4043.                 if (endDoctypeDeclHandler)
  4044.                     endDoctypeDeclHandler(handlerArg);
  4045.                 break;
  4046.             case XML_ROLE_INSTANCE_START:
  4047.                 processor = contentProcessor;
  4048.                 return contentProcessor(parser, s, end, nextPtr);
  4049.             case XML_ROLE_ATTLIST_ELEMENT_NAME:
  4050.                 declElementType = getElementType(parser, enc, s, next);
  4051.                 if (!declElementType)
  4052.                     return ERROR_EXPAT_NO_MEMORY;
  4053.                 break;
  4054.             case XML_ROLE_ATTRIBUTE_NAME:
  4055.                 declAttributeId = getAttributeId(parser, enc, s, next);
  4056.                 if (!declAttributeId)
  4057.                     return ERROR_EXPAT_NO_MEMORY;
  4058.                 declAttributeIsCdata = 0;
  4059.                 declAttributeType = 0;
  4060.                 declAttributeIsId = 0;
  4061.                 break;
  4062.             case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
  4063.                 declAttributeIsCdata = 1;
  4064.                 declAttributeType = "CDATA";
  4065.                 break;
  4066.             case XML_ROLE_ATTRIBUTE_TYPE_ID:
  4067.                 declAttributeIsId = 1;
  4068.                 declAttributeType = "ID";
  4069.                 break;
  4070.             case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
  4071.                 declAttributeType = "IDREF";
  4072.                 break;
  4073.             case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
  4074.                 declAttributeType = "IDREFS";
  4075.                 break;
  4076.             case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
  4077.                 declAttributeType = "ENTITY";
  4078.                 break;
  4079.             case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
  4080.                 declAttributeType = "ENTITIES";
  4081.                 break;
  4082.             case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
  4083.                 declAttributeType = "NMTOKEN";
  4084.                 break;
  4085.             case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
  4086.                 declAttributeType = "NMTOKENS";
  4087.                 break;
  4088.  
  4089.             case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
  4090.             case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
  4091.                 if (attlistDeclHandler)
  4092.                 {
  4093.                     char *prefix;
  4094.  
  4095.                     if (declAttributeType)
  4096.                     {
  4097.                         prefix = "|";
  4098.                     }
  4099.                     else
  4100.                     {
  4101.                         prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
  4102.                                   ? "NOTATION("
  4103.                                   : "(");
  4104.                     }
  4105.                     if (!poolAppendString(&tempPool, prefix))
  4106.                         return ERROR_EXPAT_NO_MEMORY;
  4107.                     if (!poolAppend(&tempPool, enc, s, next, NULL))
  4108.                         return ERROR_EXPAT_NO_MEMORY;
  4109.                     declAttributeType = tempPool.start;
  4110.                 }
  4111.                 break;
  4112.             case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
  4113.             case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
  4114.                 if (dtd.complete
  4115.                     && !defineAttribute(declElementType, declAttributeId,
  4116.                                    declAttributeIsCdata, declAttributeIsId, 0,
  4117.                                         parser))
  4118.                     return ERROR_EXPAT_NO_MEMORY;
  4119.                 if (attlistDeclHandler && declAttributeType)
  4120.                 {
  4121.                     if (*declAttributeType == '('
  4122.                         || (*declAttributeType == 'N' && declAttributeType[1] == 'O'))
  4123.                     {
  4124.                         /* Enumerated or Notation type */
  4125.                         if (!poolAppendChar(&tempPool, ')')
  4126.                             || !poolAppendChar(&tempPool, '\0'))
  4127.                             return ERROR_EXPAT_NO_MEMORY;
  4128.                         declAttributeType = tempPool.start;
  4129.                         poolFinish(&tempPool);
  4130.                     }
  4131.                     *eventEndPP = s;
  4132.                     attlistDeclHandler(handlerArg, declElementType->name,
  4133.                                      declAttributeId->name, declAttributeType,
  4134.                                 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
  4135.                     poolClear(&tempPool);
  4136.                 }
  4137.                 break;
  4138.             case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
  4139.             case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
  4140.                 {
  4141.                     const XML_Char *attVal;
  4142.                     XMLERROR result
  4143.                     = storeAttributeValue(parser, enc, declAttributeIsCdata,
  4144.                                           s + enc->minBytesPerChar,
  4145.                                           next - enc->minBytesPerChar,
  4146.                                           &dtd.pool);
  4147.  
  4148.                     if (result)
  4149.                         return result;
  4150.                     attVal = poolStart(&dtd.pool);
  4151.                     poolFinish(&dtd.pool);
  4152.                     if (dtd.complete
  4153.                     /* ID attributes aren't allowed to have a default */
  4154.                         && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
  4155.                         return ERROR_EXPAT_NO_MEMORY;
  4156.                     if (attlistDeclHandler && declAttributeType)
  4157.                     {
  4158.                         if (*declAttributeType == '('
  4159.                             || (*declAttributeType == 'N' && declAttributeType[1] == 'O'))
  4160.                         {
  4161.                             /* Enumerated or Notation type */
  4162.                             if (!poolAppendChar(&tempPool, ')')
  4163.                                 || !poolAppendChar(&tempPool, '\0'))
  4164.                                 return ERROR_EXPAT_NO_MEMORY;
  4165.                             declAttributeType = tempPool.start;
  4166.                             poolFinish(&tempPool);
  4167.                         }
  4168.                         *eventEndPP = s;
  4169.                         attlistDeclHandler(handlerArg, declElementType->name,
  4170.                                      declAttributeId->name, declAttributeType,
  4171.                                            attVal,
  4172.                                       role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
  4173.                         poolClear(&tempPool);
  4174.                     }
  4175.                     break;
  4176.                 }
  4177.             case XML_ROLE_ENTITY_VALUE:
  4178.                 {
  4179.                     XMLERROR result = storeEntityValue(parser, enc,
  4180.                                                      s + enc->minBytesPerChar,
  4181.                                                  next - enc->minBytesPerChar);
  4182.  
  4183.                     if (declEntity)
  4184.                     {
  4185.                         declEntity->textPtr = poolStart(&dtd.pool);
  4186.                         declEntity->textLen = poolLength(&dtd.pool);
  4187.                         poolFinish(&dtd.pool);
  4188.                         if (entityDeclHandler)
  4189.                         {
  4190.                             *eventEndPP = s;
  4191.                             entityDeclHandler(handlerArg,
  4192.                                               declEntity->name,
  4193.                                               declEntity->is_param,
  4194.                                               declEntity->textPtr,
  4195.                                               declEntity->textLen,
  4196.                                               curBase, 0, 0, 0);
  4197.                         }
  4198.                     }
  4199.                     else
  4200.                         poolDiscard(&dtd.pool);
  4201.                     if (result != ERROR_EXPAT_NONE)
  4202.                         return result;
  4203.                 }
  4204.                 break;
  4205.             case XML_ROLE_DOCTYPE_SYSTEM_ID:
  4206.                 if (startDoctypeDeclHandler)
  4207.                 {
  4208.                     doctypeSysid = poolStoreString(&tempPool,
  4209.                                                    enc,
  4210.                                                    s + 1,
  4211.                                                    next - 1,
  4212.                                                    NULL);
  4213.                     if (!doctypeSysid)
  4214.                         return ERROR_EXPAT_NO_MEMORY;
  4215.                     poolFinish(&tempPool);
  4216.                 }
  4217.                 if (!dtd.standalone
  4218. #ifdef XML_DTD
  4219.                     && !paramEntityParsing
  4220. #endif /* XML_DTD */
  4221.                     && notStandaloneHandler
  4222.                     && !notStandaloneHandler(handlerArg))
  4223.                     return ERROR_EXPAT_NOT_STANDALONE;
  4224.                 hadExternalDoctype = 1;
  4225. #ifndef XML_DTD
  4226.                 break;
  4227. #else /* XML_DTD */
  4228.                 if (!declEntity)
  4229.                 {
  4230.                     declEntity = (ENTITY *) lookup(&dtd.paramEntities,
  4231.                                                    externalSubsetName,
  4232.                                                    sizeof(ENTITY));
  4233.                     declEntity->publicId = 0;
  4234.                     if (!declEntity)
  4235.                         return ERROR_EXPAT_NO_MEMORY;
  4236.                 }
  4237.                 /* fall through */
  4238. #endif /* XML_DTD */
  4239.             case XML_ROLE_ENTITY_SYSTEM_ID:
  4240.                 if (declEntity)
  4241.                 {
  4242.                     declEntity->systemId = poolStoreString(&dtd.pool,
  4243.                                                            enc,
  4244.                                                            s + enc->minBytesPerChar,
  4245.                                                            next - enc->minBytesPerChar,
  4246.                                                            NULL);
  4247.                     if (!declEntity->systemId)
  4248.                         return ERROR_EXPAT_NO_MEMORY;
  4249.                     declEntity->base = curBase;
  4250.                     poolFinish(&dtd.pool);
  4251.                 }
  4252.                 break;
  4253.             case XML_ROLE_ENTITY_COMPLETE:
  4254.                 if (declEntity && entityDeclHandler)
  4255.                 {
  4256.                     *eventEndPP = s;
  4257.                     entityDeclHandler(handlerArg,
  4258.                                       declEntity->name,
  4259.                                       0, 0, 0,
  4260.                                       declEntity->base,
  4261.                                       declEntity->systemId,
  4262.                                       declEntity->publicId,
  4263.                                       0);
  4264.                 }
  4265.                 break;
  4266.             case XML_ROLE_ENTITY_NOTATION_NAME:
  4267.                 if (declEntity)
  4268.                 {
  4269.                     declEntity->notation = poolStoreString(&dtd.pool,
  4270.                                                            enc,
  4271.                                                            s,
  4272.                                                            next,
  4273.                                                            NULL);
  4274.                     if (!declEntity->notation)
  4275.                         return ERROR_EXPAT_NO_MEMORY;
  4276.                     poolFinish(&dtd.pool);
  4277.                     if (unparsedEntityDeclHandler)
  4278.                     {
  4279.                         *eventEndPP = s;
  4280.                         unparsedEntityDeclHandler(handlerArg,
  4281.                                                   declEntity->name,
  4282.                                                   declEntity->base,
  4283.                                                   declEntity->systemId,
  4284.                                                   declEntity->publicId,
  4285.                                                   declEntity->notation);
  4286.                     }
  4287.                     else if (entityDeclHandler)
  4288.                     {
  4289.                         *eventEndPP = s;
  4290.                         entityDeclHandler(handlerArg,
  4291.                                           declEntity->name,
  4292.                                           0, 0, 0,
  4293.                                           declEntity->base,
  4294.                                           declEntity->systemId,
  4295.                                           declEntity->publicId,
  4296.                                           declEntity->notation);
  4297.                     }
  4298.                 }
  4299.                 break;
  4300.             case XML_ROLE_GENERAL_ENTITY_NAME:
  4301.                 {
  4302.                     const XML_Char *name;
  4303.  
  4304.                     if (XmlPredefinedEntityName(enc, s, next))
  4305.                     {
  4306.                         declEntity = 0;
  4307.                         break;
  4308.                     }
  4309.                     name = poolStoreString(&dtd.pool,
  4310.                                            enc,
  4311.                                            s,
  4312.                                            next,
  4313.                                            NULL);
  4314.                     if (!name)
  4315.                         return ERROR_EXPAT_NO_MEMORY;
  4316.                     if (dtd.complete)
  4317.                     {
  4318.                         declEntity = (ENTITY *) lookup(&dtd.generalEntities, name, sizeof(ENTITY));
  4319.                         if (!declEntity)
  4320.                             return ERROR_EXPAT_NO_MEMORY;
  4321.                         if (declEntity->name != name)
  4322.                         {
  4323.                             poolDiscard(&dtd.pool);
  4324.                             declEntity = 0;
  4325.                         }
  4326.                         else
  4327.                         {
  4328.                             poolFinish(&dtd.pool);
  4329.                             declEntity->publicId = 0;
  4330.                             declEntity->is_param = 0;
  4331.                         }
  4332.                     }
  4333.                     else
  4334.                     {
  4335.                         poolDiscard(&dtd.pool);
  4336.                         declEntity = 0;
  4337.                     }
  4338.                 }
  4339.                 break;
  4340.             case XML_ROLE_PARAM_ENTITY_NAME:
  4341. #ifdef XML_DTD
  4342.                 if (dtd.complete)
  4343.                 {
  4344.                     const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next, NULL);
  4345.  
  4346.                     if (!name)
  4347.                         return ERROR_EXPAT_NO_MEMORY;
  4348.                     declEntity = (ENTITY *) lookup(&dtd.paramEntities,
  4349.                                                    name, sizeof(ENTITY));
  4350.                     if (!declEntity)
  4351.                         return ERROR_EXPAT_NO_MEMORY;
  4352.                     if (declEntity->name != name)
  4353.                     {
  4354.                         poolDiscard(&dtd.pool);
  4355.                         declEntity = 0;
  4356.                     }
  4357.                     else
  4358.                     {
  4359.                         poolFinish(&dtd.pool);
  4360.                         declEntity->publicId = 0;
  4361.                         declEntity->is_param = 1;
  4362.                     }
  4363.                 }
  4364. #else /* not XML_DTD */
  4365.                 declEntity = 0;
  4366. #endif /* not XML_DTD */
  4367.                 break;
  4368.             case XML_ROLE_NOTATION_NAME:
  4369.                 declNotationPublicId = 0;
  4370.                 declNotationName = 0;
  4371.                 if (notationDeclHandler)
  4372.                 {
  4373.                     declNotationName = poolStoreString(&tempPool, enc, s, next, NULL);
  4374.                     if (!declNotationName)
  4375.                         return ERROR_EXPAT_NO_MEMORY;
  4376.                     poolFinish(&tempPool);
  4377.                 }
  4378.                 break;
  4379.             case XML_ROLE_NOTATION_PUBLIC_ID:
  4380.                 if (!XmlIsPublicId(enc, s, next, eventPP))
  4381.                     return ERROR_EXPAT_SYNTAX;
  4382.                 if (declNotationName)
  4383.                 {
  4384.                     XML_Char *tem = poolStoreString(&tempPool,
  4385.                                                     enc,
  4386.                                                     s + enc->minBytesPerChar,
  4387.                                                     next - enc->minBytesPerChar,
  4388.                                                     NULL);
  4389.  
  4390.                     if (!tem)
  4391.                         return ERROR_EXPAT_NO_MEMORY;
  4392.                     normalizePublicId(tem);
  4393.                     declNotationPublicId = tem;
  4394.                     poolFinish(&tempPool);
  4395.                 }
  4396.                 break;
  4397.             case XML_ROLE_NOTATION_SYSTEM_ID:
  4398.                 if (declNotationName && notationDeclHandler)
  4399.                 {
  4400.                     const XML_Char *systemId
  4401.                     = poolStoreString(&tempPool, enc,
  4402.                                       s + enc->minBytesPerChar,
  4403.                                       next - enc->minBytesPerChar,
  4404.                                       NULL);
  4405.  
  4406.                     if (!systemId)
  4407.                         return ERROR_EXPAT_NO_MEMORY;
  4408.                     *eventEndPP = s;
  4409.                     notationDeclHandler(handlerArg,
  4410.                                         declNotationName,
  4411.                                         curBase,
  4412.                                         systemId,
  4413.                                         declNotationPublicId);
  4414.                 }
  4415.                 poolClear(&tempPool);
  4416.                 break;
  4417.             case XML_ROLE_NOTATION_NO_SYSTEM_ID:
  4418.                 if (declNotationPublicId && notationDeclHandler)
  4419.                 {
  4420.                     *eventEndPP = s;
  4421.                     notationDeclHandler(handlerArg,
  4422.                                         declNotationName,
  4423.                                         curBase,
  4424.                                         0,
  4425.                                         declNotationPublicId);
  4426.                 }
  4427.                 poolClear(&tempPool);
  4428.                 break;
  4429.             case XML_ROLE_ERROR:
  4430.                 switch (tok)
  4431.                 {
  4432.                     case XML_TOK_PARAM_ENTITY_REF:
  4433.                         return ERROR_EXPAT_PARAM_ENTITY_REF;
  4434.                     case XML_TOK_XML_DECL:
  4435.                         return ERROR_EXPAT_MISPLACED_XML_PI;
  4436.                     default:
  4437.                         return ERROR_EXPAT_SYNTAX;
  4438.                 }
  4439. #ifdef XML_DTD
  4440.             case XML_ROLE_IGNORE_SECT:
  4441.                 {
  4442.                     XMLERROR result;
  4443.  
  4444.                     if (defaultHandler)
  4445.                         reportDefault(parser, enc, s, next);
  4446.                     result = doIgnoreSection(parser, enc, &next, end, nextPtr);
  4447.                     if (!next)
  4448.                     {
  4449.                         processor = ignoreSectionProcessor;
  4450.                         return result;
  4451.                     }
  4452.                 }
  4453.                 break;
  4454. #endif /* XML_DTD */
  4455.             case XML_ROLE_GROUP_OPEN:
  4456.                 if (prologState.level >= groupSize)
  4457.                 {
  4458.                     if (groupSize)
  4459.                     {
  4460.                         groupConnector = (char*)REALLOC(groupConnector, groupSize *= 2);
  4461.                         if (dtd.scaffIndex)
  4462.                             dtd.scaffIndex = (int*)REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
  4463.                     }
  4464.                     else
  4465.                         groupConnector = (char*)MALLOC(groupSize = 32);
  4466.                     if (!groupConnector)
  4467.                         return ERROR_EXPAT_NO_MEMORY;
  4468.                 }
  4469.                 groupConnector[prologState.level] = 0;
  4470.                 if (dtd.in_eldecl)
  4471.                 {
  4472.                     int myindex = nextScaffoldPart(parser);
  4473.  
  4474.                     if (myindex < 0)
  4475.                         return ERROR_EXPAT_NO_MEMORY;
  4476.                     dtd.scaffIndex[dtd.scaffLevel] = myindex;
  4477.                     dtd.scaffLevel++;
  4478.                     dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
  4479.                 }
  4480.                 break;
  4481.             case XML_ROLE_GROUP_SEQUENCE:
  4482.                 if (groupConnector[prologState.level] == '|')
  4483.                     return ERROR_EXPAT_SYNTAX;
  4484.                 groupConnector[prologState.level] = ',';
  4485.                 break;
  4486.             case XML_ROLE_GROUP_CHOICE:
  4487.                 if (groupConnector[prologState.level] == ',')
  4488.                     return ERROR_EXPAT_SYNTAX;
  4489.                 if (dtd.in_eldecl
  4490.                     && !groupConnector[prologState.level]
  4491.                     && dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type != XML_CTYPE_MIXED
  4492.                     )
  4493.                 {
  4494.                     dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_CHOICE;
  4495.                 }
  4496.                 groupConnector[prologState.level] = '|';
  4497.                 break;
  4498.             case XML_ROLE_PARAM_ENTITY_REF:
  4499. #ifdef XML_DTD
  4500.             case XML_ROLE_INNER_PARAM_ENTITY_REF:
  4501.                 if (paramEntityParsing
  4502.                  && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF))
  4503.                 {
  4504.                     const XML_Char *name;
  4505.                     ENTITY *entity;
  4506.  
  4507.                     name = poolStoreString(&dtd.pool, enc,
  4508.                                            s + enc->minBytesPerChar,
  4509.                                            next - enc->minBytesPerChar,
  4510.                                            NULL);
  4511.                     if (!name)
  4512.                         return ERROR_EXPAT_NO_MEMORY;
  4513.                     entity = (ENTITY *) lookup(&dtd.paramEntities, name, 0);
  4514.                     poolDiscard(&dtd.pool);
  4515.                     if (!entity)
  4516.                     {
  4517.                         /* FIXME what to do if !dtd.complete? */
  4518.                         return ERROR_EXPAT_UNDEFINED_ENTITY;
  4519.                     }
  4520.                     if (entity->open)
  4521.                         return ERROR_EXPAT_RECURSIVE_ENTITY_REF;
  4522.                     if (entity->textPtr)
  4523.                     {
  4524.                         XMLERROR result;
  4525.  
  4526.                         result = processInternalParamEntity(parser, entity);
  4527.                         if (result != ERROR_EXPAT_NONE)
  4528.                             return result;
  4529.                         break;
  4530.                     }
  4531.                     if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
  4532.                         return ERROR_EXPAT_PARAM_ENTITY_REF;
  4533.                     if (externalEntityRefHandler)
  4534.                     {
  4535.                         dtd.complete = 0;
  4536.                         entity->open = 1;
  4537.                         if (!externalEntityRefHandler(handlerArg,       // V0.9.14 (2001-08-09) [umoeller]
  4538.                                                       externalEntityRefHandlerArg,
  4539.                                                       0,
  4540.                                                       entity->base,
  4541.                                                       entity->systemId,
  4542.                                                       entity->publicId))
  4543.                         {
  4544.                             entity->open = 0;
  4545.                             return ERROR_EXPAT_EXTERNAL_ENTITY_HANDLING;
  4546.                         }
  4547.                         entity->open = 0;
  4548.                         if (dtd.complete)
  4549.                             break;
  4550.                     }
  4551.                 }
  4552. #endif /* XML_DTD */
  4553.                 if (!dtd.standalone
  4554.                     && notStandaloneHandler
  4555.                     && !notStandaloneHandler(handlerArg))
  4556.                     return ERROR_EXPAT_NOT_STANDALONE;
  4557.                 dtd.complete = 0;
  4558.                 if (defaultHandler)
  4559.                     reportDefault(parser, enc, s, next);
  4560.                 break;
  4561.  
  4562.                 /* Element declaration stuff */
  4563.  
  4564.             case XML_ROLE_ELEMENT_NAME:
  4565.                 if (elementDeclHandler)
  4566.                 {
  4567.                     declElementType = getElementType(parser, enc, s, next);
  4568.                     if (!declElementType)
  4569.                         return ERROR_EXPAT_NO_MEMORY;
  4570.                     dtd.scaffLevel = 0;
  4571.                     dtd.scaffCount = 0;
  4572.                     dtd.in_eldecl = 1;
  4573.                 }
  4574.                 break;
  4575.  
  4576.             case XML_ROLE_CONTENT_ANY:
  4577.             case XML_ROLE_CONTENT_EMPTY:
  4578.                 if (dtd.in_eldecl)
  4579.                 {
  4580.                     if (elementDeclHandler)
  4581.                     {
  4582.                         XMLCONTENT *content = (XMLCONTENT *) MALLOC(sizeof(XMLCONTENT));
  4583.  
  4584.                         if (!content)
  4585.                             return ERROR_EXPAT_NO_MEMORY;
  4586.                         content->quant = XML_CQUANT_NONE;
  4587.                         content->name = 0;
  4588.                         content->numchildren = 0;
  4589.                         content->children = 0;
  4590.                         content->type = ((role == XML_ROLE_CONTENT_ANY) ?
  4591.                                          XML_CTYPE_ANY :
  4592.                                          XML_CTYPE_EMPTY);
  4593.                         *eventEndPP = s;
  4594.                         elementDeclHandler(handlerArg, declElementType->name, content);
  4595.                     }
  4596.                     dtd.in_eldecl = 0;
  4597.                 }
  4598.                 break;
  4599.  
  4600.             case XML_ROLE_CONTENT_PCDATA:
  4601.                 if (dtd.in_eldecl)
  4602.                 {
  4603.                     dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_MIXED;
  4604.                 }
  4605.                 break;
  4606.  
  4607.             case XML_ROLE_CONTENT_ELEMENT:
  4608.                 quant = XML_CQUANT_NONE;
  4609.                 goto elementContent;
  4610.             case XML_ROLE_CONTENT_ELEMENT_OPT:
  4611.                 quant = XML_CQUANT_OPT;
  4612.                 goto elementContent;
  4613.             case XML_ROLE_CONTENT_ELEMENT_REP:
  4614.                 quant = XML_CQUANT_REP;
  4615.                 goto elementContent;
  4616.             case XML_ROLE_CONTENT_ELEMENT_PLUS:
  4617.                 quant = XML_CQUANT_PLUS;
  4618.               elementContent:
  4619.                 if (dtd.in_eldecl)
  4620.                 {
  4621.                     ELEMENT_TYPE *el;
  4622.                     const char *nxt = quant == XML_CQUANT_NONE ? next : next - 1;
  4623.                     int myindex = nextScaffoldPart(parser);
  4624.  
  4625.                     if (myindex < 0)
  4626.                         return ERROR_EXPAT_NO_MEMORY;
  4627.                     dtd.scaffold[myindex].type = XML_CTYPE_NAME;
  4628.                     dtd.scaffold[myindex].quant = quant;
  4629.                     el = getElementType(parser, enc, s, nxt);
  4630.                     if (!el)
  4631.                         return ERROR_EXPAT_NO_MEMORY;
  4632.                     dtd.scaffold[myindex].name = el->name;
  4633.                     dtd.contentStringLen += nxt - s + 1;
  4634.                 }
  4635.                 break;
  4636.  
  4637.             case XML_ROLE_GROUP_CLOSE:
  4638.                 quant = XML_CQUANT_NONE;
  4639.                 goto closeGroup;
  4640.             case XML_ROLE_GROUP_CLOSE_OPT:
  4641.                 quant = XML_CQUANT_OPT;
  4642.                 goto closeGroup;
  4643.             case XML_ROLE_GROUP_CLOSE_REP:
  4644.                 quant = XML_CQUANT_REP;
  4645.                 goto closeGroup;
  4646.             case XML_ROLE_GROUP_CLOSE_PLUS:
  4647.                 quant = XML_CQUANT_PLUS;
  4648.               closeGroup:
  4649.                 if (dtd.in_eldecl)
  4650.                 {
  4651.                     dtd.scaffLevel--;
  4652.                     dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
  4653.                     if (dtd.scaffLevel == 0)
  4654.                     {
  4655.                         if (elementDeclHandler)
  4656.                         {
  4657.                             XMLCONTENT *model = build_model(parser);
  4658.  
  4659.                             if (!model)
  4660.                                 return ERROR_EXPAT_NO_MEMORY;
  4661.                             *eventEndPP = s;
  4662.                             elementDeclHandler(handlerArg, declElementType->name, model);
  4663.                         }
  4664.                         dtd.in_eldecl = 0;
  4665.                         dtd.contentStringLen = 0;
  4666.                     }
  4667.                 }
  4668.                 break;
  4669.                 /* End element declaration stuff */
  4670.  
  4671.             case XML_ROLE_NONE:
  4672.                 switch (tok)
  4673.                 {
  4674.                     case XML_TOK_PI:
  4675.                         if (!reportProcessingInstruction(parser, enc, s, next))
  4676.                             return ERROR_EXPAT_NO_MEMORY;
  4677.                         break;
  4678.                     case XML_TOK_COMMENT:
  4679.                         if (!reportComment(parser, enc, s, next))
  4680.                             return ERROR_EXPAT_NO_MEMORY;
  4681.                         break;
  4682.                 }
  4683.                 break;
  4684.         }
  4685.         if (defaultHandler)
  4686.         {
  4687.             switch (tok)
  4688.             {
  4689.                 case XML_TOK_PI:
  4690.                 case XML_TOK_COMMENT:
  4691.                 case XML_TOK_BOM:
  4692.                 case XML_TOK_XML_DECL:
  4693. #ifdef XML_DTD
  4694.                 case XML_TOK_IGNORE_SECT:
  4695. #endif /* XML_DTD */
  4696.                 case XML_TOK_PARAM_ENTITY_REF:
  4697.                     break;
  4698.                 default:
  4699. #ifdef XML_DTD
  4700.                     if (role != XML_ROLE_IGNORE_SECT)
  4701. #endif /* XML_DTD */
  4702.                         reportDefault(parser, enc, s, next);
  4703.             }
  4704.         }
  4705.         s = next;
  4706.         tok = XmlPrologTok(enc, s, end, &next);
  4707.     }
  4708.     /* not reached */
  4709. }
  4710.  
  4711. static XMLERROR epilogProcessor(XML_Parser parser,
  4712.                                 const char *s,
  4713.                                 const char *end,
  4714.                                 const char **nextPtr)
  4715. {
  4716.     processor = epilogProcessor;
  4717.     eventPtr = s;
  4718.     for (;;)
  4719.     {
  4720.         const char *next;
  4721.         int tok = XmlPrologTok(encoding, s, end, &next);
  4722.  
  4723.         eventEndPtr = next;
  4724.         switch (tok)
  4725.         {
  4726.             case -XML_TOK_PROLOG_S:
  4727.                 if (defaultHandler)
  4728.                 {
  4729.                     eventEndPtr = end;
  4730.                     reportDefault(parser, encoding, s, end);
  4731.                 }
  4732.                 /* fall through */
  4733.             case XML_TOK_NONE:
  4734.                 if (nextPtr)
  4735.                     *nextPtr = end;
  4736.                 return ERROR_EXPAT_NONE;
  4737.             case XML_TOK_PROLOG_S:
  4738.                 if (defaultHandler)
  4739.                     reportDefault(parser, encoding, s, next);
  4740.                 break;
  4741.             case XML_TOK_PI:
  4742.                 if (!reportProcessingInstruction(parser, encoding, s, next))
  4743.                     return ERROR_EXPAT_NO_MEMORY;
  4744.                 break;
  4745.             case XML_TOK_COMMENT:
  4746.                 if (!reportComment(parser, encoding, s, next))
  4747.                     return ERROR_EXPAT_NO_MEMORY;
  4748.                 break;
  4749.             case XML_TOK_INVALID:
  4750.                 eventPtr = next;
  4751.                 return ERROR_EXPAT_INVALID_TOKEN;
  4752.             case XML_TOK_PARTIAL:
  4753.                 if (nextPtr)
  4754.                 {
  4755.                     *nextPtr = s;
  4756.                     return ERROR_EXPAT_NONE;
  4757.                 }
  4758.                 return ERROR_EXPAT_UNCLOSED_TOKEN;
  4759.             case XML_TOK_PARTIAL_CHAR:
  4760.                 if (nextPtr)
  4761.                 {
  4762.                     *nextPtr = s;
  4763.                     return ERROR_EXPAT_NONE;
  4764.                 }
  4765.                 return ERROR_EXPAT_PARTIAL_CHAR;
  4766.             default:
  4767.                 return ERROR_EXPAT_JUNK_AFTER_DOC_ELEMENT;
  4768.         }
  4769.         eventPtr = s = next;
  4770.     }
  4771. }
  4772.  
  4773. #ifdef XML_DTD
  4774.  
  4775. static XMLERROR processInternalParamEntity(XML_Parser parser,
  4776.                                            ENTITY * entity)
  4777. {
  4778.     const char *s, *end, *next;
  4779.     int tok;
  4780.     XMLERROR result;
  4781.     OPEN_INTERNAL_ENTITY openEntity;
  4782.  
  4783.     entity->open = 1;
  4784.     openEntity.next = openInternalEntities;
  4785.     openInternalEntities = &openEntity;
  4786.     openEntity.entity = entity;
  4787.     openEntity.internalEventPtr = 0;
  4788.     openEntity.internalEventEndPtr = 0;
  4789.     s = (char *)entity->textPtr;
  4790.     end = (char *)(entity->textPtr + entity->textLen);
  4791.     tok = XmlPrologTok(internalEncoding, s, end, &next);
  4792.     result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
  4793.     entity->open = 0;
  4794.     openInternalEntities = openEntity.next;
  4795.     return result;
  4796. }
  4797.  
  4798. #endif /* XML_DTD */
  4799.  
  4800. static XMLERROR errorProcessor(XML_Parser parser,
  4801.                                const char *s,
  4802.                                const char *end,
  4803.                                const char **nextPtr)
  4804. {
  4805.     return errorCode;
  4806. }
  4807.  
  4808. static XMLERROR storeAttributeValue(XML_Parser parser,
  4809.                                     const ENCODING * enc,
  4810.                                     int isCdata,
  4811.                                     const char *ptr,
  4812.                                     const char *end,
  4813.                                     STRING_POOL * pool)
  4814. {
  4815.     XMLERROR result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
  4816.  
  4817.     if (result)
  4818.         return result;
  4819.     if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
  4820.         poolChop(pool);
  4821.     if (!poolAppendChar(pool, XML_T('\0')))
  4822.         return ERROR_EXPAT_NO_MEMORY;
  4823.     return ERROR_EXPAT_NONE;
  4824. }
  4825.  
  4826.  
  4827. /*
  4828.  *@@ appendAttributeValue:
  4829.  *
  4830.  *@@changed V0.9.14 (2001-08-09) [umoeller]: fixed ERROR_EXPAT_UNDEFINED_ENTITY with callback-defined encodings
  4831.  */
  4832.  
  4833. static XMLERROR appendAttributeValue(XML_Parser parser,
  4834.                                      const ENCODING * enc,
  4835.                                      int isCdata,
  4836.                                      const char *ptr,
  4837.                                      const char *end,
  4838.                                      STRING_POOL * pool)
  4839. {
  4840.     for (;;)
  4841.     {
  4842.         const char *next;
  4843.         int tok = XmlAttributeValueTok(enc, ptr, end, &next);
  4844.  
  4845.         switch (tok)
  4846.         {
  4847.             case XML_TOK_NONE:
  4848.                 return ERROR_EXPAT_NONE;
  4849.             case XML_TOK_INVALID:
  4850.                 if (enc == encoding)
  4851.                     eventPtr = next;
  4852.                 return ERROR_EXPAT_INVALID_TOKEN;
  4853.             case XML_TOK_PARTIAL:
  4854.                 if (enc == encoding)
  4855.                     eventPtr = ptr;
  4856.                 return ERROR_EXPAT_INVALID_TOKEN;
  4857.             case XML_TOK_CHAR_REF:
  4858.                 {
  4859.                     XML_Char buf[XML_ENCODE_MAX];
  4860.                     int i;
  4861.                     int n = XmlCharRefNumber(enc, ptr);
  4862.  
  4863.                     if (n < 0)
  4864.                     {
  4865.                         if (enc == encoding)
  4866.                             eventPtr = ptr;
  4867.                         return ERROR_EXPAT_BAD_CHAR_REF;
  4868.                     }
  4869.                     if (!isCdata
  4870.                         && n == 0x20    /* space */
  4871.                      && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
  4872.                         break;
  4873.                     n = XmlEncode(n, (ICHAR *) buf);
  4874.                     if (!n)
  4875.                     {
  4876.                         if (enc == encoding)
  4877.                             eventPtr = ptr;
  4878.                         return ERROR_EXPAT_BAD_CHAR_REF;
  4879.                     }
  4880.                     for (i = 0; i < n; i++)
  4881.                     {
  4882.                         if (!poolAppendChar(pool, buf[i]))
  4883.                             return ERROR_EXPAT_NO_MEMORY;
  4884.                     }
  4885.                 }
  4886.                 break;
  4887.             case XML_TOK_DATA_CHARS:
  4888.                 if (!poolAppend(pool, enc, ptr, next, NULL))
  4889.                     return ERROR_EXPAT_NO_MEMORY;
  4890.                 break;
  4891.                 break;
  4892.             case XML_TOK_TRAILING_CR:
  4893.                 next = ptr + enc->minBytesPerChar;
  4894.                 /* fall through */
  4895.             case XML_TOK_ATTRIBUTE_VALUE_S:
  4896.             case XML_TOK_DATA_NEWLINE:
  4897.                 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
  4898.                     break;
  4899.                 if (!poolAppendChar(pool, 0x20))
  4900.                     return ERROR_EXPAT_NO_MEMORY;
  4901.                 break;
  4902.             case XML_TOK_ENTITY_REF:
  4903.                 {
  4904.                     const XML_Char *name;
  4905.                     ENTITY *entity;
  4906.                     unsigned long ulOfs; // V0.9.14 (2001-08-09) [umoeller]
  4907.                     XML_Char ch = XmlPredefinedEntityName(enc,
  4908.                                                    ptr + enc->minBytesPerChar,
  4909.                                                  next - enc->minBytesPerChar);
  4910.  
  4911.                     if (ch)
  4912.                     {
  4913.                         if (!poolAppendChar(pool, ch))
  4914.                             return ERROR_EXPAT_NO_MEMORY;
  4915.                         break;
  4916.                     }
  4917.                     name = poolStoreString(&temp2Pool, enc,
  4918.                                            ptr + enc->minBytesPerChar,
  4919.                                            next - enc->minBytesPerChar,
  4920.                                            &ulOfs); // V0.9.14 (2001-08-09) [umoeller]
  4921.                     if (!name)
  4922.                         return ERROR_EXPAT_NO_MEMORY;
  4923.                     entity = (ENTITY *) lookup(&dtd.generalEntities,
  4924.                                                name + ulOfs, // V0.9.14 (2001-08-09) [umoeller]
  4925.                                                0);
  4926.                     poolDiscard(&temp2Pool);
  4927.                     if (!entity)
  4928.                     {
  4929.                         if (dtd.complete)
  4930.                         {
  4931.                             if (enc == encoding)
  4932.                                 eventPtr = ptr;
  4933.                             return ERROR_EXPAT_UNDEFINED_ENTITY;
  4934.                         }
  4935.                     }
  4936.                     else if (entity->open)
  4937.                     {
  4938.                         if (enc == encoding)
  4939.                             eventPtr = ptr;
  4940.                         return ERROR_EXPAT_RECURSIVE_ENTITY_REF;
  4941.                     }
  4942.                     else if (entity->notation)
  4943.                     {
  4944.                         if (enc == encoding)
  4945.                             eventPtr = ptr;
  4946.                         return ERROR_EXPAT_BINARY_ENTITY_REF;
  4947.                     }
  4948.                     else if (!entity->textPtr)
  4949.                     {
  4950.                         if (enc == encoding)
  4951.                             eventPtr = ptr;
  4952.                         return ERROR_EXPAT_ATTRIBUTE_EXTERNAL_ENTITY_REF;
  4953.                     }
  4954.                     else
  4955.                     {
  4956.                         XMLERROR result;
  4957.                         const XML_Char *textEnd = entity->textPtr + entity->textLen;
  4958.  
  4959.                         entity->open = 1;
  4960.                         result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
  4961.                         entity->open = 0;
  4962.                         if (result)
  4963.                             return result;
  4964.                     }
  4965.                 }
  4966.                 break;
  4967.             default:
  4968.                 if (enc == encoding)
  4969.                     eventPtr = ptr;
  4970.                 return ERROR_EXPAT_UNEXPECTED_STATE;
  4971.         }
  4972.         ptr = next;
  4973.     }
  4974.     /* not reached */
  4975. }
  4976.  
  4977. static XMLERROR storeEntityValue(XML_Parser parser,
  4978.                                  const ENCODING * enc,
  4979.                                  const char *entityTextPtr,
  4980.                                  const char *entityTextEnd)
  4981. {
  4982.     STRING_POOL *pool = &(dtd.pool);
  4983.  
  4984.     for (;;)
  4985.     {
  4986.         const char *next;
  4987.         int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
  4988.  
  4989.         switch (tok)
  4990.         {
  4991.             case XML_TOK_PARAM_ENTITY_REF:
  4992. #ifdef XML_DTD
  4993.                 if (parentParser || enc != encoding)
  4994.                 {
  4995.                     XMLERROR result;
  4996.                     const XML_Char *name;
  4997.                     ENTITY *entity;
  4998.  
  4999.                     name = poolStoreString(&tempPool, enc,
  5000.                                            entityTextPtr + enc->minBytesPerChar,
  5001.                                            next - enc->minBytesPerChar,
  5002.                                            NULL);
  5003.                     if (!name)
  5004.                         return ERROR_EXPAT_NO_MEMORY;
  5005.                     entity = (ENTITY *) lookup(&dtd.paramEntities, name, 0);
  5006.                     poolDiscard(&tempPool);
  5007.                     if (!entity)
  5008.                     {
  5009.                         if (enc == encoding)
  5010.                             eventPtr = entityTextPtr;
  5011.                         return ERROR_EXPAT_UNDEFINED_ENTITY;
  5012.                     }
  5013.                     if (entity->open)
  5014.                     {
  5015.                         if (enc == encoding)
  5016.                             eventPtr = entityTextPtr;
  5017.                         return ERROR_EXPAT_RECURSIVE_ENTITY_REF;
  5018.                     }
  5019.                     if (entity->systemId)
  5020.                     {
  5021.                         if (enc == encoding)
  5022.                             eventPtr = entityTextPtr;
  5023.                         return ERROR_EXPAT_PARAM_ENTITY_REF;
  5024.                     }
  5025.                     entity->open = 1;
  5026.                     result = storeEntityValue(parser,
  5027.                                               internalEncoding,
  5028.                                               (char *)entity->textPtr,
  5029.                                  (char *)(entity->textPtr + entity->textLen));
  5030.                     entity->open = 0;
  5031.                     if (result)
  5032.                         return result;
  5033.                     break;
  5034.                 }
  5035. #endif /* XML_DTD */
  5036.                 eventPtr = entityTextPtr;
  5037.                 return ERROR_EXPAT_SYNTAX;
  5038.             case XML_TOK_NONE:
  5039.                 return ERROR_EXPAT_NONE;
  5040.             case XML_TOK_ENTITY_REF:
  5041.             case XML_TOK_DATA_CHARS:
  5042.                 if (!poolAppend(pool, enc, entityTextPtr, next, NULL))
  5043.                     return ERROR_EXPAT_NO_MEMORY;
  5044.                 break;
  5045.             case XML_TOK_TRAILING_CR:
  5046.                 next = entityTextPtr + enc->minBytesPerChar;
  5047.                 /* fall through */
  5048.             case XML_TOK_DATA_NEWLINE:
  5049.                 if (pool->end == pool->ptr && !poolGrow(pool))
  5050.                     return ERROR_EXPAT_NO_MEMORY;
  5051.                 *(pool->ptr)++ = 0xA;
  5052.                 break;
  5053.             case XML_TOK_CHAR_REF:
  5054.                 {
  5055.                     XML_Char buf[XML_ENCODE_MAX];
  5056.                     int i;
  5057.                     int n = XmlCharRefNumber(enc, entityTextPtr);
  5058.  
  5059.                     if (n < 0)
  5060.                     {
  5061.                         if (enc == encoding)
  5062.                             eventPtr = entityTextPtr;
  5063.                         return ERROR_EXPAT_BAD_CHAR_REF;
  5064.                     }
  5065.                     n = XmlEncode(n, (ICHAR *) buf);
  5066.                     if (!n)
  5067.                     {
  5068.                         if (enc == encoding)
  5069.                             eventPtr = entityTextPtr;
  5070.                         return ERROR_EXPAT_BAD_CHAR_REF;
  5071.                     }
  5072.                     for (i = 0; i < n; i++)
  5073.                     {
  5074.                         if (pool->end == pool->ptr && !poolGrow(pool))
  5075.                             return ERROR_EXPAT_NO_MEMORY;
  5076.                         *(pool->ptr)++ = buf[i];
  5077.                     }
  5078.                 }
  5079.                 break;
  5080.             case XML_TOK_PARTIAL:
  5081.                 if (enc == encoding)
  5082.                     eventPtr = entityTextPtr;
  5083.                 return ERROR_EXPAT_INVALID_TOKEN;
  5084.             case XML_TOK_INVALID:
  5085.                 if (enc == encoding)
  5086.                     eventPtr = next;
  5087.                 return ERROR_EXPAT_INVALID_TOKEN;
  5088.             default:
  5089.                 if (enc == encoding)
  5090.                     eventPtr = entityTextPtr;
  5091.                 return ERROR_EXPAT_UNEXPECTED_STATE;
  5092.         }
  5093.         entityTextPtr = next;
  5094.     }
  5095.     /* not reached */
  5096. }
  5097.  
  5098. static void  normalizeLines(XML_Char * s)
  5099. {
  5100.     XML_Char *p;
  5101.  
  5102.     for (;; s++)
  5103.     {
  5104.         if (*s == XML_T('\0'))
  5105.             return;
  5106.         if (*s == 0xD)
  5107.             break;
  5108.     }
  5109.     p = s;
  5110.     do
  5111.     {
  5112.         if (*s == 0xD)
  5113.         {
  5114.             *p++ = 0xA;
  5115.             if (*++s == 0xA)
  5116.                 s++;
  5117.         }
  5118.         else
  5119.             *p++ = *s++;
  5120.     }
  5121.     while (*s);
  5122.     *p = XML_T('\0');
  5123. }
  5124.  
  5125. static int reportProcessingInstruction(XML_Parser parser,
  5126.                                        const ENCODING * enc,
  5127.                                        const char *start,
  5128.                                        const char *end)
  5129. {
  5130.     const XML_Char *target;
  5131.     XML_Char *data;
  5132.     const char *tem;
  5133.  
  5134.     if (!processingInstructionHandler)
  5135.     {
  5136.         if (defaultHandler)
  5137.             reportDefault(parser, enc, start, end);
  5138.         return 1;
  5139.     }
  5140.     start += enc->minBytesPerChar * 2;
  5141.     tem = start + XmlNameLength(enc, start);
  5142.     target = poolStoreString(&tempPool, enc, start, tem, NULL);
  5143.     if (!target)
  5144.         return 0;
  5145.     poolFinish(&tempPool);
  5146.     data = poolStoreString(&tempPool, enc,
  5147.                            XmlSkipS(enc, tem),
  5148.                            end - enc->minBytesPerChar * 2,
  5149.                            NULL);
  5150.     if (!data)
  5151.         return 0;
  5152.     normalizeLines(data);
  5153.     processingInstructionHandler(handlerArg, target, data);
  5154.     poolClear(&tempPool);
  5155.     return 1;
  5156. }
  5157.  
  5158. static int reportComment(XML_Parser parser,
  5159.                          const ENCODING * enc,
  5160.                          const char *start,
  5161.                          const char *end)
  5162. {
  5163.     XML_Char *data;
  5164.  
  5165.     if (!commentHandler)
  5166.     {
  5167.         if (defaultHandler)
  5168.             reportDefault(parser, enc, start, end);
  5169.         return 1;
  5170.     }
  5171.     data = poolStoreString(&tempPool,
  5172.                            enc,
  5173.                            start + enc->minBytesPerChar * 4,
  5174.                            end - enc->minBytesPerChar * 3,
  5175.                            NULL);
  5176.     if (!data)
  5177.         return 0;
  5178.     normalizeLines(data);
  5179.     commentHandler(handlerArg, data);
  5180.     poolClear(&tempPool);
  5181.     return 1;
  5182. }
  5183.  
  5184. static void reportDefault(XML_Parser parser,
  5185.                           const ENCODING * enc,
  5186.                           const char *s,
  5187.                           const char *end)
  5188. {
  5189.     if (MUST_CONVERT(enc, s))
  5190.     {
  5191.         const char **eventPP;
  5192.         const char **eventEndPP;
  5193.  
  5194.         if (enc == encoding)
  5195.         {
  5196.             eventPP = &eventPtr;
  5197.             eventEndPP = &eventEndPtr;
  5198.         }
  5199.         else
  5200.         {
  5201.             eventPP = &(openInternalEntities->internalEventPtr);
  5202.             eventEndPP = &(openInternalEntities->internalEventEndPtr);
  5203.         }
  5204.         do
  5205.         {
  5206.             ICHAR *dataPtr = (ICHAR *) dataBuf;
  5207.  
  5208.             XmlConvert(enc, &s, end, &dataPtr, (ICHAR *) dataBufEnd);
  5209.             *eventEndPP = s;
  5210.             defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *) dataBuf);
  5211.             *eventPP = s;
  5212.         }
  5213.         while (s != end);
  5214.     }
  5215.     else
  5216.         defaultHandler(handlerArg, (XML_Char *) s, (XML_Char *) end - (XML_Char *) s);
  5217. }
  5218.  
  5219.  
  5220. static int defineAttribute(ELEMENT_TYPE * type,
  5221.                            ATTRIBUTE_ID * attId,
  5222.                            int isCdata,
  5223.                            int isId,
  5224.                            const XML_Char * value,
  5225.                            XML_Parser parser)
  5226. {
  5227.     DEFAULT_ATTRIBUTE *att;
  5228.  
  5229.     if (value || isId)
  5230.     {
  5231.         /* The handling of default attributes gets messed up if we have
  5232.          * a default which duplicates a non-default. */
  5233.         int i;
  5234.  
  5235.         for (i = 0; i < type->nDefaultAtts; i++)
  5236.             if (attId == type->defaultAtts[i].id)
  5237.                 return 1;
  5238.         if (isId && !type->idAtt && !attId->xmlns)
  5239.             type->idAtt = attId;
  5240.     }
  5241.     if (type->nDefaultAtts == type->allocDefaultAtts)
  5242.     {
  5243.         if (type->allocDefaultAtts == 0)
  5244.         {
  5245.             type->allocDefaultAtts = 8;
  5246.             type->defaultAtts = (DEFAULT_ATTRIBUTE*)MALLOC(type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
  5247.         }
  5248.         else
  5249.         {
  5250.             type->allocDefaultAtts *= 2;
  5251.             type->defaultAtts = (DEFAULT_ATTRIBUTE*)REALLOC(type->defaultAtts,
  5252.                           type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
  5253.         }
  5254.         if (!type->defaultAtts)
  5255.             return 0;
  5256.     }
  5257.     att = type->defaultAtts + type->nDefaultAtts;
  5258.     att->id = attId;
  5259.     att->value = value;
  5260.     att->isCdata = isCdata;
  5261.     if (!isCdata)
  5262.         attId->maybeTokenized = 1;
  5263.     type->nDefaultAtts += 1;
  5264.     return 1;
  5265. }
  5266.  
  5267. static int setElementTypePrefix(XML_Parser parser,
  5268.                                 ELEMENT_TYPE * elementType)
  5269. {
  5270.     const XML_Char *name;
  5271.  
  5272.     for (name = elementType->name; *name; name++)
  5273.     {
  5274.         if (*name == XML_T(':'))
  5275.         {
  5276.             PREFIX *prefix;
  5277.             const XML_Char *s;
  5278.  
  5279.             for (s = elementType->name; s != name; s++)
  5280.             {
  5281.                 if (!poolAppendChar(&dtd.pool, *s))
  5282.                     return 0;
  5283.             }
  5284.             if (!poolAppendChar(&dtd.pool, XML_T('\0')))
  5285.                 return 0;
  5286.             prefix = (PREFIX *) lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
  5287.             if (!prefix)
  5288.                 return 0;
  5289.             if (prefix->name == poolStart(&dtd.pool))
  5290.                 poolFinish(&dtd.pool);
  5291.             else
  5292.                 poolDiscard(&dtd.pool);
  5293.             elementType->prefix = prefix;
  5294.  
  5295.         }
  5296.     }
  5297.     return 1;
  5298. }
  5299.  
  5300. static ATTRIBUTE_ID * getAttributeId(XML_Parser parser,
  5301.                                      const ENCODING * enc,
  5302.                                      const char *start,
  5303.                                      const char *end)
  5304. {
  5305.     ATTRIBUTE_ID *id;
  5306.     const XML_Char *name;
  5307.  
  5308.     if (!poolAppendChar(&dtd.pool, XML_T('\0')))
  5309.         return 0;
  5310.     name = poolStoreString(&dtd.pool, enc, start, end, NULL);
  5311.     if (!name)
  5312.         return 0;
  5313.     ++name;
  5314.     id = (ATTRIBUTE_ID *) lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
  5315.     if (!id)
  5316.         return 0;
  5317.     if (id->name != name)
  5318.         poolDiscard(&dtd.pool);
  5319.     else
  5320.     {
  5321.         poolFinish(&dtd.pool);
  5322.         if (!ns)
  5323.             ;
  5324.         else if (name[0] == 'x'
  5325.                  && name[1] == 'm'
  5326.                  && name[2] == 'l'
  5327.                  && name[3] == 'n'
  5328.                  && name[4] == 's'
  5329.                  && (name[5] == XML_T('\0') || name[5] == XML_T(':')))
  5330.         {
  5331.             if (name[5] == '\0')
  5332.                 id->prefix = &dtd.defaultPrefix;
  5333.             else
  5334.                 id->prefix = (PREFIX *) lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
  5335.             id->xmlns = 1;
  5336.         }
  5337.         else
  5338.         {
  5339.             int i;
  5340.  
  5341.             for (i = 0; name[i]; i++)
  5342.             {
  5343.                 if (name[i] == XML_T(':'))
  5344.                 {
  5345.                     int j;
  5346.  
  5347.                     for (j = 0; j < i; j++)
  5348.                     {
  5349.                         if (!poolAppendChar(&dtd.pool, name[j]))
  5350.                             return 0;
  5351.                     }
  5352.                     if (!poolAppendChar(&dtd.pool, XML_T('\0')))
  5353.                         return 0;
  5354.                     id->prefix = (PREFIX *) lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
  5355.                     if (id->prefix->name == poolStart(&dtd.pool))
  5356.                         poolFinish(&dtd.pool);
  5357.                     else
  5358.                         poolDiscard(&dtd.pool);
  5359.                     break;
  5360.                 }
  5361.             }
  5362.         }
  5363.     }
  5364.     return id;
  5365. }
  5366.  
  5367. #define CONTEXT_SEP XML_T('\f')
  5368.  
  5369. static const XML_Char *getContext(XML_Parser parser)
  5370. {
  5371.     HASH_TABLE_ITER iter;
  5372.     int needSep = 0;
  5373.  
  5374.     if (dtd.defaultPrefix.binding)
  5375.     {
  5376.         int i;
  5377.         int len;
  5378.  
  5379.         if (!poolAppendChar(&tempPool, XML_T('=')))
  5380.             return 0;
  5381.         len = dtd.defaultPrefix.binding->uriLen;
  5382.         if (namespaceSeparator != XML_T('\0'))
  5383.             len--;
  5384.         for (i = 0; i < len; i++)
  5385.             if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
  5386.                 return 0;
  5387.         needSep = 1;
  5388.     }
  5389.  
  5390.     hashTableIterInit(&iter, &(dtd.prefixes));
  5391.     for (;;)
  5392.     {
  5393.         int i;
  5394.         int len;
  5395.         const XML_Char *s;
  5396.         PREFIX *prefix = (PREFIX *) hashTableIterNext(&iter);
  5397.  
  5398.         if (!prefix)
  5399.             break;
  5400.         if (!prefix->binding)
  5401.             continue;
  5402.         if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
  5403.             return 0;
  5404.         for (s = prefix->name; *s; s++)
  5405.             if (!poolAppendChar(&tempPool, *s))
  5406.                 return 0;
  5407.         if (!poolAppendChar(&tempPool, XML_T('=')))
  5408.             return 0;
  5409.         len = prefix->binding->uriLen;
  5410.         if (namespaceSeparator != XML_T('\0'))
  5411.             len--;
  5412.         for (i = 0; i < len; i++)
  5413.             if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
  5414.                 return 0;
  5415.         needSep = 1;
  5416.     }
  5417.  
  5418.  
  5419.     hashTableIterInit(&iter, &(dtd.generalEntities));
  5420.     for (;;)
  5421.     {
  5422.         const XML_Char *s;
  5423.         ENTITY *e = (ENTITY *) hashTableIterNext(&iter);
  5424.  
  5425.         if (!e)
  5426.             break;
  5427.         if (!e->open)
  5428.             continue;
  5429.         if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
  5430.             return 0;
  5431.         for (s = e->name; *s; s++)
  5432.             if (!poolAppendChar(&tempPool, *s))
  5433.                 return 0;
  5434.         needSep = 1;
  5435.     }
  5436.  
  5437.     if (!poolAppendChar(&tempPool, XML_T('\0')))
  5438.         return 0;
  5439.     return tempPool.start;
  5440. }
  5441.  
  5442. static int setContext(XML_Parser parser,
  5443.                       const XML_Char * context)
  5444. {
  5445.     const XML_Char *s = context;
  5446.  
  5447.     while (*context != XML_T('\0'))
  5448.     {
  5449.         if (*s == CONTEXT_SEP || *s == XML_T('\0'))
  5450.         {
  5451.             ENTITY *e;
  5452.  
  5453.             if (!poolAppendChar(&tempPool, XML_T('\0')))
  5454.                 return 0;
  5455.             e = (ENTITY *) lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
  5456.             if (e)
  5457.                 e->open = 1;
  5458.             if (*s != XML_T('\0'))
  5459.                 s++;
  5460.             context = s;
  5461.             poolDiscard(&tempPool);
  5462.         }
  5463.         else if (*s == '=')
  5464.         {
  5465.             PREFIX *prefix;
  5466.  
  5467.             if (poolLength(&tempPool) == 0)
  5468.                 prefix = &dtd.defaultPrefix;
  5469.             else
  5470.             {
  5471.                 if (!poolAppendChar(&tempPool, XML_T('\0')))
  5472.                     return 0;
  5473.                 prefix = (PREFIX *) lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
  5474.                 if (!prefix)
  5475.                     return 0;
  5476.                 if (prefix->name == poolStart(&tempPool))
  5477.                 {
  5478.                     prefix->name = poolCopyString(&dtd.pool, prefix->name);
  5479.                     if (!prefix->name)
  5480.                         return 0;
  5481.                 }
  5482.                 poolDiscard(&tempPool);
  5483.             }
  5484.             for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
  5485.                 if (!poolAppendChar(&tempPool, *context))
  5486.                     return 0;
  5487.             if (!poolAppendChar(&tempPool, XML_T('\0')))
  5488.                 return 0;
  5489.             if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
  5490.                 return 0;
  5491.             poolDiscard(&tempPool);
  5492.             if (*context != XML_T('\0'))
  5493.                 ++context;
  5494.             s = context;
  5495.         }
  5496.         else
  5497.         {
  5498.             if (!poolAppendChar(&tempPool, *s))
  5499.                 return 0;
  5500.             s++;
  5501.         }
  5502.     }
  5503.     return 1;
  5504. }
  5505.  
  5506.  
  5507. static void normalizePublicId(XML_Char * publicId)
  5508. {
  5509.     XML_Char *p = publicId;
  5510.     XML_Char *s;
  5511.  
  5512.     for (s = publicId; *s; s++)
  5513.     {
  5514.         switch (*s)
  5515.         {
  5516.             case 0x20:
  5517.             case 0xD:
  5518.             case 0xA:
  5519.                 if (p != publicId && p[-1] != 0x20)
  5520.                     *p++ = 0x20;
  5521.                 break;
  5522.             default:
  5523.                 *p++ = *s;
  5524.         }
  5525.     }
  5526.     if (p != publicId && p[-1] == 0x20)
  5527.         --p;
  5528.     *p = XML_T('\0');
  5529. }
  5530.  
  5531. static int dtdInit(DTD * p,
  5532.                    XML_Parser parser)
  5533. {
  5534.     XML_Memory_Handling_Suite *ms = &((Parser *) parser)->m_mem;
  5535.  
  5536.     poolInit(&(p->pool), ms);
  5537.     hashTableInit(&(p->generalEntities), ms);
  5538.     hashTableInit(&(p->elementTypes), ms);
  5539.     hashTableInit(&(p->attributeIds), ms);
  5540.     hashTableInit(&(p->prefixes), ms);
  5541.     p->complete = 1;
  5542.     p->standalone = 0;
  5543. #ifdef XML_DTD
  5544.     hashTableInit(&(p->paramEntities), ms);
  5545. #endif /* XML_DTD */
  5546.     p->defaultPrefix.name = 0;
  5547.     p->defaultPrefix.binding = 0;
  5548.  
  5549.     p->in_eldecl = 0;
  5550.     p->scaffIndex = 0;
  5551.     p->scaffLevel = 0;
  5552.     p->scaffold = 0;
  5553.     p->contentStringLen = 0;
  5554.     p->scaffSize = 0;
  5555.     p->scaffCount = 0;
  5556.  
  5557.     return 1;
  5558. }
  5559.  
  5560. #ifdef XML_DTD
  5561.  
  5562. static void dtdSwap(DTD * p1, DTD * p2)
  5563. {
  5564.     DTD tem;
  5565.  
  5566.     memcpy(&tem, p1, sizeof(DTD));
  5567.     memcpy(p1, p2, sizeof(DTD));
  5568.     memcpy(p2, &tem, sizeof(DTD));
  5569. }
  5570.  
  5571. #endif /* XML_DTD */
  5572.  
  5573. static void dtdDestroy(DTD * p, XML_Parser parser)
  5574. {
  5575.     HASH_TABLE_ITER iter;
  5576.  
  5577.     hashTableIterInit(&iter, &(p->elementTypes));
  5578.     for (;;)
  5579.     {
  5580.         ELEMENT_TYPE *e = (ELEMENT_TYPE *) hashTableIterNext(&iter);
  5581.  
  5582.         if (!e)
  5583.             break;
  5584.         if (e->allocDefaultAtts != 0)
  5585.             FREE(e->defaultAtts);
  5586.     }
  5587.     hashTableDestroy(&(p->generalEntities));
  5588. #ifdef XML_DTD
  5589.     hashTableDestroy(&(p->paramEntities));
  5590. #endif /* XML_DTD */
  5591.     hashTableDestroy(&(p->elementTypes));
  5592.     hashTableDestroy(&(p->attributeIds));
  5593.     hashTableDestroy(&(p->prefixes));
  5594.     poolDestroy(&(p->pool));
  5595.     if (p->scaffIndex)
  5596.         FREE(p->scaffIndex);
  5597.     if (p->scaffold)
  5598.         FREE(p->scaffold);
  5599. }
  5600.  
  5601. /* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
  5602.  * The new DTD has already been initialized. */
  5603.  
  5604. static int dtdCopy(DTD * newDtd, const DTD * oldDtd, XML_Parser parser)
  5605. {
  5606.     HASH_TABLE_ITER iter;
  5607.  
  5608.     /* Copy the prefix table. */
  5609.  
  5610.     hashTableIterInit(&iter, &(oldDtd->prefixes));
  5611.     for (;;)
  5612.     {
  5613.         const XML_Char *name;
  5614.         const PREFIX *oldP = (PREFIX *) hashTableIterNext(&iter);
  5615.  
  5616.         if (!oldP)
  5617.             break;
  5618.         name = poolCopyString(&(newDtd->pool), oldP->name);
  5619.         if (!name)
  5620.             return 0;
  5621.         if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
  5622.             return 0;
  5623.     }
  5624.  
  5625.     hashTableIterInit(&iter, &(oldDtd->attributeIds));
  5626.  
  5627.     /* Copy the attribute id table. */
  5628.  
  5629.     for (;;)
  5630.     {
  5631.         ATTRIBUTE_ID *newA;
  5632.         const XML_Char *name;
  5633.         const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *) hashTableIterNext(&iter);
  5634.  
  5635.         if (!oldA)
  5636.             break;
  5637.         /* Remember to allocate the scratch byte before the name. */
  5638.         if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
  5639.             return 0;
  5640.         name = poolCopyString(&(newDtd->pool), oldA->name);
  5641.         if (!name)
  5642.             return 0;
  5643.         ++name;
  5644.         newA = (ATTRIBUTE_ID *) lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
  5645.         if (!newA)
  5646.             return 0;
  5647.         newA->maybeTokenized = oldA->maybeTokenized;
  5648.         if (oldA->prefix)
  5649.         {
  5650.             newA->xmlns = oldA->xmlns;
  5651.             if (oldA->prefix == &oldDtd->defaultPrefix)
  5652.                 newA->prefix = &newDtd->defaultPrefix;
  5653.             else
  5654.                 newA->prefix = (PREFIX *) lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
  5655.         }
  5656.     }
  5657.  
  5658.     /* Copy the element type table. */
  5659.  
  5660.     hashTableIterInit(&iter, &(oldDtd->elementTypes));
  5661.  
  5662.     for (;;)
  5663.     {
  5664.         int i;
  5665.         ELEMENT_TYPE *newE;
  5666.         const XML_Char *name;
  5667.         const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *) hashTableIterNext(&iter);
  5668.  
  5669.         if (!oldE)
  5670.             break;
  5671.         name = poolCopyString(&(newDtd->pool), oldE->name);
  5672.         if (!name)
  5673.             return 0;
  5674.         newE = (ELEMENT_TYPE *) lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
  5675.         if (!newE)
  5676.             return 0;
  5677.         if (oldE->nDefaultAtts)
  5678.         {
  5679.             newE->defaultAtts = (DEFAULT_ATTRIBUTE *) MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
  5680.             if (!newE->defaultAtts)
  5681.                 return 0;
  5682.         }
  5683.         if (oldE->idAtt)
  5684.             newE->idAtt = (ATTRIBUTE_ID *) lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
  5685.         newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
  5686.         if (oldE->prefix)
  5687.             newE->prefix = (PREFIX *) lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
  5688.         for (i = 0; i < newE->nDefaultAtts; i++)
  5689.         {
  5690.             newE->defaultAtts[i].id = (ATTRIBUTE_ID *) lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
  5691.             newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
  5692.             if (oldE->defaultAtts[i].value)
  5693.             {
  5694.                 newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
  5695.                 if (!newE->defaultAtts[i].value)
  5696.                     return 0;
  5697.             }
  5698.             else
  5699.                 newE->defaultAtts[i].value = 0;
  5700.         }
  5701.     }
  5702.  
  5703.     /* Copy the entity tables. */
  5704.     if (!copyEntityTable(&(newDtd->generalEntities),
  5705.                          &(newDtd->pool),
  5706.                          &(oldDtd->generalEntities), parser))
  5707.         return 0;
  5708.  
  5709. #ifdef XML_DTD
  5710.     if (!copyEntityTable(&(newDtd->paramEntities),
  5711.                          &(newDtd->pool),
  5712.                          &(oldDtd->paramEntities), parser))
  5713.         return 0;
  5714. #endif /* XML_DTD */
  5715.  
  5716.     newDtd->complete = oldDtd->complete;
  5717.     newDtd->standalone = oldDtd->standalone;
  5718.  
  5719.     /* Don't want deep copying for scaffolding */
  5720.     newDtd->in_eldecl = oldDtd->in_eldecl;
  5721.     newDtd->scaffold = oldDtd->scaffold;
  5722.     newDtd->contentStringLen = oldDtd->contentStringLen;
  5723.     newDtd->scaffSize = oldDtd->scaffSize;
  5724.     newDtd->scaffLevel = oldDtd->scaffLevel;
  5725.     newDtd->scaffIndex = oldDtd->scaffIndex;
  5726.  
  5727.     return 1;
  5728. }                               /* End dtdCopy */
  5729.  
  5730. static int copyEntityTable(HASH_TABLE * newTable,
  5731.                            STRING_POOL * newPool,
  5732.                            const HASH_TABLE * oldTable,
  5733.                            XML_Parser parser)
  5734. {
  5735.     HASH_TABLE_ITER iter;
  5736.     const XML_Char *cachedOldBase = 0;
  5737.     const XML_Char *cachedNewBase = 0;
  5738.  
  5739.     hashTableIterInit(&iter, oldTable);
  5740.  
  5741.     for (;;)
  5742.     {
  5743.         ENTITY *newE;
  5744.         const XML_Char *name;
  5745.         const ENTITY *oldE = (ENTITY *) hashTableIterNext(&iter);
  5746.  
  5747.         if (!oldE)
  5748.             break;
  5749.         name = poolCopyString(newPool, oldE->name);
  5750.         if (!name)
  5751.             return 0;
  5752.         newE = (ENTITY *) lookup(newTable, name, sizeof(ENTITY));
  5753.         if (!newE)
  5754.             return 0;
  5755.         if (oldE->systemId)
  5756.         {
  5757.             const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
  5758.  
  5759.             if (!tem)
  5760.                 return 0;
  5761.             newE->systemId = tem;
  5762.             if (oldE->base)
  5763.             {
  5764.                 if (oldE->base == cachedOldBase)
  5765.                     newE->base = cachedNewBase;
  5766.                 else
  5767.                 {
  5768.                     cachedOldBase = oldE->base;
  5769.                     tem = poolCopyString(newPool, cachedOldBase);
  5770.                     if (!tem)
  5771.                         return 0;
  5772.                     cachedNewBase = newE->base = tem;
  5773.                 }
  5774.             }
  5775.         }
  5776.         else
  5777.         {
  5778.             const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
  5779.  
  5780.             if (!tem)
  5781.                 return 0;
  5782.             newE->textPtr = tem;
  5783.             newE->textLen = oldE->textLen;
  5784.         }
  5785.         if (oldE->notation)
  5786.         {
  5787.             const XML_Char *tem = poolCopyString(newPool, oldE->notation);
  5788.  
  5789.             if (!tem)
  5790.                 return 0;
  5791.             newE->notation = tem;
  5792.         }
  5793.     }
  5794.     return 1;
  5795. }
  5796.  
  5797. #define INIT_SIZE 64
  5798.  
  5799. static int keyeq(KEY s1, KEY s2)
  5800. {
  5801.     for (; *s1 == *s2; s1++, s2++)
  5802.         if (*s1 == 0)
  5803.             return 1;
  5804.     return 0;
  5805. }
  5806.  
  5807. static unsigned long hash(KEY s)
  5808. {
  5809.     unsigned long h = 0;
  5810.  
  5811.     while (*s)
  5812.         h = (h << 5) + h + (unsigned char)*s++;
  5813.     return h;
  5814. }
  5815.  
  5816. static NAMED *lookup(HASH_TABLE * table,
  5817.                      KEY name,
  5818.                      size_t createSize)
  5819. {
  5820.     size_t i;
  5821.  
  5822.     if (table->size == 0)
  5823.     {
  5824.         size_t tsize;
  5825.  
  5826.         if (!createSize)
  5827.             return 0;
  5828.         tsize = INIT_SIZE * sizeof(NAMED *);
  5829.         table->v = (NAMED**)table->mem->malloc_fcn(tsize);
  5830.         if (!table->v)
  5831.             return 0;
  5832.         memset(table->v, 0, tsize);
  5833.         table->size = INIT_SIZE;
  5834.         table->usedLim = INIT_SIZE / 2;
  5835.         i = hash(name) & (table->size - 1);
  5836.     }
  5837.     else
  5838.     {
  5839.         unsigned long h = hash(name);
  5840.  
  5841.         for (i = h & (table->size - 1);
  5842.              table->v[i];
  5843.              i == 0 ? i = table->size - 1 : --i)
  5844.         {
  5845.             if (keyeq(name, table->v[i]->name))
  5846.                 return table->v[i];
  5847.         }
  5848.         if (!createSize)
  5849.             return 0;
  5850.         if (table->used == table->usedLim)
  5851.         {
  5852.             /* check for overflow */
  5853.             size_t newSize = table->size * 2;
  5854.             size_t tsize = newSize * sizeof(NAMED *);
  5855.             NAMED **newV = (NAMED**)table->mem->malloc_fcn(tsize);
  5856.  
  5857.             if (!newV)
  5858.                 return 0;
  5859.             memset(newV, 0, tsize);
  5860.             for (i = 0; i < table->size; i++)
  5861.                 if (table->v[i])
  5862.                 {
  5863.                     size_t j;
  5864.  
  5865.                     for (j = hash(table->v[i]->name) & (newSize - 1);
  5866.                          newV[j];
  5867.                          j == 0 ? j = newSize - 1 : --j)
  5868.                         ;
  5869.                     newV[j] = table->v[i];
  5870.                 }
  5871.             table->mem->free_fcn(table->v);
  5872.             table->v = newV;
  5873.             table->size = newSize;
  5874.             table->usedLim = newSize / 2;
  5875.             for (i = h & (table->size - 1);
  5876.                  table->v[i];
  5877.                  i == 0 ? i = table->size - 1 : --i)
  5878.                 ;
  5879.         }
  5880.     }
  5881.     table->v[i] = (NAMED*)table->mem->malloc_fcn(createSize);
  5882.     if (!table->v[i])
  5883.         return 0;
  5884.     memset(table->v[i], 0, createSize);
  5885.     table->v[i]->name = name;
  5886.     (table->used)++;
  5887.     return table->v[i];
  5888. }
  5889.  
  5890. static void hashTableDestroy(HASH_TABLE * table)
  5891. {
  5892.     size_t i;
  5893.  
  5894.     for (i = 0; i < table->size; i++)
  5895.     {
  5896.         NAMED *p = table->v[i];
  5897.  
  5898.         if (p)
  5899.             table->mem->free_fcn(p);
  5900.     }
  5901.     if (table->v)
  5902.         table->mem->free_fcn(table->v);
  5903. }
  5904.  
  5905. static void hashTableInit(HASH_TABLE * p, XML_Memory_Handling_Suite * ms)
  5906. {
  5907.     p->size = 0;
  5908.     p->usedLim = 0;
  5909.     p->used = 0;
  5910.     p->v = 0;
  5911.     p->mem = ms;
  5912. }
  5913.  
  5914. static void hashTableIterInit(HASH_TABLE_ITER * iter, const HASH_TABLE * table)
  5915. {
  5916.     iter->p = table->v;
  5917.     iter->end = iter->p + table->size;
  5918. }
  5919.  
  5920. static NAMED *hashTableIterNext(HASH_TABLE_ITER * iter)
  5921. {
  5922.     while (iter->p != iter->end)
  5923.     {
  5924.         NAMED *tem = *(iter->p)++;
  5925.  
  5926.         if (tem)
  5927.             return tem;
  5928.     }
  5929.     return 0;
  5930. }
  5931.  
  5932.  
  5933. static void poolInit(STRING_POOL * pool, XML_Memory_Handling_Suite * ms)
  5934. {
  5935.     pool->blocks = 0;
  5936.     pool->freeBlocks = 0;
  5937.     pool->start = 0;
  5938.     pool->ptr = 0;
  5939.     pool->end = 0;
  5940.     pool->mem = ms;
  5941. }
  5942.  
  5943. static void poolClear(STRING_POOL * pool)
  5944. {
  5945.     if (!pool->freeBlocks)
  5946.         pool->freeBlocks = pool->blocks;
  5947.     else
  5948.     {
  5949.         BLOCK *p = pool->blocks;
  5950.  
  5951.         while (p)
  5952.         {
  5953.             BLOCK *tem = p->next;
  5954.  
  5955.             p->next = pool->freeBlocks;
  5956.             pool->freeBlocks = p;
  5957.             p = tem;
  5958.         }
  5959.     }
  5960.     pool->blocks = 0;
  5961.     pool->start = 0;
  5962.     pool->ptr = 0;
  5963.     pool->end = 0;
  5964. }
  5965.  
  5966. static void poolDestroy(STRING_POOL * pool)
  5967. {
  5968.     BLOCK *p = pool->blocks;
  5969.  
  5970.     while (p)
  5971.     {
  5972.         BLOCK *tem = p->next;
  5973.  
  5974.         pool->mem->free_fcn(p);
  5975.         p = tem;
  5976.     }
  5977.     pool->blocks = 0;
  5978.     p = pool->freeBlocks;
  5979.     while (p)
  5980.     {
  5981.         BLOCK *tem = p->next;
  5982.  
  5983.         pool->mem->free_fcn(p);
  5984.         p = tem;
  5985.     }
  5986.     pool->freeBlocks = 0;
  5987.     pool->ptr = 0;
  5988.     pool->start = 0;
  5989.     pool->end = 0;
  5990. }
  5991.  
  5992. /*
  5993.  *@@ poolAppend:
  5994.  *      appends a new string to a pool.
  5995.  *      Returns pool->start if the pool is valid,
  5996.  *      or NULL if storing failed.
  5997.  *
  5998.  *      V0.9.14: I added the pulOfs parameter which, after
  5999.  *      the string was stored, receives the offset from
  6000.  *      pool->start at which the string was stored in the
  6001.  *      pool. I am not quite sure how all this works, but
  6002.  *      if a user-defined encoding is in place (via
  6003.  *      XML_SetUnknownEncodingHandler), the first entry
  6004.  *      in the pool is always the encoding name from the
  6005.  *      xml header, and all entity references failed here
  6006.  *      because the lookup would always be done for
  6007.  *      the encoding name instead of the entity name
  6008.  *      (which then is the second entry in the pool).
  6009.  *      Whatever.
  6010.  *
  6011.  *@@changed V0.9.14 (2001-08-09) [umoeller]: added pulOfs param
  6012.  */
  6013.  
  6014. static XML_Char* poolAppend(STRING_POOL * pool,
  6015.                             const ENCODING * enc,
  6016.                             const char *ptr,
  6017.                             const char *end,
  6018.                             unsigned long *pulOfs)  // out: offset of beginning of stored
  6019.                                                     // string from pool->start
  6020.                                                     // V0.9.14 (2001-08-09) [umoeller]
  6021. {
  6022.     if (!pool->ptr && !poolGrow(pool))
  6023.         return 0;
  6024.     for (;;)
  6025.     {
  6026.         char *pOldStart = pool->ptr;
  6027.         XmlConvert(enc,
  6028.                    &ptr,                    // fromP
  6029.                    end,
  6030.                    (ICHAR**)&(pool->ptr),   // toP
  6031.                    (ICHAR *)pool->end);
  6032.                 // expands to:
  6033.                 // (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
  6034.                 // -- for cp850, we end up in
  6035.                 // -- for Latin1, we end up in
  6036.         if (pulOfs)
  6037.             *pulOfs = pOldStart - pool->start; // V0.9.14 (2001-08-09) [umoeller]
  6038.  
  6039.         if (ptr == end)
  6040.             break;
  6041.         if (!poolGrow(pool))
  6042.             return 0;
  6043.     }
  6044.     return pool->start;
  6045. }
  6046.  
  6047. static const XML_Char* poolCopyString(STRING_POOL *pool,
  6048.                                       const XML_Char *s)
  6049. {
  6050.     do
  6051.     {
  6052.         if (!poolAppendChar(pool, *s))
  6053.             return 0;
  6054.     }
  6055.     while (*s++);
  6056.     s = pool->start;
  6057.     poolFinish(pool);
  6058.     return s;
  6059. }
  6060.  
  6061. static const XML_Char *poolCopyStringN(STRING_POOL * pool, const XML_Char * s, int n)
  6062. {
  6063.     if (!pool->ptr && !poolGrow(pool))
  6064.         return 0;
  6065.     for (; n > 0; --n, s++)
  6066.     {
  6067.         if (!poolAppendChar(pool, *s))
  6068.             return 0;
  6069.  
  6070.     }
  6071.     s = pool->start;
  6072.     poolFinish(pool);
  6073.     return s;
  6074. }
  6075.  
  6076. static const XML_Char* poolAppendString(STRING_POOL *pool,
  6077.                                         const XML_Char *s)
  6078. {
  6079.     while (*s)
  6080.     {
  6081.         if (!poolAppendChar(pool, *s))
  6082.             return 0;
  6083.         s++;
  6084.     }
  6085.     return pool->start;
  6086. }                               /* End poolAppendString */
  6087.  
  6088. /*
  6089.  *@@ poolStoreString:
  6090.  *
  6091.  *@@changed V0.9.14 (2001-08-09) [umoeller]: added pulOfs param
  6092.  */
  6093.  
  6094. static XML_Char* poolStoreString(STRING_POOL *pool,
  6095.                                  const ENCODING *enc,
  6096.                                  const char *ptr,
  6097.                                  const char *end,
  6098.                                  unsigned long *pulOfs) // V0.9.14 (2001-08-09) [umoeller]
  6099. {
  6100.     if (!poolAppend(pool,
  6101.                     enc,
  6102.                     ptr,
  6103.                     end,
  6104.                     pulOfs))    // V0.9.14 (2001-08-09) [umoeller]
  6105.         return 0;
  6106.     if (    (pool->ptr == pool->end)
  6107.          && (!poolGrow(pool))
  6108.        )
  6109.         return 0;
  6110.     *(pool->ptr)++ = 0;
  6111.     return pool->start;
  6112. }
  6113.  
  6114. static int poolGrow(STRING_POOL *pool)
  6115. {
  6116.     if (pool->freeBlocks)
  6117.     {
  6118.         if (pool->start == 0)
  6119.         {
  6120.             pool->blocks = pool->freeBlocks;
  6121.             pool->freeBlocks = pool->freeBlocks->next;
  6122.             pool->blocks->next = 0;
  6123.             pool->start = pool->blocks->s;
  6124.             pool->end = pool->start + pool->blocks->size;
  6125.             pool->ptr = pool->start;
  6126.             return 1;
  6127.         }
  6128.         if (pool->end - pool->start < pool->freeBlocks->size)
  6129.         {
  6130.             BLOCK *tem = pool->freeBlocks->next;
  6131.  
  6132.             pool->freeBlocks->next = pool->blocks;
  6133.             pool->blocks = pool->freeBlocks;
  6134.             pool->freeBlocks = tem;
  6135.             memcpy(pool->blocks->s,
  6136.                    pool->start,
  6137.                    (pool->end - pool->start) * sizeof(XML_Char));
  6138.             pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
  6139.             pool->start = pool->blocks->s;
  6140.             pool->end = pool->start + pool->blocks->size;
  6141.             return 1;
  6142.         }
  6143.     }
  6144.     if (pool->blocks && pool->start == pool->blocks->s)
  6145.     {
  6146.         int blockSize = (pool->end - pool->start) * 2;
  6147.  
  6148.         pool->blocks = (BLOCK*)pool->mem->realloc_fcn(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
  6149.         if (!pool->blocks)
  6150.             return 0;
  6151.         pool->blocks->size = blockSize;
  6152.         pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
  6153.         pool->start = pool->blocks->s;
  6154.         pool->end = pool->start + blockSize;
  6155.     }
  6156.     else
  6157.     {
  6158.         BLOCK *tem;
  6159.         int blockSize = pool->end - pool->start;
  6160.  
  6161.         if (blockSize < INIT_BLOCK_SIZE)
  6162.             blockSize = INIT_BLOCK_SIZE;
  6163.         else
  6164.             blockSize *= 2;
  6165.         tem = (BLOCK*)pool->mem->malloc_fcn(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
  6166.         if (!tem)
  6167.             return 0;
  6168.         tem->size = blockSize;
  6169.         tem->next = pool->blocks;
  6170.         pool->blocks = tem;
  6171.         if (pool->ptr != pool->start)
  6172.             memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
  6173.         pool->ptr = tem->s + (pool->ptr - pool->start);
  6174.         pool->start = tem->s;
  6175.         pool->end = tem->s + blockSize;
  6176.     }
  6177.     return 1;
  6178. }
  6179.  
  6180. static int nextScaffoldPart(XML_Parser parser)
  6181. {
  6182.     CONTENT_SCAFFOLD *me;
  6183.     int next;
  6184.  
  6185.     if (!dtd.scaffIndex)
  6186.     {
  6187.         dtd.scaffIndex = (int*)MALLOC(groupSize * sizeof(int));
  6188.  
  6189.         if (!dtd.scaffIndex)
  6190.             return -1;
  6191.         dtd.scaffIndex[0] = 0;
  6192.     }
  6193.  
  6194.     if (dtd.scaffCount >= dtd.scaffSize)
  6195.     {
  6196.         if (dtd.scaffold)
  6197.         {
  6198.             dtd.scaffSize *= 2;
  6199.             dtd.scaffold = (CONTENT_SCAFFOLD *) REALLOC(dtd.scaffold,
  6200.                                     dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
  6201.         }
  6202.         else
  6203.         {
  6204.             dtd.scaffSize = 32;
  6205.             dtd.scaffold = (CONTENT_SCAFFOLD *) MALLOC(dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
  6206.         }
  6207.         if (!dtd.scaffold)
  6208.             return -1;
  6209.     }
  6210.     next = dtd.scaffCount++;
  6211.     me = &dtd.scaffold[next];
  6212.     if (dtd.scaffLevel)
  6213.     {
  6214.         CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]];
  6215.  
  6216.         if (parent->lastchild)
  6217.         {
  6218.             dtd.scaffold[parent->lastchild].nextsib = next;
  6219.         }
  6220.         if (!parent->childcnt)
  6221.             parent->firstchild = next;
  6222.         parent->lastchild = next;
  6223.         parent->childcnt++;
  6224.     }
  6225.     me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
  6226.     return next;
  6227. }                               /* End nextScaffoldPart */
  6228.  
  6229. static void  build_node(XML_Parser parser,
  6230.                         int src_node,
  6231.                         XMLCONTENT * dest,
  6232.                         XMLCONTENT ** contpos,
  6233.                         char **strpos)
  6234. {
  6235.     dest->type = dtd.scaffold[src_node].type;
  6236.     dest->quant = dtd.scaffold[src_node].quant;
  6237.     if (dest->type == XML_CTYPE_NAME)
  6238.     {
  6239.         const char *src;
  6240.  
  6241.         dest->name = *strpos;
  6242.         src = dtd.scaffold[src_node].name;
  6243.         for (;;)
  6244.         {
  6245.             *(*strpos)++ = *src;
  6246.             if (!*src)
  6247.                 break;
  6248.             src++;
  6249.         }
  6250.         dest->numchildren = 0;
  6251.         dest->children = 0;
  6252.     }
  6253.     else
  6254.     {
  6255.         unsigned int i;
  6256.         int cn;
  6257.  
  6258.         dest->numchildren = dtd.scaffold[src_node].childcnt;
  6259.         dest->children = *contpos;
  6260.         *contpos += dest->numchildren;
  6261.         for (i = 0, cn = dtd.scaffold[src_node].firstchild;
  6262.              i < dest->numchildren;
  6263.              i++, cn = dtd.scaffold[cn].nextsib)
  6264.         {
  6265.             build_node(parser, cn, &(dest->children[i]), contpos, strpos);
  6266.         }
  6267.         dest->name = 0;
  6268.     }
  6269. }                               /* End build_node */
  6270.  
  6271. static XMLCONTENT * build_model(XML_Parser parser)
  6272. {
  6273.     XMLCONTENT *ret;
  6274.     XMLCONTENT *cpos;
  6275.     char *str;
  6276.     int allocsize = dtd.scaffCount * sizeof(XMLCONTENT) + dtd.contentStringLen;
  6277.  
  6278.     ret = (XMLCONTENT*)MALLOC(allocsize);
  6279.     if (!ret)
  6280.         return 0;
  6281.  
  6282.     str = (char *)(&ret[dtd.scaffCount]);
  6283.     cpos = &ret[1];
  6284.  
  6285.     build_node(parser, 0, ret, &cpos, &str);
  6286.     return ret;
  6287. }                               /* End build_model */
  6288.  
  6289. static ELEMENT_TYPE * getElementType(XML_Parser parser,
  6290.                                      const ENCODING * enc,
  6291.                                      const char *ptr,
  6292.                                      const char *end)
  6293. {
  6294.     const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end, NULL);
  6295.     ELEMENT_TYPE *ret;
  6296.  
  6297.     if (!name)
  6298.         return 0;
  6299.     ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
  6300.     if (!ret)
  6301.         return 0;
  6302.     if (ret->name != name)
  6303.         poolDiscard(&dtd.pool);
  6304.     else
  6305.     {
  6306.         poolFinish(&dtd.pool);
  6307.         if (!setElementTypePrefix(parser, ret))
  6308.             return 0;
  6309.     }
  6310.     return ret;
  6311. }                               /* End getElementType */
  6312.