Jabber WindowGram Client (JWGC)

Introduction Screenshots Installation Downloads
Documentation Browse Source Resources Project Site

Stable Version
-none-

Latest Version
beta5



Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

xmlparse.c

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
00003 See the file COPYING for copying permission.
00004 */
00005 
00006 
00007 #ifdef COMPILED_FROM_DSP
00008 #  include "winconfig.h"
00009 #  define XMLPARSEAPI __declspec(dllexport)
00010 #  include "expat.h"
00011 #  undef XMLPARSEAPI
00012 #else
00013 #include <config.h>
00014 
00015 #ifdef __declspec
00016 #  define XMLPARSEAPI __declspec(dllexport)
00017 #endif
00018 
00019 #include "expat.h"
00020 
00021 #ifdef __declspec
00022 #  undef XMLPARSEAPI
00023 #endif
00024 #endif /* ndef COMPILED_FROM_DSP */
00025 
00026 #include <stddef.h>
00027 
00028 #ifdef XML_UNICODE
00029 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
00030 #define XmlConvert XmlUtf16Convert
00031 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
00032 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
00033 #define XmlEncode XmlUtf16Encode
00034 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
00035 typedef unsigned short ICHAR;
00036 #else
00037 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
00038 #define XmlConvert XmlUtf8Convert
00039 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
00040 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
00041 #define XmlEncode XmlUtf8Encode
00042 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
00043 typedef char ICHAR;
00044 #endif
00045 
00046 
00047 #ifndef XML_NS
00048 
00049 #define XmlInitEncodingNS XmlInitEncoding
00050 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
00051 #undef XmlGetInternalEncodingNS
00052 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
00053 #define XmlParseXmlDeclNS XmlParseXmlDecl
00054 
00055 #endif
00056 
00057 #ifdef XML_UNICODE_WCHAR_T
00058 #define XML_T(x) L ## x
00059 #else
00060 #define XML_T(x) x
00061 #endif
00062 
00063 /* Round up n to be a multiple of sz, where sz is a power of 2. */
00064 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
00065 
00066 #include "xmltok.h"
00067 #include "xmlrole.h"
00068 
00069 typedef const XML_Char *KEY;
00070 
00071 typedef struct {
00072   KEY name;
00073 } NAMED;
00074 
00075 typedef struct {
00076   NAMED **v;
00077   size_t size;
00078   size_t used;
00079   size_t usedLim;
00080   XML_Memory_Handling_Suite *mem;
00081 } HASH_TABLE;
00082 
00083 typedef struct {
00084   NAMED **p;
00085   NAMED **end;
00086 } HASH_TABLE_ITER;
00087 
00088 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
00089 #define INIT_DATA_BUF_SIZE 1024
00090 #define INIT_ATTS_SIZE 16
00091 #define INIT_BLOCK_SIZE 1024
00092 #define INIT_BUFFER_SIZE 1024
00093 
00094 #define EXPAND_SPARE 24
00095 
00096 typedef struct binding {
00097   struct prefix *prefix;
00098   struct binding *nextTagBinding;
00099   struct binding *prevPrefixBinding;
00100   const struct attribute_id *attId;
00101   XML_Char *uri;
00102   int uriLen;
00103   int uriAlloc;
00104 } BINDING;
00105 
00106 typedef struct prefix {
00107   const XML_Char *name;
00108   BINDING *binding;
00109 } PREFIX;
00110 
00111 typedef struct {
00112   const XML_Char *str;
00113   const XML_Char *localPart;
00114   int uriLen;
00115 } TAG_NAME;
00116 
00117 typedef struct tag {
00118   struct tag *parent;
00119   const char *rawName;
00120   int rawNameLength;
00121   TAG_NAME name;
00122   char *buf;
00123   char *bufEnd;
00124   BINDING *bindings;
00125 } TAG;
00126 
00127 typedef struct {
00128   const XML_Char *name;
00129   const XML_Char *textPtr;
00130   int textLen;
00131   const XML_Char *systemId;
00132   const XML_Char *base;
00133   const XML_Char *publicId;
00134   const XML_Char *notation;
00135   char open;
00136   char is_param;
00137 } ENTITY;
00138 
00139 typedef struct {
00140   enum XML_Content_Type         type;
00141   enum XML_Content_Quant        quant;
00142   const XML_Char *              name;
00143   int                           firstchild;
00144   int                           lastchild;
00145   int                           childcnt;
00146   int                           nextsib;
00147 } CONTENT_SCAFFOLD;
00148 
00149 typedef struct block {
00150   struct block *next;
00151   int size;
00152   XML_Char s[1];
00153 } BLOCK;
00154 
00155 typedef struct {
00156   BLOCK *blocks;
00157   BLOCK *freeBlocks;
00158   const XML_Char *end;
00159   XML_Char *ptr;
00160   XML_Char *start;
00161   XML_Memory_Handling_Suite *mem;
00162 } STRING_POOL;
00163 
00164 /* The XML_Char before the name is used to determine whether
00165 an attribute has been specified. */
00166 typedef struct attribute_id {
00167   XML_Char *name;
00168   PREFIX *prefix;
00169   char maybeTokenized;
00170   char xmlns;
00171 } ATTRIBUTE_ID;
00172 
00173 typedef struct {
00174   const ATTRIBUTE_ID *id;
00175   char isCdata;
00176   const XML_Char *value;
00177 } DEFAULT_ATTRIBUTE;
00178 
00179 typedef struct {
00180   const XML_Char *name;
00181   PREFIX *prefix;
00182   const ATTRIBUTE_ID *idAtt;
00183   int nDefaultAtts;
00184   int allocDefaultAtts;
00185   DEFAULT_ATTRIBUTE *defaultAtts;
00186 } ELEMENT_TYPE;
00187 
00188 typedef struct {
00189   HASH_TABLE generalEntities;
00190   HASH_TABLE elementTypes;
00191   HASH_TABLE attributeIds;
00192   HASH_TABLE prefixes;
00193   STRING_POOL pool;
00194   int complete;
00195   int standalone;
00196 #ifdef XML_DTD
00197   HASH_TABLE paramEntities;
00198 #endif /* XML_DTD */
00199   PREFIX defaultPrefix;
00200   /* === scaffolding for building content model === */
00201   int in_eldecl;
00202   CONTENT_SCAFFOLD *scaffold;
00203   unsigned contentStringLen;
00204   unsigned scaffSize;
00205   unsigned scaffCount;
00206   int scaffLevel;
00207   int *scaffIndex;
00208 } DTD;
00209 
00210 typedef struct open_internal_entity {
00211   const char *internalEventPtr;
00212   const char *internalEventEndPtr;
00213   struct open_internal_entity *next;
00214   ENTITY *entity;
00215 } OPEN_INTERNAL_ENTITY;
00216 
00217 typedef enum XML_Error Processor(XML_Parser parser,
00218                                  const char *start,
00219                                  const char *end,
00220                                  const char **endPtr);
00221 
00222 static Processor prologProcessor;
00223 static Processor prologInitProcessor;
00224 static Processor contentProcessor;
00225 static Processor cdataSectionProcessor;
00226 #ifdef XML_DTD
00227 static Processor ignoreSectionProcessor;
00228 #endif /* XML_DTD */
00229 static Processor epilogProcessor;
00230 static Processor errorProcessor;
00231 static Processor externalEntityInitProcessor;
00232 static Processor externalEntityInitProcessor2;
00233 static Processor externalEntityInitProcessor3;
00234 static Processor externalEntityContentProcessor;
00235 
00236 static enum XML_Error
00237 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
00238 static enum XML_Error
00239 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
00240 static enum XML_Error
00241 initializeEncoding(XML_Parser parser);
00242 static enum XML_Error
00243 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
00244          const char *end, int tok, const char *next, const char **nextPtr);
00245 static enum XML_Error
00246 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
00247           const char *start, const char *end, const char **endPtr);
00248 static enum XML_Error
00249 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
00250 #ifdef XML_DTD
00251 static enum XML_Error
00252 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
00253 #endif /* XML_DTD */
00254 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
00255                                 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
00256 static
00257 int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
00258 
00259 static int
00260 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
00261                 int isCdata, int isId, const XML_Char *dfltValue,
00262                 XML_Parser parser);
00263 
00264 static enum XML_Error
00265 storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
00266                     STRING_POOL *);
00267 static enum XML_Error
00268 appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
00269                     STRING_POOL *);
00270 static ATTRIBUTE_ID *
00271 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
00272 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
00273 static enum XML_Error
00274 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
00275 static int
00276 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
00277 static int
00278 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
00279 static void
00280 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
00281 
00282 static const XML_Char *getContext(XML_Parser parser);
00283 static int setContext(XML_Parser parser, const XML_Char *context);
00284 static void normalizePublicId(XML_Char *s);
00285 static int dtdInit(DTD *, XML_Parser parser);
00286 
00287 static void dtdDestroy(DTD *, XML_Parser parser);
00288 
00289 static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
00290 
00291 static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *,
00292                            XML_Parser parser);
00293 
00294 #ifdef XML_DTD
00295 static void dtdSwap(DTD *, DTD *);
00296 #endif /* XML_DTD */
00297 
00298 static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
00299 
00300 static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
00301 
00302 static void hashTableDestroy(HASH_TABLE *);
00303 static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
00304 static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
00305 static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
00306 static void poolClear(STRING_POOL *);
00307 static void poolDestroy(STRING_POOL *);
00308 static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
00309                             const char *ptr, const char *end);
00310 static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
00311                                   const char *ptr, const char *end);
00312 
00313 static int poolGrow(STRING_POOL *pool);
00314 
00315 static int nextScaffoldPart(XML_Parser parser);
00316 static XML_Content *build_model(XML_Parser parser);
00317 
00318 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
00319 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
00320 static const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s);
00321 static ELEMENT_TYPE * getElementType(XML_Parser Paraser,
00322                                      const ENCODING *enc,
00323                                      const char *ptr,
00324                                      const char *end);
00325 
00326 #define poolStart(pool) ((pool)->start)
00327 #define poolEnd(pool) ((pool)->ptr)
00328 #define poolLength(pool) ((pool)->ptr - (pool)->start)
00329 #define poolChop(pool) ((void)--(pool->ptr))
00330 #define poolLastChar(pool) (((pool)->ptr)[-1])
00331 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
00332 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
00333 #define poolAppendChar(pool, c) \
00334   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
00335    ? 0 \
00336    : ((*((pool)->ptr)++ = c), 1))
00337 
00338 typedef struct {
00339   /* The first member must be userData so that the XML_GetUserData macro works. */
00340   void *m_userData;
00341   void *m_handlerArg;
00342   char *m_buffer;
00343   XML_Memory_Handling_Suite m_mem;
00344   /* first character to be parsed */
00345   const char *m_bufferPtr;
00346   /* past last character to be parsed */
00347   char *m_bufferEnd;
00348   /* allocated end of buffer */
00349   const char *m_bufferLim;
00350   long m_parseEndByteIndex;
00351   const char *m_parseEndPtr;
00352   XML_Char *m_dataBuf;
00353   XML_Char *m_dataBufEnd;
00354   XML_StartElementHandler m_startElementHandler;
00355   XML_EndElementHandler m_endElementHandler;
00356   XML_CharacterDataHandler m_characterDataHandler;
00357   XML_ProcessingInstructionHandler m_processingInstructionHandler;
00358   XML_CommentHandler m_commentHandler;
00359   XML_StartCdataSectionHandler m_startCdataSectionHandler;
00360   XML_EndCdataSectionHandler m_endCdataSectionHandler;
00361   XML_DefaultHandler m_defaultHandler;
00362   XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
00363   XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
00364   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
00365   XML_NotationDeclHandler m_notationDeclHandler;
00366   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
00367   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
00368   XML_NotStandaloneHandler m_notStandaloneHandler;
00369   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
00370   void *m_externalEntityRefHandlerArg;
00371   XML_UnknownEncodingHandler m_unknownEncodingHandler;
00372   XML_ElementDeclHandler m_elementDeclHandler;
00373   XML_AttlistDeclHandler m_attlistDeclHandler;
00374   XML_EntityDeclHandler m_entityDeclHandler;
00375   XML_XmlDeclHandler m_xmlDeclHandler;
00376   const ENCODING *m_encoding;
00377   INIT_ENCODING m_initEncoding;
00378   const ENCODING *m_internalEncoding;
00379   const XML_Char *m_protocolEncodingName;
00380   int m_ns;
00381   int m_ns_triplets;
00382   void *m_unknownEncodingMem;
00383   void *m_unknownEncodingData;
00384   void *m_unknownEncodingHandlerData;
00385   void (*m_unknownEncodingRelease)(void *);
00386   PROLOG_STATE m_prologState;
00387   Processor *m_processor;
00388   enum XML_Error m_errorCode;
00389   const char *m_eventPtr;
00390   const char *m_eventEndPtr;
00391   const char *m_positionPtr;
00392   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
00393   int m_defaultExpandInternalEntities;
00394   int m_tagLevel;
00395   ENTITY *m_declEntity;
00396   const XML_Char *m_doctypeName;
00397   const XML_Char *m_doctypeSysid;
00398   const XML_Char *m_doctypePubid;
00399   const XML_Char *m_declAttributeType;
00400   const XML_Char *m_declNotationName;
00401   const XML_Char *m_declNotationPublicId;
00402   ELEMENT_TYPE *m_declElementType;
00403   ATTRIBUTE_ID *m_declAttributeId;
00404   char m_declAttributeIsCdata;
00405   char m_declAttributeIsId;
00406   DTD m_dtd;
00407   const XML_Char *m_curBase;
00408   TAG *m_tagStack;
00409   TAG *m_freeTagList;
00410   BINDING *m_inheritedBindings;
00411   BINDING *m_freeBindingList;
00412   int m_attsSize;
00413   int m_nSpecifiedAtts;
00414   int m_idAttIndex;
00415   ATTRIBUTE *m_atts;
00416   POSITION m_position;
00417   STRING_POOL m_tempPool;
00418   STRING_POOL m_temp2Pool;
00419   char *m_groupConnector;
00420   unsigned m_groupSize;
00421   int m_hadExternalDoctype;
00422   XML_Char m_namespaceSeparator;
00423 #ifdef XML_DTD
00424   enum XML_ParamEntityParsing m_paramEntityParsing;
00425   XML_Parser m_parentParser;
00426 #endif
00427 } Parser;
00428 
00429 #define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
00430 #define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
00431 #define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
00432 
00433 #define userData (((Parser *)parser)->m_userData)
00434 #define handlerArg (((Parser *)parser)->m_handlerArg)
00435 #define startElementHandler (((Parser *)parser)->m_startElementHandler)
00436 #define endElementHandler (((Parser *)parser)->m_endElementHandler)
00437 #define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
00438 #define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
00439 #define commentHandler (((Parser *)parser)->m_commentHandler)
00440 #define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
00441 #define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
00442 #define defaultHandler (((Parser *)parser)->m_defaultHandler)
00443 #define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
00444 #define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
00445 #define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
00446 #define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
00447 #define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
00448 #define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
00449 #define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
00450 #define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
00451 #define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
00452 #define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
00453 #define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
00454 #define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
00455 #define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
00456 #define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
00457 #define encoding (((Parser *)parser)->m_encoding)
00458 #define initEncoding (((Parser *)parser)->m_initEncoding)
00459 #define internalEncoding (((Parser *)parser)->m_internalEncoding)
00460 #define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
00461 #define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
00462 #define unknownEncodingHandlerData \
00463   (((Parser *)parser)->m_unknownEncodingHandlerData)
00464 #define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
00465 #define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
00466 #define ns (((Parser *)parser)->m_ns)
00467 #define ns_triplets (((Parser *)parser)->m_ns_triplets)
00468 #define prologState (((Parser *)parser)->m_prologState)
00469 #define processor (((Parser *)parser)->m_processor)
00470 #define errorCode (((Parser *)parser)->m_errorCode)
00471 #define eventPtr (((Parser *)parser)->m_eventPtr)
00472 #define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
00473 #define positionPtr (((Parser *)parser)->m_positionPtr)
00474 #define position (((Parser *)parser)->m_position)
00475 #define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
00476 #define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
00477 #define tagLevel (((Parser *)parser)->m_tagLevel)
00478 #define buffer (((Parser *)parser)->m_buffer)
00479 #define bufferPtr (((Parser *)parser)->m_bufferPtr)
00480 #define bufferEnd (((Parser *)parser)->m_bufferEnd)
00481 #define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
00482 #define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
00483 #define bufferLim (((Parser *)parser)->m_bufferLim)
00484 #define dataBuf (((Parser *)parser)->m_dataBuf)
00485 #define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
00486 #define dtd (((Parser *)parser)->m_dtd)
00487 #define curBase (((Parser *)parser)->m_curBase)
00488 #define declEntity (((Parser *)parser)->m_declEntity)
00489 #define doctypeName (((Parser *)parser)->m_doctypeName)
00490 #define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
00491 #define doctypePubid (((Parser *)parser)->m_doctypePubid)
00492 #define declAttributeType (((Parser *)parser)->m_declAttributeType)
00493 #define declNotationName (((Parser *)parser)->m_declNotationName)
00494 #define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
00495 #define declElementType (((Parser *)parser)->m_declElementType)
00496 #define declAttributeId (((Parser *)parser)->m_declAttributeId)
00497 #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
00498 #define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
00499 #define freeTagList (((Parser *)parser)->m_freeTagList)
00500 #define freeBindingList (((Parser *)parser)->m_freeBindingList)
00501 #define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
00502 #define tagStack (((Parser *)parser)->m_tagStack)
00503 #define atts (((Parser *)parser)->m_atts)
00504 #define attsSize (((Parser *)parser)->m_attsSize)
00505 #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
00506 #define idAttIndex (((Parser *)parser)->m_idAttIndex)
00507 #define tempPool (((Parser *)parser)->m_tempPool)
00508 #define temp2Pool (((Parser *)parser)->m_temp2Pool)
00509 #define groupConnector (((Parser *)parser)->m_groupConnector)
00510 #define groupSize (((Parser *)parser)->m_groupSize)
00511 #define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
00512 #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
00513 #ifdef XML_DTD
00514 #define parentParser (((Parser *)parser)->m_parentParser)
00515 #define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
00516 #endif /* XML_DTD */
00517 
00518 #ifdef COMPILED_FROM_DSP
00519 BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p) {
00520   return TRUE;
00521 }
00522 #endif /* def COMPILED_FROM_DSP */
00523 
00524 #ifdef _MSC_VER
00525 #ifdef _DEBUG
00526 Parser *asParser(XML_Parser parser)
00527 {
00528   return parser;
00529 }
00530 #endif
00531 #endif
00532 
00533 XML_Parser XML_ParserCreate(const XML_Char *encodingName)
00534 {
00535   return XML_ParserCreate_MM(encodingName, NULL, NULL);
00536 }
00537 
00538 XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
00539 {
00540   XML_Char tmp[2];
00541   *tmp = nsSep;
00542   return XML_ParserCreate_MM(encodingName, NULL, tmp);
00543 }
00544 
00545 XML_Parser
00546 XML_ParserCreate_MM(const XML_Char *encodingName,
00547                     const XML_Memory_Handling_Suite *memsuite,
00548                     const XML_Char *nameSep) {
00549   
00550   XML_Parser parser;
00551   static
00552   const XML_Char implicitContext[] = {
00553     XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
00554     XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
00555     XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
00556     XML_T('.'), XML_T('w'), XML_T('3'),
00557     XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
00558     XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
00559     XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
00560     XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
00561     XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
00562     XML_T('\0')
00563   };
00564 
00565 
00566   if (memsuite) {
00567     XML_Memory_Handling_Suite *mtemp;
00568     parser = memsuite->malloc_fcn(sizeof(Parser));
00569     mtemp = &(((Parser *) parser)->m_mem);
00570     mtemp->malloc_fcn = memsuite->malloc_fcn;
00571     mtemp->realloc_fcn = memsuite->realloc_fcn;
00572     mtemp->free_fcn = memsuite->free_fcn;
00573   }
00574   else {
00575     XML_Memory_Handling_Suite *mtemp;
00576     parser = malloc(sizeof(Parser));
00577     mtemp = &(((Parser *) parser)->m_mem);
00578     mtemp->malloc_fcn = malloc;
00579     mtemp->realloc_fcn = realloc;
00580     mtemp->free_fcn = free;
00581   }
00582 
00583   if (!parser)
00584     return parser;
00585   processor = prologInitProcessor;
00586   XmlPrologStateInit(&prologState);
00587   userData = 0;
00588   handlerArg = 0;
00589   startElementHandler = 0;
00590   endElementHandler = 0;
00591   characterDataHandler = 0;
00592   processingInstructionHandler = 0;
00593   commentHandler = 0;
00594   startCdataSectionHandler = 0;
00595   endCdataSectionHandler = 0;
00596   defaultHandler = 0;
00597   startDoctypeDeclHandler = 0;
00598   endDoctypeDeclHandler = 0;
00599   unparsedEntityDeclHandler = 0;
00600   notationDeclHandler = 0;
00601   startNamespaceDeclHandler = 0;
00602   endNamespaceDeclHandler = 0;
00603   notStandaloneHandler = 0;
00604   externalEntityRefHandler = 0;
00605   externalEntityRefHandlerArg = parser;
00606   unknownEncodingHandler = 0;
00607   elementDeclHandler = 0;
00608   attlistDeclHandler = 0;
00609   entityDeclHandler = 0;
00610   xmlDeclHandler = 0;
00611   buffer = 0;
00612   bufferPtr = 0;
00613   bufferEnd = 0;
00614   parseEndByteIndex = 0;
00615   parseEndPtr = 0;
00616   bufferLim = 0;
00617   declElementType = 0;
00618   declAttributeId = 0;
00619   declEntity = 0;
00620   doctypeName = 0;
00621   doctypeSysid = 0;
00622   doctypePubid = 0;
00623   declAttributeType = 0;
00624   declNotationName = 0;
00625   declNotationPublicId = 0;
00626   memset(&position, 0, sizeof(POSITION));
00627   errorCode = XML_ERROR_NONE;
00628   eventPtr = 0;
00629   eventEndPtr = 0;
00630   positionPtr = 0;
00631   openInternalEntities = 0;
00632   tagLevel = 0;
00633   tagStack = 0;
00634   freeTagList = 0;
00635   freeBindingList = 0;
00636   inheritedBindings = 0;
00637   attsSize = INIT_ATTS_SIZE;
00638   atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
00639   nSpecifiedAtts = 0;
00640   dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
00641   groupSize = 0;
00642   groupConnector = 0;
00643   hadExternalDoctype = 0;
00644   unknownEncodingMem = 0;
00645   unknownEncodingRelease = 0;
00646   unknownEncodingData = 0;
00647   unknownEncodingHandlerData = 0;
00648   namespaceSeparator = '!';
00649 #ifdef XML_DTD
00650   parentParser = 0;
00651   paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
00652 #endif
00653   ns = 0;
00654   ns_triplets = 0;
00655   poolInit(&tempPool, &(((Parser *) parser)->m_mem));
00656   poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
00657   protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
00658   curBase = 0;
00659   if (!dtdInit(&dtd, parser) || !atts || !dataBuf
00660       || (encodingName && !protocolEncodingName)) {
00661     XML_ParserFree(parser);
00662     return 0;
00663   }
00664   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
00665 
00666   if (nameSep) {
00667     XmlInitEncodingNS(&initEncoding, &encoding, 0);
00668     ns = 1;
00669     internalEncoding = XmlGetInternalEncodingNS();
00670     namespaceSeparator = *nameSep;
00671 
00672     if (! setContext(parser, implicitContext)) {
00673       XML_ParserFree(parser);
00674       return 0;
00675     }
00676   }
00677   else {
00678     XmlInitEncoding(&initEncoding, &encoding, 0);
00679     internalEncoding = XmlGetInternalEncoding();
00680   }
00681 
00682   return parser;
00683 }  /* End XML_ParserCreate_MM */
00684 
00685 int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
00686 {
00687   if (!encodingName)
00688     protocolEncodingName = 0;
00689   else {
00690     protocolEncodingName = poolCopyString(&tempPool, encodingName);
00691     if (!protocolEncodingName)
00692       return 0;
00693   }
00694   return 1;
00695 }
00696 
00697 XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
00698                                           const XML_Char *context,
00699                                           const XML_Char *encodingName)
00700 {
00701   XML_Parser parser = oldParser;
00702   DTD *oldDtd = &dtd;
00703   XML_StartElementHandler oldStartElementHandler = startElementHandler;
00704   XML_EndElementHandler oldEndElementHandler = endElementHandler;
00705   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
00706   XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
00707   XML_CommentHandler oldCommentHandler = commentHandler;
00708   XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
00709   XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
00710   XML_DefaultHandler oldDefaultHandler = defaultHandler;
00711   XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
00712   XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
00713   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
00714   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
00715   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
00716   XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
00717   XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
00718   XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
00719   XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
00720   XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
00721   XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
00722   ELEMENT_TYPE * oldDeclElementType = declElementType;
00723 
00724   void *oldUserData = userData;
00725   void *oldHandlerArg = handlerArg;
00726   int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
00727   void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
00728 #ifdef XML_DTD
00729   int oldParamEntityParsing = paramEntityParsing;
00730 #endif
00731   int oldns_triplets = ns_triplets;
00732 
00733   if (ns) {
00734     XML_Char tmp[2];
00735 
00736     *tmp = namespaceSeparator;
00737     parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
00738                                  tmp);
00739   }
00740   else {
00741     parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
00742                                  NULL);
00743   }
00744 
00745   if (!parser)
00746     return 0;
00747 
00748   startElementHandler = oldStartElementHandler;
00749   endElementHandler = oldEndElementHandler;
00750   characterDataHandler = oldCharacterDataHandler;
00751   processingInstructionHandler = oldProcessingInstructionHandler;
00752   commentHandler = oldCommentHandler;
00753   startCdataSectionHandler = oldStartCdataSectionHandler;
00754   endCdataSectionHandler = oldEndCdataSectionHandler;
00755   defaultHandler = oldDefaultHandler;
00756   unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
00757   notationDeclHandler = oldNotationDeclHandler;
00758   startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
00759   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
00760   notStandaloneHandler = oldNotStandaloneHandler;
00761   externalEntityRefHandler = oldExternalEntityRefHandler;
00762   unknownEncodingHandler = oldUnknownEncodingHandler;
00763   elementDeclHandler = oldElementDeclHandler;
00764   attlistDeclHandler = oldAttlistDeclHandler;
00765   entityDeclHandler = oldEntityDeclHandler;
00766   xmlDeclHandler = oldXmlDeclHandler;
00767   declElementType = oldDeclElementType;
00768   userData = oldUserData;
00769   if (oldUserData == oldHandlerArg)
00770     handlerArg = userData;
00771   else
00772     handlerArg = parser;
00773   if (oldExternalEntityRefHandlerArg != oldParser)
00774     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
00775   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
00776   ns_triplets = oldns_triplets;
00777 #ifdef XML_DTD
00778   paramEntityParsing = oldParamEntityParsing;
00779   if (context) {
00780 #endif /* XML_DTD */
00781     if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
00782       XML_ParserFree(parser);
00783       return 0;
00784     }
00785     processor = externalEntityInitProcessor;
00786 #ifdef XML_DTD
00787   }
00788   else {
00789     dtdSwap(&dtd, oldDtd);
00790     parentParser = oldParser;
00791     XmlPrologStateInitExternalEntity(&prologState);
00792     dtd.complete = 1;
00793     hadExternalDoctype = 1;
00794   }
00795 #endif /* XML_DTD */
00796   return parser;
00797 }
00798 
00799 static
00800 void destroyBindings(BINDING *bindings, XML_Parser parser)
00801 {
00802   for (;;) {
00803     BINDING *b = bindings;
00804     if (!b)
00805       break;
00806     bindings = b->nextTagBinding;
00807     FREE(b->uri);
00808     FREE(b);
00809   }
00810 }
00811 
00812 void XML_ParserFree(XML_Parser parser)
00813 {
00814   for (;;) {
00815     TAG *p;
00816     if (tagStack == 0) {
00817       if (freeTagList == 0)
00818         break;
00819       tagStack = freeTagList;
00820       freeTagList = 0;
00821     }
00822     p = tagStack;
00823     tagStack = tagStack->parent;
00824     FREE(p->buf);
00825     destroyBindings(p->bindings, parser);
00826     FREE(p);
00827   }
00828   destroyBindings(freeBindingList, parser);
00829   destroyBindings(inheritedBindings, parser);
00830   poolDestroy(&tempPool);
00831   poolDestroy(&temp2Pool);
00832 #ifdef XML_DTD
00833   if (parentParser) {
00834     if (hadExternalDoctype)
00835       dtd.complete = 0;
00836     dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
00837   }
00838 #endif /* XML_DTD */
00839   dtdDestroy(&dtd, parser);
00840   FREE((void *)atts);
00841   if (groupConnector)
00842     FREE(groupConnector);
00843   if (buffer)
00844     FREE(buffer);
00845   FREE(dataBuf);
00846   if (unknownEncodingMem)
00847     FREE(unknownEncodingMem);
00848   if (unknownEncodingRelease)
00849     unknownEncodingRelease(unknownEncodingData);
00850   FREE(parser);
00851 }
00852 
00853 void XML_UseParserAsHandlerArg(XML_Parser parser)
00854 {
00855   handlerArg = parser;
00856 }
00857 
00858 void
00859 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
00860   ns_triplets = do_nst;
00861 }
00862 
00863 void XML_SetUserData(XML_Parser parser, void *p)
00864 {
00865   if (handlerArg == userData)
00866     handlerArg = userData = p;
00867   else
00868     userData = p;
00869 }
00870 
00871 int XML_SetBase(XML_Parser parser, const XML_Char *p)
00872 {
00873   if (p) {
00874     p = poolCopyString(&dtd.pool, p);
00875     if (!p)
00876       return 0;
00877     curBase = p;
00878   }
00879   else
00880     curBase = 0;
00881   return 1;
00882 }
00883 
00884 const XML_Char *XML_GetBase(XML_Parser parser)
00885 {
00886   return curBase;
00887 }
00888 
00889 int XML_GetSpecifiedAttributeCount(XML_Parser parser)
00890 {
00891   return nSpecifiedAtts;
00892 }
00893 
00894 int XML_GetIdAttributeIndex(XML_Parser parser)
00895 {
00896   return idAttIndex;
00897 }
00898 
00899 void XML_SetElementHandler(XML_Parser parser,
00900                            XML_StartElementHandler start,
00901                            XML_EndElementHandler end)
00902 {
00903   startElementHandler = start;
00904   endElementHandler = end;
00905 }
00906 
00907 void XML_SetStartElementHandler(XML_Parser parser,
00908                                 XML_StartElementHandler start) {
00909   startElementHandler = start;
00910 }
00911 
00912 void XML_SetEndElementHandler(XML_Parser parser,
00913                               XML_EndElementHandler end) {
00914   endElementHandler = end;
00915 }
00916 
00917 void XML_SetCharacterDataHandler(XML_Parser parser,
00918                                  XML_CharacterDataHandler handler)
00919 {
00920   characterDataHandler = handler;
00921 }
00922 
00923 void XML_SetProcessingInstructionHandler(XML_Parser parser,
00924                                          XML_ProcessingInstructionHandler handler)
00925 {
00926   processingInstructionHandler = handler;
00927 }
00928 
00929 void XML_SetCommentHandler(XML_Parser parser,
00930                            XML_CommentHandler handler)
00931 {
00932   commentHandler = handler;
00933 }
00934 
00935 void XML_SetCdataSectionHandler(XML_Parser parser,
00936                                 XML_StartCdataSectionHandler start,
00937                                 XML_EndCdataSectionHandler end)
00938 {
00939   startCdataSectionHandler = start;
00940   endCdataSectionHandler = end;
00941 }
00942 
00943 void XML_SetStartCdataSectionHandler(XML_Parser parser,
00944                                      XML_StartCdataSectionHandler start) {
00945   startCdataSectionHandler = start;
00946 }
00947 
00948 void XML_SetEndCdataSectionHandler(XML_Parser parser,
00949                                    XML_EndCdataSectionHandler end) {
00950   endCdataSectionHandler = end;
00951 }
00952 
00953 void XML_SetDefaultHandler(XML_Parser parser,
00954                            XML_DefaultHandler handler)
00955 {
00956   defaultHandler = handler;
00957   defaultExpandInternalEntities = 0;
00958 }
00959 
00960 void XML_SetDefaultHandlerExpand(XML_Parser parser,
00961                                  XML_DefaultHandler handler)
00962 {
00963   defaultHandler = handler;
00964   defaultExpandInternalEntities = 1;
00965 }
00966 
00967 void XML_SetDoctypeDeclHandler(XML_Parser parser,
00968                                XML_StartDoctypeDeclHandler start,
00969                                XML_EndDoctypeDeclHandler end)
00970 {
00971   startDoctypeDeclHandler = start;
00972   endDoctypeDeclHandler = end;
00973 }
00974 
00975 void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
00976                                     XML_StartDoctypeDeclHandler start) {
00977   startDoctypeDeclHandler = start;
00978 }
00979 
00980 void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
00981                                   XML_EndDoctypeDeclHandler end) {
00982   endDoctypeDeclHandler = end;
00983 }
00984 
00985 void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
00986                                       XML_UnparsedEntityDeclHandler handler)
00987 {
00988   unparsedEntityDeclHandler = handler;
00989 }
00990 
00991 void XML_SetNotationDeclHandler(XML_Parser parser,
00992                                 XML_NotationDeclHandler handler)
00993 {
00994   notationDeclHandler = handler;
00995 }
00996 
00997 void XML_SetNamespaceDeclHandler(XML_Parser parser,
00998                                  XML_StartNamespaceDeclHandler start,
00999                                  XML_EndNamespaceDeclHandler end)
01000 {
01001   startNamespaceDeclHandler = start;
01002   endNamespaceDeclHandler = end;
01003 }
01004 
01005 void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
01006                                       XML_StartNamespaceDeclHandler start) {
01007   startNamespaceDeclHandler = start;
01008 }
01009 
01010 void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
01011                                     XML_EndNamespaceDeclHandler end) {
01012   endNamespaceDeclHandler = end;
01013 }
01014 
01015 
01016 void XML_SetNotStandaloneHandler(XML_Parser parser,
01017                                  XML_NotStandaloneHandler handler)
01018 {
01019   notStandaloneHandler = handler;
01020 }
01021 
01022 void XML_SetExternalEntityRefHandler(XML_Parser parser,
01023                                      XML_ExternalEntityRefHandler handler)
01024 {
01025   externalEntityRefHandler = handler;
01026 }
01027 
01028 void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
01029 {
01030   if (arg)
01031     externalEntityRefHandlerArg = arg;
01032   else
01033     externalEntityRefHandlerArg = parser;
01034 }
01035 
01036 void XML_SetUnknownEncodingHandler(XML_Parser parser,
01037                                    XML_UnknownEncodingHandler handler,
01038                                    void *data)
01039 {
01040   unknownEncodingHandler = handler;
01041   unknownEncodingHandlerData = data;
01042 }
01043 
01044 void XML_SetElementDeclHandler(XML_Parser parser,
01045                                XML_ElementDeclHandler eldecl)
01046 {
01047   elementDeclHandler = eldecl;
01048 }
01049 
01050 void XML_SetAttlistDeclHandler(XML_Parser parser,
01051                                XML_AttlistDeclHandler attdecl)
01052 {
01053   attlistDeclHandler = attdecl;
01054 }
01055 
01056 void XML_SetEntityDeclHandler(XML_Parser parser,
01057                               XML_EntityDeclHandler handler)
01058 {
01059   entityDeclHandler = handler;
01060 }
01061 
01062 void XML_SetXmlDeclHandler(XML_Parser parser,
01063                            XML_XmlDeclHandler handler) {
01064   xmlDeclHandler = handler;
01065 }
01066 
01067 int XML_SetParamEntityParsing(XML_Parser parser,
01068                               enum XML_ParamEntityParsing parsing)
01069 {
01070 #ifdef XML_DTD
01071   paramEntityParsing = parsing;
01072   return 1;
01073 #else
01074   return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
01075 #endif
01076 }
01077 
01078 int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
01079 {
01080   if (len == 0) {
01081     if (!isFinal)
01082       return 1;
01083     positionPtr = bufferPtr;
01084     errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
01085     if (errorCode == XML_ERROR_NONE)
01086       return 1;
01087     eventEndPtr = eventPtr;
01088     processor = errorProcessor;
01089     return 0;
01090   }
01091 #ifndef XML_CONTEXT_BYTES
01092   else if (bufferPtr == bufferEnd) {
01093     const char *end;
01094     int nLeftOver;
01095     parseEndByteIndex += len;
01096     positionPtr = s;
01097     if (isFinal) {
01098       errorCode = processor(parser, s, parseEndPtr = s + len, 0);
01099       if (errorCode == XML_ERROR_NONE)
01100         return 1;
01101       eventEndPtr = eventPtr;
01102       processor = errorProcessor;
01103       return 0;
01104     }
01105     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
01106     if (errorCode != XML_ERROR_NONE) {
01107       eventEndPtr = eventPtr;
01108       processor = errorProcessor;
01109       return 0;
01110     }
01111     XmlUpdatePosition(encoding, positionPtr, end, &position);
01112     nLeftOver = s + len - end;
01113     if (nLeftOver) {
01114       if (buffer == 0 || nLeftOver > bufferLim - buffer) {
01115         /* FIXME avoid integer overflow */
01116         buffer = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
01117         /* FIXME storage leak if realloc fails */
01118         if (!buffer) {
01119           errorCode = XML_ERROR_NO_MEMORY;
01120           eventPtr = eventEndPtr = 0;
01121           processor = errorProcessor;
01122           return 0;
01123         }
01124         bufferLim = buffer + len * 2;
01125       }
01126       memcpy(buffer, end, nLeftOver);
01127       bufferPtr = buffer;
01128       bufferEnd = buffer + nLeftOver;
01129     }
01130     return 1;
01131   }
01132 #endif  /* not defined XML_CONTEXT_BYTES */
01133   else {
01134     memcpy(XML_GetBuffer(parser, len), s, len);
01135     return XML_ParseBuffer(parser, len, isFinal);
01136   }
01137 }
01138 
01139 int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
01140 {
01141   const char *start = bufferPtr;
01142   positionPtr = start;
01143   bufferEnd += len;
01144   parseEndByteIndex += len;
01145   errorCode = processor(parser, start, parseEndPtr = bufferEnd,
01146                         isFinal ? (const char **)0 : &bufferPtr);
01147   if (errorCode == XML_ERROR_NONE) {
01148     if (!isFinal)
01149       XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
01150     return 1;
01151   }
01152   else {
01153     eventEndPtr = eventPtr;
01154     processor = errorProcessor;
01155     return 0;
01156   }
01157 }
01158 
01159 void *XML_GetBuffer(XML_Parser parser, int len)
01160 {
01161   if (len > bufferLim - bufferEnd) {
01162     /* FIXME avoid integer overflow */
01163     int neededSize = len + (bufferEnd - bufferPtr);
01164 #ifdef XML_CONTEXT_BYTES
01165     int keep = bufferPtr - buffer;
01166 
01167     if (keep > XML_CONTEXT_BYTES)
01168       keep = XML_CONTEXT_BYTES;
01169     neededSize += keep;
01170 #endif  /* defined XML_CONTEXT_BYTES */
01171     if (neededSize  <= bufferLim - buffer) {
01172 #ifdef XML_CONTEXT_BYTES
01173       if (keep < bufferPtr - buffer) {
01174         int offset = (bufferPtr - buffer) - keep;
01175         memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
01176         bufferEnd -= offset;
01177         bufferPtr -= offset;
01178       }
01179 #else
01180       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
01181       bufferEnd = buffer + (bufferEnd - bufferPtr);
01182       bufferPtr = buffer;
01183 #endif  /* not defined XML_CONTEXT_BYTES */
01184     }
01185     else {
01186       char *newBuf;
01187       int bufferSize = bufferLim - bufferPtr;
01188       if (bufferSize == 0)
01189         bufferSize = INIT_BUFFER_SIZE;
01190       do {
01191         bufferSize *= 2;
01192       } while (bufferSize < neededSize);
01193       newBuf = MALLOC(bufferSize);
01194       if (newBuf == 0) {
01195         errorCode = XML_ERROR_NO_MEMORY;
01196         return 0;
01197       }
01198       bufferLim = newBuf + bufferSize;
01199 #ifdef XML_CONTEXT_BYTES
01200       if (bufferPtr) {
01201         int keep = bufferPtr - buffer;
01202         if (keep > XML_CONTEXT_BYTES)
01203           keep = XML_CONTEXT_BYTES;
01204         memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
01205         FREE(buffer);
01206         buffer = newBuf;
01207         bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
01208         bufferPtr = buffer + keep;
01209       }
01210       else {
01211         bufferEnd = newBuf + (bufferEnd - bufferPtr);
01212         bufferPtr = buffer = newBuf;
01213       }
01214 #else
01215       if (bufferPtr) {
01216         memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
01217         FREE(buffer);
01218       }
01219       bufferEnd = newBuf + (bufferEnd - bufferPtr);
01220       bufferPtr = buffer = newBuf;
01221 #endif  /* not defined XML_CONTEXT_BYTES */
01222     }
01223   }
01224   return bufferEnd;
01225 }
01226 
01227 enum XML_Error XML_GetErrorCode(XML_Parser parser)
01228 {
01229   return errorCode;
01230 }
01231 
01232 long XML_GetCurrentByteIndex(XML_Parser parser)
01233 {
01234   if (eventPtr)
01235     return parseEndByteIndex - (parseEndPtr - eventPtr);
01236   return -1;
01237 }
01238 
01239 int XML_GetCurrentByteCount(XML_Parser parser)
01240 {
01241   if (eventEndPtr && eventPtr)
01242     return eventEndPtr - eventPtr;
01243   return 0;
01244 }
01245 
01246 const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
01247 {
01248 #ifdef XML_CONTEXT_BYTES
01249   if (eventPtr && buffer) {
01250     *offset = eventPtr - buffer;
01251     *size   = bufferEnd - buffer;
01252     return buffer;
01253   }
01254 #endif /* defined XML_CONTEXT_BYTES */
01255   return (char *) 0;
01256 }
01257 
01258 int XML_GetCurrentLineNumber(XML_Parser parser)
01259 {
01260   if (eventPtr) {
01261     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
01262     positionPtr = eventPtr;
01263   }
01264   return position.lineNumber + 1;
01265 }
01266 
01267 int XML_GetCurrentColumnNumber(XML_Parser parser)
01268 {
01269   if (eventPtr) {
01270     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
01271     positionPtr = eventPtr;
01272   }
01273   return position.columnNumber;
01274 }
01275 
01276 void XML_DefaultCurrent(XML_Parser parser)
01277 {
01278   if (defaultHandler) {
01279     if (openInternalEntities)
01280       reportDefault(parser,
01281                     internalEncoding,
01282                     openInternalEntities->internalEventPtr,
01283                     openInternalEntities->internalEventEndPtr);
01284     else
01285       reportDefault(parser, encoding, eventPtr, eventEndPtr);
01286   }
01287 }
01288 
01289 const XML_LChar *XML_ErrorString(int code)
01290 {
01291   static const XML_LChar *message[] = {
01292     0,
01293     XML_T("out of memory"),
01294     XML_T("syntax error"),
01295     XML_T("no element found"),
01296     XML_T("not well-formed (invalid token)"),
01297     XML_T("unclosed token"),
01298     XML_T("unclosed token"),
01299     XML_T("mismatched tag"),
01300     XML_T("duplicate attribute"),
01301     XML_T("junk after document element"),
01302     XML_T("illegal parameter entity reference"),
01303     XML_T("undefined entity"),
01304     XML_T("recursive entity reference"),
01305     XML_T("asynchronous entity"),
01306     XML_T("reference to invalid character number"),
01307     XML_T("reference to binary entity"),
01308     XML_T("reference to external entity in attribute"),
01309     XML_T("xml processing instruction not at start of external entity"),
01310     XML_T("unknown encoding"),
01311     XML_T("encoding specified in XML declaration is incorrect"),
01312     XML_T("unclosed CDATA section"),
01313     XML_T("error in processing external entity reference"),
01314     XML_T("document is not standalone"),
01315     XML_T("unexpected parser state - please send a bug report")
01316   };
01317   if (code > 0 && code < sizeof(message)/sizeof(message[0]))
01318     return message[code];
01319   return 0;
01320 }
01321 
01322 const XML_LChar *
01323 XML_ExpatVersion() {
01324   return VERSION;
01325 }
01326 
01327 static
01328 enum XML_Error contentProcessor(XML_Parser parser,
01329                                 const char *start,
01330                                 const char *end,
01331                                 const char **endPtr)
01332 {
01333   return doContent(parser, 0, encoding, start, end, endPtr);
01334 }
01335 
01336 static
01337 enum XML_Error externalEntityInitProcessor(XML_Parser parser,
01338                                            const char *start,
01339                                            const char *end,
01340                                            const char **endPtr)
01341 {
01342   enum XML_Error result = initializeEncoding(parser);
01343   if (result != XML_ERROR_NONE)
01344     return result;
01345   processor = externalEntityInitProcessor2;
01346   return externalEntityInitProcessor2(parser, start, end, endPtr);
01347 }
01348 
01349 static
01350 enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
01351                                             const char *start,
01352                                             const char *end,
01353                                             const char **endPtr)
01354 {
01355   const char *next;
01356   int tok = XmlContentTok(encoding, start, end, &next);
01357   switch (tok) {
01358   case XML_TOK_BOM:
01359     start = next;
01360     break;
01361   case XML_TOK_PARTIAL:
01362     if (endPtr) {
01363       *endPtr = start;
01364       return XML_ERROR_NONE;
01365     }
01366     eventPtr = start;
01367     return XML_ERROR_UNCLOSED_TOKEN;
01368   case XML_TOK_PARTIAL_CHAR:
01369     if (endPtr) {
01370       *endPtr = start;
01371       return XML_ERROR_NONE;
01372     }
01373     eventPtr = start;
01374     return XML_ERROR_PARTIAL_CHAR;
01375   }
01376   processor = externalEntityInitProcessor3;
01377   return externalEntityInitProcessor3(parser, start, end, endPtr);
01378 }
01379 
01380 static
01381 enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
01382                                             const char *start,
01383                                             const char *end,
01384                                             const char **endPtr)
01385 {
01386   const char *next;
01387   int tok = XmlContentTok(encoding, start, end, &next);
01388   switch (tok) {
01389   case XML_TOK_XML_DECL:
01390     {
01391       enum XML_Error result = processXmlDecl(parser, 1, start, next);
01392       if (result != XML_ERROR_NONE)
01393         return result;
01394       start = next;
01395     }
01396     break;
01397   case XML_TOK_PARTIAL:
01398     if (endPtr) {
01399       *endPtr = start;
01400       return XML_ERROR_NONE;
01401     }
01402     eventPtr = start;
01403     return XML_ERROR_UNCLOSED_TOKEN;
01404   case XML_TOK_PARTIAL_CHAR:
01405     if (endPtr) {
01406       *endPtr = start;
01407       return XML_ERROR_NONE;
01408     }
01409     eventPtr = start;
01410     return XML_ERROR_PARTIAL_CHAR;
01411   }
01412   processor = externalEntityContentProcessor;
01413   tagLevel = 1;
01414   return doContent(parser, 1, encoding, start, end, endPtr);
01415 }
01416 
01417 static
01418 enum XML_Error externalEntityContentProcessor(XML_Parser parser,
01419                                               const char *start,
01420                                               const char *end,
01421                                               const char **endPtr)
01422 {
01423   return doContent(parser, 1, encoding, start, end, endPtr);
01424 }
01425 
01426 static enum XML_Error
01427 doContent(XML_Parser parser,
01428           int startTagLevel,
01429           const ENCODING *enc,
01430           const char *s,
01431           const char *end,
01432           const char **nextPtr)
01433 {
01434   const char **eventPP;
01435   const char **eventEndPP;
01436   if (enc == encoding) {
01437     eventPP = &eventPtr;
01438     eventEndPP = &eventEndPtr;
01439   }
01440   else {
01441     eventPP = &(openInternalEntities->internalEventPtr);
01442     eventEndPP = &(openInternalEntities->internalEventEndPtr);
01443   }
01444   *eventPP = s;
01445   for (;;) {
01446     const char *next = s; /* XmlContentTok doesn't always set the last arg */
01447     int tok = XmlContentTok(enc, s, end, &next);
01448     *eventEndPP = next;
01449     switch (tok) {
01450     case XML_TOK_TRAILING_CR:
01451       if (nextPtr) {
01452         *nextPtr = s;
01453         return XML_ERROR_NONE;
01454       }
01455       *eventEndPP = end;
01456       if (characterDataHandler) {
01457         XML_Char c = 0xA;
01458         characterDataHandler(handlerArg, &c, 1);
01459       }
01460       else if (defaultHandler)
01461         reportDefault(parser, enc, s, end);
01462       if (startTagLevel == 0)
01463         return XML_ERROR_NO_ELEMENTS;
01464       if (tagLevel != startTagLevel)
01465         return XML_ERROR_ASYNC_ENTITY;
01466       return XML_ERROR_NONE;
01467     case XML_TOK_NONE:
01468       if (nextPtr) {
01469         *nextPtr = s;
01470         return XML_ERROR_NONE;
01471       }
01472       if (startTagLevel > 0) {
01473         if (tagLevel != startTagLevel)
01474           return XML_ERROR_ASYNC_ENTITY;
01475         return XML_ERROR_NONE;
01476       }
01477       return XML_ERROR_NO_ELEMENTS;
01478     case XML_TOK_INVALID:
01479       *eventPP = next;
01480       return XML_ERROR_INVALID_TOKEN;
01481     case XML_TOK_PARTIAL:
01482       if (nextPtr) {
01483         *nextPtr = s;
01484         return XML_ERROR_NONE;
01485       }
01486       return XML_ERROR_UNCLOSED_TOKEN;
01487     case XML_TOK_PARTIAL_CHAR:
01488       if (nextPtr) {
01489         *nextPtr = s;
01490         return XML_ERROR_NONE;
01491       }
01492       return XML_ERROR_PARTIAL_CHAR;
01493     case XML_TOK_ENTITY_REF:
01494       {
01495         const XML_Char *name;
01496         ENTITY *entity;
01497         XML_Char ch = XmlPredefinedEntityName(enc,
01498                                               s + enc->minBytesPerChar,
01499                                               next - enc->minBytesPerChar);
01500         if (ch) {
01501           if (characterDataHandler)
01502             characterDataHandler(handlerArg, &ch, 1);
01503           else if (defaultHandler)
01504             reportDefault(parser, enc, s, next);
01505           break;
01506         }
01507         name = poolStoreString(&dtd.pool, enc,
01508                                 s + enc->minBytesPerChar,
01509                                 next - enc->minBytesPerChar);
01510         if (!name)
01511           return XML_ERROR_NO_MEMORY;
01512         entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
01513         poolDiscard(&dtd.pool);
01514         if (!entity) {
01515           if (dtd.complete || dtd.standalone)
01516             return XML_ERROR_UNDEFINED_ENTITY;
01517           if (defaultHandler)
01518             reportDefault(parser, enc, s, next);
01519           break;
01520         }
01521         if (entity->open)
01522           return XML_ERROR_RECURSIVE_ENTITY_REF;
01523         if (entity->notation)
01524           return XML_ERROR_BINARY_ENTITY_REF;
01525         if (entity) {
01526           if (entity->textPtr) {
01527             enum XML_Error result;
01528             OPEN_INTERNAL_ENTITY openEntity;
01529             if (defaultHandler && !defaultExpandInternalEntities) {
01530               reportDefault(parser, enc, s, next);
01531               break;
01532             }
01533             entity->open = 1;
01534             openEntity.next = openInternalEntities;
01535             openInternalEntities = &openEntity;
01536             openEntity.entity = entity;
01537             openEntity.internalEventPtr = 0;
01538             openEntity.internalEventEndPtr = 0;
01539             result = doContent(parser,
01540                                tagLevel,
01541                                internalEncoding,
01542                                (char *)entity->textPtr,
01543                                (char *)(entity->textPtr + entity->textLen),
01544                                0);
01545             entity->open = 0;
01546             openInternalEntities = openEntity.next;
01547             if (result)
01548               return result;
01549           }
01550           else if (externalEntityRefHandler) {
01551             const XML_Char *context;
01552             entity->open = 1;
01553             context = getContext(parser);
01554             entity->open = 0;
01555             if (!context)
01556               return XML_ERROR_NO_MEMORY;
01557             if (!externalEntityRefHandler(externalEntityRefHandlerArg,
01558                                           context,
01559                                           entity->base,
01560                                           entity->systemId,
01561                                           entity->publicId))
01562               return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
01563             poolDiscard(&tempPool);
01564           }
01565           else if (defaultHandler)
01566             reportDefault(parser, enc, s, next);
01567         }
01568         break;
01569       }
01570     case XML_TOK_START_TAG_WITH_ATTS:
01571       if (!startElementHandler) {
01572         enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
01573         if (result)
01574           return result;
01575       }
01576       /* fall through */
01577     case XML_TOK_START_TAG_NO_ATTS:
01578       {
01579         TAG *tag;
01580         if (freeTagList) {
01581           tag = freeTagList;
01582           freeTagList = freeTagList->parent;
01583         }
01584         else {
01585           tag = MALLOC(sizeof(TAG));
01586           if (!tag)
01587             return XML_ERROR_NO_MEMORY;
01588           tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
01589           if (!tag->buf)
01590             return XML_ERROR_NO_MEMORY;
01591           tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
01592         }
01593         tag->bindings = 0;
01594         tag->parent = tagStack;
01595         tagStack = tag;
01596         tag->name.localPart = 0;
01597         tag->rawName = s + enc->minBytesPerChar;
01598         tag->rawNameLength = XmlNameLength(enc, tag->rawName);
01599         if (nextPtr) {
01600           /* Need to guarantee that:
01601              tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
01602           if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
01603             int bufSize = tag->rawNameLength * 4;
01604             bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
01605             tag->buf = REALLOC(tag->buf, bufSize);
01606             if (!tag->buf)
01607               return XML_ERROR_NO_MEMORY;
01608             tag->bufEnd = tag->buf + bufSize;
01609           }
01610           memcpy(tag->buf, tag->rawName, tag->rawNameLength);
01611           tag->rawName = tag->buf;
01612         }
01613         ++tagLevel;
01614         if (startElementHandler) {
01615           enum XML_Error result;
01616           XML_Char *toPtr;
01617           for (;;) {
01618             const char *rawNameEnd = tag->rawName + tag->rawNameLength;
01619             const char *fromPtr = tag->rawName;
01620             int bufSize;
01621             if (nextPtr)
01622               toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
01623             else
01624               toPtr = (XML_Char *)tag->buf;
01625             tag->name.str = toPtr;
01626             XmlConvert(enc,
01627                        &fromPtr, rawNameEnd,
01628                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
01629             if (fromPtr == rawNameEnd)
01630               break;
01631             bufSize = (tag->bufEnd - tag->buf) << 1;
01632             tag->buf = REALLOC(tag->buf, bufSize);
01633             if (!tag->buf)
01634               return XML_ERROR_NO_MEMORY;
01635             tag->bufEnd = tag->buf + bufSize;
01636             if (nextPtr)
01637               tag->rawName = tag->buf;
01638           }
01639           *toPtr = XML_T('\0');
01640           result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
01641           if (result)
01642             return result;
01643           startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
01644           poolClear(&tempPool);
01645         }
01646         else {
01647           tag->name.str = 0;
01648           if (defaultHandler)
01649             reportDefault(parser, enc, s, next);
01650         }
01651         break;
01652       }
01653     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
01654       if (!startElementHandler) {
01655         enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
01656         if (result)
01657           return result;
01658       }
01659       /* fall through */
01660     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
01661       if (startElementHandler || endElementHandler) {
01662         const char *rawName = s + enc->minBytesPerChar;
01663         enum XML_Error result;
01664         BINDING *bindings = 0;
01665         TAG_NAME name;
01666         name.str = poolStoreString(&tempPool, enc, rawName,
01667                                    rawName + XmlNameLength(enc, rawName));
01668         if (!name.str)
01669           return XML_ERROR_NO_MEMORY;
01670         poolFinish(&tempPool);
01671         result = storeAtts(parser, enc, s, &name, &bindings);
01672         if (result)
01673           return result;
01674         poolFinish(&tempPool);
01675         if (startElementHandler)
01676           startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
01677         if (endElementHandler) {
01678           if (startElementHandler)
01679             *eventPP = *eventEndPP;
01680           endElementHandler(handlerArg, name.str);
01681         }
01682         poolClear(&tempPool);
01683         while (bindings) {
01684           BINDING *b = bindings;
01685           if (endNamespaceDeclHandler)
01686             endNamespaceDeclHandler(handlerArg, b->prefix->name);
01687           bindings = bindings->nextTagBinding;
01688           b->nextTagBinding = freeBindingList;
01689           freeBindingList = b;
01690           b->prefix->binding = b->prevPrefixBinding;
01691         }
01692       }
01693       else if (defaultHandler)
01694         reportDefault(parser, enc, s, next);
01695       if (tagLevel == 0)
01696         return epilogProcessor(parser, next, end, nextPtr);
01697       break;
01698     case XML_TOK_END_TAG:
01699       if (tagLevel == startTagLevel)
01700         return XML_ERROR_ASYNC_ENTITY;
01701       else {
01702         int len;
01703         const char *rawName;
01704         TAG *tag = tagStack;
01705         tagStack = tag->parent;
01706         tag->parent = freeTagList;
01707         freeTagList = tag;
01708         rawName = s + enc->minBytesPerChar*2;
01709         len = XmlNameLength(enc, rawName);
01710         if (len != tag->rawNameLength
01711             || memcmp(tag->rawName, rawName, len) != 0) {
01712           *eventPP = rawName;
01713           return XML_ERROR_TAG_MISMATCH;
01714         }
01715         --tagLevel;
01716         if (endElementHandler && tag->name.str) {
01717           if (tag->name.localPart) {
01718             XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
01719             const XML_Char *from = tag->name.localPart;
01720             while ((*to++ = *from++) != 0)
01721               ;
01722           }
01723           endElementHandler(handlerArg, tag->name.str);
01724         }
01725         else if (defaultHandler)
01726           reportDefault(parser, enc, s, next);
01727         while (tag->bindings) {
01728           BINDING *b = tag->bindings;
01729           if (endNamespaceDeclHandler)
01730             endNamespaceDeclHandler(handlerArg, b->prefix->name);
01731           tag->bindings = tag->bindings->nextTagBinding;
01732           b->nextTagBinding = freeBindingList;
01733           freeBindingList = b;
01734           b->prefix->binding = b->prevPrefixBinding;
01735         }
01736         if (tagLevel == 0)
01737           return epilogProcessor(parser, next, end, nextPtr);
01738       }
01739       break;
01740     case XML_TOK_CHAR_REF:
01741       {
01742         int n = XmlCharRefNumber(enc, s);
01743         if (n < 0)
01744           return XML_ERROR_BAD_CHAR_REF;
01745         if (characterDataHandler) {
01746           XML_Char buf[XML_ENCODE_MAX];
01747           characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
01748         }
01749         else if (defaultHandler)
01750           reportDefault(parser, enc, s, next);
01751       }
01752       break;
01753     case XML_TOK_XML_DECL:
01754       return XML_ERROR_MISPLACED_XML_PI;
01755     case XML_TOK_DATA_NEWLINE:
01756       if (characterDataHandler) {
01757         XML_Char c = 0xA;
01758         characterDataHandler(handlerArg, &c, 1);
01759       }
01760       else if (defaultHandler)
01761         reportDefault(parser, enc, s, next);
01762       break;
01763     case XML_TOK_CDATA_SECT_OPEN:
01764       {
01765         enum XML_Error result;
01766         if (startCdataSectionHandler)
01767           startCdataSectionHandler(handlerArg);
01768 #if 0
01769         /* Suppose you doing a transformation on a document that involves
01770            changing only the character data.  You set up a defaultHandler
01771            and a characterDataHandler.  The defaultHandler simply copies
01772            characters through.  The characterDataHandler does the transformation
01773            and writes the characters out escaping them as necessary.  This case
01774            will fail to work if we leave out the following two lines (because &
01775            and < inside CDATA sections will be incorrectly escaped).
01776 
01777            However, now we have a start/endCdataSectionHandler, so it seems
01778            easier to let the user deal with this. */
01779 
01780         else if (characterDataHandler)
01781           characterDataHandler(handlerArg, dataBuf, 0);
01782 #endif
01783         else if (defaultHandler)
01784           reportDefault(parser, enc, s, next);
01785         result = doCdataSection(parser, enc, &next, end, nextPtr);
01786         if (!next) {
01787           processor = cdataSectionProcessor;
01788           return result;
01789         }
01790       }
01791       break;
01792     case XML_TOK_TRAILING_RSQB:
01793       if (nextPtr) {
01794         *nextPtr = s;
01795         return XML_ERROR_NONE;
01796       }
01797       if (characterDataHandler) {
01798         if (MUST_CONVERT(enc, s)) {
01799           ICHAR *dataPtr = (ICHAR *)dataBuf;
01800           XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
01801           characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
01802         }
01803         else
01804           characterDataHandler(handlerArg,
01805                                (XML_Char *)s,
01806                                (XML_Char *)end - (XML_Char *)s);
01807       }
01808       else if (defaultHandler)
01809         reportDefault(parser, enc, s, end);
01810       if (startTagLevel == 0) {
01811         *eventPP = end;
01812         return XML_ERROR_NO_ELEMENTS;
01813       }
01814       if (tagLevel != startTagLevel) {
01815         *eventPP = end;
01816         return XML_ERROR_ASYNC_ENTITY;
01817       }
01818       return XML_ERROR_NONE;
01819     case XML_TOK_DATA_CHARS:
01820       if (characterDataHandler) {
01821         if (MUST_CONVERT(enc, s)) {
01822           for (;;) {
01823             ICHAR *dataPtr = (ICHAR *)dataBuf;
01824             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
01825             *eventEndPP = s;
01826             characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
01827             if (s == next)
01828               break;
01829             *eventPP = s;
01830           }
01831         }
01832         else
01833           characterDataHandler(handlerArg,
01834                                (XML_Char *)s,
01835                                (XML_Char *)next - (XML_Char *)s);
01836       }
01837       else if (defaultHandler)
01838         reportDefault(parser, enc, s, next);
01839       break;
01840     case XML_TOK_PI:
01841       if (!reportProcessingInstruction(parser, enc, s, next))
01842         return XML_ERROR_NO_MEMORY;
01843       break;
01844     case XML_TOK_COMMENT:
01845       if (!reportComment(parser, enc, s, next))
01846         return XML_ERROR_NO_MEMORY;
01847       break;
01848     default:
01849       if (defaultHandler)
01850         reportDefault(parser, enc, s, next);
01851       break;
01852     }
01853     *eventPP = s = next;
01854   }
01855   /* not reached */
01856 }
01857 
01858 /* If tagNamePtr is non-null, build a real list of attributes,
01859 otherwise just check the attributes for well-formedness. */
01860 
01861 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
01862                                 const char *attStr, TAG_NAME *tagNamePtr,
01863                                 BINDING **bindingsPtr)
01864 {
01865   ELEMENT_TYPE *elementType = 0;
01866   int nDefaultAtts = 0;
01867   const XML_Char **appAtts;   /* the attribute list to pass to the application */
01868   int attIndex = 0;
01869   int i;
01870   int n;
01871   int nPrefixes = 0;
01872   BINDING *binding;
01873   const XML_Char *localPart;
01874 
01875   /* lookup the element type name */
01876   if (tagNamePtr) {
01877     elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
01878     if (!elementType) {
01879       tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
01880       if (!tagNamePtr->str)
01881         return XML_ERROR_NO_MEMORY;
01882       elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
01883       if (!elementType)
01884         return XML_ERROR_NO_MEMORY;
01885       if (ns && !setElementTypePrefix(parser, elementType))
01886         return XML_ERROR_NO_MEMORY;
01887     }
01888     nDefaultAtts = elementType->nDefaultAtts;
01889   }
01890   /* get the attributes from the tokenizer */
01891   n = XmlGetAttributes(enc, attStr, attsSize, atts);
01892   if (n + nDefaultAtts > attsSize) {
01893     int oldAttsSize = attsSize;
01894     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
01895     atts = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
01896     if (!atts)
01897       return XML_ERROR_NO_MEMORY;
01898     if (n > oldAttsSize)
01899       XmlGetAttributes(enc, attStr, n, atts);
01900   }
01901   appAtts = (const XML_Char **)atts;
01902   for (i = 0; i < n; i++) {
01903     /* add the name and value to the attribute list */
01904     ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
01905                                          atts[i].name
01906                                          + XmlNameLength(enc, atts[i].name));
01907     if (!attId)
01908       return XML_ERROR_NO_MEMORY;
01909     /* detect duplicate attributes */
01910     if ((attId->name)[-1]) {
01911       if (enc == encoding)
01912         eventPtr = atts[i].name;
01913       return XML_ERROR_DUPLICATE_ATTRIBUTE;
01914     }
01915     (attId->name)[-1] = 1;
01916     appAtts[attIndex++] = attId->name;
01917     if (!atts[i].normalized) {
01918       enum XML_Error result;
01919       int isCdata = 1;
01920 
01921       /* figure out whether declared as other than CDATA */
01922       if (attId->maybeTokenized) {
01923         int j;
01924         for (j = 0; j < nDefaultAtts; j++) {
01925           if (attId == elementType->defaultAtts[j].id) {
01926             isCdata = elementType->defaultAtts[j].isCdata;
01927             break;
01928           }
01929         }
01930       }
01931 
01932       /* normalize the attribute value */
01933       result = storeAttributeValue(parser, enc, isCdata,
01934                                    atts[i].valuePtr, atts[i].valueEnd,
01935                                    &tempPool);
01936       if (result)
01937         return result;
01938       if (tagNamePtr) {
01939         appAtts[attIndex] = poolStart(&tempPool);
01940         poolFinish(&tempPool);
01941       }
01942       else
01943         poolDiscard(&tempPool);
01944     }
01945     else if (tagNamePtr) {
01946       /* the value did not need normalizing */
01947       appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
01948       if (appAtts[attIndex] == 0)
01949         return XML_ERROR_NO_MEMORY;
01950       poolFinish(&tempPool);
01951     }
01952     /* handle prefixed attribute names */
01953     if (attId->prefix && tagNamePtr) {
01954       if (attId->xmlns) {
01955         /* deal with namespace declarations here */
01956         if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
01957           return XML_ERROR_NO_MEMORY;
01958         --attIndex;
01959       }
01960       else {
01961         /* deal with other prefixed names later */
01962         attIndex++;
01963         nPrefixes++;
01964         (attId->name)[-1] = 2;
01965       }
01966     }
01967     else
01968       attIndex++;
01969   }
01970   if (tagNamePtr) {
01971     int j;
01972     nSpecifiedAtts = attIndex;
01973     if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
01974       for (i = 0; i < attIndex; i += 2)
01975         if (appAtts[i] == elementType->idAtt->name) {
01976           idAttIndex = i;
01977           break;
01978         }
01979     }
01980     else
01981       idAttIndex = -1;
01982     /* do attribute defaulting */
01983     for (j = 0; j < nDefaultAtts; j++) {
01984       const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
01985       if (!(da->id->name)[-1] && da->value) {
01986         if (da->id->prefix) {
01987           if (da->id->xmlns) {
01988             if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
01989               return XML_ERROR_NO_MEMORY;
01990           }
01991           else {
01992             (da->id->name)[-1] = 2;
01993             nPrefixes++;
01994             appAtts[attIndex++] = da->id->name;
01995             appAtts[attIndex++] = da->value;
01996           }
01997         }
01998         else {
01999           (da->id->name)[-1] = 1;
02000           appAtts[attIndex++] = da->id->name;
02001           appAtts[attIndex++] = da->value;
02002         }
02003       }
02004     }
02005     appAtts[attIndex] = 0;
02006   }
02007   i = 0;
02008   if (nPrefixes) {
02009     /* expand prefixed attribute names */
02010     for (; i < attIndex; i += 2) {
02011       if (appAtts[i][-1] == 2) {
02012         ATTRIBUTE_ID *id;
02013         ((XML_Char *)(appAtts[i]))[-1] = 0;
02014         id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
02015         if (id->prefix->binding) {
02016           int j;
02017           const BINDING *b = id->prefix->binding;
02018           const XML_Char *s = appAtts[i];
02019           for (j = 0; j < b->uriLen; j++) {
02020             if (!poolAppendChar(&tempPool, b->uri[j]))
02021               return XML_ERROR_NO_MEMORY;
02022           }
02023           while (*s++ != ':')
02024             ;
02025           do {
02026             if (!poolAppendChar(&tempPool, *s))
02027               return XML_ERROR_NO_MEMORY;
02028           } while (*s++);
02029           if (ns_triplets) {
02030             tempPool.ptr[-1] = namespaceSeparator;
02031             s = b->prefix->name;
02032             do {
02033               if (!poolAppendChar(&tempPool, *s))
02034                 return XML_ERROR_NO_MEMORY;
02035             } while (*s++);
02036           }
02037 
02038           appAtts[i] = poolStart(&tempPool);
02039           poolFinish(&tempPool);
02040         }
02041         if (!--nPrefixes)
02042           break;
02043       }
02044       else
02045         ((XML_Char *)(appAtts[i]))[-1] = 0;
02046     }
02047   }
02048   /* clear the flags that say whether attributes were specified */
02049   for (; i < attIndex; i += 2)
02050     ((XML_Char *)(appAtts[i]))[-1] = 0;
02051   if (!tagNamePtr)
02052     return XML_ERROR_NONE;
02053   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
02054     binding->attId->name[-1] = 0;
02055   /* expand the element type name */
02056   if (elementType->prefix) {
02057     binding = elementType->prefix->binding;
02058     if (!binding)
02059       return XML_ERROR_NONE;
02060     localPart = tagNamePtr->str;
02061     while (*localPart++ != XML_T(':'))
02062       ;
02063   }
02064   else if (dtd.defaultPrefix.binding) {
02065     binding = dtd.defaultPrefix.binding;
02066     localPart = tagNamePtr->str;
02067   }
02068   else
02069     return XML_ERROR_NONE;
02070   tagNamePtr->localPart = localPart;
02071   tagNamePtr->uriLen = binding->uriLen;
02072   for (i = 0; localPart[i++];)
02073     ;
02074   n = i + binding->uriLen;
02075   if (n > binding->uriAlloc) {
02076     TAG *p;
02077     XML_Char *uri = MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
02078     if (!uri)
02079       return XML_ERROR_NO_MEMORY;
02080     binding->uriAlloc = n + EXPAND_SPARE;
02081     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
02082     for (p = tagStack; p; p = p->parent)
02083       if (p->name.str == binding->uri)
02084         p->name.str = uri;
02085     FREE(binding->uri);
02086     binding->uri = uri;
02087   }
02088   memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
02089   tagNamePtr->str = binding->uri;
02090   return XML_ERROR_NONE;
02091 }
02092 
02093 static
02094 int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
02095 {
02096   BINDING *b;
02097   int len;
02098   for (len = 0; uri[len]; len++)
02099     ;
02100   if (namespaceSeparator)
02101     len++;
02102   if (freeBindingList) {
02103     b = freeBindingList;
02104     if (len > b->uriAlloc) {
02105       b->uri = REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
02106       if (!b->uri)
02107         return 0;
02108       b->uriAlloc = len + EXPAND_SPARE;
02109     }
02110     freeBindingList = b->nextTagBinding;
02111   }
02112   else {
02113     b = MALLOC(sizeof(BINDING));
02114     if (!b)
02115       return 0;
02116     b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
02117     if (!b->uri) {
02118       FREE(b);
02119       return 0;
02120     }
02121     b->uriAlloc = len + EXPAND_SPARE;
02122   }
02123   b->uriLen = len;
02124   memcpy(b->uri, uri, len * sizeof(XML_Char));
02125   if (namespaceSeparator)
02126     b->uri[len - 1] = namespaceSeparator;
02127   b->prefix = prefix;
02128   b->attId = attId;
02129   b->prevPrefixBinding = prefix->binding;
02130   if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
02131     prefix->binding = 0;
02132   else
02133     prefix->binding = b;
02134   b->nextTagBinding = *bindingsPtr;
02135   *bindingsPtr = b;
02136   if (startNamespaceDeclHandler)
02137     startNamespaceDeclHandler(handlerArg, prefix->name,
02138                               prefix->binding ? uri : 0);
02139   return 1;
02140 }
02141 
02142 /* The idea here is to avoid using stack for each CDATA section when
02143 the whole file is parsed with one call. */
02144 
02145 static
02146 enum XML_Error cdataSectionProcessor(XML_Parser parser,
02147                                      const char *start,
02148                                      const char *end,
02149                                      const char **endPtr)
02150 {
02151   enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
02152   if (start) {
02153     processor = contentProcessor;
02154     return contentProcessor(parser, start, end, endPtr);
02155   }
02156   return result;
02157 }
02158 
02159 /* startPtr gets set to non-null is the section is closed, and to null if
02160 the section is not yet closed. */
02161 
02162 static
02163 enum XML_Error doCdataSection(XML_Parser parser,
02164                               const ENCODING *enc,
02165                               const char **startPtr,
02166                               const char *end,
02167                               const char **nextPtr)
02168 {
02169   const char *s = *startPtr;
02170   const char **eventPP;
02171   const char **eventEndPP;
02172   if (enc == encoding) {
02173     eventPP = &eventPtr;
02174     *eventPP = s;
02175     eventEndPP = &eventEndPtr;
02176   }
02177   else {
02178     eventPP = &(openInternalEntities->internalEventPtr);
02179     eventEndPP = &(openInternalEntities->internalEventEndPtr);
02180   }
02181   *eventPP = s;
02182   *startPtr = 0;
02183   for (;;) {
02184     const char *next;
02185     int tok = XmlCdataSectionTok(enc, s, end, &next);
02186     *eventEndPP = next;
02187     switch (tok) {
02188     case XML_TOK_CDATA_SECT_CLOSE:
02189       if (endCdataSectionHandler)
02190         endCdataSectionHandler(handlerArg);
02191 #if 0
02192       /* see comment under XML_TOK_CDATA_SECT_OPEN */
02193       else if (characterDataHandler)
02194         characterDataHandler(handlerArg, dataBuf, 0);
02195 #endif
02196       else if (defaultHandler)
02197         reportDefault(parser, enc, s, next);
02198       *startPtr = next;
02199       return XML_ERROR_NONE;
02200     case XML_TOK_DATA_NEWLINE:
02201       if (characterDataHandler) {
02202         XML_Char c = 0xA;
02203         characterDataHandler(handlerArg, &c, 1);
02204       }
02205       else if (defaultHandler)
02206         reportDefault(parser, enc, s, next);
02207       break;
02208     case XML_TOK_DATA_CHARS:
02209       if (characterDataHandler) {
02210         if (MUST_CONVERT(enc, s)) {
02211           for (;;) {
02212             ICHAR *dataPtr = (ICHAR *)dataBuf;
02213             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
02214             *eventEndPP = next;
02215             characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
02216             if (s == next)
02217               break;
02218             *eventPP = s;
02219           }
02220         }
02221         else
02222           characterDataHandler(handlerArg,
02223                                (XML_Char *)s,
02224                                (XML_Char *)next - (XML_Char *)s);
02225       }
02226       else if (defaultHandler)
02227         reportDefault(parser, enc, s, next);
02228       break;
02229     case XML_TOK_INVALID:
02230       *eventPP = next;
02231       return XML_ERROR_INVALID_TOKEN;
02232     case XML_TOK_PARTIAL_CHAR:
02233       if (nextPtr) {
02234         *nextPtr = s;
02235         return XML_ERROR_NONE;
02236       }
02237       return XML_ERROR_PARTIAL_CHAR;
02238     case XML_TOK_PARTIAL:
02239     case XML_TOK_NONE:
02240       if (nextPtr) {
02241         *nextPtr = s;
02242         return XML_ERROR_NONE;
02243       }
02244       return XML_ERROR_UNCLOSED_CDATA_SECTION;
02245     default:
02246       *eventPP = next;
02247       return XML_ERROR_UNEXPECTED_STATE;
02248     }
02249     *eventPP = s = next;
02250   }
02251   /* not reached */
02252 }
02253 
02254 #ifdef XML_DTD
02255 
02256 /* The idea here is to avoid using stack for each IGNORE section when
02257 the whole file is parsed with one call. */
02258 
02259 static
02260 enum XML_Error ignoreSectionProcessor(XML_Parser parser,
02261                                       const char *start,
02262                                       const char *end,
02263                                       const char **endPtr)
02264 {
02265   enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
02266   if (start) {
02267     processor = prologProcessor;
02268     return prologProcessor(parser, start, end, endPtr);
02269   }
02270   return result;
02271 }
02272 
02273 /* startPtr gets set to non-null is the section is closed, and to null if
02274 the section is not yet closed. */
02275 
02276 static
02277 enum XML_Error doIgnoreSection(XML_Parser parser,
02278                                const ENCODING *enc,
02279                                const char **startPtr,
02280                                const char *end,
02281                                const char **nextPtr)
02282 {
02283   const char *next;
02284   int tok;
02285   const char *s = *startPtr;
02286   const char **eventPP;
02287   const char **eventEndPP;
02288   if (enc == encoding) {
02289     eventPP = &eventPtr;
02290     *eventPP = s;
02291     eventEndPP = &eventEndPtr;
02292   }
02293   else {
02294     eventPP = &(openInternalEntities->internalEventPtr);
02295     eventEndPP = &(openInternalEntities->internalEventEndPtr);
02296   }
02297   *eventPP = s;
02298   *startPtr = 0;
02299   tok = XmlIgnoreSectionTok(enc, s, end, &next);
02300   *eventEndPP = next;
02301   switch (tok) {
02302   case XML_TOK_IGNORE_SECT:
02303     if (defaultHandler)
02304       reportDefault(parser, enc, s, next);
02305     *startPtr = next;
02306     return XML_ERROR_NONE;
02307   case XML_TOK_INVALID:
02308     *eventPP = next;
02309     return XML_ERROR_INVALID_TOKEN;
02310   case XML_TOK_PARTIAL_CHAR:
02311     if (nextPtr) {
02312       *nextPtr = s;
02313       return XML_ERROR_NONE;
02314     }
02315     return XML_ERROR_PARTIAL_CHAR;
02316   case XML_TOK_PARTIAL:
02317   case XML_TOK_NONE:
02318     if (nextPtr) {
02319       *nextPtr = s;
02320       return XML_ERROR_NONE;
02321     }
02322     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
02323   default:
02324     *eventPP = next;
02325     return XML_ERROR_UNEXPECTED_STATE;
02326   }
02327   /* not reached */
02328 }
02329 
02330 #endif /* XML_DTD */
02331 
02332 static enum XML_Error
02333 initializeEncoding(XML_Parser parser)
02334 {
02335   const char *s;
02336 #ifdef XML_UNICODE
02337   char encodingBuf[128];
02338   if (!protocolEncodingName)
02339     s = 0;
02340   else {
02341     int i;
02342     for (i = 0; protocolEncodingName[i]; i++) {
02343       if (i == sizeof(encodingBuf) - 1
02344           || (protocolEncodingName[i] & ~0x7f) != 0) {
02345         encodingBuf[0] = '\0';
02346         break;
02347       }
02348       encodingBuf[i] = (char)protocolEncodingName[i];
02349     }
02350     encodingBuf[i] = '\0';
02351     s = encodingBuf;
02352   }
02353 #else
02354   s = protocolEncodingName;
02355 #endif
02356   if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
02357     return XML_ERROR_NONE;
02358   return handleUnknownEncoding(parser, protocolEncodingName);
02359 }
02360 
02361 static enum XML_Error
02362 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
02363                const char *s, const char *next)
02364 {
02365   const char *encodingName = 0;
02366   const char *storedEncName = 0;
02367   const ENCODING *newEncoding = 0;
02368   const char *version = 0;
02369   const char *versionend;
02370   const char *storedversion = 0;
02371   int standalone = -1;
02372   if (!(ns
02373         ? XmlParseXmlDeclNS
02374         : XmlParseXmlDecl)(isGeneralTextEntity,
02375                            encoding,
02376                            s,
02377                            next,
02378                            &eventPtr,
02379                            &version,
02380                            &versionend,
02381                            &encodingName,
02382                            &newEncoding,
02383                            &standalone))
02384     return XML_ERROR_SYNTAX;
02385   if (!isGeneralTextEntity && standalone == 1) {
02386     dtd.standalone = 1;
02387 #ifdef XML_DTD
02388     if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
02389       paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
02390 #endif /* XML_DTD */
02391   }
02392   if (xmlDeclHandler) {
02393     if (encodingName) {
02394       storedEncName = poolStoreString(&temp2Pool,
02395                                       encoding,
02396                                       encodingName,
02397                                       encodingName
02398                                       + XmlNameLength(encoding, encodingName));
02399       if (! storedEncName)
02400         return XML_ERROR_NO_MEMORY;
02401       poolFinish(&temp2Pool);
02402     }
02403     if (version) {
02404       storedversion = poolStoreString(&temp2Pool,
02405                                       encoding,
02406                                       version,
02407                                       versionend - encoding->minBytesPerChar);
02408       if (! storedversion)
02409         return XML_ERROR_NO_MEMORY;
02410     }
02411     xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
02412   }
02413   else if (defaultHandler)
02414     reportDefault(parser, encoding, s, next);
02415   if (!protocolEncodingName) {
02416     if (newEncoding) {
02417       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
02418         eventPtr = encodingName;
02419         return XML_ERROR_INCORRECT_ENCODING;
02420       }
02421       encoding = newEncoding;
02422     }
02423     else if (encodingName) {
02424       enum XML_Error result;
02425       if (! storedEncName) {
02426         storedEncName = poolStoreString(&temp2Pool,
02427                                         encoding,
02428                                         encodingName,
02429                                         encodingName
02430                                         + XmlNameLength(encoding, encodingName));
02431         if (! storedEncName)
02432           return XML_ERROR_NO_MEMORY;
02433       }
02434       result = handleUnknownEncoding(parser, storedEncName);
02435       poolClear(&tempPool);
02436       if (result == XML_ERROR_UNKNOWN_ENCODING)
02437         eventPtr = encodingName;
02438       return result;
02439     }
02440   }
02441 
02442   if (storedEncName || storedversion)
02443     poolClear(&temp2Pool);
02444 
02445   return XML_ERROR_NONE;
02446 }
02447 
02448 static enum XML_Error
02449 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
02450 {
02451   if (unknownEncodingHandler) {
02452     XML_Encoding info;
02453     int i;
02454     for (i = 0; i < 256; i++)
02455       info.map[i] = -1;
02456     info.convert = 0;
02457     info.data = 0;
02458     info.release = 0;
02459     if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
02460       ENCODING *enc;
02461       unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
02462       if (!unknownEncodingMem) {
02463         if (info.release)
02464           info.release(info.data);
02465         return XML_ERROR_NO_MEMORY;
02466       }
02467       enc = (ns
02468              ? XmlInitUnknownEncodingNS
02469              : XmlInitUnknownEncoding)(unknownEncodingMem,
02470                                        info.map,
02471                                        info.convert,
02472                                        info.data);
02473       if (enc) {
02474         unknownEncodingData = info.data;
02475         unknownEncodingRelease = info.release;
02476         encoding = enc;
02477         return XML_ERROR_NONE;
02478       }
02479     }
02480     if (info.release)
02481       info.release(info.data);
02482   }
02483   return XML_ERROR_UNKNOWN_ENCODING;
02484 }
02485 
02486 static enum XML_Error
02487 prologInitProcessor(XML_Parser parser,
02488                     const char *s,
02489                     const char *end,
02490                     const char **nextPtr)
02491 {
02492   enum XML_Error result = initializeEncoding(parser);
02493   if (result != XML_ERROR_NONE)
02494     return result;
02495   processor = prologProcessor;
02496   return prologProcessor(parser, s, end, nextPtr);
02497 }
02498 
02499 static enum XML_Error
02500 prologProcessor(XML_Parser parser,
02501                 const char *s,
02502                 const char *end,
02503                 const char **nextPtr)
02504 {
02505   const char *next;
02506   int tok = XmlPrologTok(encoding, s, end, &next);
02507   return doProlog(parser, encoding, s, end, tok, next, nextPtr);
02508 }
02509 
02510 static enum XML_Error
02511 doProlog(XML_Parser parser,
02512          const ENCODING *enc,
02513          const char *s,
02514          const char *end,
02515          int tok,
02516          const char *next,
02517          const char **nextPtr)
02518 {
02519 #ifdef XML_DTD
02520   static const XML_Char externalSubsetName[] = { '#' , '\0' };
02521 #endif /* XML_DTD */
02522 
02523   const char **eventPP;
02524   const char **eventEndPP;
02525   enum XML_Content_Quant quant;
02526 
02527   if (enc == encoding) {
02528     eventPP = &eventPtr;
02529     eventEndPP = &eventEndPtr;
02530   }
02531   else {
02532     eventPP = &(openInternalEntities->internalEventPtr);
02533     eventEndPP = &(openInternalEntities->internalEventEndPtr);
02534   }
02535   for (;;) {
02536     int role;
02537     *eventPP = s;
02538     *eventEndPP = next;
02539     if (tok <= 0) {
02540       if (nextPtr != 0 && tok != XML_TOK_INVALID) {
02541         *nextPtr = s;
02542         return XML_ERROR_NONE;
02543       }
02544       switch (tok) {
02545       case XML_TOK_INVALID:
02546         *eventPP = next;
02547         return XML_ERROR_INVALID_TOKEN;
02548       case XML_TOK_PARTIAL:
02549         return XML_ERROR_UNCLOSED_TOKEN;
02550       case XML_TOK_PARTIAL_CHAR:
02551         return XML_ERROR_PARTIAL_CHAR;
02552       case XML_TOK_NONE:
02553 #ifdef XML_DTD
02554         if (enc != encoding)
02555           return XML_ERROR_NONE;
02556         if (parentParser) {
02557           if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
02558               == XML_ROLE_ERROR)
02559             return XML_ERROR_SYNTAX;
02560           hadExternalDoctype = 0;
02561           return XML_ERROR_NONE;
02562         }
02563 #endif /* XML_DTD */
02564         return XML_ERROR_NO_ELEMENTS;
02565       default:
02566         tok = -tok;
02567         next = end;
02568         break;
02569       }
02570     }
02571     role = XmlTokenRole(&prologState, tok, s, next, enc);
02572     switch (role) {
02573     case XML_ROLE_XML_DECL:
02574       {
02575         enum XML_Error result = processXmlDecl(parser, 0, s, next);
02576         if (result != XML_ERROR_NONE)
02577           return result;
02578         enc = encoding;
02579       }
02580       break;
02581     case XML_ROLE_DOCTYPE_NAME:
02582       if (startDoctypeDeclHandler) {
02583         doctypeName = poolStoreString(&tempPool, enc, s, next);
02584         if (! doctypeName)
02585           return XML_ERROR_NO_MEMORY;
02586         poolFinish(&tempPool);
02587         doctypeSysid = 0;
02588         doctypePubid = 0;
02589       }
02590       break;
02591     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
02592       if (startDoctypeDeclHandler) {
02593         startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
02594                                 doctypePubid, 1);
02595         doctypeName = 0;
02596         poolClear(&tempPool);
02597       }
02598       break;
02599 #ifdef XML_DTD
02600     case XML_ROLE_TEXT_DECL:
02601       {
02602         enum XML_Error result = processXmlDecl(parser, 1, s, next);
02603         if (result != XML_ERROR_NONE)
02604           return result;
02605         enc = encoding;
02606       }
02607       break;
02608 #endif /* XML_DTD */
02609     case XML_ROLE_DOCTYPE_PUBLIC_ID:
02610       if (startDoctypeDeclHandler) {
02611         doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1);
02612         if (! doctypePubid)
02613           return XML_ERROR_NO_MEMORY;
02614         poolFinish(&tempPool);
02615       }
02616 #ifdef XML_DTD
02617       declEntity = (ENTITY *)lookup(&dtd.paramEntities,
02618                                     externalSubsetName,
02619                                     sizeof(ENTITY));
02620       if (!declEntity)
02621         return XML_ERROR_NO_MEMORY;
02622 #endif /* XML_DTD */
02623       /* fall through */
02624     case XML_ROLE_ENTITY_PUBLIC_ID:
02625       if (!XmlIsPublicId(enc, s, next, eventPP))
02626         return XML_ERROR_SYNTAX;
02627       if (declEntity) {
02628         XML_Char *tem = poolStoreString(&dtd.pool,
02629                                         enc,
02630                                         s + enc->minBytesPerChar,
02631                                         next - enc->minBytesPerChar);
02632         if (!tem)
02633           return XML_ERROR_NO_MEMORY;
02634         normalizePublicId(tem);
02635         declEntity->publicId = tem;
02636         poolFinish(&dtd.pool);
02637       }
02638       break;
02639     case XML_ROLE_DOCTYPE_CLOSE:
02640       if (doctypeName) {
02641         startDoctypeDeclHandler(handlerArg, doctypeName,
02642                                 doctypeSysid, doctypePubid, 0);
02643         poolClear(&tempPool);
02644       }
02645       if (dtd.complete && hadExternalDoctype) {
02646         dtd.complete = 0;
02647 #ifdef XML_DTD
02648         if (paramEntityParsing && externalEntityRefHandler) {
02649           ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
02650                                             externalSubsetName,
02651                                             0);
02652           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
02653                                         0,
02654                                         entity->base,
02655                                         entity->systemId,
02656                                         entity->publicId))
02657            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
02658         }
02659 #endif /* XML_DTD */
02660         if (!dtd.complete
02661             && !dtd.standalone
02662             && notStandaloneHandler
02663             && !notStandaloneHandler(handlerArg))
02664           return XML_ERROR_NOT_STANDALONE;
02665       }
02666       if (endDoctypeDeclHandler)
02667         endDoctypeDeclHandler(handlerArg);
02668       break;
02669     case XML_ROLE_INSTANCE_START:
02670       processor = contentProcessor;
02671       return contentProcessor(parser, s, end, nextPtr);
02672     case XML_ROLE_ATTLIST_ELEMENT_NAME:
02673       declElementType = getElementType(parser, enc, s, next);
02674       if (!declElementType)
02675         return XML_ERROR_NO_MEMORY;
02676       break;
02677     case XML_ROLE_ATTRIBUTE_NAME:
02678       declAttributeId = getAttributeId(parser, enc, s, next);
02679       if (!declAttributeId)
02680         return XML_ERROR_NO_MEMORY;
02681       declAttributeIsCdata = 0;
02682       declAttributeType = 0;
02683       declAttributeIsId = 0;
02684       break;
02685     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
02686       declAttributeIsCdata = 1;
02687       declAttributeType = "CDATA";
02688       break;
02689     case XML_ROLE_ATTRIBUTE_TYPE_ID:
02690       declAttributeIsId = 1;
02691       declAttributeType = "ID";
02692       break;
02693     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
02694       declAttributeType = "IDREF";
02695       break;
02696     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
02697       declAttributeType = "IDREFS";
02698       break;
02699     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
02700       declAttributeType = "ENTITY";
02701       break;
02702     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
02703       declAttributeType = "ENTITIES";
02704       break;
02705     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
02706       declAttributeType = "NMTOKEN";
02707       break;
02708     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
02709       declAttributeType = "NMTOKENS";
02710       break;
02711 
02712     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
02713     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
02714       if (attlistDeclHandler)
02715       {
02716         char *prefix;
02717         if (declAttributeType) {
02718           prefix = "|";
02719         }
02720         else {
02721           prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
02722                     ? "NOTATION("
02723                     : "(");
02724         }
02725         if (! poolAppendString(&tempPool, prefix))
02726           return XML_ERROR_NO_MEMORY;
02727         if (! poolAppend(&tempPool, enc, s, next))
02728           return XML_ERROR_NO_MEMORY;
02729         declAttributeType = tempPool.start;
02730       }
02731       break;
02732     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
02733     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
02734       if (dtd.complete
02735           && !defineAttribute(declElementType, declAttributeId,
02736                               declAttributeIsCdata, declAttributeIsId, 0,
02737                               parser))
02738         return XML_ERROR_NO_MEMORY;
02739       if (attlistDeclHandler && declAttributeType) {
02740         if (*declAttributeType == '('
02741             || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
02742           /* Enumerated or Notation type */
02743           if (! poolAppendChar(&tempPool, ')')
02744               || ! poolAppendChar(&tempPool, '\0'))
02745             return XML_ERROR_NO_MEMORY;
02746           declAttributeType = tempPool.start;
02747           poolFinish(&tempPool);
02748         }
02749         *eventEndPP = s;
02750         attlistDeclHandler(handlerArg, declElementType->name,
02751                            declAttributeId->name, declAttributeType,
02752                            0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
02753         poolClear(&tempPool);
02754       }
02755       break;
02756     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
02757     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
02758       {
02759         const XML_Char *attVal;
02760         enum XML_Error result
02761           = storeAttributeValue(parser, enc, declAttributeIsCdata,
02762                                 s + enc->minBytesPerChar,
02763                                 next - enc->minBytesPerChar,
02764                                 &dtd.pool);
02765         if (result)
02766           return result;
02767         attVal = poolStart(&dtd.pool);
02768         poolFinish(&dtd.pool);
02769         if (dtd.complete
02770             /* ID attributes aren't allowed to have a default */
02771             && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
02772           return XML_ERROR_NO_MEMORY;
02773         if (attlistDeclHandler && declAttributeType) {
02774           if (*declAttributeType == '('
02775               || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
02776             /* Enumerated or Notation type */
02777             if (! poolAppendChar(&tempPool, ')')
02778                 || ! poolAppendChar(&tempPool, '\0'))
02779               return XML_ERROR_NO_MEMORY;
02780             declAttributeType = tempPool.start;
02781             poolFinish(&tempPool);
02782           }
02783           *eventEndPP = s;
02784           attlistDeclHandler(handlerArg, declElementType->name,
02785                              declAttributeId->name, declAttributeType,
02786                              attVal,
02787                              role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
02788           poolClear(&tempPool);
02789         }
02790         break;
02791       }
02792     case XML_ROLE_ENTITY_VALUE:
02793       {
02794         enum XML_Error result = storeEntityValue(parser, enc,
02795                                                  s + enc->minBytesPerChar,
02796                                                  next - enc->minBytesPerChar);
02797         if (declEntity) {
02798           declEntity->textPtr = poolStart(&dtd.pool);
02799           declEntity->textLen = poolLength(&dtd.pool);
02800           poolFinish(&dtd.pool);
02801           if (entityDeclHandler) {
02802             *eventEndPP = s;
02803             entityDeclHandler(handlerArg,
02804                               declEntity->name,
02805                               declEntity->is_param,
02806                               declEntity->textPtr,
02807                               declEntity->textLen,
02808                               curBase, 0, 0, 0);
02809           }
02810         }
02811         else
02812           poolDiscard(&dtd.pool);
02813         if (result != XML_ERROR_NONE)
02814           return result;
02815       }
02816       break;
02817     case XML_ROLE_DOCTYPE_SYSTEM_ID:
02818       if (startDoctypeDeclHandler) {
02819         doctypeSysid = poolStoreString(&tempPool, enc, s + 1, next - 1);
02820         if (! doctypeSysid)
02821           return XML_ERROR_NO_MEMORY;
02822         poolFinish(&tempPool);
02823       }
02824       if (!dtd.standalone
02825 #ifdef XML_DTD
02826           && !paramEntityParsing
02827 #endif /* XML_DTD */
02828           && notStandaloneHandler
02829           && !notStandaloneHandler(handlerArg))
02830         return XML_ERROR_NOT_STANDALONE;
02831       hadExternalDoctype = 1;
02832 #ifndef XML_DTD
02833       break;
02834 #else /* XML_DTD */
02835       if (!declEntity) {
02836         declEntity = (ENTITY *)lookup(&dtd.paramEntities,
02837                                       externalSubsetName,
02838                                       sizeof(ENTITY));
02839         declEntity->publicId = 0;
02840         if (!declEntity)
02841           return XML_ERROR_NO_MEMORY;
02842       }
02843       /* fall through */
02844 #endif /* XML_DTD */
02845     case XML_ROLE_ENTITY_SYSTEM_ID:
02846       if (declEntity) {
02847         declEntity->systemId = poolStoreString(&dtd.pool, enc,
02848                                                s + enc->minBytesPerChar,
02849                                                next - enc->minBytesPerChar);
02850         if (!declEntity->systemId)
02851           return XML_ERROR_NO_MEMORY;
02852         declEntity->base = curBase;
02853         poolFinish(&dtd.pool);
02854       }
02855       break;
02856     case XML_ROLE_ENTITY_COMPLETE:
02857       if (declEntity && entityDeclHandler) {
02858         *eventEndPP = s;
02859         entityDeclHandler(handlerArg,
02860                           declEntity->name,
02861                           0,0,0,
02862                           declEntity->base,
02863                           declEntity->systemId,
02864                           declEntity->publicId,
02865                           0);
02866       }
02867       break;
02868     case XML_ROLE_ENTITY_NOTATION_NAME:
02869       if (declEntity) {
02870         declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
02871         if (!declEntity->notation)
02872           return XML_ERROR_NO_MEMORY;
02873         poolFinish(&dtd.pool);
02874         if (unparsedEntityDeclHandler) {
02875           *eventEndPP = s;
02876           unparsedEntityDeclHandler(handlerArg,
02877                                     declEntity->name,
02878                                     declEntity->base,
02879                                     declEntity->systemId,
02880                                     declEntity->publicId,
02881                                     declEntity->notation);
02882         }
02883         else if (entityDeclHandler) {
02884           *eventEndPP = s;
02885           entityDeclHandler(handlerArg,
02886                             declEntity->name,
02887                             0,0,0,
02888                             declEntity->base,
02889                             declEntity->systemId,
02890                             declEntity->publicId,
02891                             declEntity->notation);
02892         }
02893       }
02894       break;
02895     case XML_ROLE_GENERAL_ENTITY_NAME:
02896       {
02897         const XML_Char *name;
02898         if (XmlPredefinedEntityName(enc, s, next)) {
02899           declEntity = 0;
02900           break;
02901         }
02902         name = poolStoreString(&dtd.pool, enc, s, next);
02903         if (!name)
02904           return XML_ERROR_NO_MEMORY;
02905         if (dtd.complete) {
02906           declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
02907           if (!declEntity)
02908             return XML_ERROR_NO_MEMORY;
02909           if (declEntity->name != name) {
02910             poolDiscard(&dtd.pool);
02911             declEntity = 0;
02912           }
02913           else {
02914             poolFinish(&dtd.pool);
02915             declEntity->publicId = 0;
02916             declEntity->is_param = 0;
02917           }
02918         }
02919         else {
02920           poolDiscard(&dtd.pool);
02921           declEntity = 0;
02922         }
02923       }
02924       break;
02925     case XML_ROLE_PARAM_ENTITY_NAME:
02926 #ifdef XML_DTD
02927       if (dtd.complete) {
02928         const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
02929         if (!name)
02930           return XML_ERROR_NO_MEMORY;
02931         declEntity = (ENTITY *)lookup(&dtd.paramEntities,
02932                                       name, sizeof(ENTITY));
02933         if (!declEntity)
02934           return XML_ERROR_NO_MEMORY;
02935         if (declEntity->name != name) {
02936           poolDiscard(&dtd.pool);
02937           declEntity = 0;
02938         }
02939         else {
02940           poolFinish(&dtd.pool);
02941           declEntity->publicId = 0;
02942           declEntity->is_param = 1;
02943         }
02944       }
02945 #else /* not XML_DTD */
02946       declEntity = 0;
02947 #endif /* not XML_DTD */
02948       break;
02949     case XML_ROLE_NOTATION_NAME:
02950       declNotationPublicId = 0;
02951       declNotationName = 0;
02952       if (notationDeclHandler) {
02953         declNotationName = poolStoreString(&tempPool, enc, s, next);
02954         if (!declNotationName)
02955           return XML_ERROR_NO_MEMORY;
02956         poolFinish(&tempPool);
02957       }
02958       break;
02959     case XML_ROLE_NOTATION_PUBLIC_ID:
02960       if (!XmlIsPublicId(enc, s, next, eventPP))
02961         return XML_ERROR_SYNTAX;
02962       if (declNotationName) {
02963         XML_Char *tem = poolStoreString(&tempPool,
02964                                         enc,
02965                                         s + enc->minBytesPerChar,
02966                                         next - enc->minBytesPerChar);
02967         if (!tem)
02968           return XML_ERROR_NO_MEMORY;
02969         normalizePublicId(tem);
02970         declNotationPublicId = tem;
02971         poolFinish(&tempPool);
02972       }
02973       break;
02974     case XML_ROLE_NOTATION_SYSTEM_ID:
02975       if (declNotationName && notationDeclHandler) {
02976         const XML_Char *systemId
02977           = poolStoreString(&tempPool, enc,
02978                             s + enc->minBytesPerChar,
02979                             next - enc->minBytesPerChar);
02980         if (!systemId)
02981           return XML_ERROR_NO_MEMORY;
02982         *eventEndPP = s;
02983         notationDeclHandler(handlerArg,
02984                             declNotationName,
02985                             curBase,
02986                             systemId,
02987                             declNotationPublicId);
02988       }
02989       poolClear(&tempPool);
02990       break;
02991     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
02992       if (declNotationPublicId && notationDeclHandler) {
02993         *eventEndPP = s;
02994         notationDeclHandler(handlerArg,
02995                             declNotationName,
02996                             curBase,
02997                             0,
02998                             declNotationPublicId);
02999       }
03000       poolClear(&tempPool);
03001       break;
03002     case XML_ROLE_ERROR:
03003       switch (tok) {
03004       case XML_TOK_PARAM_ENTITY_REF:
03005         return XML_ERROR_PARAM_ENTITY_REF;
03006       case XML_TOK_XML_DECL:
03007         return XML_ERROR_MISPLACED_XML_PI;
03008       default:
03009         return XML_ERROR_SYNTAX;
03010       }
03011 #ifdef XML_DTD
03012     case XML_ROLE_IGNORE_SECT:
03013       {
03014         enum XML_Error result;
03015         if (defaultHandler)
03016           reportDefault(parser, enc, s, next);
03017         result = doIgnoreSection(parser, enc, &next, end, nextPtr);
03018         if (!next) {
03019           processor = ignoreSectionProcessor;
03020           return result;
03021         }
03022       }
03023       break;
03024 #endif /* XML_DTD */
03025     case XML_ROLE_GROUP_OPEN:
03026       if (prologState.level >= groupSize) {
03027         if (groupSize) {
03028           groupConnector = REALLOC(groupConnector, groupSize *= 2);
03029           if (dtd.scaffIndex)
03030             dtd.scaffIndex = REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
03031         }
03032         else
03033           groupConnector = MALLOC(groupSize = 32);
03034         if (!groupConnector)
03035           return XML_ERROR_NO_MEMORY;
03036       }
03037       groupConnector[prologState.level] = 0;
03038       if (dtd.in_eldecl) {
03039         int myindex = nextScaffoldPart(parser);
03040         if (myindex < 0)
03041           return XML_ERROR_NO_MEMORY;
03042         dtd.scaffIndex[dtd.scaffLevel] = myindex;
03043         dtd.scaffLevel++;
03044         dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
03045       }
03046       break;
03047     case XML_ROLE_GROUP_SEQUENCE:
03048       if (groupConnector[prologState.level] == '|')
03049         return XML_ERROR_SYNTAX;
03050       groupConnector[prologState.level] = ',';
03051       break;
03052     case XML_ROLE_GROUP_CHOICE:
03053       if (groupConnector[prologState.level] == ',')
03054         return XML_ERROR_SYNTAX;
03055       if (dtd.in_eldecl
03056           && ! groupConnector[prologState.level]
03057           && dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type != XML_CTYPE_MIXED
03058           ) {
03059         dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_CHOICE;
03060       }
03061       groupConnector[prologState.level] = '|';
03062       break;
03063     case XML_ROLE_PARAM_ENTITY_REF:
03064 #ifdef XML_DTD
03065     case XML_ROLE_INNER_PARAM_ENTITY_REF:
03066       if (paramEntityParsing
03067           && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
03068         const XML_Char *name;
03069         ENTITY *entity;
03070         name = poolStoreString(&dtd.pool, enc,
03071                                 s + enc->minBytesPerChar,
03072                                 next - enc->minBytesPerChar);
03073         if (!name)
03074           return XML_ERROR_NO_MEMORY;
03075         entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
03076         poolDiscard(&dtd.pool);
03077         if (!entity) {
03078           /* FIXME what to do if !dtd.complete? */
03079           return XML_ERROR_UNDEFINED_ENTITY;
03080         }
03081         if (entity->open)
03082           return XML_ERROR_RECURSIVE_ENTITY_REF;
03083         if (entity->textPtr) {
03084           enum XML_Error result;
03085           result = processInternalParamEntity(parser, entity);
03086           if (result != XML_ERROR_NONE)
03087             return result;
03088           break;
03089         }
03090         if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
03091           return XML_ERROR_PARAM_ENTITY_REF;
03092         if (externalEntityRefHandler) {
03093           dtd.complete = 0;
03094           entity->open = 1;
03095           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
03096                                         0,
03097                                         entity->base,
03098                                         entity->systemId,
03099                                         entity->publicId)) {
03100             entity->open = 0;
03101             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
03102           }
03103           entity->open = 0;
03104           if (dtd.complete)
03105             break;
03106         }
03107       }
03108 #endif /* XML_DTD */
03109       if (!dtd.standalone
03110           && notStandaloneHandler
03111           && !notStandaloneHandler(handlerArg))
03112         return XML_ERROR_NOT_STANDALONE;
03113       dtd.complete = 0;
03114       if (defaultHandler)
03115         reportDefault(parser, enc, s, next);
03116       break;
03117 
03118       /* Element declaration stuff */
03119 
03120     case XML_ROLE_ELEMENT_NAME:
03121       if (elementDeclHandler) {
03122         declElementType = getElementType(parser, enc, s, next);
03123         if (! declElementType)
03124           return XML_ERROR_NO_MEMORY;
03125         dtd.scaffLevel = 0;
03126         dtd.scaffCount = 0;
03127         dtd.in_eldecl = 1;
03128       }
03129       break;
03130 
03131     case XML_ROLE_CONTENT_ANY:
03132     case XML_ROLE_CONTENT_EMPTY:
03133       if (dtd.in_eldecl) {
03134         if (elementDeclHandler) {
03135           XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
03136           if (! content)
03137             return XML_ERROR_NO_MEMORY;
03138           content->quant = XML_CQUANT_NONE;
03139           content->name = 0;
03140           content->numchildren = 0;
03141           content->children = 0;
03142           content->type = ((role == XML_ROLE_CONTENT_ANY) ?
03143                            XML_CTYPE_ANY :
03144                            XML_CTYPE_EMPTY);
03145           *eventEndPP = s;
03146           elementDeclHandler(handlerArg, declElementType->name, content);
03147         }
03148         dtd.in_eldecl = 0;
03149       }
03150       break;
03151       
03152     case XML_ROLE_CONTENT_PCDATA:
03153       if (dtd.in_eldecl) {
03154         dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_MIXED;
03155       }
03156       break;
03157 
03158     case XML_ROLE_CONTENT_ELEMENT:
03159       quant = XML_CQUANT_NONE;
03160       goto elementContent;
03161     case XML_ROLE_CONTENT_ELEMENT_OPT:
03162       quant = XML_CQUANT_OPT;
03163       goto elementContent;
03164     case XML_ROLE_CONTENT_ELEMENT_REP:
03165       quant = XML_CQUANT_REP;
03166       goto elementContent;
03167     case XML_ROLE_CONTENT_ELEMENT_PLUS:
03168       quant = XML_CQUANT_PLUS;
03169     elementContent:
03170       if (dtd.in_eldecl)
03171         {
03172           ELEMENT_TYPE *el;
03173           const char *nxt = quant == XML_CQUANT_NONE ? next : next - 1;
03174           int myindex = nextScaffoldPart(parser);
03175           if (myindex < 0)
03176             return XML_ERROR_NO_MEMORY;
03177           dtd.scaffold[myindex].type = XML_CTYPE_NAME;
03178           dtd.scaffold[myindex].quant = quant;
03179           el = getElementType(parser, enc, s, nxt);
03180           if (! el)
03181             return XML_ERROR_NO_MEMORY;
03182           dtd.scaffold[myindex].name = el->name;
03183           dtd.contentStringLen +=  nxt - s + 1;
03184         }
03185       break;
03186 
03187     case XML_ROLE_GROUP_CLOSE:
03188       quant = XML_CQUANT_NONE;
03189       goto closeGroup;
03190     case XML_ROLE_GROUP_CLOSE_OPT:
03191       quant = XML_CQUANT_OPT;
03192       goto closeGroup;
03193     case XML_ROLE_GROUP_CLOSE_REP:
03194       quant = XML_CQUANT_REP;
03195       goto closeGroup;
03196     case XML_ROLE_GROUP_CLOSE_PLUS:
03197       quant = XML_CQUANT_PLUS;
03198     closeGroup:
03199       if (dtd.in_eldecl) {
03200         dtd.scaffLevel--;
03201         dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
03202         if (dtd.scaffLevel == 0) {
03203           if (elementDeclHandler) {
03204             XML_Content *model = build_model(parser);
03205             if (! model)
03206               return XML_ERROR_NO_MEMORY;
03207             *eventEndPP = s;
03208             elementDeclHandler(handlerArg, declElementType->name, model);
03209           }
03210           dtd.in_eldecl = 0;
03211           dtd.contentStringLen = 0;
03212         }
03213       }
03214       break;
03215       /* End element declaration stuff */
03216 
03217     case XML_ROLE_NONE:
03218       switch (tok) {
03219       case XML_TOK_PI:
03220         if (!reportProcessingInstruction(parser, enc, s, next))
03221           return XML_ERROR_NO_MEMORY;
03222         break;
03223       case XML_TOK_COMMENT:
03224         if (!reportComment(parser, enc, s, next))
03225           return XML_ERROR_NO_MEMORY;
03226         break;
03227       }
03228       break;
03229     }
03230     if (defaultHandler) {
03231       switch (tok) {
03232       case XML_TOK_PI:
03233       case XML_TOK_COMMENT:
03234       case XML_TOK_BOM:
03235       case XML_TOK_XML_DECL:
03236 #ifdef XML_DTD
03237       case XML_TOK_IGNORE_SECT:
03238 #endif /* XML_DTD */
03239       case XML_TOK_PARAM_ENTITY_REF:
03240         break;
03241       default:
03242 #ifdef XML_DTD
03243         if (role != XML_ROLE_IGNORE_SECT)
03244 #endif /* XML_DTD */
03245           reportDefault(parser, enc, s, next);
03246       }
03247     }
03248     s = next;
03249     tok = XmlPrologTok(enc, s, end, &next);
03250   }
03251   /* not reached */
03252 }
03253 
03254 static
03255 enum XML_Error epilogProcessor(XML_Parser parser,
03256                                const char *s,
03257                                const char *end,
03258                                const char **nextPtr)
03259 {
03260   processor = epilogProcessor;
03261   eventPtr = s;
03262   for (;;) {
03263     const char *next;
03264     int tok = XmlPrologTok(encoding, s, end, &next);
03265     eventEndPtr = next;
03266     switch (tok) {
03267     case -XML_TOK_PROLOG_S:
03268       if (defaultHandler) {
03269         eventEndPtr = end;
03270         reportDefault(parser, encoding, s, end);
03271       }
03272       /* fall through */
03273     case XML_TOK_NONE:
03274       if (nextPtr)
03275         *nextPtr = end;
03276       return XML_ERROR_NONE;
03277     case XML_TOK_PROLOG_S:
03278       if (defaultHandler)
03279         reportDefault(parser, encoding, s, next);
03280       break;
03281     case XML_TOK_PI:
03282       if (!reportProcessingInstruction(parser, encoding, s, next))
03283         return XML_ERROR_NO_MEMORY;
03284       break;
03285     case XML_TOK_COMMENT:
03286       if (!reportComment(parser, encoding, s, next))
03287         return XML_ERROR_NO_MEMORY;
03288       break;
03289     case XML_TOK_INVALID:
03290       eventPtr = next;
03291       return XML_ERROR_INVALID_TOKEN;
03292     case XML_TOK_PARTIAL:
03293       if (nextPtr) {
03294         *nextPtr = s;
03295         return XML_ERROR_NONE;
03296       }
03297       return XML_ERROR_UNCLOSED_TOKEN;
03298     case XML_TOK_PARTIAL_CHAR:
03299       if (nextPtr) {
03300         *nextPtr = s;
03301         return XML_ERROR_NONE;
03302       }
03303       return XML_ERROR_PARTIAL_CHAR;
03304     default:
03305       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
03306     }
03307     eventPtr = s = next;
03308   }
03309 }
03310 
03311 #ifdef XML_DTD
03312 
03313 static enum XML_Error
03314 processInternalParamEntity(XML_Parser parser, ENTITY *entity)
03315 {
03316   const char *s, *end, *next;
03317   int tok;
03318   enum XML_Error result;
03319   OPEN_INTERNAL_ENTITY openEntity;
03320   entity->open = 1;
03321   openEntity.next = openInternalEntities;
03322   openInternalEntities = &openEntity;
03323   openEntity.entity = entity;
03324   openEntity.internalEventPtr = 0;
03325   openEntity.internalEventEndPtr = 0;
03326   s = (char *)entity->textPtr;
03327   end = (char *)(entity->textPtr + entity->textLen);
03328   tok = XmlPrologTok(internalEncoding, s, end, &next);
03329   result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
03330   entity->open = 0;
03331   openInternalEntities = openEntity.next;
03332   return result;
03333 }
03334 
03335 #endif /* XML_DTD */
03336 
03337 static
03338 enum XML_Error errorProcessor(XML_Parser parser,
03339                               const char *s,
03340                               const char *end,
03341                               const char **nextPtr)
03342 {
03343   return errorCode;
03344 }
03345 
03346 static enum XML_Error
03347 storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
03348                     const char *ptr, const char *end,
03349                     STRING_POOL *pool)
03350 {
03351   enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
03352   if (result)
03353     return result;
03354   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
03355     poolChop(pool);
03356   if (!poolAppendChar(pool, XML_T('\0')))
03357     return XML_ERROR_NO_MEMORY;
03358   return XML_ERROR_NONE;
03359 }
03360 
03361 static enum XML_Error
03362 appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
03363                      const char *ptr, const char *end,
03364                      STRING_POOL *pool)
03365 {
03366   for (;;) {
03367     const char *next;
03368     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
03369     switch (tok) {
03370     case XML_TOK_NONE:
03371       return XML_ERROR_NONE;
03372     case XML_TOK_INVALID:
03373       if (enc == encoding)
03374         eventPtr = next;
03375       return XML_ERROR_INVALID_TOKEN;
03376     case XML_TOK_PARTIAL:
03377       if (enc == encoding)
03378         eventPtr = ptr;
03379       return XML_ERROR_INVALID_TOKEN;
03380     case XML_TOK_CHAR_REF:
03381       {
03382         XML_Char buf[XML_ENCODE_MAX];
03383         int i;
03384         int n = XmlCharRefNumber(enc, ptr);
03385         if (n < 0) {
03386           if (enc == encoding)
03387             eventPtr = ptr;
03388           return XML_ERROR_BAD_CHAR_REF;
03389         }
03390         if (!isCdata
03391             && n == 0x20 /* space */
03392             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
03393           break;
03394         n = XmlEncode(n, (ICHAR *)buf);
03395         if (!n) {
03396           if (enc == encoding)
03397             eventPtr = ptr;
03398           return XML_ERROR_BAD_CHAR_REF;
03399         }
03400         for (i = 0; i < n; i++) {
03401           if (!poolAppendChar(pool, buf[i]))
03402             return XML_ERROR_NO_MEMORY;
03403         }
03404       }
03405       break;
03406     case XML_TOK_DATA_CHARS:
03407       if (!poolAppend(pool, enc, ptr, next))
03408         return XML_ERROR_NO_MEMORY;
03409       break;
03410       break;
03411     case XML_TOK_TRAILING_CR:
03412       next = ptr + enc->minBytesPerChar;
03413       /* fall through */
03414     case XML_TOK_ATTRIBUTE_VALUE_S:
03415     case XML_TOK_DATA_NEWLINE:
03416       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
03417         break;
03418       if (!poolAppendChar(pool, 0x20))
03419         return XML_ERROR_NO_MEMORY;
03420       break;
03421     case XML_TOK_ENTITY_REF:
03422       {
03423         const XML_Char *name;
03424         ENTITY *entity;
03425         XML_Char ch = XmlPredefinedEntityName(enc,
03426                                               ptr + enc->minBytesPerChar,
03427                                               next - enc->minBytesPerChar);
03428         if (ch) {
03429           if (!poolAppendChar(pool, ch))
03430             return XML_ERROR_NO_MEMORY;
03431           break;
03432         }
03433         name = poolStoreString(&temp2Pool, enc,
03434                                ptr + enc->minBytesPerChar,
03435                                next - enc->minBytesPerChar);
03436         if (!name)
03437           return XML_ERROR_NO_MEMORY;
03438         entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
03439         poolDiscard(&temp2Pool);
03440         if (!entity) {
03441           if (dtd.complete) {
03442             if (enc == encoding)
03443               eventPtr = ptr;
03444             return XML_ERROR_UNDEFINED_ENTITY;
03445           }
03446         }
03447         else if (entity->open) {
03448           if (enc == encoding)
03449             eventPtr = ptr;
03450           return XML_ERROR_RECURSIVE_ENTITY_REF;
03451         }
03452         else if (entity->notation) {
03453           if (enc == encoding)
03454             eventPtr = ptr;
03455           return XML_ERROR_BINARY_ENTITY_REF;
03456         }
03457         else if (!entity->textPtr) {
03458           if (enc == encoding)
03459             eventPtr = ptr;
03460           return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
03461         }
03462         else {
03463           enum XML_Error result;
03464           const XML_Char *textEnd = entity->textPtr + entity->textLen;
03465           entity->open = 1;
03466           result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
03467           entity->open = 0;
03468           if (result)
03469             return result;
03470         }
03471       }
03472       break;
03473     default:
03474       if (enc == encoding)
03475         eventPtr = ptr;
03476       return XML_ERROR_UNEXPECTED_STATE;
03477     }
03478     ptr = next;
03479   }
03480   /* not reached */
03481 }
03482 
03483 static
03484 enum XML_Error storeEntityValue(XML_Parser parser,
03485                                 const ENCODING *enc,
03486                                 const char *entityTextPtr,
03487                                 const char *entityTextEnd)
03488 {
03489   STRING_POOL *pool = &(dtd.pool);
03490   for (;;) {
03491     const char *next;
03492     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
03493     switch (tok) {
03494     case XML_TOK_PARAM_ENTITY_REF:
03495 #ifdef XML_DTD
03496       if (parentParser || enc != encoding) {
03497         enum XML_Error result;
03498         const XML_Char *name;
03499         ENTITY *entity;
03500         name = poolStoreString(&tempPool, enc,
03501                                entityTextPtr + enc->minBytesPerChar,
03502                                next - enc->minBytesPerChar);
03503         if (!name)
03504           return XML_ERROR_NO_MEMORY;
03505         entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
03506         poolDiscard(&tempPool);
03507         if (!entity) {
03508           if (enc == encoding)
03509             eventPtr = entityTextPtr;
03510           return XML_ERROR_UNDEFINED_ENTITY;
03511         }
03512         if (entity->open) {
03513           if (enc == encoding)
03514             eventPtr = entityTextPtr;
03515           return XML_ERROR_RECURSIVE_ENTITY_REF;
03516         }
03517         if (entity->systemId) {
03518           if (enc == encoding)
03519             eventPtr = entityTextPtr;
03520           return XML_ERROR_PARAM_ENTITY_REF;
03521         }
03522         entity->open = 1;
03523         result = storeEntityValue(parser,
03524                                   internalEncoding,
03525                                   (char *)entity->textPtr,
03526                                   (char *)(entity->textPtr + entity->textLen));
03527         entity->open = 0;
03528         if (result)
03529           return result;
03530         break;
03531       }
03532 #endif /* XML_DTD */
03533       eventPtr = entityTextPtr;
03534       return XML_ERROR_SYNTAX;
03535     case XML_TOK_NONE:
03536       return XML_ERROR_NONE;
03537     case XML_TOK_ENTITY_REF:
03538     case XML_TOK_DATA_CHARS:
03539       if (!poolAppend(pool, enc, entityTextPtr, next))
03540         return XML_ERROR_NO_MEMORY;
03541       break;
03542     case XML_TOK_TRAILING_CR:
03543       next = entityTextPtr + enc->minBytesPerChar;
03544       /* fall through */
03545     case XML_TOK_DATA_NEWLINE:
03546       if (pool->end == pool->ptr && !poolGrow(pool))
03547         return XML_ERROR_NO_MEMORY;
03548       *(pool->ptr)++ = 0xA;
03549       break;
03550     case XML_TOK_CHAR_REF:
03551       {
03552         XML_Char buf[XML_ENCODE_MAX];
03553         int i;
03554         int n = XmlCharRefNumber(enc, entityTextPtr);
03555         if (n < 0) {
03556           if (enc == encoding)
03557             eventPtr = entityTextPtr;
03558           return XML_ERROR_BAD_CHAR_REF;
03559         }
03560         n = XmlEncode(n, (ICHAR *)buf);
03561         if (!n) {
03562           if (enc == encoding)
03563             eventPtr = entityTextPtr;
03564           return XML_ERROR_BAD_CHAR_REF;
03565         }
03566         for (i = 0; i < n; i++) {
03567           if (pool->end == pool->ptr && !poolGrow(pool))
03568             return XML_ERROR_NO_MEMORY;
03569           *(pool->ptr)++ = buf[i];
03570         }
03571       }
03572       break;
03573     case XML_TOK_PARTIAL:
03574       if (enc == encoding)
03575         eventPtr = entityTextPtr;
03576       return XML_ERROR_INVALID_TOKEN;
03577     case XML_TOK_INVALID:
03578       if (enc == encoding)
03579         eventPtr = next;
03580       return XML_ERROR_INVALID_TOKEN;
03581     default:
03582       if (enc == encoding)
03583         eventPtr = entityTextPtr;
03584       return XML_ERROR_UNEXPECTED_STATE;
03585     }
03586     entityTextPtr = next;
03587   }
03588   /* not reached */
03589 }
03590 
03591 static void
03592 normalizeLines(XML_Char *s)
03593 {
03594   XML_Char *p;
03595   for (;; s++) {
03596     if (*s == XML_T('\0'))
03597       return;
03598     if (*s == 0xD)
03599       break;
03600   }
03601   p = s;
03602   do {
03603     if (*s == 0xD) {
03604       *p++ = 0xA;
03605       if (*++s == 0xA)
03606         s++;
03607     }
03608     else
03609       *p++ = *s++;
03610   } while (*s);
03611   *p = XML_T('\0');
03612 }
03613 
03614 static int
03615 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
03616 {
03617   const XML_Char *target;
03618   XML_Char *data;
03619   const char *tem;
03620   if (!processingInstructionHandler) {
03621     if (defaultHandler)
03622       reportDefault(parser, enc, start, end);
03623     return 1;
03624   }
03625   start += enc->minBytesPerChar * 2;
03626   tem = start + XmlNameLength(enc, start);
03627   target = poolStoreString(&tempPool, enc, start, tem);
03628   if (!target)
03629     return 0;
03630   poolFinish(&tempPool);
03631   data = poolStoreString(&tempPool, enc,
03632                         XmlSkipS(enc, tem),
03633                         end - enc->minBytesPerChar*2);
03634   if (!data)
03635     return 0;
03636   normalizeLines(data);
03637   processingInstructionHandler(handlerArg, target, data);
03638   poolClear(&tempPool);
03639   return 1;
03640 }
03641 
03642 static int
03643 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
03644 {
03645   XML_Char *data;
03646   if (!commentHandler) {
03647     if (defaultHandler)
03648       reportDefault(parser, enc, start, end);
03649     return 1;
03650   }
03651   data = poolStoreString(&tempPool,
03652                          enc,
03653                          start + enc->minBytesPerChar * 4, 
03654                          end - enc->minBytesPerChar * 3);
03655   if (!data)
03656     return 0;
03657   normalizeLines(data);
03658   commentHandler(handlerArg, data);
03659   poolClear(&tempPool);
03660   return 1;
03661 }
03662 
03663 static void
03664 reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
03665 {
03666   if (MUST_CONVERT(enc, s)) {
03667     const char **eventPP;
03668     const char **eventEndPP;
03669     if (enc == encoding) {
03670       eventPP = &eventPtr;
03671       eventEndPP = &eventEndPtr;
03672     }
03673     else {
03674       eventPP = &(openInternalEntities->internalEventPtr);
03675       eventEndPP = &(openInternalEntities->internalEventEndPtr);
03676     }
03677     do {
03678       ICHAR *dataPtr = (ICHAR *)dataBuf;
03679       XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
03680       *eventEndPP = s;
03681       defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
03682       *eventPP = s;
03683     } while (s != end);
03684   }
03685   else
03686     defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
03687 }
03688 
03689 
03690 static int
03691 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata,
03692                 int isId, const XML_Char *value, XML_Parser parser)
03693 {
03694   DEFAULT_ATTRIBUTE *att;
03695   if (value || isId) {
03696     /* The handling of default attributes gets messed up if we have
03697        a default which duplicates a non-default. */
03698     int i;
03699     for (i = 0; i < type->nDefaultAtts; i++)
03700       if (attId == type->defaultAtts[i].id)
03701         return 1;
03702     if (isId && !type->idAtt && !attId->xmlns)
03703       type->idAtt = attId;
03704   }
03705   if (type->nDefaultAtts == type->allocDefaultAtts) {
03706     if (type->allocDefaultAtts == 0) {
03707       type->allocDefaultAtts = 8;
03708       type->defaultAtts = MALLOC(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
03709     }
03710     else {
03711       type->allocDefaultAtts *= 2;
03712       type->defaultAtts = REALLOC(type->defaultAtts,
03713                                   type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
03714     }
03715     if (!type->defaultAtts)
03716       return 0;
03717   }
03718   att = type->defaultAtts + type->nDefaultAtts;
03719   att->id = attId;
03720   att->value = value;
03721   att->isCdata = isCdata;
03722   if (!isCdata)
03723     attId->maybeTokenized = 1;
03724   type->nDefaultAtts += 1;
03725   return 1;
03726 }
03727 
03728 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
03729 {
03730   const XML_Char *name;
03731   for (name = elementType->name; *name; name++) {
03732     if (*name == XML_T(':')) {
03733       PREFIX *prefix;
03734       const XML_Char *s;
03735       for (s = elementType->name; s != name; s++) {
03736         if (!poolAppendChar(&dtd.pool, *s))
03737           return 0;
03738       }
03739       if (!poolAppendChar(&dtd.pool, XML_T('\0')))
03740         return 0;
03741       prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
03742       if (!prefix)
03743         return 0;
03744       if (prefix->name == poolStart(&dtd.pool))
03745         poolFinish(&dtd.pool);
03746       else
03747         poolDiscard(&dtd.pool);
03748       elementType->prefix = prefix;
03749 
03750     }
03751   }
03752   return 1;
03753 }
03754 
03755 static ATTRIBUTE_ID *
03756 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
03757 {
03758   ATTRIBUTE_ID *id;
03759   const XML_Char *name;
03760   if (!poolAppendChar(&dtd.pool, XML_T('\0')))
03761     return 0;
03762   name = poolStoreString(&dtd.pool, enc, start, end);
03763   if (!name)
03764     return 0;
03765   ++name;
03766   id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
03767   if (!id)
03768     return 0;
03769   if (id->name != name)
03770     poolDiscard(&dtd.pool);
03771   else {
03772     poolFinish(&dtd.pool);
03773     if (!ns)
03774       ;
03775     else if (name[0] == 'x'
03776         && name[1] == 'm'
03777         && name[2] == 'l'
03778         && name[3] == 'n'
03779         && name[4] == 's'
03780         && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
03781       if (name[5] == '\0')
03782         id->prefix = &dtd.defaultPrefix;
03783       else
03784         id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
03785       id->xmlns = 1;
03786     }
03787     else {
03788       int i;
03789       for (i = 0; name[i]; i++) {
03790         if (name[i] == XML_T(':')) {
03791           int j;
03792           for (j = 0; j < i; j++) {
03793             if (!poolAppendChar(&dtd.pool, name[j]))
03794               return 0;
03795           }
03796           if (!poolAppendChar(&dtd.pool, XML_T('\0')))
03797             return 0;
03798           id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
03799           if (id->prefix->name == poolStart(&dtd.pool))
03800             poolFinish(&dtd.pool);
03801           else
03802             poolDiscard(&dtd.pool);
03803           break;
03804         }
03805       }
03806     }
03807   }
03808   return id;
03809 }
03810 
03811 #define CONTEXT_SEP XML_T('\f')
03812 
03813 static
03814 const XML_Char *getContext(XML_Parser parser)
03815 {
03816   HASH_TABLE_ITER iter;
03817   int needSep = 0;
03818 
03819   if (dtd.defaultPrefix.binding) {
03820     int i;
03821     int len;
03822     if (!poolAppendChar(&tempPool, XML_T('=')))
03823       return 0;
03824     len = dtd.defaultPrefix.binding->uriLen;
03825     if (namespaceSeparator != XML_T('\0'))
03826       len--;
03827     for (i = 0; i < len; i++)
03828       if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
03829         return 0;
03830     needSep = 1;
03831   }
03832 
03833   hashTableIterInit(&iter, &(dtd.prefixes));
03834   for (;;) {
03835     int i;
03836     int len;
03837     const XML_Char *s;
03838     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
03839     if (!prefix)
03840       break;
03841     if (!prefix->binding)
03842       continue;
03843     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
03844       return 0;
03845     for (s = prefix->name; *s; s++)
03846       if (!poolAppendChar(&tempPool, *s))
03847         return 0;
03848     if (!poolAppendChar(&tempPool, XML_T('=')))
03849       return 0;
03850     len = prefix->binding->uriLen;
03851     if (namespaceSeparator != XML_T('\0'))
03852       len--;
03853     for (i = 0; i < len; i++)
03854       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
03855         return 0;
03856     needSep = 1;
03857   }
03858 
03859 
03860   hashTableIterInit(&iter, &(dtd.generalEntities));
03861   for (;;) {
03862     const XML_Char *s;
03863     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
03864     if (!e)
03865       break;
03866     if (!e->open)
03867       continue;
03868     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
03869       return 0;
03870     for (s = e->name; *s; s++)
03871       if (!poolAppendChar(&tempPool, *s))
03872         return 0;
03873     needSep = 1;
03874   }
03875 
03876   if (!poolAppendChar(&tempPool, XML_T('\0')))
03877     return 0;
03878   return tempPool.start;
03879 }
03880 
03881 static
03882 int setContext(XML_Parser parser, const XML_Char *context)
03883 {
03884   const XML_Char *s = context;
03885 
03886   while (*context != XML_T('\0')) {
03887     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
03888       ENTITY *e;
03889       if (!poolAppendChar(&tempPool, XML_T('\0')))
03890         return 0;
03891       e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
03892       if (e)
03893         e->open = 1;
03894       if (*s != XML_T('\0'))
03895         s++;
03896       context = s;
03897       poolDiscard(&tempPool);
03898     }
03899     else if (*s == '=') {
03900       PREFIX *prefix;
03901       if (poolLength(&tempPool) == 0)
03902         prefix = &dtd.defaultPrefix;
03903       else {
03904         if (!poolAppendChar(&tempPool, XML_T('\0')))
03905           return 0;
03906         prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
03907         if (!prefix)
03908           return 0;
03909         if (prefix->name == poolStart(&tempPool)) {
03910           prefix->name = poolCopyString(&dtd.pool, prefix->name);
03911           if (!prefix->name)
03912             return 0;
03913         }
03914         poolDiscard(&tempPool);
03915       }
03916       for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
03917         if (!poolAppendChar(&tempPool, *context))
03918           return 0;
03919       if (!poolAppendChar(&tempPool, XML_T('\0')))
03920         return 0;
03921       if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
03922         return 0;
03923       poolDiscard(&tempPool);
03924       if (*context != XML_T('\0'))
03925         ++context;
03926       s = context;
03927     }
03928     else {
03929       if (!poolAppendChar(&tempPool, *s))
03930         return 0;
03931       s++;
03932     }
03933   }
03934   return 1;
03935 }
03936 
03937 
03938 static
03939 void normalizePublicId(XML_Char *publicId)
03940 {
03941   XML_Char *p = publicId;
03942   XML_Char *s;
03943   for (s = publicId; *s; s++) {
03944     switch (*s) {
03945     case 0x20:
03946     case 0xD:
03947     case 0xA:
03948       if (p != publicId && p[-1] != 0x20)
03949         *p++ = 0x20;
03950       break;
03951     default:
03952       *p++ = *s;
03953     }
03954   }
03955   if (p != publicId && p[-1] == 0x20)
03956     --p;
03957   *p = XML_T('\0');
03958 }
03959 
03960 static int dtdInit(DTD *p, XML_Parser parser)
03961 {
03962   XML_Memory_Handling_Suite *ms = &((Parser *) parser)->m_mem; 
03963   poolInit(&(p->pool), ms);
03964   hashTableInit(&(p->generalEntities), ms);
03965   hashTableInit(&(p->elementTypes), ms);
03966   hashTableInit(&(p->attributeIds), ms);
03967   hashTableInit(&(p->prefixes), ms);
03968   p->complete = 1;
03969   p->standalone = 0;
03970 #ifdef XML_DTD
03971   hashTableInit(&(p->paramEntities), ms);
03972 #endif /* XML_DTD */
03973   p->defaultPrefix.name = 0;
03974   p->defaultPrefix.binding = 0;
03975 
03976   p->in_eldecl = 0;
03977   p->scaffIndex = 0;
03978   p->scaffLevel = 0;
03979   p->scaffold = 0;
03980   p->contentStringLen = 0;
03981   p->scaffSize = 0;
03982   p->scaffCount = 0;
03983 
03984   return 1;
03985 }
03986 
03987 #ifdef XML_DTD
03988 
03989 static void dtdSwap(DTD *p1, DTD *p2)
03990 {
03991   DTD tem;
03992   memcpy(&tem, p1, sizeof(DTD));
03993   memcpy(p1, p2, sizeof(DTD));
03994   memcpy(p2, &tem, sizeof(DTD));
03995 }
03996 
03997 #endif /* XML_DTD */
03998 
03999 static void dtdDestroy(DTD *p, XML_Parser parser)
04000 {
04001   HASH_TABLE_ITER iter;
04002   hashTableIterInit(&iter, &(p->elementTypes));
04003   for (;;) {
04004     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
04005     if (!e)
04006       break;
04007     if (e->allocDefaultAtts != 0)
04008       FREE(e->defaultAtts);
04009   }
04010   hashTableDestroy(&(p->generalEntities));
04011 #ifdef XML_DTD
04012   hashTableDestroy(&(p->paramEntities));
04013 #endif /* XML_DTD */
04014   hashTableDestroy(&(p->elementTypes));
04015   hashTableDestroy(&(p->attributeIds));
04016   hashTableDestroy(&(p->prefixes));
04017   poolDestroy(&(p->pool));
04018   if (p->scaffIndex)
04019     FREE(p->scaffIndex);
04020   if (p->scaffold)
04021     FREE(p->scaffold);
04022 }
04023 
04024 /* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
04025 The new DTD has already been initialized. */
04026 
04027 static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser)
04028 {
04029   HASH_TABLE_ITER iter;
04030 
04031   /* Copy the prefix table. */
04032 
04033   hashTableIterInit(&iter, &(oldDtd->prefixes));
04034   for (;;) {
04035     const XML_Char *name;
04036     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
04037     if (!oldP)
04038       break;
04039     name = poolCopyString(&(newDtd->pool), oldP->name);
04040     if (!name)
04041       return 0;
04042     if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
04043       return 0;
04044   }
04045 
04046   hashTableIterInit(&iter, &(oldDtd->attributeIds));
04047 
04048   /* Copy the attribute id table. */
04049 
04050   for (;;) {
04051     ATTRIBUTE_ID *newA;
04052     const XML_Char *name;
04053     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
04054 
04055     if (!oldA)
04056       break;
04057     /* Remember to allocate the scratch byte before the name. */
04058     if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
04059       return 0;
04060     name = poolCopyString(&(newDtd->pool), oldA->name);
04061     if (!name)
04062       return 0;
04063     ++name;
04064     newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
04065     if (!newA)
04066       return 0;
04067     newA->maybeTokenized = oldA->maybeTokenized;
04068     if (oldA->prefix) {
04069       newA->xmlns = oldA->xmlns;
04070       if (oldA->prefix == &oldDtd->defaultPrefix)
04071         newA->prefix = &newDtd->defaultPrefix;
04072       else
04073         newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
04074     }
04075   }
04076 
04077   /* Copy the element type table. */
04078 
04079   hashTableIterInit(&iter, &(oldDtd->elementTypes));
04080 
04081   for (;;) {
04082     int i;
04083     ELEMENT_TYPE *newE;
04084     const XML_Char *name;
04085     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
04086     if (!oldE)
04087       break;
04088     name = poolCopyString(&(newDtd->pool), oldE->name);
04089     if (!name)
04090       return 0;
04091     newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
04092     if (!newE)
04093       return 0;
04094     if (oldE->nDefaultAtts) {
04095       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
04096       if (!newE->defaultAtts)
04097         return 0;
04098     }
04099     if (oldE->idAtt)
04100       newE->idAtt = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
04101     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
04102     if (oldE->prefix)
04103       newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
04104     for (i = 0; i < newE->nDefaultAtts; i++) {
04105       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
04106       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
04107       if (oldE->defaultAtts[i].value) {
04108         newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
04109         if (!newE->defaultAtts[i].value)
04110           return 0;
04111       }
04112       else
04113         newE->defaultAtts[i].value = 0;
04114     }
04115   }
04116 
04117   /* Copy the entity tables. */
04118   if (!copyEntityTable(&(newDtd->generalEntities),
04119                        &(newDtd->pool),
04120                        &(oldDtd->generalEntities), parser))
04121       return 0;
04122 
04123 #ifdef XML_DTD
04124   if (!copyEntityTable(&(newDtd->paramEntities),
04125                        &(newDtd->pool),
04126                        &(oldDtd->paramEntities), parser))
04127       return 0;
04128 #endif /* XML_DTD */
04129 
04130   newDtd->complete = oldDtd->complete;
04131   newDtd->standalone = oldDtd->standalone;
04132 
04133   /* Don't want deep copying for scaffolding */
04134   newDtd->in_eldecl = oldDtd->in_eldecl;
04135   newDtd->scaffold = oldDtd->scaffold;
04136   newDtd->contentStringLen = oldDtd->contentStringLen;
04137   newDtd->scaffSize = oldDtd->scaffSize;
04138   newDtd->scaffLevel = oldDtd->scaffLevel;
04139   newDtd->scaffIndex = oldDtd->scaffIndex;
04140 
04141   return 1;
04142 }  /* End dtdCopy */
04143 
04144 static int copyEntityTable(HASH_TABLE *newTable,
04145                            STRING_POOL *newPool,
04146                            const HASH_TABLE *oldTable,
04147                            XML_Parser parser)
04148 {
04149   HASH_TABLE_ITER iter;
04150   const XML_Char *cachedOldBase = 0;
04151   const XML_Char *cachedNewBase = 0;
04152 
04153   hashTableIterInit(&iter, oldTable);
04154 
04155   for (;;) {
04156     ENTITY *newE;
04157     const XML_Char *name;
04158     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
04159     if (!oldE)
04160       break;
04161     name = poolCopyString(newPool, oldE->name);
04162     if (!name)
04163       return 0;
04164     newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
04165     if (!newE)
04166       return 0;
04167     if (oldE->systemId) {
04168       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
04169       if (!tem)
04170         return 0;
04171       newE->systemId = tem;
04172       if (oldE->base) {
04173         if (oldE->base == cachedOldBase)
04174           newE->base = cachedNewBase;
04175         else {
04176           cachedOldBase = oldE->base;
04177           tem = poolCopyString(newPool, cachedOldBase);
04178           if (!tem)
04179             return 0;
04180           cachedNewBase = newE->base = tem;
04181         }
04182       }
04183     }
04184     else {
04185       const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
04186       if (!tem)
04187         return 0;
04188       newE->textPtr = tem;
04189       newE->textLen = oldE->textLen;
04190     }
04191     if (oldE->notation) {
04192       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
04193       if (!tem)
04194         return 0;
04195       newE->notation = tem;
04196     }
04197   }
04198   return 1;
04199 }
04200 
04201 #define INIT_SIZE 64
04202 
04203 static
04204 int keyeq(KEY s1, KEY s2)
04205 {
04206   for (; *s1 == *s2; s1++, s2++)
04207     if (*s1 == 0)
04208       return 1;
04209   return 0;
04210 }
04211 
04212 static
04213 unsigned long hash(KEY s)
04214 {
04215   unsigned long h = 0;
04216   while (*s)
04217     h = (h << 5) + h + (unsigned char)*s++;
04218   return h;
04219 }
04220 
04221 static
04222 NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
04223 {
04224   size_t i;
04225   if (table->size == 0) {
04226     size_t tsize;
04227 
04228     if (!createSize)
04229       return 0;
04230     tsize = INIT_SIZE * sizeof(NAMED *);
04231     table->v = table->mem->malloc_fcn(tsize);
04232     if (!table->v)
04233       return 0;
04234     memset(table->v, 0, tsize);
04235     table->size = INIT_SIZE;
04236     table->usedLim = INIT_SIZE / 2;
04237     i = hash(name) & (table->size - 1);
04238   }
04239   else {
04240     unsigned long h = hash(name);
04241     for (i = h & (table->size - 1);
04242          table->v[i];
04243          i == 0 ? i = table->size - 1 : --i) {
04244       if (keyeq(name, table->v[i]->name))
04245         return table->v[i];
04246     }
04247     if (!createSize)
04248       return 0;
04249     if (table->used == table->usedLim) {
04250       /* check for overflow */
04251       size_t newSize = table->size * 2;
04252       size_t tsize = newSize * sizeof(NAMED *);
04253       NAMED **newV = table->mem->malloc_fcn(tsize);
04254       if (!newV)
04255         return 0;
04256       memset(newV, 0, tsize);
04257       for (i = 0; i < table->size; i++)
04258         if (table->v[i]) {
04259           size_t j;
04260           for (j = hash(table->v[i]->name) & (newSize - 1);
04261                newV[j];
04262                j == 0 ? j = newSize - 1 : --j)
04263             ;
04264           newV[j] = table->v[i];
04265         }
04266       table->mem->free_fcn(table->v);
04267       table->v = newV;
04268       table->size = newSize;
04269       table->usedLim = newSize/2;
04270       for (i = h & (table->size - 1);
04271            table->v[i];
04272            i == 0 ? i = table->size - 1 : --i)
04273         ;
04274     }
04275   }
04276   table->v[i] = table->mem->malloc_fcn(createSize);
04277   if (!table->v[i])
04278     return 0;
04279   memset(table->v[i], 0, createSize);
04280   table->v[i]->name = name;
04281   (table->used)++;
04282   return table->v[i];
04283 }
04284 
04285 static
04286 void hashTableDestroy(HASH_TABLE *table)
04287 {
04288   size_t i;
04289   for (i = 0; i < table->size; i++) {
04290     NAMED *p = table->v[i];
04291     if (p)
04292       table->mem->free_fcn(p);
04293   }
04294   if (table->v)
04295     table->mem->free_fcn(table->v);
04296 }
04297 
04298 static
04299 void hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms)
04300 {
04301   p->size = 0;
04302   p->usedLim = 0;
04303   p->used = 0;
04304   p->v = 0;
04305   p->mem = ms;
04306 }
04307 
04308 static
04309 void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
04310 {
04311   iter->p = table->v;
04312   iter->end = iter->p + table->size;
04313 }
04314 
04315 static
04316 NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
04317 {
04318   while (iter->p != iter->end) {
04319     NAMED *tem = *(iter->p)++;
04320     if (tem)
04321       return tem;
04322   }
04323   return 0;
04324 }
04325 
04326 
04327 static
04328 void poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms)
04329 {
04330   pool->blocks = 0;
04331   pool->freeBlocks = 0;
04332   pool->start = 0;
04333   pool->ptr = 0;
04334   pool->end = 0;
04335   pool->mem = ms;
04336 }
04337 
04338 static
04339 void poolClear(STRING_POOL *pool)
04340 {
04341   if (!pool->freeBlocks)
04342     pool->freeBlocks = pool->blocks;
04343   else {
04344     BLOCK *p = pool->blocks;
04345     while (p) {
04346       BLOCK *tem = p->next;
04347       p->next = pool->freeBlocks;
04348       pool->freeBlocks = p;
04349       p = tem;
04350     }
04351   }
04352   pool->blocks = 0;
04353   pool->start = 0;
04354   pool->ptr = 0;
04355   pool->end = 0;
04356 }
04357 
04358 static
04359 void poolDestroy(STRING_POOL *pool)
04360 {
04361   BLOCK *p = pool->blocks;
04362   while (p) {
04363     BLOCK *tem = p->next;
04364     pool->mem->free_fcn(p);
04365     p = tem;
04366   }
04367   pool->blocks = 0;
04368   p = pool->freeBlocks;
04369   while (p) {
04370     BLOCK *tem = p->next;
04371     pool->mem->free_fcn(p);
04372     p = tem;
04373   }
04374   pool->freeBlocks = 0;
04375   pool->ptr = 0;
04376   pool->start = 0;
04377   pool->end = 0;
04378 }
04379 
04380 static
04381 XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
04382                      const char *ptr, const char *end)
04383 {
04384   if (!pool->ptr && !poolGrow(pool))
04385     return 0;
04386   for (;;) {
04387     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
04388     if (ptr == end)
04389       break;
04390     if (!poolGrow(pool))
04391       return 0;
04392   }
04393   return pool->start;
04394 }
04395 
04396 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
04397 {
04398   do {
04399     if (!poolAppendChar(pool, *s))
04400       return 0;
04401   } while (*s++);
04402   s = pool->start;
04403   poolFinish(pool);
04404   return s;
04405 }
04406 
04407 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
04408 {
04409   if (!pool->ptr && !poolGrow(pool))
04410     return 0;
04411   for (; n > 0; --n, s++) {
04412     if (!poolAppendChar(pool, *s))
04413       return 0;
04414 
04415   }
04416   s = pool->start;
04417   poolFinish(pool);
04418   return s;
04419 }
04420 
04421 static
04422 const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s)
04423 {
04424   while (*s) {
04425     if (!poolAppendChar(pool, *s))
04426       return 0;
04427     s++;
04428   } 
04429   return pool->start;
04430 }  /* End poolAppendString */
04431 
04432 static
04433 XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
04434                           const char *ptr, const char *end)
04435 {
04436   if (!poolAppend(pool, enc, ptr, end))
04437     return 0;
04438   if (pool->ptr == pool->end && !poolGrow(pool))
04439     return 0;
04440   *(pool->ptr)++ = 0;
04441   return pool->start;
04442 }
04443 
04444 static
04445 int poolGrow(STRING_POOL *pool)
04446 {
04447   if (pool->freeBlocks) {
04448     if (pool->start == 0) {
04449       pool->blocks = pool->freeBlocks;
04450       pool->freeBlocks = pool->freeBlocks->next;
04451       pool->blocks->next = 0;
04452       pool->start = pool->blocks->s;
04453       pool->end = pool->start + pool->blocks->size;
04454       pool->ptr = pool->start;
04455       return 1;
04456     }
04457     if (pool->end - pool->start < pool->freeBlocks->size) {
04458       BLOCK *tem = pool->freeBlocks->next;
04459       pool->freeBlocks->next = pool->blocks;
04460       pool->blocks = pool->freeBlocks;
04461       pool->freeBlocks = tem;
04462       memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
04463       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
04464       pool->start = pool->blocks->s;
04465       pool->end = pool->start + pool->blocks->size;
04466       return 1;
04467     }
04468   }
04469   if (pool->blocks && pool->start == pool->blocks->s) {
04470     int blockSize = (pool->end - pool->start)*2;
04471     pool->blocks = pool->mem->realloc_fcn(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
04472     if (!pool->blocks)
04473       return 0;
04474     pool->blocks->size = blockSize;
04475     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
04476     pool->start = pool->blocks->s;
04477     pool->end = pool->start + blockSize;
04478   }
04479   else {
04480     BLOCK *tem;
04481     int blockSize = pool->end - pool->start;
04482     if (blockSize < INIT_BLOCK_SIZE)
04483       blockSize = INIT_BLOCK_SIZE;
04484     else
04485       blockSize *= 2;
04486     tem = pool->mem->malloc_fcn(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
04487     if (!tem)
04488       return 0;
04489     tem->size = blockSize;
04490     tem->next = pool->blocks;
04491     pool->blocks = tem;
04492     if (pool->ptr != pool->start)
04493       memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
04494     pool->ptr = tem->s + (pool->ptr - pool->start);
04495     pool->start = tem->s;
04496     pool->end = tem->s + blockSize;
04497   }
04498   return 1;
04499 }
04500 
04501 static int
04502 nextScaffoldPart(XML_Parser parser)
04503 {
04504   CONTENT_SCAFFOLD * me;
04505   int next;
04506 
04507   if (! dtd.scaffIndex) {
04508     dtd.scaffIndex = MALLOC(groupSize * sizeof(int));
04509     if (! dtd.scaffIndex)
04510       return -1;
04511     dtd.scaffIndex[0] = 0;
04512   }
04513 
04514   if (dtd.scaffCount >= dtd.scaffSize) {
04515     if (dtd.scaffold) {
04516       dtd.scaffSize *= 2;
04517       dtd.scaffold = (CONTENT_SCAFFOLD *) REALLOC(dtd.scaffold,
04518                                               dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
04519     }
04520     else {
04521       dtd.scaffSize = 32;
04522       dtd.scaffold = (CONTENT_SCAFFOLD *) MALLOC(dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
04523     }
04524     if (! dtd.scaffold)
04525       return -1;
04526   }
04527   next = dtd.scaffCount++;
04528   me = &dtd.scaffold[next];
04529   if (dtd.scaffLevel) { 
04530     CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]];
04531     if (parent->lastchild) {
04532       dtd.scaffold[parent->lastchild].nextsib = next;
04533     }
04534     if (! parent->childcnt)
04535       parent->firstchild = next;
04536     parent->lastchild = next;
04537     parent->childcnt++;
04538   }
04539   me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
04540   return next;
04541 }  /* End nextScaffoldPart */
04542 
04543 static void
04544 build_node (XML_Parser parser,
04545             int src_node,
04546             XML_Content *dest,
04547             XML_Content **contpos,
04548             char **strpos)
04549 {
04550   dest->type = dtd.scaffold[src_node].type;
04551   dest->quant = dtd.scaffold[src_node].quant;
04552   if (dest->type == XML_CTYPE_NAME) {
04553     const char *src;
04554     dest->name = *strpos;
04555     src = dtd.scaffold[src_node].name;
04556     for (;;) {
04557       *(*strpos)++ = *src;
04558       if (! *src)
04559         break;
04560       src++;
04561     }
04562     dest->numchildren = 0;
04563     dest->children = 0;
04564   }
04565   else {
04566     unsigned int i;
04567     int cn;
04568     dest->numchildren = dtd.scaffold[src_node].childcnt;
04569     dest->children = *contpos;
04570     *contpos += dest->numchildren;
04571     for (i = 0, cn = dtd.scaffold[src_node].firstchild;
04572          i < dest->numchildren;
04573          i++, cn = dtd.scaffold[cn].nextsib) {
04574       build_node(parser, cn, &(dest->children[i]), contpos, strpos);
04575     }
04576     dest->name = 0;
04577   }
04578 }  /* End build_node */
04579 
04580 static XML_Content *
04581 build_model (XML_Parser parser)
04582 {
04583   XML_Content *ret;
04584   XML_Content *cpos;
04585   char * str;
04586   int allocsize = dtd.scaffCount * sizeof(XML_Content) + dtd.contentStringLen;
04587   
04588   ret = MALLOC(allocsize);
04589   if (! ret)
04590     return 0;
04591 
04592   str =  (char *) (&ret[dtd.scaffCount]);
04593   cpos = &ret[1];
04594 
04595   build_node(parser, 0, ret, &cpos, &str);
04596   return ret;
04597 }  /* End build_model */
04598 
04599 static ELEMENT_TYPE *
04600 getElementType(XML_Parser parser,
04601                const ENCODING *enc,
04602                const char *ptr,
04603                const char *end)
04604 {
04605   const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
04606   ELEMENT_TYPE *ret;
04607 
04608   if (! name)
04609     return 0;
04610   ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
04611   if (! ret)
04612     return 0;
04613   if (ret->name != name)
04614     poolDiscard(&dtd.pool);
04615   else {
04616     poolFinish(&dtd.pool);
04617     if (!setElementTypePrefix(parser, ret))
04618       return 0;
04619   }
04620   return ret;
04621 }  /* End getElementType */


Last updated at Tue Dec 18 21:07:42 PST 2007. This site and project hosted by...SourceForge.net Logo
Source Perspective by Fisheye