head 1.4; access; symbols; locks; strict; comment @# @; 1.4 date 2002.09.07.01.50.41; author curt; state Exp; branches; next 1.3; 1.3 date 2002.08.31.19.01.59; author curt; state Exp; branches; next 1.2; 1.2 date 2002.08.31.18.54.05; author curt; state Exp; branches; next 1.1; 1.1 date 2002.02.15.17.22.03; author curt; state Exp; branches; next ; desc @@ 1.4 log @Updated doxygen docs. @ text @
Main Page Class Hierarchy Compound List File List Compound Members File Members

# xmlparse.c

    00001 /*
    00002 The contents of this file are subject to the Mozilla Public License
    00003 Version 1.1 (the "License"); you may not use this file except in
    00004 compliance with the License. You may obtain a copy of the License at
    00005 http://www.mozilla.org/MPL/
    00006
    00007 Software distributed under the License is distributed on an "AS IS"
    00008 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
    00009 License for the specific language governing rights and limitations
    00010 under the License.
    00011
    00012 The Original Code is expat.
    00013
    00014 The Initial Developer of the Original Code is James Clark.
    00015 Portions created by James Clark are Copyright (C) 1998, 1999
    00016 James Clark. All Rights Reserved.
    00017
    00018 Contributor(s):
    00019
    00020 Alternatively, the contents of this file may be used under the terms
    00021 of the GNU General Public License (the "GPL"), in which case the
    00022 provisions of the GPL are applicable instead of those above.  If you
    00023 wish to allow use of your version of this file only under the terms of
    00024 the GPL and not to allow others to use your version of this file under
    00025 the MPL, indicate your decision by deleting the provisions above and
    00026 replace them with the notice and other provisions required by the
    00027 GPL. If you do not delete the provisions above, a recipient may use
    00028 your version of this file under either the MPL or the GPL.
    00029 */
    00030
    00031 #include "xmldef.h"
    00032 #include "xmlparse.h"
    00033
    00034 #ifdef XML_UNICODE
    00035 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
    00036 #define XmlConvert XmlUtf16Convert
    00037 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
    00038 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
    00039 #define XmlEncode XmlUtf16Encode
    00040 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
    00041 typedef unsigned short ICHAR;
    00042 #else
    00043 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
    00044 #define XmlConvert XmlUtf8Convert
    00045 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
    00046 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
    00047 #define XmlEncode XmlUtf8Encode
    00048 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
    00049 typedef char ICHAR;
    00050 #endif
    00051
    00052
    00053 #ifndef XML_NS
    00054
    00055 #define XmlInitEncodingNS XmlInitEncoding
    00056 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
    00057 #undef XmlGetInternalEncodingNS
    00058 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
    00059 #define XmlParseXmlDeclNS XmlParseXmlDecl
    00060
    00061 #endif
    00062
    00063
    00064 #ifdef XML_UNICODE_WCHAR_T
    00065 #define XML_T(x) L ## x
    00066 #else
    00067 #define XML_T(x) x
    00068 #endif
    00069
    00070 /* Round up n to be a multiple of sz, where sz is a power of 2. */
    00071 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
    00072
    00073 #include "xmltok.h"
    00074 #include "xmlrole.h"
    00075 #include "hashtable.h"
    00076
    00077 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
    00078 #define INIT_DATA_BUF_SIZE 1024
    00079 #define INIT_ATTS_SIZE 16
    00080 #define INIT_BLOCK_SIZE 1024
    00081 #define INIT_BUFFER_SIZE 1024
    00082
    00083 #define EXPAND_SPARE 24
    00084
    00085 typedef struct binding {
    00086   struct prefix *prefix;
    00087   struct binding *nextTagBinding;
    00088   struct binding *prevPrefixBinding;
    00089   const struct attribute_id *attId;
    00090   XML_Char *uri;
    00091   int uriLen;
    00092   int uriAlloc;
    00093 } BINDING;
    00094
    00095 typedef struct prefix {
    00096   const XML_Char *name;
    00097   BINDING *binding;
    00098 } PREFIX;
    00099
    00100 typedef struct {
    00101   const XML_Char *str;
    00102   const XML_Char *localPart;
    00103   int uriLen;
    00104 } TAG_NAME;
    00105
    00106 typedef struct tag {
    00107   struct tag *parent;
    00108   const char *rawName;
    00109   int rawNameLength;
    00110   TAG_NAME name;
    00111   char *buf;
    00112   char *bufEnd;
    00113   BINDING *bindings;
    00114 } TAG;
    00115
    00116 typedef struct {
    00117   const XML_Char *name;
    00118   const XML_Char *textPtr;
    00119   int textLen;
    00120   const XML_Char *systemId;
    00121   const XML_Char *base;
    00122   const XML_Char *publicId;
    00123   const XML_Char *notation;
    00124   char open;
    00125 } ENTITY;
    00126
    00127 typedef struct block {
    00128   struct block *next;
    00129   int size;
    00130   XML_Char s[1];
    00131 } BLOCK;
    00132
    00133 typedef struct {
    00134   BLOCK *blocks;
    00135   BLOCK *freeBlocks;
    00136   const XML_Char *end;
    00137   XML_Char *ptr;
    00138   XML_Char *start;
    00139 } STRING_POOL;
    00140
    00141 /* The XML_Char before the name is used to determine whether
    00142 an attribute has been specified. */
    00143 typedef struct attribute_id {
    00144   XML_Char *name;
    00145   PREFIX *prefix;
    00146   char maybeTokenized;
    00147   char xmlns;
    00148 } ATTRIBUTE_ID;
    00149
    00150 typedef struct {
    00151   const ATTRIBUTE_ID *id;
    00152   char isCdata;
    00153   const XML_Char *value;
    00154 } DEFAULT_ATTRIBUTE;
    00155
    00156 typedef struct {
    00157   const XML_Char *name;
    00158   PREFIX *prefix;
    00159   int nDefaultAtts;
    00160   int allocDefaultAtts;
    00161   DEFAULT_ATTRIBUTE *defaultAtts;
    00162 } ELEMENT_TYPE;
    00163
    00164 typedef struct {
    00165   HASH_TABLE generalEntities;
    00166   HASH_TABLE elementTypes;
    00167   HASH_TABLE attributeIds;
    00168   HASH_TABLE prefixes;
    00169   STRING_POOL pool;
    00170   int complete;
    00171   int standalone;
    00172   const XML_Char *base;
    00173   PREFIX defaultPrefix;
    00174 } DTD;
    00175
    00176 typedef struct open_internal_entity {
    00177   const char *internalEventPtr;
    00178   const char *internalEventEndPtr;
    00179   struct open_internal_entity *next;
    00180   ENTITY *entity;
    00181 } OPEN_INTERNAL_ENTITY;
    00182
    00183 typedef enum XML_Error Processor(XML_Parser parser,
    00184                                  const char *start,
    00185                                  const char *end,
    00186                                  const char **endPtr);
    00187
    00188 static Processor prologProcessor;
    00189 static Processor prologInitProcessor;
    00190 static Processor contentProcessor;
    00191 static Processor cdataSectionProcessor;
    00192 static Processor epilogProcessor;
    00193 static Processor externalEntityInitProcessor;
    00194 static Processor externalEntityInitProcessor2;
    00195 static Processor externalEntityInitProcessor3;
    00196 static Processor externalEntityContentProcessor;
    00197
    00198 static enum XML_Error
    00199 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
    00200 static enum XML_Error
    00201 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
    00202 static enum XML_Error
    00203 initializeEncoding(XML_Parser parser);
    00204 static enum XML_Error
    00205 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
    00206           const char *start, const char *end, const char **endPtr);
    00207 static enum XML_Error
    00208 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
    00209 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
    00210                                 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
    00211 static
    00212 int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
    00213 static int
    00214 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, const XML_Char *dfltValue);
    00215 static enum XML_Error
    00216 storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
    00217                     STRING_POOL *);
    00218 static enum XML_Error
    00219 appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
    00220                     STRING_POOL *);
    00221 static ATTRIBUTE_ID *
    00222 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
    00223 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
    00224 static enum XML_Error
    00225 storeEntityValue(XML_Parser parser, const char *start, const char *end);
    00226 static int
    00227 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
    00228 static int
    00229 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
    00230 static void
    00231 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
    00232
    00233 static const XML_Char *getContext(XML_Parser parser);
    00234 static int setContext(XML_Parser parser, const XML_Char *context);
    00235 static void normalizePublicId(XML_Char *s);
    00236 static int dtdInit(DTD *);
    00237 static void dtdDestroy(DTD *);
    00238 static int dtdCopy(DTD *newDtd, const DTD *oldDtd);
    00239 static void poolInit(STRING_POOL *);
    00240 static void poolClear(STRING_POOL *);
    00241 static void poolDestroy(STRING_POOL *);
    00242 static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
    00243                             const char *ptr, const char *end);
    00244 static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
    00245                                   const char *ptr, const char *end);
    00246 static int poolGrow(STRING_POOL *pool);
    00247 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
    00248 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
    00249
    00250 #define poolStart(pool) ((pool)->start)
    00251 #define poolEnd(pool) ((pool)->ptr)
    00252 #define poolLength(pool) ((pool)->ptr - (pool)->start)
    00253 #define poolChop(pool) ((void)--(pool->ptr))
    00254 #define poolLastChar(pool) (((pool)->ptr)[-1])
    00255 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
    00256 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
    00257 #define poolAppendChar(pool, c) \
    00258   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
    00259    ? 0 \
    00260    : ((*((pool)->ptr)++ = c), 1))
    00261
    00262 typedef struct {
    00263   /* The first member must be userData so that the XML_GetUserData macro works. */
    00264   void *m_userData;
    00265   void *m_handlerArg;
    00266   char *m_buffer;
    00267   /* first character to be parsed */
    00268   const char *m_bufferPtr;
    00269   /* past last character to be parsed */
    00270   char *m_bufferEnd;
    00271   /* allocated end of buffer */
    00272   const char *m_bufferLim;
    00273   long m_parseEndByteIndex;
    00274   const char *m_parseEndPtr;
    00275   XML_Char *m_dataBuf;
    00276   XML_Char *m_dataBufEnd;
    00277   XML_StartElementHandler m_startElementHandler;
    00278   XML_EndElementHandler m_endElementHandler;
    00279   XML_CharacterDataHandler m_characterDataHandler;
    00280   XML_ProcessingInstructionHandler m_processingInstructionHandler;
    00281   XML_CommentHandler m_commentHandler;
    00282   XML_StartCdataSectionHandler m_startCdataSectionHandler;
    00283   XML_EndCdataSectionHandler m_endCdataSectionHandler;
    00284   XML_DefaultHandler m_defaultHandler;
    00285   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
    00286   XML_NotationDeclHandler m_notationDeclHandler;
    00287   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
    00288   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
    00289   XML_NotStandaloneHandler m_notStandaloneHandler;
    00290   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
    00291   void *m_externalEntityRefHandlerArg;
    00292   XML_UnknownEncodingHandler m_unknownEncodingHandler;
    00293   const ENCODING *m_encoding;
    00294   INIT_ENCODING m_initEncoding;
    00295   const XML_Char *m_protocolEncodingName;
    00296   int m_ns;
    00297   void *m_unknownEncodingMem;
    00298   void *m_unknownEncodingData;
    00299   void *m_unknownEncodingHandlerData;
    00300   void (*m_unknownEncodingRelease)(void *);
    00301   PROLOG_STATE m_prologState;
    00302   Processor *m_processor;
    00303   enum XML_Error m_errorCode;
    00304   const char *m_eventPtr;
    00305   const char *m_eventEndPtr;
    00306   const char *m_positionPtr;
    00307   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
    00308   int m_defaultExpandInternalEntities;
    00309   int m_tagLevel;
    00310   ENTITY *m_declEntity;
    00311   const XML_Char *m_declNotationName;
    00312   const XML_Char *m_declNotationPublicId;
    00313   ELEMENT_TYPE *m_declElementType;
    00314   ATTRIBUTE_ID *m_declAttributeId;
    00315   char m_declAttributeIsCdata;
    00316   DTD m_dtd;
    00317   TAG *m_tagStack;
    00318   TAG *m_freeTagList;
    00319   BINDING *m_inheritedBindings;
    00320   BINDING *m_freeBindingList;
    00321   int m_attsSize;
    00322   int m_nSpecifiedAtts;
    00323   ATTRIBUTE *m_atts;
    00324   POSITION m_position;
    00325   STRING_POOL m_tempPool;
    00326   STRING_POOL m_temp2Pool;
    00327   char *m_groupConnector;
    00328   unsigned m_groupSize;
    00329   int m_hadExternalDoctype;
    00330   XML_Char m_namespaceSeparator;
    00331 } Parser;
    00332
    00333 #define userData (((Parser *)parser)->m_userData)
    00334 #define handlerArg (((Parser *)parser)->m_handlerArg)
    00335 #define startElementHandler (((Parser *)parser)->m_startElementHandler)
    00336 #define endElementHandler (((Parser *)parser)->m_endElementHandler)
    00337 #define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
    00338 #define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
    00339 #define commentHandler (((Parser *)parser)->m_commentHandler)
    00340 #define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
    00341 #define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
    00342 #define defaultHandler (((Parser *)parser)->m_defaultHandler)
    00343 #define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
    00344 #define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
    00345 #define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
    00346 #define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
    00347 #define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
    00348 #define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
    00349 #define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
    00350 #define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
    00351 #define encoding (((Parser *)parser)->m_encoding)
    00352 #define initEncoding (((Parser *)parser)->m_initEncoding)
    00353 #define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
    00354 #define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
    00355 #define unknownEncodingHandlerData \
    00356   (((Parser *)parser)->m_unknownEncodingHandlerData)
    00357 #define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
    00358 #define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
    00359 #define ns (((Parser *)parser)->m_ns)
    00360 #define prologState (((Parser *)parser)->m_prologState)
    00361 #define processor (((Parser *)parser)->m_processor)
    00362 #define errorCode (((Parser *)parser)->m_errorCode)
    00363 #define eventPtr (((Parser *)parser)->m_eventPtr)
    00364 #define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
    00365 #define positionPtr (((Parser *)parser)->m_positionPtr)
    00366 #define position (((Parser *)parser)->m_position)
    00367 #define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
    00368 #define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
    00369 #define tagLevel (((Parser *)parser)->m_tagLevel)
    00370 #define buffer (((Parser *)parser)->m_buffer)
    00371 #define bufferPtr (((Parser *)parser)->m_bufferPtr)
    00372 #define bufferEnd (((Parser *)parser)->m_bufferEnd)
    00373 #define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
    00374 #define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
    00375 #define bufferLim (((Parser *)parser)->m_bufferLim)
    00376 #define dataBuf (((Parser *)parser)->m_dataBuf)
    00377 #define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
    00378 #define dtd (((Parser *)parser)->m_dtd)
    00379 #define declEntity (((Parser *)parser)->m_declEntity)
    00380 #define declNotationName (((Parser *)parser)->m_declNotationName)
    00381 #define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
    00382 #define declElementType (((Parser *)parser)->m_declElementType)
    00383 #define declAttributeId (((Parser *)parser)->m_declAttributeId)
    00384 #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
    00385 #define freeTagList (((Parser *)parser)->m_freeTagList)
    00386 #define freeBindingList (((Parser *)parser)->m_freeBindingList)
    00387 #define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
    00388 #define tagStack (((Parser *)parser)->m_tagStack)
    00389 #define atts (((Parser *)parser)->m_atts)
    00390 #define attsSize (((Parser *)parser)->m_attsSize)
    00391 #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
    00392 #define tempPool (((Parser *)parser)->m_tempPool)
    00393 #define temp2Pool (((Parser *)parser)->m_temp2Pool)
    00394 #define groupConnector (((Parser *)parser)->m_groupConnector)
    00395 #define groupSize (((Parser *)parser)->m_groupSize)
    00396 #define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
    00397 #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
    00398
    00399 #ifdef _MSC_VER
    00400 #ifdef _DEBUG
    00401 Parser *asParser(XML_Parser parser)
    00402 {
    00403   return parser;
    00404 }
    00405 #endif
    00406 #endif
    00407
    00408 XML_Parser XML_ParserCreate(const XML_Char *encodingName)
    00409 {
    00410   XML_Parser parser = malloc(sizeof(Parser));
    00411   if (!parser)
    00412     return parser;
    00413   processor = prologInitProcessor;
    00414   XmlPrologStateInit(&prologState);
    00415   userData = 0;
    00416   handlerArg = 0;
    00417   startElementHandler = 0;
    00418   endElementHandler = 0;
    00419   characterDataHandler = 0;
    00420   processingInstructionHandler = 0;
    00421   commentHandler = 0;
    00422   startCdataSectionHandler = 0;
    00423   endCdataSectionHandler = 0;
    00424   defaultHandler = 0;
    00425   unparsedEntityDeclHandler = 0;
    00426   notationDeclHandler = 0;
    00427   startNamespaceDeclHandler = 0;
    00428   endNamespaceDeclHandler = 0;
    00429   notStandaloneHandler = 0;
    00430   externalEntityRefHandler = 0;
    00431   externalEntityRefHandlerArg = parser;
    00432   unknownEncodingHandler = 0;
    00433   buffer = 0;
    00434   bufferPtr = 0;
    00435   bufferEnd = 0;
    00436   parseEndByteIndex = 0;
    00437   parseEndPtr = 0;
    00438   bufferLim = 0;
    00439   declElementType = 0;
    00440   declAttributeId = 0;
    00441   declEntity = 0;
    00442   declNotationName = 0;
    00443   declNotationPublicId = 0;
    00444   memset(&position, 0, sizeof(POSITION));
    00445   errorCode = XML_ERROR_NONE;
    00446   eventPtr = 0;
    00447   eventEndPtr = 0;
    00448   positionPtr = 0;
    00449   openInternalEntities = 0;
    00450   tagLevel = 0;
    00451   tagStack = 0;
    00452   freeTagList = 0;
    00453   freeBindingList = 0;
    00454   inheritedBindings = 0;
    00455   attsSize = INIT_ATTS_SIZE;
    00456   atts = malloc(attsSize * sizeof(ATTRIBUTE));
    00457   nSpecifiedAtts = 0;
    00458   dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
    00459   groupSize = 0;
    00460   groupConnector = 0;
    00461   hadExternalDoctype = 0;
    00462   unknownEncodingMem = 0;
    00463   unknownEncodingRelease = 0;
    00464   unknownEncodingData = 0;
    00465   unknownEncodingHandlerData = 0;
    00466   namespaceSeparator = '!';
    00467   ns = 0;
    00468   poolInit(&tempPool);
    00469   poolInit(&temp2Pool);
    00470   protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
    00471   if (!dtdInit(&dtd) || !atts || !dataBuf
    00472       || (encodingName && !protocolEncodingName)) {
    00473     XML_ParserFree(parser);
    00474     return 0;
    00475   }
    00476   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
    00477   XmlInitEncoding(&initEncoding, &encoding, 0);
    00478   return parser;
    00479 }
    00480
    00481 XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
    00482 {
    00483   static
    00484   const XML_Char implicitContext[] = {
    00485     XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
    00486     XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
    00487     XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
    00488     XML_T('.'), XML_T('w'), XML_T('3'),
    00489     XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
    00490     XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
    00491     XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
    00492     XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
    00493     XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
    00494     XML_T('\0')
    00495   };
    00496
    00497   XML_Parser parser = XML_ParserCreate(encodingName);
    00498   if (parser) {
    00499     XmlInitEncodingNS(&initEncoding, &encoding, 0);
    00500     ns = 1;
    00501     namespaceSeparator = nsSep;
    00502   }
    00503   if (!setContext(parser, implicitContext)) {
    00504     XML_ParserFree(parser);
    00505     return 0;
    00506   }
    00507   return parser;
    00508 }
    00509
    00510 int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
    00511 {
    00512   if (!encodingName)
    00513     protocolEncodingName = 0;
    00514   else {
    00515     protocolEncodingName = poolCopyString(&tempPool, encodingName);
    00516     if (!protocolEncodingName)
    00517       return 0;
    00518   }
    00519   return 1;
    00520 }
    00521
    00522 XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
    00523                                           const XML_Char *context,
    00524                                           const XML_Char *encodingName)
    00525 {
    00526   XML_Parser parser = oldParser;
    00527   DTD *oldDtd = &dtd;
    00528   XML_StartElementHandler oldStartElementHandler = startElementHandler;
    00529   XML_EndElementHandler oldEndElementHandler = endElementHandler;
    00530   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
    00531   XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
    00532   XML_CommentHandler oldCommentHandler = commentHandler;
    00533   XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
    00534   XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
    00535   XML_DefaultHandler oldDefaultHandler = defaultHandler;
    00536   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
    00537   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
    00538   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
    00539   XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
    00540   XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
    00541   void *oldUserData = userData;
    00542   void *oldHandlerArg = handlerArg;
    00543   int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
    00544   void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
    00545
    00546   parser = (ns
    00547             ? XML_ParserCreateNS(encodingName, namespaceSeparator)
    00548             : XML_ParserCreate(encodingName));
    00549   if (!parser)
    00550     return 0;
    00551   startElementHandler = oldStartElementHandler;
    00552   endElementHandler = oldEndElementHandler;
    00553   characterDataHandler = oldCharacterDataHandler;
    00554   processingInstructionHandler = oldProcessingInstructionHandler;
    00555   commentHandler = oldCommentHandler;
    00556   startCdataSectionHandler = oldStartCdataSectionHandler;
    00557   endCdataSectionHandler = oldEndCdataSectionHandler;
    00558   defaultHandler = oldDefaultHandler;
    00559   startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
    00560   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
    00561   notStandaloneHandler = oldNotStandaloneHandler;
    00562   externalEntityRefHandler = oldExternalEntityRefHandler;
    00563   unknownEncodingHandler = oldUnknownEncodingHandler;
    00564   userData = oldUserData;
    00565   if (oldUserData == oldHandlerArg)
    00566     handlerArg = userData;
    00567   else
    00568     handlerArg = parser;
    00569   if (oldExternalEntityRefHandlerArg != oldParser)
    00570     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
    00571   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
    00572   if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) {
    00573     XML_ParserFree(parser);
    00574     return 0;
    00575   }
    00576   processor = externalEntityInitProcessor;
    00577   return parser;
    00578 }
    00579
    00580 static
    00581 void destroyBindings(BINDING *bindings)
    00582 {
    00583   for (;;) {
    00584     BINDING *b = bindings;
    00585     if (!b)
    00586       break;
    00587     bindings = b->nextTagBinding;
    00588     free(b->uri);
    00589     free(b);
    00590   }
    00591 }
    00592
    00593 void XML_ParserFree(XML_Parser parser)
    00594 {
    00595   for (;;) {
    00596     TAG *p;
    00597     if (tagStack == 0) {
    00598       if (freeTagList == 0)
    00599         break;
    00600       tagStack = freeTagList;
    00601       freeTagList = 0;
    00602     }
    00603     p = tagStack;
    00604     tagStack = tagStack->parent;
    00605     free(p->buf);
    00606     destroyBindings(p->bindings);
    00607     free(p);
    00608   }
    00609   destroyBindings(freeBindingList);
    00610   destroyBindings(inheritedBindings);
    00611   poolDestroy(&tempPool);
    00612   poolDestroy(&temp2Pool);
    00613   dtdDestroy(&dtd);
    00614   free((void *)atts);
    00615   free(groupConnector);
    00616   free(buffer);
    00617   free(dataBuf);
    00618   free(unknownEncodingMem);
    00619   if (unknownEncodingRelease)
    00620     unknownEncodingRelease(unknownEncodingData);
    00621   free(parser);
    00622 }
    00623
    00624 void XML_UseParserAsHandlerArg(XML_Parser parser)
    00625 {
    00626   handlerArg = parser;
    00627 }
    00628
    00629 void XML_SetUserData(XML_Parser parser, void *p)
    00630 {
    00631   if (handlerArg == userData)
    00632     handlerArg = userData = p;
    00633   else
    00634     userData = p;
    00635 }
    00636
    00637 int XML_SetBase(XML_Parser parser, const XML_Char *p)
    00638 {
    00639   if (p) {
    00640     p = poolCopyString(&dtd.pool, p);
    00641     if (!p)
    00642       return 0;
    00643     dtd.base = p;
    00644   }
    00645   else
    00646     dtd.base = 0;
    00647   return 1;
    00648 }
    00649
    00650 const XML_Char *XML_GetBase(XML_Parser parser)
    00651 {
    00652   return dtd.base;
    00653 }
    00654
    00655 int XML_GetSpecifiedAttributeCount(XML_Parser parser)
    00656 {
    00657   return nSpecifiedAtts;
    00658 }
    00659
    00660 void XML_SetElementHandler(XML_Parser parser,
    00661                            XML_StartElementHandler start,
    00662                            XML_EndElementHandler end)
    00663 {
    00664   startElementHandler = start;
    00665   endElementHandler = end;
    00666 }
    00667
    00668 void XML_SetCharacterDataHandler(XML_Parser parser,
    00669                                  XML_CharacterDataHandler handler)
    00670 {
    00671   characterDataHandler = handler;
    00672 }
    00673
    00674 void XML_SetProcessingInstructionHandler(XML_Parser parser,
    00675                                          XML_ProcessingInstructionHandler handler)
    00676 {
    00677   processingInstructionHandler = handler;
    00678 }
    00679
    00680 void XML_SetCommentHandler(XML_Parser parser,
    00681                            XML_CommentHandler handler)
    00682 {
    00683   commentHandler = handler;
    00684 }
    00685
    00686 void XML_SetCdataSectionHandler(XML_Parser parser,
    00687                                 XML_StartCdataSectionHandler start,
    00688                                 XML_EndCdataSectionHandler end)
    00689 {
    00690   startCdataSectionHandler = start;
    00691   endCdataSectionHandler = end;
    00692 }
    00693
    00694 void XML_SetDefaultHandler(XML_Parser parser,
    00695                            XML_DefaultHandler handler)
    00696 {
    00697   defaultHandler = handler;
    00698   defaultExpandInternalEntities = 0;
    00699 }
    00700
    00701 void XML_SetDefaultHandlerExpand(XML_Parser parser,
    00702                                  XML_DefaultHandler handler)
    00703 {
    00704   defaultHandler = handler;
    00705   defaultExpandInternalEntities = 1;
    00706 }
    00707
    00708 void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
    00709                                       XML_UnparsedEntityDeclHandler handler)
    00710 {
    00711   unparsedEntityDeclHandler = handler;
    00712 }
    00713
    00714 void XML_SetNotationDeclHandler(XML_Parser parser,
    00715                                 XML_NotationDeclHandler handler)
    00716 {
    00717   notationDeclHandler = handler;
    00718 }
    00719
    00720 void XML_SetNamespaceDeclHandler(XML_Parser parser,
    00721                                  XML_StartNamespaceDeclHandler start,
    00722                                  XML_EndNamespaceDeclHandler end)
    00723 {
    00724   startNamespaceDeclHandler = start;
    00725   endNamespaceDeclHandler = end;
    00726 }
    00727
    00728 void XML_SetNotStandaloneHandler(XML_Parser parser,
    00729                                  XML_NotStandaloneHandler handler)
    00730 {
    00731   notStandaloneHandler = handler;
    00732 }
    00733
    00734 void XML_SetExternalEntityRefHandler(XML_Parser parser,
    00735                                      XML_ExternalEntityRefHandler handler)
    00736 {
    00737   externalEntityRefHandler = handler;
    00738 }
    00739
    00740 void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
    00741 {
    00742   if (arg)
    00743     externalEntityRefHandlerArg = arg;
    00744   else
    00745     externalEntityRefHandlerArg = parser;
    00746 }
    00747
    00748 void XML_SetUnknownEncodingHandler(XML_Parser parser,
    00749                                    XML_UnknownEncodingHandler handler,
    00750                                    void *data)
    00751 {
    00752   unknownEncodingHandler = handler;
    00753   unknownEncodingHandlerData = data;
    00754 }
    00755
    00756 int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
    00757 {
    00758   if (len == 0) {
    00759     if (!isFinal)
    00760       return 1;
    00761     positionPtr = bufferPtr;
    00762     errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
    00763     if (errorCode == XML_ERROR_NONE)
    00764       return 1;
    00765     eventEndPtr = eventPtr;
    00766     return 0;
    00767   }
    00768   else if (bufferPtr == bufferEnd) {
    00769     const char *end;
    00770     int nLeftOver;
    00771     parseEndByteIndex += len;
    00772     positionPtr = s;
    00773     if (isFinal) {
    00774       errorCode = processor(parser, s, parseEndPtr = s + len, 0);
    00775       if (errorCode == XML_ERROR_NONE)
    00776         return 1;
    00777       eventEndPtr = eventPtr;
    00778       return 0;
    00779     }
    00780     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
    00781     if (errorCode != XML_ERROR_NONE) {
    00782       eventEndPtr = eventPtr;
    00783       return 0;
    00784     }
    00785     XmlUpdatePosition(encoding, positionPtr, end, &position);
    00786     nLeftOver = s + len - end;
    00787     if (nLeftOver) {
    00788       if (buffer == 0 || nLeftOver > bufferLim - buffer) {
    00789         /* FIXME avoid integer overflow */
    00790         buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2);
    00791         if (!buffer) {
    00792           errorCode = XML_ERROR_NO_MEMORY;
    00793           eventPtr = eventEndPtr = 0;
    00794           return 0;
    00795         }
    00796         bufferLim = buffer + len * 2;
    00797       }
    00798       memcpy(buffer, end, nLeftOver);
    00799       bufferPtr = buffer;
    00800       bufferEnd = buffer + nLeftOver;
    00801     }
    00802     return 1;
    00803   }
    00804   else {
    00805     memcpy(XML_GetBuffer(parser, len), s, len);
    00806     return XML_ParseBuffer(parser, len, isFinal);
    00807   }
    00808 }
    00809
    00810 int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
    00811 {
    00812   const char *start = bufferPtr;
    00813   positionPtr = start;
    00814   bufferEnd += len;
    00815   parseEndByteIndex += len;
    00816   errorCode = processor(parser, start, parseEndPtr = bufferEnd,
    00817                         isFinal ? (const char **)0 : &bufferPtr);
    00818   if (errorCode == XML_ERROR_NONE) {
    00819     if (!isFinal)
    00820       XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
    00821     return 1;
    00822   }
    00823   else {
    00824     eventEndPtr = eventPtr;
    00825     return 0;
    00826   }
    00827 }
    00828
    00829 void *XML_GetBuffer(XML_Parser parser, int len)
    00830 {
    00831   if (len > bufferLim - bufferEnd) {
    00832     /* FIXME avoid integer overflow */
    00833     int neededSize = len + (bufferEnd - bufferPtr);
    00834     if (neededSize  <= bufferLim - buffer) {
    00835       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
    00836       bufferEnd = buffer + (bufferEnd - bufferPtr);
    00837       bufferPtr = buffer;
    00838     }
    00839     else {
    00840       char *newBuf;
    00841       int bufferSize = bufferLim - bufferPtr;
    00842       if (bufferSize == 0)
    00843         bufferSize = INIT_BUFFER_SIZE;
    00844       do {
    00845         bufferSize *= 2;
    00846       } while (bufferSize < neededSize);
    00847       newBuf = malloc(bufferSize);
    00848       if (newBuf == 0) {
    00849         errorCode = XML_ERROR_NO_MEMORY;
    00850         return 0;
    00851       }
    00852       bufferLim = newBuf + bufferSize;
    00853       if (bufferPtr) {
    00854         memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
    00855         free(buffer);
    00856       }
    00857       bufferEnd = newBuf + (bufferEnd - bufferPtr);
    00858       bufferPtr = buffer = newBuf;
    00859     }
    00860   }
    00861   return bufferEnd;
    00862 }
    00863
    00864 enum XML_Error XML_GetErrorCode(XML_Parser parser)
    00865 {
    00866   return errorCode;
    00867 }
    00868
    00869 long XML_GetCurrentByteIndex(XML_Parser parser)
    00870 {
    00871   if (eventPtr)
    00872     return parseEndByteIndex - (parseEndPtr - eventPtr);
    00873   return -1;
    00874 }
    00875
    00876 int XML_GetCurrentByteCount(XML_Parser parser)
    00877 {
    00878   if (eventEndPtr && eventPtr)
    00879     return eventEndPtr - eventPtr;
    00880   return 0;
    00881 }
    00882
    00883 int XML_GetCurrentLineNumber(XML_Parser parser)
    00884 {
    00885   if (eventPtr) {
    00886     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
    00887     positionPtr = eventPtr;
    00888   }
    00889   return position.lineNumber + 1;
    00890 }
    00891
    00892 int XML_GetCurrentColumnNumber(XML_Parser parser)
    00893 {
    00894   if (eventPtr) {
    00895     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
    00896     positionPtr = eventPtr;
    00897   }
    00898   return position.columnNumber;
    00899 }
    00900
    00901 void XML_DefaultCurrent(XML_Parser parser)
    00902 {
    00903   if (defaultHandler) {
    00904     if (openInternalEntities)
    00905       reportDefault(parser,
    00906                     ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(),
    00907                     openInternalEntities->internalEventPtr,
    00908                     openInternalEntities->internalEventEndPtr);
    00909     else
    00910       reportDefault(parser, encoding, eventPtr, eventEndPtr);
    00911   }
    00912 }
    00913
    00914 const XML_LChar *XML_ErrorString(int code)
    00915 {
    00916   static const XML_LChar *message[] = {
    00917     0,
    00918     XML_T("out of memory"),
    00919     XML_T("syntax error"),
    00920     XML_T("no element found"),
    00921     XML_T("not well-formed"),
    00922     XML_T("unclosed token"),
    00923     XML_T("unclosed token"),
    00924     XML_T("mismatched tag"),
    00925     XML_T("duplicate attribute"),
    00926     XML_T("junk after document element"),
    00927     XML_T("illegal parameter entity reference"),
    00928     XML_T("undefined entity"),
    00929     XML_T("recursive entity reference"),
    00930     XML_T("asynchronous entity"),
    00931     XML_T("reference to invalid character number"),
    00932     XML_T("reference to binary entity"),
    00933     XML_T("reference to external entity in attribute"),
    00934     XML_T("xml processing instruction not at start of external entity"),
    00935     XML_T("unknown encoding"),
    00936     XML_T("encoding specified in XML declaration is incorrect"),
    00937     XML_T("unclosed CDATA section"),
    00938     XML_T("error in processing external entity reference"),
    00939     XML_T("document is not standalone")
    00940   };
    00941   if (code > 0 && code < sizeof(message)/sizeof(message[0]))
    00942     return message[code];
    00943   return 0;
    00944 }
    00945
    00946 static
    00947 enum XML_Error contentProcessor(XML_Parser parser,
    00948                                 const char *start,
    00949                                 const char *end,
    00950                                 const char **endPtr)
    00951 {
    00952   return doContent(parser, 0, encoding, start, end, endPtr);
    00953 }
    00954
    00955 static
    00956 enum XML_Error externalEntityInitProcessor(XML_Parser parser,
    00957                                            const char *start,
    00958                                            const char *end,
    00959                                            const char **endPtr)
    00960 {
    00961   enum XML_Error result = initializeEncoding(parser);
    00962   if (result != XML_ERROR_NONE)
    00963     return result;
    00964   processor = externalEntityInitProcessor2;
    00965   return externalEntityInitProcessor2(parser, start, end, endPtr);
    00966 }
    00967
    00968 static
    00969 enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
    00970                                             const char *start,
    00971                                             const char *end,
    00972                                             const char **endPtr)
    00973 {
    00974   const char *next;
    00975   int tok = XmlContentTok(encoding, start, end, &next);
    00976   switch (tok) {
    00977   case XML_TOK_BOM:
    00978     start = next;
    00979     break;
    00980   case XML_TOK_PARTIAL:
    00981     if (endPtr) {
    00982       *endPtr = start;
    00983       return XML_ERROR_NONE;
    00984     }
    00985     eventPtr = start;
    00986     return XML_ERROR_UNCLOSED_TOKEN;
    00987   case XML_TOK_PARTIAL_CHAR:
    00988     if (endPtr) {
    00989       *endPtr = start;
    00990       return XML_ERROR_NONE;
    00991     }
    00992     eventPtr = start;
    00993     return XML_ERROR_PARTIAL_CHAR;
    00994   }
    00995   processor = externalEntityInitProcessor3;
    00996   return externalEntityInitProcessor3(parser, start, end, endPtr);
    00997 }
    00998
    00999 static
    01000 enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
    01001                                             const char *start,
    01002                                             const char *end,
    01003                                             const char **endPtr)
    01004 {
    01005   const char *next;
    01006   int tok = XmlContentTok(encoding, start, end, &next);
    01007   switch (tok) {
    01008   case XML_TOK_XML_DECL:
    01009     {
    01010       enum XML_Error result = processXmlDecl(parser, 1, start, next);
    01011       if (result != XML_ERROR_NONE)
    01012         return result;
    01013       start = next;
    01014     }
    01015     break;
    01016   case XML_TOK_PARTIAL:
    01017     if (endPtr) {
    01018       *endPtr = start;
    01019       return XML_ERROR_NONE;
    01020     }
    01021     eventPtr = start;
    01022     return XML_ERROR_UNCLOSED_TOKEN;
    01023   case XML_TOK_PARTIAL_CHAR:
    01024     if (endPtr) {
    01025       *endPtr = start;
    01026       return XML_ERROR_NONE;
    01027     }
    01028     eventPtr = start;
    01029     return XML_ERROR_PARTIAL_CHAR;
    01030   }
    01031   processor = externalEntityContentProcessor;
    01032   tagLevel = 1;
    01033   return doContent(parser, 1, encoding, start, end, endPtr);
    01034 }
    01035
    01036 static
    01037 enum XML_Error externalEntityContentProcessor(XML_Parser parser,
    01038                                               const char *start,
    01039                                               const char *end,
    01040                                               const char **endPtr)
    01041 {
    01042   return doContent(parser, 1, encoding, start, end, endPtr);
    01043 }
    01044
    01045 static enum XML_Error
    01046 doContent(XML_Parser parser,
    01047           int startTagLevel,
    01048           const ENCODING *enc,
    01049           const char *s,
    01050           const char *end,
    01051           const char **nextPtr)
    01052 {
    01053   const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
    01054   const char **eventPP;
    01055   const char **eventEndPP;
    01056   if (enc == encoding) {
    01057     eventPP = &eventPtr;
    01058     eventEndPP = &eventEndPtr;
    01059   }
    01060   else {
    01061     eventPP = &(openInternalEntities->internalEventPtr);
    01062     eventEndPP = &(openInternalEntities->internalEventEndPtr);
    01063   }
    01064   *eventPP = s;
    01065   for (;;) {
    01066     const char *next = s; /* XmlContentTok doesn't always set the last arg */
    01067     int tok = XmlContentTok(enc, s, end, &next);
    01068     *eventEndPP = next;
    01069     switch (tok) {
    01070     case XML_TOK_TRAILING_CR:
    01071       if (nextPtr) {
    01072         *nextPtr = s;
    01073         return XML_ERROR_NONE;
    01074       }
    01075       *eventEndPP = end;
    01076       if (characterDataHandler) {
    01077         XML_Char c = 0xA;
    01078         characterDataHandler(handlerArg, &c, 1);
    01079       }
    01080       else if (defaultHandler)
    01081         reportDefault(parser, enc, s, end);
    01082       if (startTagLevel == 0)
    01083         return XML_ERROR_NO_ELEMENTS;
    01084       if (tagLevel != startTagLevel)
    01085         return XML_ERROR_ASYNC_ENTITY;
    01086       return XML_ERROR_NONE;
    01087     case XML_TOK_NONE:
    01088       if (nextPtr) {
    01089         *nextPtr = s;
    01090         return XML_ERROR_NONE;
    01091       }
    01092       if (startTagLevel > 0) {
    01093         if (tagLevel != startTagLevel)
    01094           return XML_ERROR_ASYNC_ENTITY;
    01095         return XML_ERROR_NONE;
    01096       }
    01097       return XML_ERROR_NO_ELEMENTS;
    01098     case XML_TOK_INVALID:
    01099       *eventPP = next;
    01100       return XML_ERROR_INVALID_TOKEN;
    01101     case XML_TOK_PARTIAL:
    01102       if (nextPtr) {
    01103         *nextPtr = s;
    01104         return XML_ERROR_NONE;
    01105       }
    01106       return XML_ERROR_UNCLOSED_TOKEN;
    01107     case XML_TOK_PARTIAL_CHAR:
    01108       if (nextPtr) {
    01109         *nextPtr = s;
    01110         return XML_ERROR_NONE;
    01111       }
    01112       return XML_ERROR_PARTIAL_CHAR;
    01113     case XML_TOK_ENTITY_REF:
    01114       {
    01115         const XML_Char *name;
    01116         ENTITY *entity;
    01117         XML_Char ch = XmlPredefinedEntityName(enc,
    01118                                               s + enc->minBytesPerChar,
    01119                                               next - enc->minBytesPerChar);
    01120         if (ch) {
    01121           if (characterDataHandler)
    01122             characterDataHandler(handlerArg, &ch, 1);
    01123           else if (defaultHandler)
    01124             reportDefault(parser, enc, s, next);
    01125           break;
    01126         }
    01127         name = poolStoreString(&dtd.pool, enc,
    01128                                 s + enc->minBytesPerChar,
    01129                                 next - enc->minBytesPerChar);
    01130         if (!name)
    01131           return XML_ERROR_NO_MEMORY;
    01132         entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
    01133         poolDiscard(&dtd.pool);
    01134         if (!entity) {
    01135           if (dtd.complete || dtd.standalone)
    01136             return XML_ERROR_UNDEFINED_ENTITY;
    01137           if (defaultHandler)
    01138             reportDefault(parser, enc, s, next);
    01139           break;
    01140         }
    01141         if (entity->open)
    01142           return XML_ERROR_RECURSIVE_ENTITY_REF;
    01143         if (entity->notation)
    01144           return XML_ERROR_BINARY_ENTITY_REF;
    01145         if (entity) {
    01146           if (entity->textPtr) {
    01147             enum XML_Error result;
    01148             OPEN_INTERNAL_ENTITY openEntity;
    01149             if (defaultHandler && !defaultExpandInternalEntities) {
    01150               reportDefault(parser, enc, s, next);
    01151               break;
    01152             }
    01153             entity->open = 1;
    01154             openEntity.next = openInternalEntities;
    01155             openInternalEntities = &openEntity;
    01156             openEntity.entity = entity;
    01157             openEntity.internalEventPtr = 0;
    01158             openEntity.internalEventEndPtr = 0;
    01159             result = doContent(parser,
    01160                                tagLevel,
    01161                                internalEnc,
    01162                                (char *)entity->textPtr,
    01163                                (char *)(entity->textPtr + entity->textLen),
    01164                                0);
    01165             entity->open = 0;
    01166             openInternalEntities = openEntity.next;
    01167             if (result)
    01168               return result;
    01169           }
    01170           else if (externalEntityRefHandler) {
    01171             const XML_Char *context;
    01172             entity->open = 1;
    01173             context = getContext(parser);
    01174             entity->open = 0;
    01175             if (!context)
    01176               return XML_ERROR_NO_MEMORY;
    01177             if (!externalEntityRefHandler(externalEntityRefHandlerArg,
    01178                                           context,
    01179                                           dtd.base,
    01180                                           entity->systemId,
    01181                                           entity->publicId))
    01182               return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
    01183             poolDiscard(&tempPool);
    01184           }
    01185           else if (defaultHandler)
    01186             reportDefault(parser, enc, s, next);
    01187         }
    01188         break;
    01189       }
    01190     case XML_TOK_START_TAG_WITH_ATTS:
    01191       if (!startElementHandler) {
    01192         enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
    01193         if (result)
    01194           return result;
    01195       }
    01196       /* fall through */
    01197     case XML_TOK_START_TAG_NO_ATTS:
    01198       {
    01199         TAG *tag;
    01200         if (freeTagList) {
    01201           tag = freeTagList;
    01202           freeTagList = freeTagList->parent;
    01203         }
    01204         else {
    01205           tag = malloc(sizeof(TAG));
    01206           if (!tag)
    01207             return XML_ERROR_NO_MEMORY;
    01208           tag->buf = malloc(INIT_TAG_BUF_SIZE);
    01209           if (!tag->buf)
    01210             return XML_ERROR_NO_MEMORY;
    01211           tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
    01212         }
    01213         tag->bindings = 0;
    01214         tag->parent = tagStack;
    01215         tagStack = tag;
    01216         tag->name.localPart = 0;
    01217         tag->rawName = s + enc->minBytesPerChar;
    01218         tag->rawNameLength = XmlNameLength(enc, tag->rawName);
    01219         if (nextPtr) {
    01220           /* Need to guarantee that:
    01221              tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
    01222           if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
    01223             int bufSize = tag->rawNameLength * 4;
    01224             bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
    01225             tag->buf = realloc(tag->buf, bufSize);
    01226             if (!tag->buf)
    01227               return XML_ERROR_NO_MEMORY;
    01228             tag->bufEnd = tag->buf + bufSize;
    01229           }
    01230           memcpy(tag->buf, tag->rawName, tag->rawNameLength);
    01231           tag->rawName = tag->buf;
    01232         }
    01233         ++tagLevel;
    01234         if (startElementHandler) {
    01235           enum XML_Error result;
    01236           XML_Char *toPtr;
    01237           for (;;) {
    01238             const char *rawNameEnd = tag->rawName + tag->rawNameLength;
    01239             const char *fromPtr = tag->rawName;
    01240             int bufSize;
    01241             if (nextPtr)
    01242               toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
    01243             else
    01244               toPtr = (XML_Char *)tag->buf;
    01245             tag->name.str = toPtr;
    01246             XmlConvert(enc,
    01247                        &fromPtr, rawNameEnd,
    01248                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
    01249             if (fromPtr == rawNameEnd)
    01250               break;
    01251             bufSize = (tag->bufEnd - tag->buf) << 1;
    01252             tag->buf = realloc(tag->buf, bufSize);
    01253             if (!tag->buf)
    01254               return XML_ERROR_NO_MEMORY;
    01255             tag->bufEnd = tag->buf + bufSize;
    01256             if (nextPtr)
    01257               tag->rawName = tag->buf;
    01258           }
    01259           *toPtr = XML_T('\0');
    01260           result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
    01261           if (result)
    01262             return result;
    01263           startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
    01264           poolClear(&tempPool);
    01265         }
    01266         else {
    01267           tag->name.str = 0;
    01268           if (defaultHandler)
    01269             reportDefault(parser, enc, s, next);
    01270         }
    01271         break;
    01272       }
    01273     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
    01274       if (!startElementHandler) {
    01275         enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
    01276         if (result)
    01277           return result;
    01278       }
    01279       /* fall through */
    01280     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
    01281       if (startElementHandler || endElementHandler) {
    01282         const char *rawName = s + enc->minBytesPerChar;
    01283         enum XML_Error result;
    01284         BINDING *bindings = 0;
    01285         TAG_NAME name;
    01286         name.str = poolStoreString(&tempPool, enc, rawName,
    01287                                    rawName + XmlNameLength(enc, rawName));
    01288         if (!name.str)
    01289           return XML_ERROR_NO_MEMORY;
    01290         poolFinish(&tempPool);
    01291         result = storeAtts(parser, enc, s, &name, &bindings);
    01292         if (result)
    01293           return result;
    01294         poolFinish(&tempPool);
    01295         if (startElementHandler)
    01296           startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
    01297         if (endElementHandler) {
    01298           if (startElementHandler)
    01299             *eventPP = *eventEndPP;
    01300           endElementHandler(handlerArg, name.str);
    01301         }
    01302         poolClear(&tempPool);
    01303         while (bindings) {
    01304           BINDING *b = bindings;
    01305           if (endNamespaceDeclHandler)
    01306             endNamespaceDeclHandler(handlerArg, b->prefix->name);
    01307           bindings = bindings->nextTagBinding;
    01308           b->nextTagBinding = freeBindingList;
    01309           freeBindingList = b;
    01310           b->prefix->binding = b->prevPrefixBinding;
    01311         }
    01312       }
    01313       else if (defaultHandler)
    01314         reportDefault(parser, enc, s, next);
    01315       if (tagLevel == 0)
    01316         return epilogProcessor(parser, next, end, nextPtr);
    01317       break;
    01318     case XML_TOK_END_TAG:
    01319       if (tagLevel == startTagLevel)
    01320         return XML_ERROR_ASYNC_ENTITY;
    01321       else {
    01322         int len;
    01323         const char *rawName;
    01324         TAG *tag = tagStack;
    01325         tagStack = tag->parent;
    01326         tag->parent = freeTagList;
    01327         freeTagList = tag;
    01328         rawName = s + enc->minBytesPerChar*2;
    01329         len = XmlNameLength(enc, rawName);
    01330         if (len != tag->rawNameLength
    01331             || memcmp(tag->rawName, rawName, len) != 0) {
    01332           *eventPP = rawName;
    01333           return XML_ERROR_TAG_MISMATCH;
    01334         }
    01335         --tagLevel;
    01336         if (endElementHandler && tag->name.str) {
    01337           if (tag->name.localPart) {
    01338             XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
    01339             const XML_Char *from = tag->name.localPart;
    01340             while ((*to++ = *from++) != 0)
    01341               ;
    01342           }
    01343           endElementHandler(handlerArg, tag->name.str);
    01344         }
    01345         else if (defaultHandler)
    01346           reportDefault(parser, enc, s, next);
    01347         while (tag->bindings) {
    01348           BINDING *b = tag->bindings;
    01349           if (endNamespaceDeclHandler)
    01350             endNamespaceDeclHandler(handlerArg, b->prefix->name);
    01351           tag->bindings = tag->bindings->nextTagBinding;
    01352           b->nextTagBinding = freeBindingList;
    01353           freeBindingList = b;
    01354           b->prefix->binding = b->prevPrefixBinding;
    01355         }
    01356         if (tagLevel == 0)
    01357           return epilogProcessor(parser, next, end, nextPtr);
    01358       }
    01359       break;
    01360     case XML_TOK_CHAR_REF:
    01361       {
    01362         int n = XmlCharRefNumber(enc, s);
    01363         if (n < 0)
    01364           return XML_ERROR_BAD_CHAR_REF;
    01365         if (characterDataHandler) {
    01366           XML_Char buf[XML_ENCODE_MAX];
    01367           characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
    01368         }
    01369         else if (defaultHandler)
    01370           reportDefault(parser, enc, s, next);
    01371       }
    01372       break;
    01373     case XML_TOK_XML_DECL:
    01374       return XML_ERROR_MISPLACED_XML_PI;
    01375     case XML_TOK_DATA_NEWLINE:
    01376       if (characterDataHandler) {
    01377         XML_Char c = 0xA;
    01378         characterDataHandler(handlerArg, &c, 1);
    01379       }
    01380       else if (defaultHandler)
    01381         reportDefault(parser, enc, s, next);
    01382       break;
    01383     case XML_TOK_CDATA_SECT_OPEN:
    01384       {
    01385         enum XML_Error result;
    01386         if (startCdataSectionHandler)
    01387           startCdataSectionHandler(handlerArg);
    01388 #if 0
    01389         /* Suppose you doing a transformation on a document that involves
    01390            changing only the character data.  You set up a defaultHandler
    01391            and a characterDataHandler.  The defaultHandler simply copies
    01392            characters through.  The characterDataHandler does the transformation
    01393            and writes the characters out escaping them as necessary.  This case
    01394            will fail to work if we leave out the following two lines (because &
    01395            and < inside CDATA sections will be incorrectly escaped).
    01396
    01397            However, now we have a start/endCdataSectionHandler, so it seems
    01398            easier to let the user deal with this. */
    01399
    01400         else if (characterDataHandler)
    01401           characterDataHandler(handlerArg, dataBuf, 0);
    01402 #endif
    01403         else if (defaultHandler)
    01404           reportDefault(parser, enc, s, next);
    01405         result = doCdataSection(parser, enc, &next, end, nextPtr);
    01406         if (!next) {
    01407           processor = cdataSectionProcessor;
    01408           return result;
    01409         }
    01410       }
    01411       break;
    01412     case XML_TOK_TRAILING_RSQB:
    01413       if (nextPtr) {
    01414         *nextPtr = s;
    01415         return XML_ERROR_NONE;
    01416       }
    01417       if (characterDataHandler) {
    01418         if (MUST_CONVERT(enc, s)) {
    01419           ICHAR *dataPtr = (ICHAR *)dataBuf;
    01420           XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
    01421           characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
    01422         }
    01423         else
    01424           characterDataHandler(handlerArg,
    01425                                (XML_Char *)s,
    01426                                (XML_Char *)end - (XML_Char *)s);
    01427       }
    01428       else if (defaultHandler)
    01429         reportDefault(parser, enc, s, end);
    01430       if (startTagLevel == 0) {
    01431         *eventPP = end;
    01432         return XML_ERROR_NO_ELEMENTS;
    01433       }
    01434       if (tagLevel != startTagLevel) {
    01435         *eventPP = end;
    01436         return XML_ERROR_ASYNC_ENTITY;
    01437       }
    01438       return XML_ERROR_NONE;
    01439     case XML_TOK_DATA_CHARS:
    01440       if (characterDataHandler) {
    01441         if (MUST_CONVERT(enc, s)) {
    01442           for (;;) {
    01443             ICHAR *dataPtr = (ICHAR *)dataBuf;
    01444             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
    01445             *eventEndPP = s;
    01446             characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
    01447             if (s == next)
    01448               break;
    01449             *eventPP = s;
    01450           }
    01451         }
    01452         else
    01453           characterDataHandler(handlerArg,
    01454                                (XML_Char *)s,
    01455                                (XML_Char *)next - (XML_Char *)s);
    01456       }
    01457       else if (defaultHandler)
    01458         reportDefault(parser, enc, s, next);
    01459       break;
    01460     case XML_TOK_PI:
    01461       if (!reportProcessingInstruction(parser, enc, s, next))
    01462         return XML_ERROR_NO_MEMORY;
    01463       break;
    01464     case XML_TOK_COMMENT:
    01465       if (!reportComment(parser, enc, s, next))
    01466         return XML_ERROR_NO_MEMORY;
    01467       break;
    01468     default:
    01469       if (defaultHandler)
    01470         reportDefault(parser, enc, s, next);
    01471       break;
    01472     }
    01473     *eventPP = s = next;
    01474   }
    01475   /* not reached */
    01476 }
    01477
    01478 /* If tagNamePtr is non-null, build a real list of attributes,
    01479 otherwise just check the attributes for well-formedness. */
    01480
    01481 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
    01482                                 const char *s, TAG_NAME *tagNamePtr,
    01483                                 BINDING **bindingsPtr)
    01484 {
    01485   ELEMENT_TYPE *elementType = 0;
    01486   int nDefaultAtts = 0;
    01487   const XML_Char **appAtts;
    01488   int attIndex = 0;
    01489   int i;
    01490   int n;
    01491   int nPrefixes = 0;
    01492   BINDING *binding;
    01493   const XML_Char *localPart;
    01494
    01495   if (tagNamePtr) {
    01496     elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, 0);
    01497     if (!elementType) {
    01498       tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
    01499       if (!tagNamePtr->str)
    01500         return XML_ERROR_NO_MEMORY;
    01501       elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
    01502       if (!elementType)
    01503         return XML_ERROR_NO_MEMORY;
    01504       if (ns && !setElementTypePrefix(parser, elementType))
    01505         return XML_ERROR_NO_MEMORY;
    01506     }
    01507     nDefaultAtts = elementType->nDefaultAtts;
    01508   }
    01509   n = XmlGetAttributes(enc, s, attsSize, atts);
    01510   if (n + nDefaultAtts > attsSize) {
    01511     int oldAttsSize = attsSize;
    01512     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
    01513     atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
    01514     if (!atts)
    01515       return XML_ERROR_NO_MEMORY;
    01516     if (n > oldAttsSize)
    01517       XmlGetAttributes(enc, s, n, atts);
    01518   }
    01519   appAtts = (const XML_Char **)atts;
    01520   for (i = 0; i < n; i++) {
    01521     ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
    01522                                          atts[i].name
    01523                                          + XmlNameLength(enc, atts[i].name));
    01524     if (!attId)
    01525       return XML_ERROR_NO_MEMORY;
    01526     if ((attId->name)[-1]) {
    01527       if (enc == encoding)
    01528         eventPtr = atts[i].name;
    01529       return XML_ERROR_DUPLICATE_ATTRIBUTE;
    01530     }
    01531     (attId->name)[-1] = 1;
    01532     appAtts[attIndex++] = attId->name;
    01533     if (!atts[i].normalized) {
    01534       enum XML_Error result;
    01535       int isCdata = 1;
    01536
    01537       if (attId->maybeTokenized) {
    01538         int j;
    01539         for (j = 0; j < nDefaultAtts; j++) {
    01540           if (attId == elementType->defaultAtts[j].id) {
    01541             isCdata = elementType->defaultAtts[j].isCdata;
    01542             break;
    01543           }
    01544         }
    01545       }
    01546
    01547       result = storeAttributeValue(parser, enc, isCdata,
    01548                                    atts[i].valuePtr, atts[i].valueEnd,
    01549                                    &tempPool);
    01550       if (result)
    01551         return result;
    01552       if (tagNamePtr) {
    01553         appAtts[attIndex] = poolStart(&tempPool);
    01554         poolFinish(&tempPool);
    01555       }
    01556       else
    01557         poolDiscard(&tempPool);
    01558     }
    01559     else if (tagNamePtr) {
    01560       appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
    01561       if (appAtts[attIndex] == 0)
    01562         return XML_ERROR_NO_MEMORY;
    01563       poolFinish(&tempPool);
    01564     }
    01565     if (attId->prefix && tagNamePtr) {
    01566       if (attId->xmlns) {
    01567         if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
    01568           return XML_ERROR_NO_MEMORY;
    01569         --attIndex;
    01570       }
    01571       else {
    01572         attIndex++;
    01573         nPrefixes++;
    01574         (attId->name)[-1] = 2;
    01575       }
    01576     }
    01577     else
    01578       attIndex++;
    01579   }
    01580   nSpecifiedAtts = attIndex;
    01581   if (tagNamePtr) {
    01582     int j;
    01583     for (j = 0; j < nDefaultAtts; j++) {
    01584       const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
    01585       if (!(da->id->name)[-1] && da->value) {
    01586         if (da->id->prefix) {
    01587           if (da->id->xmlns) {
    01588             if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
    01589               return XML_ERROR_NO_MEMORY;
    01590           }
    01591           else {
    01592             (da->id->name)[-1] = 2;
    01593             nPrefixes++;
    01594             appAtts[attIndex++] = da->id->name;
    01595             appAtts[attIndex++] = da->value;
    01596           }
    01597         }
    01598         else {
    01599           (da->id->name)[-1] = 1;
    01600           appAtts[attIndex++] = da->id->name;
    01601           appAtts[attIndex++] = da->value;
    01602         }
    01603       }
    01604     }
    01605     appAtts[attIndex] = 0;
    01606   }
    01607   i = 0;
    01608   if (nPrefixes) {
    01609     for (; i < attIndex; i += 2) {
    01610       if (appAtts[i][-1] == 2) {
    01611         ATTRIBUTE_ID *id;
    01612         ((XML_Char *)(appAtts[i]))[-1] = 0;
    01613         id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
    01614         if (id->prefix->binding) {
    01615           int j;
    01616           const BINDING *b = id->prefix->binding;
    01617           const XML_Char *s = appAtts[i];
    01618           for (j = 0; j < b->uriLen; j++) {
    01619             if (!poolAppendChar(&tempPool, b->uri[j]))
    01620               return XML_ERROR_NO_MEMORY;
    01621           }
    01622           while (*s++ != ':')
    01623             ;
    01624           do {
    01625             if (!poolAppendChar(&tempPool, *s))
    01626               return XML_ERROR_NO_MEMORY;
    01627           } while (*s++);
    01628           appAtts[i] = poolStart(&tempPool);
    01629           poolFinish(&tempPool);
    01630         }
    01631         if (!--nPrefixes)
    01632           break;
    01633       }
    01634       else
    01635         ((XML_Char *)(appAtts[i]))[-1] = 0;
    01636     }
    01637   }
    01638   for (; i < attIndex; i += 2)
    01639     ((XML_Char *)(appAtts[i]))[-1] = 0;
    01640   if (!tagNamePtr)
    01641     return XML_ERROR_NONE;
    01642   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
    01643     binding->attId->name[-1] = 0;
    01644   if (elementType->prefix) {
    01645     binding = elementType->prefix->binding;
    01646     if (!binding)
    01647       return XML_ERROR_NONE;
    01648     localPart = tagNamePtr->str;
    01649     while (*localPart++ != XML_T(':'))
    01650       ;
    01651   }
    01652   else if (dtd.defaultPrefix.binding) {
    01653     binding = dtd.defaultPrefix.binding;
    01654     localPart = tagNamePtr->str;
    01655   }
    01656   else
    01657     return XML_ERROR_NONE;
    01658   tagNamePtr->localPart = localPart;
    01659   tagNamePtr->uriLen = binding->uriLen;
    01660   i = binding->uriLen;
    01661   do {
    01662     if (i == binding->uriAlloc) {
    01663       binding->uri = realloc(binding->uri, binding->uriAlloc *= 2);
    01664       if (!binding->uri)
    01665         return XML_ERROR_NO_MEMORY;
    01666     }
    01667     binding->uri[i++] = *localPart;
    01668   } while (*localPart++);
    01669   tagNamePtr->str = binding->uri;
    01670   return XML_ERROR_NONE;
    01671 }
    01672
    01673 static
    01674 int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
    01675 {
    01676   BINDING *b;
    01677   int len;
    01678   for (len = 0; uri[len]; len++)
    01679     ;
    01680   if (namespaceSeparator)
    01681     len++;
    01682   if (freeBindingList) {
    01683     b = freeBindingList;
    01684     if (len > b->uriAlloc) {
    01685       b->uri = realloc(b->uri, len + EXPAND_SPARE);
    01686       if (!b->uri)
    01687         return 0;
    01688       b->uriAlloc = len + EXPAND_SPARE;
    01689     }
    01690     freeBindingList = b->nextTagBinding;
    01691   }
    01692   else {
    01693     b = malloc(sizeof(BINDING));
    01694     if (!b)
    01695       return 0;
    01696     b->uri = malloc(sizeof(XML_Char) * len + EXPAND_SPARE);
    01697     if (!b->uri) {
    01698       free(b);
    01699       return 0;
    01700     }
    01701     b->uriAlloc = len;
    01702   }
    01703   b->uriLen = len;
    01704   memcpy(b->uri, uri, len * sizeof(XML_Char));
    01705   if (namespaceSeparator)
    01706     b->uri[len - 1] = namespaceSeparator;
    01707   b->prefix = prefix;
    01708   b->attId = attId;
    01709   b->prevPrefixBinding = prefix->binding;
    01710   if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
    01711     prefix->binding = 0;
    01712   else
    01713     prefix->binding = b;
    01714   b->nextTagBinding = *bindingsPtr;
    01715   *bindingsPtr = b;
    01716   if (startNamespaceDeclHandler)
    01717     startNamespaceDeclHandler(handlerArg, prefix->name,
    01718                               prefix->binding ? uri : 0);
    01719   return 1;
    01720 }
    01721
    01722 /* The idea here is to avoid using stack for each CDATA section when
    01723 the whole file is parsed with one call. */
    01724
    01725 static
    01726 enum XML_Error cdataSectionProcessor(XML_Parser parser,
    01727                                      const char *start,
    01728                                      const char *end,
    01729                                      const char **endPtr)
    01730 {
    01731   enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
    01732   if (start) {
    01733     processor = contentProcessor;
    01734     return contentProcessor(parser, start, end, endPtr);
    01735   }
    01736   return result;
    01737 }
    01738
    01739 /* startPtr gets set to non-null is the section is closed, and to null if
    01740 the section is not yet closed. */
    01741
    01742 static
    01743 enum XML_Error doCdataSection(XML_Parser parser,
    01744                               const ENCODING *enc,
    01745                               const char **startPtr,
    01746                               const char *end,
    01747                               const char **nextPtr)
    01748 {
    01749   const char *s = *startPtr;
    01750   const char **eventPP;
    01751   const char **eventEndPP;
    01752   if (enc == encoding) {
    01753     eventPP = &eventPtr;
    01754     *eventPP = s;
    01755     eventEndPP = &eventEndPtr;
    01756   }
    01757   else {
    01758     eventPP = &(openInternalEntities->internalEventPtr);
    01759     eventEndPP = &(openInternalEntities->internalEventEndPtr);
    01760   }
    01761   *eventPP = s;
    01762   *startPtr = 0;
    01763   for (;;) {
    01764     const char *next;
    01765     int tok = XmlCdataSectionTok(enc, s, end, &next);
    01766     *eventEndPP = next;
    01767     switch (tok) {
    01768     case XML_TOK_CDATA_SECT_CLOSE:
    01769       if (endCdataSectionHandler)
    01770         endCdataSectionHandler(handlerArg);
    01771 #if 0
    01772       /* see comment under XML_TOK_CDATA_SECT_OPEN */
    01773       else if (characterDataHandler)
    01774         characterDataHandler(handlerArg, dataBuf, 0);
    01775 #endif
    01776       else if (defaultHandler)
    01777         reportDefault(parser, enc, s, next);
    01778       *startPtr = next;
    01779       return XML_ERROR_NONE;
    01780     case XML_TOK_DATA_NEWLINE:
    01781       if (characterDataHandler) {
    01782         XML_Char c = 0xA;
    01783         characterDataHandler(handlerArg, &c, 1);
    01784       }
    01785       else if (defaultHandler)
    01786         reportDefault(parser, enc, s, next);
    01787       break;
    01788     case XML_TOK_DATA_CHARS:
    01789       if (characterDataHandler) {
    01790         if (MUST_CONVERT(enc, s)) {
    01791           for (;;) {
    01792             ICHAR *dataPtr = (ICHAR *)dataBuf;
    01793             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
    01794             *eventEndPP = next;
    01795             characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
    01796             if (s == next)
    01797               break;
    01798             *eventPP = s;
    01799           }
    01800         }
    01801         else
    01802           characterDataHandler(handlerArg,
    01803                                (XML_Char *)s,
    01804                                (XML_Char *)next - (XML_Char *)s);
    01805       }
    01806       else if (defaultHandler)
    01807         reportDefault(parser, enc, s, next);
    01808       break;
    01809     case XML_TOK_INVALID:
    01810       *eventPP = next;
    01811       return XML_ERROR_INVALID_TOKEN;
    01812     case XML_TOK_PARTIAL_CHAR:
    01813       if (nextPtr) {
    01814         *nextPtr = s;
    01815         return XML_ERROR_NONE;
    01816       }
    01817       return XML_ERROR_PARTIAL_CHAR;
    01818     case XML_TOK_PARTIAL:
    01819     case XML_TOK_NONE:
    01820       if (nextPtr) {
    01821         *nextPtr = s;
    01822         return XML_ERROR_NONE;
    01823       }
    01824       return XML_ERROR_UNCLOSED_CDATA_SECTION;
    01825     default:
    01826       abort();
    01827     }
    01828     *eventPP = s = next;
    01829   }
    01830   /* not reached */
    01831 }
    01832
    01833 static enum XML_Error
    01834 initializeEncoding(XML_Parser parser)
    01835 {
    01836   const char *s;
    01837 #ifdef XML_UNICODE
    01838   char encodingBuf[128];
    01839   if (!protocolEncodingName)
    01840     s = 0;
    01841   else {
    01842     int i;
    01843     for (i = 0; protocolEncodingName[i]; i++) {
    01844       if (i == sizeof(encodingBuf) - 1
    01845           || protocolEncodingName[i] >= 0x80
    01846           || protocolEncodingName[i] < 0) {
    01847         encodingBuf[0] = '\0';
    01848         break;
    01849       }
    01850       encodingBuf[i] = (char)protocolEncodingName[i];
    01851     }
    01852     encodingBuf[i] = '\0';
    01853     s = encodingBuf;
    01854   }
    01855 #else
    01856   s = protocolEncodingName;
    01857 #endif
    01858   if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
    01859     return XML_ERROR_NONE;
    01860   return handleUnknownEncoding(parser, protocolEncodingName);
    01861 }
    01862
    01863 static enum XML_Error
    01864 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
    01865                const char *s, const char *next)
    01866 {
    01867   const char *encodingName = 0;
    01868   const ENCODING *newEncoding = 0;
    01869   const char *version;
    01870   int standalone = -1;
    01871   if (!(ns
    01872         ? XmlParseXmlDeclNS
    01873         : XmlParseXmlDecl)(isGeneralTextEntity,
    01874                            encoding,
    01875                            s,
    01876                            next,
    01877                            &eventPtr,
    01878                            &version,
    01879                            &encodingName,
    01880                            &newEncoding,
    01881                            &standalone))
    01882     return XML_ERROR_SYNTAX;
    01883   if (!isGeneralTextEntity && standalone == 1)
    01884     dtd.standalone = 1;
    01885   if (defaultHandler)
    01886     reportDefault(parser, encoding, s, next);
    01887   if (!protocolEncodingName) {
    01888     if (newEncoding) {
    01889       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
    01890         eventPtr = encodingName;
    01891         return XML_ERROR_INCORRECT_ENCODING;
    01892       }
    01893       encoding = newEncoding;
    01894     }
    01895     else if (encodingName) {
    01896       enum XML_Error result;
    01897       const XML_Char *s = poolStoreString(&tempPool,
    01898                                           encoding,
    01899                                           encodingName,
    01900                                           encodingName
    01901                                           + XmlNameLength(encoding, encodingName));
    01902       if (!s)
    01903         return XML_ERROR_NO_MEMORY;
    01904       result = handleUnknownEncoding(parser, s);
    01905       poolDiscard(&tempPool);
    01906       if (result == XML_ERROR_UNKNOWN_ENCODING)
    01907         eventPtr = encodingName;
    01908       return result;
    01909     }
    01910   }
    01911   return XML_ERROR_NONE;
    01912 }
    01913
    01914 static enum XML_Error
    01915 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
    01916 {
    01917   if (unknownEncodingHandler) {
    01918     XML_Encoding info;
    01919     int i;
    01920     for (i = 0; i < 256; i++)
    01921       info.map[i] = -1;
    01922     info.convert = 0;
    01923     info.data = 0;
    01924     info.release = 0;
    01925     if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
    01926       ENCODING *enc;
    01927       unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding());
    01928       if (!unknownEncodingMem) {
    01929         if (info.release)
    01930           info.release(info.data);
    01931         return XML_ERROR_NO_MEMORY;
    01932       }
    01933       enc = (ns
    01934              ? XmlInitUnknownEncodingNS
    01935              : XmlInitUnknownEncoding)(unknownEncodingMem,
    01936                                        info.map,
    01937                                        info.convert,
    01938                                        info.data);
    01939       if (enc) {
    01940         unknownEncodingData = info.data;
    01941         unknownEncodingRelease = info.release;
    01942         encoding = enc;
    01943         return XML_ERROR_NONE;
    01944       }
    01945     }
    01946     if (info.release)
    01947       info.release(info.data);
    01948   }
    01949   return XML_ERROR_UNKNOWN_ENCODING;
    01950 }
    01951
    01952 static enum XML_Error
    01953 prologInitProcessor(XML_Parser parser,
    01954                     const char *s,
    01955                     const char *end,
    01956                     const char **nextPtr)
    01957 {
    01958   enum XML_Error result = initializeEncoding(parser);
    01959   if (result != XML_ERROR_NONE)
    01960     return result;
    01961   processor = prologProcessor;
    01962   return prologProcessor(parser, s, end, nextPtr);
    01963 }
    01964
    01965 static enum XML_Error
    01966 prologProcessor(XML_Parser parser,
    01967                 const char *s,
    01968                 const char *end,
    01969                 const char **nextPtr)
    01970 {
    01971   for (;;) {
    01972     const char *next;
    01973     int tok = XmlPrologTok(encoding, s, end, &next);
    01974     if (tok <= 0) {
    01975       if (nextPtr != 0 && tok != XML_TOK_INVALID) {
    01976         *nextPtr = s;
    01977         return XML_ERROR_NONE;
    01978       }
    01979       switch (tok) {
    01980       case XML_TOK_INVALID:
    01981         eventPtr = next;
    01982         return XML_ERROR_INVALID_TOKEN;
    01983       case XML_TOK_NONE:
    01984         return XML_ERROR_NO_ELEMENTS;
    01985       case XML_TOK_PARTIAL:
    01986         return XML_ERROR_UNCLOSED_TOKEN;
    01987       case XML_TOK_PARTIAL_CHAR:
    01988         return XML_ERROR_PARTIAL_CHAR;
    01989       case XML_TOK_TRAILING_CR:
    01990         eventPtr = s + encoding->minBytesPerChar;
    01991         return XML_ERROR_NO_ELEMENTS;
    01992       default:
    01993         abort();
    01994       }
    01995     }
    01996     switch (XmlTokenRole(&prologState, tok, s, next, encoding)) {
    01997     case XML_ROLE_XML_DECL:
    01998       {
    01999         enum XML_Error result = processXmlDecl(parser, 0, s, next);
    02000         if (result != XML_ERROR_NONE)
    02001           return result;
    02002       }
    02003       break;
    02004     case XML_ROLE_DOCTYPE_SYSTEM_ID:
    02005       if (!dtd.standalone
    02006           && notStandaloneHandler
    02007           && !notStandaloneHandler(handlerArg))
    02008         return XML_ERROR_NOT_STANDALONE;
    02009       hadExternalDoctype = 1;
    02010       break;
    02011     case XML_ROLE_DOCTYPE_PUBLIC_ID:
    02012     case XML_ROLE_ENTITY_PUBLIC_ID:
    02013       if (!XmlIsPublicId(encoding, s, next, &eventPtr))
    02014         return XML_ERROR_SYNTAX;
    02015       if (declEntity) {
    02016         XML_Char *tem = poolStoreString(&dtd.pool,
    02017                                         encoding,
    02018                                         s + encoding->minBytesPerChar,
    02019                                         next - encoding->minBytesPerChar);
    02020         if (!tem)
    02021           return XML_ERROR_NO_MEMORY;
    02022         normalizePublicId(tem);
    02023         declEntity->publicId = tem;
    02024         poolFinish(&dtd.pool);
    02025       }
    02026       break;
    02027     case XML_ROLE_INSTANCE_START:
    02028       processor = contentProcessor;
    02029       if (hadExternalDoctype)
    02030         dtd.complete = 0;
    02031       return contentProcessor(parser, s, end, nextPtr);
    02032     case XML_ROLE_ATTLIST_ELEMENT_NAME:
    02033       {
    02034         const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next);
    02035         if (!name)
    02036           return XML_ERROR_NO_MEMORY;
    02037         declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
    02038         if (!declElementType)
    02039           return XML_ERROR_NO_MEMORY;
    02040         if (declElementType->name != name)
    02041           poolDiscard(&dtd.pool);
    02042         else {
    02043           poolFinish(&dtd.pool);
    02044           if (!setElementTypePrefix(parser, declElementType))
    02045             return XML_ERROR_NO_MEMORY;
    02046         }
    02047         break;
    02048       }
    02049     case XML_ROLE_ATTRIBUTE_NAME:
    02050       declAttributeId = getAttributeId(parser, encoding, s, next);
    02051       if (!declAttributeId)
    02052         return XML_ERROR_NO_MEMORY;
    02053       declAttributeIsCdata = 0;
    02054       break;
    02055     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
    02056       declAttributeIsCdata = 1;
    02057       break;
    02058     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
    02059     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
    02060       if (dtd.complete
    02061           && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0))
    02062         return XML_ERROR_NO_MEMORY;
    02063       break;
    02064     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
    02065     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
    02066       {
    02067         const XML_Char *attVal;
    02068         enum XML_Error result
    02069           = storeAttributeValue(parser, encoding, declAttributeIsCdata,
    02070                                 s + encoding->minBytesPerChar,
    02071                                 next - encoding->minBytesPerChar,
    02072                                 &dtd.pool);
    02073         if (result)
    02074           return result;
    02075         attVal = poolStart(&dtd.pool);
    02076         poolFinish(&dtd.pool);
    02077         if (dtd.complete
    02078             && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal))
    02079           return XML_ERROR_NO_MEMORY;
    02080         break;
    02081       }
    02082     case XML_ROLE_ENTITY_VALUE:
    02083       {
    02084         enum XML_Error result = storeEntityValue(parser, s, next);
    02085         if (result != XML_ERROR_NONE)
    02086           return result;
    02087       }
    02088       break;
    02089     case XML_ROLE_ENTITY_SYSTEM_ID:
    02090       if (declEntity) {
    02091         declEntity->systemId = poolStoreString(&dtd.pool, encoding,
    02092                                                s + encoding->minBytesPerChar,
    02093                                                next - encoding->minBytesPerChar);
    02094         if (!declEntity->systemId)
    02095           return XML_ERROR_NO_MEMORY;
    02096         declEntity->base = dtd.base;
    02097         poolFinish(&dtd.pool);
    02098       }
    02099       break;
    02100     case XML_ROLE_ENTITY_NOTATION_NAME:
    02101       if (declEntity) {
    02102         declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next);
    02103         if (!declEntity->notation)
    02104           return XML_ERROR_NO_MEMORY;
    02105         poolFinish(&dtd.pool);
    02106         if (unparsedEntityDeclHandler) {
    02107           eventPtr = eventEndPtr = s;
    02108           unparsedEntityDeclHandler(handlerArg,
    02109                                     declEntity->name,
    02110                                     declEntity->base,
    02111                                     declEntity->systemId,
    02112                                     declEntity->publicId,
    02113                                     declEntity->notation);
    02114         }
    02115
    02116       }
    02117       break;
    02118     case XML_ROLE_GENERAL_ENTITY_NAME:
    02119       {
    02120         const XML_Char *name;
    02121         if (XmlPredefinedEntityName(encoding, s, next)) {
    02122           declEntity = 0;
    02123           break;
    02124         }
    02125         name = poolStoreString(&dtd.pool, encoding, s, next);
    02126         if (!name)
    02127           return XML_ERROR_NO_MEMORY;
    02128         if (dtd.complete) {
    02129           declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
    02130           if (!declEntity)
    02131             return XML_ERROR_NO_MEMORY;
    02132           if (declEntity->name != name) {
    02133             poolDiscard(&dtd.pool);
    02134             declEntity = 0;
    02135           }
    02136           else
    02137             poolFinish(&dtd.pool);
    02138         }
    02139         else {
    02140           poolDiscard(&dtd.pool);
    02141           declEntity = 0;
    02142         }
    02143       }
    02144       break;
    02145     case XML_ROLE_PARAM_ENTITY_NAME:
    02146       declEntity = 0;
    02147       break;
    02148     case XML_ROLE_NOTATION_NAME:
    02149       declNotationPublicId = 0;
    02150       declNotationName = 0;
    02151       if (notationDeclHandler) {
    02152         declNotationName = poolStoreString(&tempPool, encoding, s, next);
    02153         if (!declNotationName)
    02154           return XML_ERROR_NO_MEMORY;
    02155         poolFinish(&tempPool);
    02156       }
    02157       break;
    02158     case XML_ROLE_NOTATION_PUBLIC_ID:
    02159       if (!XmlIsPublicId(encoding, s, next, &eventPtr))
    02160         return XML_ERROR_SYNTAX;
    02161       if (declNotationName) {
    02162         XML_Char *tem = poolStoreString(&tempPool,
    02163                                         encoding,
    02164                                         s + encoding->minBytesPerChar,
    02165                                         next - encoding->minBytesPerChar);
    02166         if (!tem)
    02167           return XML_ERROR_NO_MEMORY;
    02168         normalizePublicId(tem);
    02169         declNotationPublicId = tem;
    02170         poolFinish(&tempPool);
    02171       }
    02172       break;
    02173     case XML_ROLE_NOTATION_SYSTEM_ID:
    02174       if (declNotationName && notationDeclHandler) {
    02175         const XML_Char *systemId
    02176           = poolStoreString(&tempPool, encoding,
    02177                             s + encoding->minBytesPerChar,
    02178                             next - encoding->minBytesPerChar);
    02179         if (!systemId)
    02180           return XML_ERROR_NO_MEMORY;
    02181         eventPtr = eventEndPtr = s;
    02182         notationDeclHandler(handlerArg,
    02183                             declNotationName,
    02184                             dtd.base,
    02185                             systemId,
    02186                             declNotationPublicId);
    02187       }
    02188       poolClear(&tempPool);
    02189       break;
    02190     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
    02191       if (declNotationPublicId && notationDeclHandler) {
    02192         eventPtr = eventEndPtr = s;
    02193         notationDeclHandler(handlerArg,
    02194                             declNotationName,
    02195                             dtd.base,
    02196                             0,
    02197                             declNotationPublicId);
    02198       }
    02199       poolClear(&tempPool);
    02200       break;
    02201     case XML_ROLE_ERROR:
    02202       eventPtr = s;
    02203       switch (tok) {
    02204       case XML_TOK_PARAM_ENTITY_REF:
    02205         return XML_ERROR_PARAM_ENTITY_REF;
    02206       case XML_TOK_XML_DECL:
    02207         return XML_ERROR_MISPLACED_XML_PI;
    02208       default:
    02209         return XML_ERROR_SYNTAX;
    02210       }
    02211     case XML_ROLE_GROUP_OPEN:
    02212       if (prologState.level >= groupSize) {
    02213         if (groupSize)
    02214           groupConnector = realloc(groupConnector, groupSize *= 2);
    02215         else
    02216           groupConnector = malloc(groupSize = 32);
    02217         if (!groupConnector)
    02218           return XML_ERROR_NO_MEMORY;
    02219       }
    02220       groupConnector[prologState.level] = 0;
    02221       break;
    02222     case XML_ROLE_GROUP_SEQUENCE:
    02223       if (groupConnector[prologState.level] == '|') {
    02224         eventPtr = s;
    02225         return XML_ERROR_SYNTAX;
    02226       }
    02227       groupConnector[prologState.level] = ',';
    02228       break;
    02229     case XML_ROLE_GROUP_CHOICE:
    02230       if (groupConnector[prologState.level] == ',') {
    02231         eventPtr = s;
    02232         return XML_ERROR_SYNTAX;
    02233       }
    02234       groupConnector[prologState.level] = '|';
    02235       break;
    02236     case XML_ROLE_PARAM_ENTITY_REF:
    02237       if (!dtd.standalone
    02238           && notStandaloneHandler
    02239           && !notStandaloneHandler(handlerArg))
    02240         return XML_ERROR_NOT_STANDALONE;
    02241       dtd.complete = 0;
    02242       break;
    02243     case XML_ROLE_NONE:
    02244       switch (tok) {
    02245       case XML_TOK_PI:
    02246         eventPtr = s;
    02247         eventEndPtr = next;
    02248         if (!reportProcessingInstruction(parser, encoding, s, next))
    02249           return XML_ERROR_NO_MEMORY;
    02250         break;
    02251       case XML_TOK_COMMENT:
    02252         eventPtr = s;
    02253         eventEndPtr = next;
    02254         if (!reportComment(parser, encoding, s, next))
    02255           return XML_ERROR_NO_MEMORY;
    02256         break;
    02257       }
    02258       break;
    02259     }
    02260     if (defaultHandler) {
    02261       switch (tok) {
    02262       case XML_TOK_PI:
    02263       case XML_TOK_COMMENT:
    02264       case XML_TOK_BOM:
    02265       case XML_TOK_XML_DECL:
    02266         break;
    02267       default:
    02268         eventPtr = s;
    02269         eventEndPtr = next;
    02270         reportDefault(parser, encoding, s, next);
    02271       }
    02272     }
    02273     s = next;
    02274   }
    02275   /* not reached */
    02276 }
    02277
    02278 static
    02279 enum XML_Error epilogProcessor(XML_Parser parser,
    02280                                const char *s,
    02281                                const char *end,
    02282                                const char **nextPtr)
    02283 {
    02284   processor = epilogProcessor;
    02285   eventPtr = s;
    02286   for (;;) {
    02287     const char *next;
    02288     int tok = XmlPrologTok(encoding, s, end, &next);
    02289     eventEndPtr = next;
    02290     switch (tok) {
    02291     case XML_TOK_TRAILING_CR:
    02292       if (defaultHandler) {
    02293         eventEndPtr = end;
    02294         reportDefault(parser, encoding, s, end);
    02295       }
    02296       /* fall through */
    02297     case XML_TOK_NONE:
    02298       if (nextPtr)
    02299         *nextPtr = end;
    02300       return XML_ERROR_NONE;
    02301     case XML_TOK_PROLOG_S:
    02302       if (defaultHandler)
    02303         reportDefault(parser, encoding, s, next);
    02304       break;
    02305     case XML_TOK_PI:
    02306       if (!reportProcessingInstruction(parser, encoding, s, next))
    02307         return XML_ERROR_NO_MEMORY;
    02308       break;
    02309     case XML_TOK_COMMENT:
    02310       if (!reportComment(parser, encoding, s, next))
    02311         return XML_ERROR_NO_MEMORY;
    02312       break;
    02313     case XML_TOK_INVALID:
    02314       eventPtr = next;
    02315       return XML_ERROR_INVALID_TOKEN;
    02316     case XML_TOK_PARTIAL:
    02317       if (nextPtr) {
    02318         *nextPtr = s;
    02319         return XML_ERROR_NONE;
    02320       }
    02321       return XML_ERROR_UNCLOSED_TOKEN;
    02322     case XML_TOK_PARTIAL_CHAR:
    02323       if (nextPtr) {
    02324         *nextPtr = s;
    02325         return XML_ERROR_NONE;
    02326       }
    02327       return XML_ERROR_PARTIAL_CHAR;
    02328     default:
    02329       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
    02330     }
    02331     eventPtr = s = next;
    02332   }
    02333 }
    02334
    02335 static enum XML_Error
    02336 storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
    02337                     const char *ptr, const char *end,
    02338                     STRING_POOL *pool)
    02339 {
    02340   enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
    02341   if (result)
    02342     return result;
    02343   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
    02344     poolChop(pool);
    02345   if (!poolAppendChar(pool, XML_T('\0')))
    02346     return XML_ERROR_NO_MEMORY;
    02347   return XML_ERROR_NONE;
    02348 }
    02349
    02350 static enum XML_Error
    02351 appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
    02352                      const char *ptr, const char *end,
    02353                      STRING_POOL *pool)
    02354 {
    02355   const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
    02356   for (;;) {
    02357     const char *next;
    02358     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
    02359     switch (tok) {
    02360     case XML_TOK_NONE:
    02361       return XML_ERROR_NONE;
    02362     case XML_TOK_INVALID:
    02363       if (enc == encoding)
    02364         eventPtr = next;
    02365       return XML_ERROR_INVALID_TOKEN;
    02366     case XML_TOK_PARTIAL:
    02367       if (enc == encoding)
    02368         eventPtr = ptr;
    02369       return XML_ERROR_INVALID_TOKEN;
    02370     case XML_TOK_CHAR_REF:
    02371       {
    02372         XML_Char buf[XML_ENCODE_MAX];
    02373         int i;
    02374         int n = XmlCharRefNumber(enc, ptr);
    02375         if (n < 0) {
    02376           if (enc == encoding)
    02377             eventPtr = ptr;
    02378           return XML_ERROR_BAD_CHAR_REF;
    02379         }
    02380         if (!isCdata
    02381             && n == 0x20 /* space */
    02382             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
    02383           break;
    02384         n = XmlEncode(n, (ICHAR *)buf);
    02385         if (!n) {
    02386           if (enc == encoding)
    02387             eventPtr = ptr;
    02388           return XML_ERROR_BAD_CHAR_REF;
    02389         }
    02390         for (i = 0; i < n; i++) {
    02391           if (!poolAppendChar(pool, buf[i]))
    02392             return XML_ERROR_NO_MEMORY;
    02393         }
    02394       }
    02395       break;
    02396     case XML_TOK_DATA_CHARS:
    02397       if (!poolAppend(pool, enc, ptr, next))
    02398         return XML_ERROR_NO_MEMORY;
    02399       break;
    02400       break;
    02401     case XML_TOK_TRAILING_CR:
    02402       next = ptr + enc->minBytesPerChar;
    02403       /* fall through */
    02404     case XML_TOK_ATTRIBUTE_VALUE_S:
    02405     case XML_TOK_DATA_NEWLINE:
    02406       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
    02407         break;
    02408       if (!poolAppendChar(pool, 0x20))
    02409         return XML_ERROR_NO_MEMORY;
    02410       break;
    02411     case XML_TOK_ENTITY_REF:
    02412       {
    02413         const XML_Char *name;
    02414         ENTITY *entity;
    02415         XML_Char ch = XmlPredefinedEntityName(enc,
    02416                                               ptr + enc->minBytesPerChar,
    02417                                               next - enc->minBytesPerChar);
    02418         if (ch) {
    02419           if (!poolAppendChar(pool, ch))
    02420             return XML_ERROR_NO_MEMORY;
    02421           break;
    02422         }
    02423         name = poolStoreString(&temp2Pool, enc,
    02424                                ptr + enc->minBytesPerChar,
    02425                                next - enc->minBytesPerChar);
    02426         if (!name)
    02427           return XML_ERROR_NO_MEMORY;
    02428         entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
    02429         poolDiscard(&temp2Pool);
    02430         if (!entity) {
    02431           if (dtd.complete) {
    02432             if (enc == encoding)
    02433               eventPtr = ptr;
    02434             return XML_ERROR_UNDEFINED_ENTITY;
    02435           }
    02436         }
    02437         else if (entity->open) {
    02438           if (enc == encoding)
    02439             eventPtr = ptr;
    02440           return XML_ERROR_RECURSIVE_ENTITY_REF;
    02441         }
    02442         else if (entity->notation) {
    02443           if (enc == encoding)
    02444             eventPtr = ptr;
    02445           return XML_ERROR_BINARY_ENTITY_REF;
    02446         }
    02447         else if (!entity->textPtr) {
    02448           if (enc == encoding)
    02449             eventPtr = ptr;
    02450           return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
    02451         }
    02452         else {
    02453           enum XML_Error result;
    02454           const XML_Char *textEnd = entity->textPtr + entity->textLen;
    02455           entity->open = 1;
    02456           result = appendAttributeValue(parser, internalEnc, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
    02457           entity->open = 0;
    02458           if (result)
    02459             return result;
    02460         }
    02461       }
    02462       break;
    02463     default:
    02464       abort();
    02465     }
    02466     ptr = next;
    02467   }
    02468   /* not reached */
    02469 }
    02470
    02471 static
    02472 enum XML_Error storeEntityValue(XML_Parser parser,
    02473                                 const char *entityTextPtr,
    02474                                 const char *entityTextEnd)
    02475 {
    02476   STRING_POOL *pool = &(dtd.pool);
    02477   entityTextPtr += encoding->minBytesPerChar;
    02478   entityTextEnd -= encoding->minBytesPerChar;
    02479   for (;;) {
    02480     const char *next;
    02481     int tok = XmlEntityValueTok(encoding, entityTextPtr, entityTextEnd, &next);
    02482     switch (tok) {
    02483     case XML_TOK_PARAM_ENTITY_REF:
    02484       eventPtr = entityTextPtr;
    02485       return XML_ERROR_SYNTAX;
    02486     case XML_TOK_NONE:
    02487       if (declEntity) {
    02488         declEntity->textPtr = pool->start;
    02489         declEntity->textLen = pool->ptr - pool->start;
    02490         poolFinish(pool);
    02491       }
    02492       else
    02493         poolDiscard(pool);
    02494       return XML_ERROR_NONE;
    02495     case XML_TOK_ENTITY_REF:
    02496     case XML_TOK_DATA_CHARS:
    02497       if (!poolAppend(pool, encoding, entityTextPtr, next))
    02498         return XML_ERROR_NO_MEMORY;
    02499       break;
    02500     case XML_TOK_TRAILING_CR:
    02501       next = entityTextPtr + encoding->minBytesPerChar;
    02502       /* fall through */
    02503     case XML_TOK_DATA_NEWLINE:
    02504       if (pool->end == pool->ptr && !poolGrow(pool))
    02505         return XML_ERROR_NO_MEMORY;
    02506       *(pool->ptr)++ = 0xA;
    02507       break;
    02508     case XML_TOK_CHAR_REF:
    02509       {
    02510         XML_Char buf[XML_ENCODE_MAX];
    02511         int i;
    02512         int n = XmlCharRefNumber(encoding, entityTextPtr);
    02513         if (n < 0) {
    02514           eventPtr = entityTextPtr;
    02515           return XML_ERROR_BAD_CHAR_REF;
    02516         }
    02517         n = XmlEncode(n, (ICHAR *)buf);
    02518         if (!n) {
    02519           eventPtr = entityTextPtr;
    02520           return XML_ERROR_BAD_CHAR_REF;
    02521         }
    02522         for (i = 0; i < n; i++) {
    02523           if (pool->end == pool->ptr && !poolGrow(pool))
    02524             return XML_ERROR_NO_MEMORY;
    02525           *(pool->ptr)++ = buf[i];
    02526         }
    02527       }
    02528       break;
    02529     case XML_TOK_PARTIAL:
    02530       eventPtr = entityTextPtr;
    02531       return XML_ERROR_INVALID_TOKEN;
    02532     case XML_TOK_INVALID:
    02533       eventPtr = next;
    02534       return XML_ERROR_INVALID_TOKEN;
    02535     default:
    02536       abort();
    02537     }
    02538     entityTextPtr = next;
    02539   }
    02540   /* not reached */
    02541 }
    02542
    02543 static void
    02544 normalizeLines(XML_Char *s)
    02545 {
    02546   XML_Char *p;
    02547   for (;; s++) {
    02548     if (*s == XML_T('\0'))
    02549       return;
    02550     if (*s == 0xD)
    02551       break;
    02552   }
    02553   p = s;
    02554   do {
    02555     if (*s == 0xD) {
    02556       *p++ = 0xA;
    02557       if (*++s == 0xA)
    02558         s++;
    02559     }
    02560     else
    02561       *p++ = *s++;
    02562   } while (*s);
    02563   *p = XML_T('\0');
    02564 }
    02565
    02566 static int
    02567 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
    02568 {
    02569   const XML_Char *target;
    02570   XML_Char *data;
    02571   const char *tem;
    02572   if (!processingInstructionHandler) {
    02573     if (defaultHandler)
    02574       reportDefault(parser, enc, start, end);
    02575     return 1;
    02576   }
    02577   start += enc->minBytesPerChar * 2;
    02578   tem = start + XmlNameLength(enc, start);
    02579   target = poolStoreString(&tempPool, enc, start, tem);
    02580   if (!target)
    02581     return 0;
    02582   poolFinish(&tempPool);
    02583   data = poolStoreString(&tempPool, enc,
    02584                         XmlSkipS(enc, tem),
    02585                         end - enc->minBytesPerChar*2);
    02586   if (!data)
    02587     return 0;
    02588   normalizeLines(data);
    02589   processingInstructionHandler(handlerArg, target, data);
    02590   poolClear(&tempPool);
    02591   return 1;
    02592 }
    02593
    02594 static int
    02595 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
    02596 {
    02597   XML_Char *data;
    02598   if (!commentHandler) {
    02599     if (defaultHandler)
    02600       reportDefault(parser, enc, start, end);
    02601     return 1;
    02602   }
    02603   data = poolStoreString(&tempPool,
    02604                          enc,
    02605                          start + enc->minBytesPerChar * 4,
    02606                          end - enc->minBytesPerChar * 3);
    02607   if (!data)
    02608     return 0;
    02609   normalizeLines(data);
    02610   commentHandler(handlerArg, data);
    02611   poolClear(&tempPool);
    02612   return 1;
    02613 }
    02614
    02615 static void
    02616 reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
    02617 {
    02618   if (MUST_CONVERT(enc, s)) {
    02619     const char **eventPP;
    02620     const char **eventEndPP;
    02621     if (enc == encoding) {
    02622       eventPP = &eventPtr;
    02623       eventEndPP = &eventEndPtr;
    02624     }
    02625     else {
    02626       eventPP = &(openInternalEntities->internalEventPtr);
    02627       eventEndPP = &(openInternalEntities->internalEventEndPtr);
    02628     }
    02629     do {
    02630       ICHAR *dataPtr = (ICHAR *)dataBuf;
    02631       XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
    02632       *eventEndPP = s;
    02633       defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
    02634       *eventPP = s;
    02635     } while (s != end);
    02636   }
    02637   else
    02638     defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
    02639 }
    02640
    02641
    02642 static int
    02643 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value)
    02644 {
    02645   DEFAULT_ATTRIBUTE *att;
    02646   if (type->nDefaultAtts == type->allocDefaultAtts) {
    02647     if (type->allocDefaultAtts == 0) {
    02648       type->allocDefaultAtts = 8;
    02649       type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
    02650     }
    02651     else {
    02652       type->allocDefaultAtts *= 2;
    02653       type->defaultAtts = realloc(type->defaultAtts,
    02654                                   type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
    02655     }
    02656     if (!type->defaultAtts)
    02657       return 0;
    02658   }
    02659   att = type->defaultAtts + type->nDefaultAtts;
    02660   att->id = attId;
    02661   att->value = value;
    02662   att->isCdata = isCdata;
    02663   if (!isCdata)
    02664     attId->maybeTokenized = 1;
    02665   type->nDefaultAtts += 1;
    02666   return 1;
    02667 }
    02668
    02669 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
    02670 {
    02671   const XML_Char *name;
    02672   for (name = elementType->name; *name; name++) {
    02673     if (*name == XML_T(':')) {
    02674       PREFIX *prefix;
    02675       const XML_Char *s;
    02676       for (s = elementType->name; s != name; s++) {
    02677         if (!poolAppendChar(&dtd.pool, *s))
    02678           return 0;
    02679       }
    02680       if (!poolAppendChar(&dtd.pool, XML_T('\0')))
    02681         return 0;
    02682       prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
    02683       if (!prefix)
    02684         return 0;
    02685       if (prefix->name == poolStart(&dtd.pool))
    02686         poolFinish(&dtd.pool);
    02687       else
    02688         poolDiscard(&dtd.pool);
    02689       elementType->prefix = prefix;
    02690
    02691     }
    02692   }
    02693   return 1;
    02694 }
    02695
    02696 static ATTRIBUTE_ID *
    02697 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
    02698 {
    02699   ATTRIBUTE_ID *id;
    02700   const XML_Char *name;
    02701   if (!poolAppendChar(&dtd.pool, XML_T('\0')))
    02702     return 0;
    02703   name = poolStoreString(&dtd.pool, enc, start, end);
    02704   if (!name)
    02705     return 0;
    02706   ++name;
    02707   id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
    02708   if (!id)
    02709     return 0;
    02710   if (id->name != name)
    02711     poolDiscard(&dtd.pool);
    02712   else {
    02713     poolFinish(&dtd.pool);
    02714     if (!ns)
    02715       ;
    02716     else if (name[0] == 'x'
    02717         && name[1] == 'm'
    02718         && name[2] == 'l'
    02719         && name[3] == 'n'
    02720         && name[4] == 's'
    02721         && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
    02722       if (name[5] == '\0')
    02723         id->prefix = &dtd.defaultPrefix;
    02724       else
    02725         id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
    02726       id->xmlns = 1;
    02727     }
    02728     else {
    02729       int i;
    02730       for (i = 0; name[i]; i++) {
    02731         if (name[i] == XML_T(':')) {
    02732           int j;
    02733           for (j = 0; j < i; j++) {
    02734             if (!poolAppendChar(&dtd.pool, name[j]))
    02735               return 0;
    02736           }
    02737           if (!poolAppendChar(&dtd.pool, XML_T('\0')))
    02738             return 0;
    02739           id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
    02740           if (id->prefix->name == poolStart(&dtd.pool))
    02741             poolFinish(&dtd.pool);
    02742           else
    02743             poolDiscard(&dtd.pool);
    02744           break;
    02745         }
    02746       }
    02747     }
    02748   }
    02749   return id;
    02750 }
    02751
    02752 #define CONTEXT_SEP XML_T('\f')
    02753
    02754 static
    02755 const XML_Char *getContext(XML_Parser parser)
    02756 {
    02757   HASH_TABLE_ITER iter;
    02758   int needSep = 0;
    02759
    02760   if (dtd.defaultPrefix.binding) {
    02761     int i;
    02762     int len;
    02763     if (!poolAppendChar(&tempPool, XML_T('=')))
    02764       return 0;
    02765     len = dtd.defaultPrefix.binding->uriLen;
    02766     if (namespaceSeparator != XML_T('\0'))
    02767       len--;
    02768     for (i = 0; i < len; i++)
    02769       if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
    02770         return 0;
    02771     needSep = 1;
    02772   }
    02773
    02774   hashTableIterInit(&iter, &(dtd.prefixes));
    02775   for (;;) {
    02776     int i;
    02777     int len;
    02778     const XML_Char *s;
    02779     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
    02780     if (!prefix)
    02781       break;
    02782     if (!prefix->binding)
    02783       continue;
    02784     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
    02785       return 0;
    02786     for (s = prefix->name; *s; s++)
    02787       if (!poolAppendChar(&tempPool, *s))
    02788         return 0;
    02789     if (!poolAppendChar(&tempPool, XML_T('=')))
    02790       return 0;
    02791     len = prefix->binding->uriLen;
    02792     if (namespaceSeparator != XML_T('\0'))
    02793       len--;
    02794     for (i = 0; i < len; i++)
    02795       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
    02796         return 0;
    02797     needSep = 1;
    02798   }
    02799
    02800
    02801   hashTableIterInit(&iter, &(dtd.generalEntities));
    02802   for (;;) {
    02803     const XML_Char *s;
    02804     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
    02805     if (!e)
    02806       break;
    02807     if (!e->open)
    02808       continue;
    02809     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
    02810       return 0;
    02811     for (s = e->name; *s; s++)
    02812       if (!poolAppendChar(&tempPool, *s))
    02813         return 0;
    02814     needSep = 1;
    02815   }
    02816
    02817   if (!poolAppendChar(&tempPool, XML_T('\0')))
    02818     return 0;
    02819   return tempPool.start;
    02820 }
    02821
    02822 static
    02823 int setContext(XML_Parser parser, const XML_Char *context)
    02824 {
    02825   const XML_Char *s = context;
    02826
    02827   while (*context != XML_T('\0')) {
    02828     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
    02829       ENTITY *e;
    02830       if (!poolAppendChar(&tempPool, XML_T('\0')))
    02831         return 0;
    02832       e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
    02833       if (e)
    02834         e->open = 1;
    02835       if (*s != XML_T('\0'))
    02836         s++;
    02837       context = s;
    02838       poolDiscard(&tempPool);
    02839     }
    02840     else if (*s == '=') {
    02841       PREFIX *prefix;
    02842       if (poolLength(&tempPool) == 0)
    02843         prefix = &dtd.defaultPrefix;
    02844       else {
    02845         if (!poolAppendChar(&tempPool, XML_T('\0')))
    02846           return 0;
    02847         prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
    02848         if (!prefix)
    02849           return 0;
    02850         if (prefix->name == poolStart(&tempPool))
    02851           poolFinish(&tempPool);
    02852         else
    02853           poolDiscard(&tempPool);
    02854       }
    02855       for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
    02856         if (!poolAppendChar(&tempPool, *context))
    02857           return 0;
    02858       if (!poolAppendChar(&tempPool, XML_T('\0')))
    02859         return 0;
    02860       if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
    02861         return 0;
    02862       poolDiscard(&tempPool);
    02863       if (*context != XML_T('\0'))
    02864         ++context;
    02865       s = context;
    02866     }
    02867     else {
    02868       if (!poolAppendChar(&tempPool, *s))
    02869         return 0;
    02870       s++;
    02871     }
    02872   }
    02873   return 1;
    02874 }
    02875
    02876
    02877 static
    02878 void normalizePublicId(XML_Char *publicId)
    02879 {
    02880   XML_Char *p = publicId;
    02881   XML_Char *s;
    02882   for (s = publicId; *s; s++) {
    02883     switch (*s) {
    02884     case 0x20:
    02885     case 0xD:
    02886     case 0xA:
    02887       if (p != publicId && p[-1] != 0x20)
    02888         *p++ = 0x20;
    02889       break;
    02890     default:
    02891       *p++ = *s;
    02892     }
    02893   }
    02894   if (p != publicId && p[-1] == 0x20)
    02895     --p;
    02896   *p = XML_T('\0');
    02897 }
    02898
    02899 static int dtdInit(DTD *p)
    02900 {
    02901   poolInit(&(p->pool));
    02902   hashTableInit(&(p->generalEntities));
    02903   hashTableInit(&(p->elementTypes));
    02904   hashTableInit(&(p->attributeIds));
    02905   hashTableInit(&(p->prefixes));
    02906   p->complete = 1;
    02907   p->standalone = 0;
    02908   p->base = 0;
    02909   p->defaultPrefix.name = 0;
    02910   p->defaultPrefix.binding = 0;
    02911   return 1;
    02912 }
    02913
    02914 static void dtdDestroy(DTD *p)
    02915 {
    02916   HASH_TABLE_ITER iter;
    02917   hashTableIterInit(&iter, &(p->elementTypes));
    02918   for (;;) {
    02919     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
    02920     if (!e)
    02921       break;
    02922     if (e->allocDefaultAtts != 0)
    02923       free(e->defaultAtts);
    02924   }
    02925   hashTableDestroy(&(p->generalEntities));
    02926   hashTableDestroy(&(p->elementTypes));
    02927   hashTableDestroy(&(p->attributeIds));
    02928   hashTableDestroy(&(p->prefixes));
    02929   poolDestroy(&(p->pool));
    02930 }
    02931
    02932 /* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
    02933 The new DTD has already been initialized. */
    02934
    02935 static int dtdCopy(DTD *newDtd, const DTD *oldDtd)
    02936 {
    02937   HASH_TABLE_ITER iter;
    02938
    02939   if (oldDtd->base) {
    02940     const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->base);
    02941     if (!tem)
    02942       return 0;
    02943     newDtd->base = tem;
    02944   }
    02945
    02946   /* Copy the prefix table. */
    02947
    02948   hashTableIterInit(&iter, &(oldDtd->prefixes));
    02949   for (;;) {
    02950     const XML_Char *name;
    02951     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
    02952     if (!oldP)
    02953       break;
    02954     name = poolCopyString(&(newDtd->pool), oldP->name);
    02955     if (!name)
    02956       return 0;
    02957     if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
    02958       return 0;
    02959   }
    02960
    02961   hashTableIterInit(&iter, &(oldDtd->attributeIds));
    02962
    02963   /* Copy the attribute id table. */
    02964
    02965   for (;;) {
    02966     ATTRIBUTE_ID *newA;
    02967     const XML_Char *name;
    02968     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
    02969
    02970     if (!oldA)
    02971       break;
    02972     /* Remember to allocate the scratch byte before the name. */
    02973     if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
    02974       return 0;
    02975     name = poolCopyString(&(newDtd->pool), oldA->name);
    02976     if (!name)
    02977       return 0;
    02978     ++name;
    02979     newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
    02980     if (!newA)
    02981       return 0;
    02982     newA->maybeTokenized = oldA->maybeTokenized;
    02983     if (oldA->prefix) {
    02984       newA->xmlns = oldA->xmlns;
    02985       if (oldA->prefix == &oldDtd->defaultPrefix)
    02986         newA->prefix = &newDtd->defaultPrefix;
    02987       else
    02988         newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
    02989     }
    02990   }
    02991
    02992   /* Copy the element type table. */
    02993
    02994   hashTableIterInit(&iter, &(oldDtd->elementTypes));
    02995
    02996   for (;;) {
    02997     int i;
    02998     ELEMENT_TYPE *newE;
    02999     const XML_Char *name;
    03000     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
    03001     if (!oldE)
    03002       break;
    03003     name = poolCopyString(&(newDtd->pool), oldE->name);
    03004     if (!name)
    03005       return 0;
    03006     newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
    03007     if (!newE)
    03008       return 0;
    03009     if (oldE->nDefaultAtts) {
    03010       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
    03011       if (!newE->defaultAtts)
    03012         return 0;
    03013     }
    03014     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
    03015     if (oldE->prefix)
    03016       newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
    03017     for (i = 0; i < newE->nDefaultAtts; i++) {
    03018       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
    03019       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
    03020       if (oldE->defaultAtts[i].value) {
    03021         newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
    03022         if (!newE->defaultAtts[i].value)
    03023           return 0;
    03024       }
    03025       else
    03026         newE->defaultAtts[i].value = 0;
    03027     }
    03028   }
    03029
    03030   /* Copy the entity table. */
    03031
    03032   hashTableIterInit(&iter, &(oldDtd->generalEntities));
    03033
    03034   for (;;) {
    03035     ENTITY *newE;
    03036     const XML_Char *name;
    03037     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
    03038     if (!oldE)
    03039       break;
    03040     name = poolCopyString(&(newDtd->pool), oldE->name);
    03041     if (!name)
    03042       return 0;
    03043     newE = (ENTITY *)lookup(&(newDtd->generalEntities), name, sizeof(ENTITY));
    03044     if (!newE)
    03045       return 0;
    03046     if (oldE->systemId) {
    03047       const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->systemId);
    03048       if (!tem)
    03049         return 0;
    03050       newE->systemId = tem;
    03051       if (oldE->base) {
    03052         if (oldE->base == oldDtd->base)
    03053           newE->base = newDtd->base;
    03054         tem = poolCopyString(&(newDtd->pool), oldE->base);
    03055         if (!tem)
    03056           return 0;
    03057         newE->base = tem;
    03058       }
    03059     }
    03060     else {
    03061       const XML_Char *tem = poolCopyStringN(&(newDtd->pool), oldE->textPtr, oldE->textLen);
    03062       if (!tem)
    03063         return 0;
    03064       newE->textPtr = tem;
    03065       newE->textLen = oldE->textLen;
    03066     }
    03067     if (oldE->notation) {
    03068       const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->notation);
    03069       if (!tem)
    03070         return 0;
    03071       newE->notation = tem;
    03072     }
    03073   }
    03074
    03075   newDtd->complete = oldDtd->complete;
    03076   newDtd->standalone = oldDtd->standalone;
    03077   return 1;
    03078 }
    03079
    03080 static
    03081 void poolInit(STRING_POOL *pool)
    03082 {
    03083   pool->blocks = 0;
    03084   pool->freeBlocks = 0;
    03085   pool->start = 0;
    03086   pool->ptr = 0;
    03087   pool->end = 0;
    03088 }
    03089
    03090 static
    03091 void poolClear(STRING_POOL *pool)
    03092 {
    03093   if (!pool->freeBlocks)
    03094     pool->freeBlocks = pool->blocks;
    03095   else {
    03096     BLOCK *p = pool->blocks;
    03097     while (p) {
    03098       BLOCK *tem = p->next;
    03099       p->next = pool->freeBlocks;
    03100       pool->freeBlocks = p;
    03101       p = tem;
    03102     }
    03103   }
    03104   pool->blocks = 0;
    03105   pool->start = 0;
    03106   pool->ptr = 0;
    03107   pool->end = 0;
    03108 }
    03109
    03110 static
    03111 void poolDestroy(STRING_POOL *pool)
    03112 {
    03113   BLOCK *p = pool->blocks;
    03114   while (p) {
    03115     BLOCK *tem = p->next;
    03116     free(p);
    03117     p = tem;
    03118   }
    03119   pool->blocks = 0;
    03120   p = pool->freeBlocks;
    03121   while (p) {
    03122     BLOCK *tem = p->next;
    03123     free(p);
    03124     p = tem;
    03125   }
    03126   pool->freeBlocks = 0;
    03127   pool->ptr = 0;
    03128   pool->start = 0;
    03129   pool->end = 0;
    03130 }
    03131
    03132 static
    03133 XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
    03134                      const char *ptr, const char *end)
    03135 {
    03136   if (!pool->ptr && !poolGrow(pool))
    03137     return 0;
    03138   for (;;) {
    03139     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
    03140     if (ptr == end)
    03141       break;
    03142     if (!poolGrow(pool))
    03143       return 0;
    03144   }
    03145   return pool->start;
    03146 }
    03147
    03148 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
    03149 {
    03150   do {
    03151     if (!poolAppendChar(pool, *s))
    03152       return 0;
    03153   } while (*s++);
    03154   s = pool->start;
    03155   poolFinish(pool);
    03156   return s;
    03157 }
    03158
    03159 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
    03160 {
    03161   if (!pool->ptr && !poolGrow(pool))
    03162     return 0;
    03163   for (; n > 0; --n, s++) {
    03164     if (!poolAppendChar(pool, *s))
    03165       return 0;
    03166
    03167   }
    03168   s = pool->start;
    03169   poolFinish(pool);
    03170   return s;
    03171 }
    03172
    03173 static
    03174 XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
    03175                           const char *ptr, const char *end)
    03176 {
    03177   if (!poolAppend(pool, enc, ptr, end))
    03178     return 0;
    03179   if (pool->ptr == pool->end && !poolGrow(pool))
    03180     return 0;
    03181   *(pool->ptr)++ = 0;
    03182   return pool->start;
    03183 }
    03184
    03185 static
    03186 int poolGrow(STRING_POOL *pool)
    03187 {
    03188   if (pool->freeBlocks) {
    03189     if (pool->start == 0) {
    03190       pool->blocks = pool->freeBlocks;
    03191       pool->freeBlocks = pool->freeBlocks->next;
    03192       pool->blocks->next = 0;
    03193       pool->start = pool->blocks->s;
    03194       pool->end = pool->start + pool->blocks->size;
    03195       pool->ptr = pool->start;
    03196       return 1;
    03197     }
    03198     if (pool->end - pool->start < pool->freeBlocks->size) {
    03199       BLOCK *tem = pool->freeBlocks->next;
    03200       pool->freeBlocks->next = pool->blocks;
    03201       pool->blocks = pool->freeBlocks;
    03202       pool->freeBlocks = tem;
    03203       memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
    03204       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
    03205       pool->start = pool->blocks->s;
    03206       pool->end = pool->start + pool->blocks->size;
    03207       return 1;
    03208     }
    03209   }
    03210   if (pool->blocks && pool->start == pool->blocks->s) {
    03211     int blockSize = (pool->end - pool->start)*2;
    03212     pool->blocks = realloc(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
    03213     if (!pool->blocks)
    03214       return 0;
    03215     pool->blocks->size = blockSize;
    03216     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
    03217     pool->start = pool->blocks->s;
    03218     pool->end = pool->start + blockSize;
    03219   }
    03220   else {
    03221     BLOCK *tem;
    03222     int blockSize = pool->end - pool->start;
    03223     if (blockSize < INIT_BLOCK_SIZE)
    03224       blockSize = INIT_BLOCK_SIZE;
    03225     else
    03226       blockSize *= 2;
    03227     tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
    03228     if (!tem)
    03229       return 0;
    03230     tem->size = blockSize;
    03231     tem->next = pool->blocks;
    03232     pool->blocks = tem;
    03233     memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
    03234     pool->ptr = tem->s + (pool->ptr - pool->start);
    03235     pool->start = tem->s;
    03236     pool->end = tem->s + blockSize;
    03237   }
    03238   return 1;
    03239 }

@ 1.3 log @Oops, try again. @ text @d3248 1 a3248 1