xmlparse.cc

Go to the documentation of this file.
00001 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
00002    See the file COPYING for copying permission.
00003 */
00004 
00005 #include <stddef.h>
00006 #include <string.h>                     /* memset(), memcpy() */
00007 #include <assert.h>
00008 
00009 #define XML_BUILDING_EXPAT 1
00010 
00011 #ifdef COMPILED_FROM_DSP
00012 #include "winconfig.h"
00013 #elif defined(MACOS_CLASSIC)
00014 #include "macconfig.h"
00015 #elif defined(__amigaos4__)
00016 #include "amigaconfig.h"
00017 #elif defined(__WATCOMC__)
00018 #include "watcomconfig.h"
00019 #elif defined(HAVE_EXPAT_CONFIG_H)
00020 #include <expat_config.h>
00021 #endif /* ndef COMPILED_FROM_DSP */
00022 
00023 #include "ascii.h"
00024 #include "expat.h"
00025 
00026 #ifdef XML_UNICODE
00027 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
00028 #define XmlConvert XmlUtf16Convert
00029 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
00030 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
00031 #define XmlEncode XmlUtf16Encode
00032 /* Using pointer subtraction to convert to integer type. */
00033 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
00034 typedef unsigned short ICHAR;
00035 #else
00036 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
00037 #define XmlConvert XmlUtf8Convert
00038 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
00039 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
00040 #define XmlEncode XmlUtf8Encode
00041 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
00042 typedef char ICHAR;
00043 #endif
00044 
00045 
00046 #ifndef XML_NS
00047 
00048 #define XmlInitEncodingNS XmlInitEncoding
00049 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
00050 #undef XmlGetInternalEncodingNS
00051 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
00052 #define XmlParseXmlDeclNS XmlParseXmlDecl
00053 
00054 #endif
00055 
00056 #ifdef XML_UNICODE
00057 
00058 #ifdef XML_UNICODE_WCHAR_T
00059 #define XML_T(x) (const wchar_t)x
00060 #define XML_L(x) L ## x
00061 #else
00062 #define XML_T(x) (const unsigned short)x
00063 #define XML_L(x) x
00064 #endif
00065 
00066 #else
00067 
00068 #define XML_T(x) x
00069 #define XML_L(x) x
00070 
00071 #endif
00072 
00073 /* Round up n to be a multiple of sz, where sz is a power of 2. */
00074 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
00075 
00076 /* Handle the case where memmove() doesn't exist. */
00077 #ifndef HAVE_MEMMOVE
00078 #ifdef HAVE_BCOPY
00079 #define memmove(d,s,l) bcopy((s),(d),(l))
00080 #else
00081 #error memmove does not exist on this platform, nor is a substitute available
00082 #endif /* HAVE_BCOPY */
00083 #endif /* HAVE_MEMMOVE */
00084 
00085 #include "internal.h"
00086 #include "xmltok.h"
00087 #include "xmlrole.h"
00088 
00089 typedef const XML_Char *KEY;
00090 
00091 typedef struct {
00092   KEY name;
00093 } NAMED;
00094 
00095 typedef struct {
00096   NAMED **v;
00097   unsigned char power;
00098   size_t size;
00099   size_t used;
00100   const XML_Memory_Handling_Suite *mem;
00101 } HASH_TABLE;
00102 
00103 /* Basic character hash algorithm, taken from Python's string hash:
00104    h = h * 1000003 ^ character, the constant being a prime number.
00105 
00106 */
00107 #ifdef XML_UNICODE
00108 #define CHAR_HASH(h, c) \
00109   (((h) * 0xF4243) ^ (unsigned short)(c))
00110 #else
00111 #define CHAR_HASH(h, c) \
00112   (((h) * 0xF4243) ^ (unsigned char)(c))
00113 #endif
00114 
00115 /* For probing (after a collision) we need a step size relative prime
00116    to the hash table size, which is a power of 2. We use double-hashing,
00117    since we can calculate a second hash value cheaply by taking those bits
00118    of the first hash value that were discarded (masked out) when the table
00119    index was calculated: index = hash & mask, where mask = table->size - 1.
00120    We limit the maximum step size to table->size / 4 (mask >> 2) and make
00121    it odd, since odd numbers are always relative prime to a power of 2.
00122 */
00123 #define SECOND_HASH(hash, mask, power) \
00124   ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
00125 #define PROBE_STEP(hash, mask, power) \
00126   ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
00127 
00128 typedef struct {
00129   NAMED **p;
00130   NAMED **end;
00131 } HASH_TABLE_ITER;
00132 
00133 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
00134 #define INIT_DATA_BUF_SIZE 1024
00135 #define INIT_ATTS_SIZE 16
00136 #define INIT_ATTS_VERSION 0xFFFFFFFF
00137 #define INIT_BLOCK_SIZE 1024
00138 #define INIT_BUFFER_SIZE 1024
00139 
00140 #define EXPAND_SPARE 24
00141 
00142 typedef struct binding {
00143   struct prefix *prefix;
00144   struct binding *nextTagBinding;
00145   struct binding *prevPrefixBinding;
00146   const struct attribute_id *attId;
00147   XML_Char *uri;
00148   int uriLen;
00149   int uriAlloc;
00150 } BINDING;
00151 
00152 typedef struct prefix {
00153   const XML_Char *name;
00154   BINDING *binding;
00155 } PREFIX;
00156 
00157 typedef struct {
00158   const XML_Char *str;
00159   const XML_Char *localPart;
00160   const XML_Char *prefix;
00161   int strLen;
00162   int uriLen;
00163   int prefixLen;
00164 } TAG_NAME;
00165 
00166 /* TAG represents an open element.
00167    The name of the element is stored in both the document and API
00168    encodings.  The memory buffer 'buf' is a separately-allocated
00169    memory area which stores the name.  During the XML_Parse()/
00170    XMLParseBuffer() when the element is open, the memory for the 'raw'
00171    version of the name (in the document encoding) is shared with the
00172    document buffer.  If the element is open across calls to
00173    XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
00174    contain the 'raw' name as well.
00175 
00176    A parser re-uses these structures, maintaining a list of allocated
00177    TAG objects in a free list.
00178 */
00179 typedef struct tag {
00180   struct tag *parent;           /* parent of this element */
00181   const char *rawName;          /* tagName in the original encoding */
00182   int rawNameLength;
00183   TAG_NAME name;                /* tagName in the API encoding */
00184   char *buf;                    /* buffer for name components */
00185   char *bufEnd;                 /* end of the buffer */
00186   BINDING *bindings;
00187 } TAG;
00188 
00189 typedef struct {
00190   const XML_Char *name;
00191   const XML_Char *textPtr;
00192   int textLen;                  /* length in XML_Chars */
00193   int processed;                /* # of processed bytes - when suspended */
00194   const XML_Char *systemId;
00195   const XML_Char *base;
00196   const XML_Char *publicId;
00197   const XML_Char *notation;
00198   XML_Bool open;
00199   XML_Bool is_param;
00200   XML_Bool is_internal; /* true if declared in internal subset outside PE */
00201 } ENTITY;
00202 
00203 typedef struct {
00204   enum XML_Content_Type         type;
00205   enum XML_Content_Quant        quant;
00206   const XML_Char *              name;
00207   int                           firstchild;
00208   int                           lastchild;
00209   int                           childcnt;
00210   int                           nextsib;
00211 } CONTENT_SCAFFOLD;
00212 
00213 #define INIT_SCAFFOLD_ELEMENTS 32
00214 
00215 typedef struct block {
00216   struct block *next;
00217   int size;
00218   XML_Char s[1];
00219 } BLOCK;
00220 
00221 typedef struct {
00222   BLOCK *blocks;
00223   BLOCK *freeBlocks;
00224   const XML_Char *end;
00225   XML_Char *ptr;
00226   XML_Char *start;
00227   const XML_Memory_Handling_Suite *mem;
00228 } STRING_POOL;
00229 
00230 /* The XML_Char before the name is used to determine whether
00231    an attribute has been specified. */
00232 typedef struct attribute_id {
00233   XML_Char *name;
00234   PREFIX *prefix;
00235   XML_Bool maybeTokenized;
00236   XML_Bool xmlns;
00237 } ATTRIBUTE_ID;
00238 
00239 typedef struct {
00240   const ATTRIBUTE_ID *id;
00241   XML_Bool isCdata;
00242   const XML_Char *value;
00243 } DEFAULT_ATTRIBUTE;
00244 
00245 typedef struct {
00246   unsigned long version;
00247   unsigned long hash;
00248   const XML_Char *uriName;
00249 } NS_ATT;
00250 
00251 typedef struct {
00252   const XML_Char *name;
00253   PREFIX *prefix;
00254   const ATTRIBUTE_ID *idAtt;
00255   int nDefaultAtts;
00256   int allocDefaultAtts;
00257   DEFAULT_ATTRIBUTE *defaultAtts;
00258 } ELEMENT_TYPE;
00259 
00260 typedef struct {
00261   HASH_TABLE generalEntities;
00262   HASH_TABLE elementTypes;
00263   HASH_TABLE attributeIds;
00264   HASH_TABLE prefixes;
00265   STRING_POOL pool;
00266   STRING_POOL entityValuePool;
00267   /* false once a parameter entity reference has been skipped */
00268   XML_Bool keepProcessing;
00269   /* true once an internal or external PE reference has been encountered;
00270      this includes the reference to an external subset */
00271   XML_Bool hasParamEntityRefs;
00272   XML_Bool standalone;
00273 #ifdef XML_DTD
00274   /* indicates if external PE has been read */
00275   XML_Bool paramEntityRead;
00276   HASH_TABLE paramEntities;
00277 #endif /* XML_DTD */
00278   PREFIX defaultPrefix;
00279   /* === scaffolding for building content model === */
00280   XML_Bool in_eldecl;
00281   CONTENT_SCAFFOLD *scaffold;
00282   unsigned contentStringLen;
00283   unsigned scaffSize;
00284   unsigned scaffCount;
00285   int scaffLevel;
00286   int *scaffIndex;
00287 } DTD;
00288 
00289 typedef struct open_internal_entity {
00290   const char *internalEventPtr;
00291   const char *internalEventEndPtr;
00292   struct open_internal_entity *next;
00293   ENTITY *entity;
00294   int startTagLevel;
00295   XML_Bool betweenDecl; /* WFC: PE Between Declarations */
00296 } OPEN_INTERNAL_ENTITY;
00297 
00298 typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
00299                                          const char *start,
00300                                          const char *end,
00301                                          const char **endPtr);
00302 
00303 static Processor prologProcessor;
00304 static Processor prologInitProcessor;
00305 static Processor contentProcessor;
00306 static Processor cdataSectionProcessor;
00307 #ifdef XML_DTD
00308 static Processor ignoreSectionProcessor;
00309 static Processor externalParEntProcessor;
00310 static Processor externalParEntInitProcessor;
00311 static Processor entityValueProcessor;
00312 static Processor entityValueInitProcessor;
00313 #endif /* XML_DTD */
00314 static Processor epilogProcessor;
00315 static Processor errorProcessor;
00316 static Processor externalEntityInitProcessor;
00317 static Processor externalEntityInitProcessor2;
00318 static Processor externalEntityInitProcessor3;
00319 static Processor externalEntityContentProcessor;
00320 static Processor internalEntityProcessor;
00321 
00322 static enum XML_Error
00323 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
00324 static enum XML_Error
00325 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
00326                const char *s, const char *next);
00327 static enum XML_Error
00328 initializeEncoding(XML_Parser parser);
00329 static enum XML_Error
00330 doProlog(XML_Parser parser, const ENCODING *enc, const char *s, 
00331          const char *end, int tok, const char *next, const char **nextPtr, 
00332          XML_Bool haveMore);
00333 static enum XML_Error
00334 processInternalEntity(XML_Parser parser, ENTITY *entity, 
00335                       XML_Bool betweenDecl);
00336 static enum XML_Error
00337 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
00338           const char *start, const char *end, const char **endPtr, 
00339           XML_Bool haveMore);
00340 static enum XML_Error
00341 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
00342                const char *end, const char **nextPtr, XML_Bool haveMore);
00343 #ifdef XML_DTD
00344 static enum XML_Error
00345 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
00346                 const char *end, const char **nextPtr, XML_Bool haveMore);
00347 #endif /* XML_DTD */
00348 
00349 static enum XML_Error
00350 storeAtts(XML_Parser parser, const ENCODING *, const char *s,
00351           TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
00352 static enum XML_Error
00353 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
00354            const XML_Char *uri, BINDING **bindingsPtr);
00355 static int
00356 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 
00357                 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
00358 static enum XML_Error
00359 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
00360                     const char *, const char *, STRING_POOL *);
00361 static enum XML_Error
00362 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
00363                      const char *, const char *, STRING_POOL *);
00364 static ATTRIBUTE_ID *
00365 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
00366                const char *end);
00367 static int
00368 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
00369 static enum XML_Error
00370 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
00371                  const char *end);
00372 static int
00373 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
00374                             const char *start, const char *end);
00375 static int
00376 reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
00377               const char *end);
00378 static void
00379 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
00380               const char *end);
00381 
00382 static const XML_Char * getContext(XML_Parser parser);
00383 static XML_Bool
00384 setContext(XML_Parser parser, const XML_Char *context);
00385 
00386 static void FASTCALL normalizePublicId(XML_Char *s);
00387 
00388 static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
00389 /* do not call if parentParser != NULL */
00390 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
00391 static void
00392 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
00393 static int
00394 dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
00395 static int
00396 copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
00397 
00398 static NAMED *
00399 lookup(HASH_TABLE *table, KEY name, size_t createSize);
00400 static void FASTCALL
00401 hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
00402 static void FASTCALL hashTableClear(HASH_TABLE *);
00403 static void FASTCALL hashTableDestroy(HASH_TABLE *);
00404 static void FASTCALL
00405 hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
00406 static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
00407 
00408 static void FASTCALL
00409 poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
00410 static void FASTCALL poolClear(STRING_POOL *);
00411 static void FASTCALL poolDestroy(STRING_POOL *);
00412 static XML_Char *
00413 poolAppend(STRING_POOL *pool, const ENCODING *enc,
00414            const char *ptr, const char *end);
00415 static XML_Char *
00416 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
00417                 const char *ptr, const char *end);
00418 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
00419 static const XML_Char * FASTCALL
00420 poolCopyString(STRING_POOL *pool, const XML_Char *s);
00421 static const XML_Char *
00422 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
00423 static const XML_Char * FASTCALL
00424 poolAppendString(STRING_POOL *pool, const XML_Char *s);
00425 
00426 static int FASTCALL nextScaffoldPart(XML_Parser parser);
00427 static XML_Content * build_model(XML_Parser parser);
00428 static ELEMENT_TYPE *
00429 getElementType(XML_Parser parser, const ENCODING *enc,
00430                const char *ptr, const char *end);
00431 
00432 static XML_Parser
00433 parserCreate(const XML_Char *encodingName,
00434              const XML_Memory_Handling_Suite *memsuite,
00435              const XML_Char *nameSep,
00436              DTD *dtd);
00437 static void
00438 parserInit(XML_Parser parser, const XML_Char *encodingName);
00439 
00440 #define poolStart(pool) ((pool)->start)
00441 #define poolEnd(pool) ((pool)->ptr)
00442 #define poolLength(pool) ((pool)->ptr - (pool)->start)
00443 #define poolChop(pool) ((void)--(pool->ptr))
00444 #define poolLastChar(pool) (((pool)->ptr)[-1])
00445 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
00446 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
00447 #define poolAppendChar(pool, c) \
00448   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
00449    ? 0 \
00450    : ((*((pool)->ptr)++ = c), 1))
00451 
00452 struct XML_ParserStruct {
00453   /* The first member must be userData so that the XML_GetUserData
00454      macro works. */
00455   void *m_userData;
00456   void *m_handlerArg;
00457   char *m_buffer;
00458   const XML_Memory_Handling_Suite m_mem;
00459   /* first character to be parsed */
00460   const char *m_bufferPtr;
00461   /* past last character to be parsed */
00462   char *m_bufferEnd;
00463   /* allocated end of buffer */
00464   const char *m_bufferLim;
00465   XML_Index m_parseEndByteIndex;
00466   const char *m_parseEndPtr;
00467   XML_Char *m_dataBuf;
00468   XML_Char *m_dataBufEnd;
00469   XML_StartElementHandler m_startElementHandler;
00470   XML_EndElementHandler m_endElementHandler;
00471   XML_CharacterDataHandler m_characterDataHandler;
00472   XML_ProcessingInstructionHandler m_processingInstructionHandler;
00473   XML_CommentHandler m_commentHandler;
00474   XML_StartCdataSectionHandler m_startCdataSectionHandler;
00475   XML_EndCdataSectionHandler m_endCdataSectionHandler;
00476   XML_DefaultHandler m_defaultHandler;
00477   XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
00478   XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
00479   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
00480   XML_NotationDeclHandler m_notationDeclHandler;
00481   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
00482   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
00483   XML_NotStandaloneHandler m_notStandaloneHandler;
00484   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
00485   XML_Parser m_externalEntityRefHandlerArg;
00486   XML_SkippedEntityHandler m_skippedEntityHandler;
00487   XML_UnknownEncodingHandler m_unknownEncodingHandler;
00488   XML_ElementDeclHandler m_elementDeclHandler;
00489   XML_AttlistDeclHandler m_attlistDeclHandler;
00490   XML_EntityDeclHandler m_entityDeclHandler;
00491   XML_XmlDeclHandler m_xmlDeclHandler;
00492   const ENCODING *m_encoding;
00493   INIT_ENCODING m_initEncoding;
00494   const ENCODING *m_internalEncoding;
00495   const XML_Char *m_protocolEncodingName;
00496   XML_Bool m_ns;
00497   XML_Bool m_ns_triplets;
00498   void *m_unknownEncodingMem;
00499   void *m_unknownEncodingData;
00500   void *m_unknownEncodingHandlerData;
00501   void (XMLCALL *m_unknownEncodingRelease)(void *);
00502   PROLOG_STATE m_prologState;
00503   Processor *m_processor;
00504   enum XML_Error m_errorCode;
00505   const char *m_eventPtr;
00506   const char *m_eventEndPtr;
00507   const char *m_positionPtr;
00508   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
00509   OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
00510   XML_Bool m_defaultExpandInternalEntities;
00511   int m_tagLevel;
00512   ENTITY *m_declEntity;
00513   const XML_Char *m_doctypeName;
00514   const XML_Char *m_doctypeSysid;
00515   const XML_Char *m_doctypePubid;
00516   const XML_Char *m_declAttributeType;
00517   const XML_Char *m_declNotationName;
00518   const XML_Char *m_declNotationPublicId;
00519   ELEMENT_TYPE *m_declElementType;
00520   ATTRIBUTE_ID *m_declAttributeId;
00521   XML_Bool m_declAttributeIsCdata;
00522   XML_Bool m_declAttributeIsId;
00523   DTD *m_dtd;
00524   const XML_Char *m_curBase;
00525   TAG *m_tagStack;
00526   TAG *m_freeTagList;
00527   BINDING *m_inheritedBindings;
00528   BINDING *m_freeBindingList;
00529   int m_attsSize;
00530   int m_nSpecifiedAtts;
00531   int m_idAttIndex;
00532   ATTRIBUTE *m_atts;
00533   NS_ATT *m_nsAtts;
00534   unsigned long m_nsAttsVersion;
00535   unsigned char m_nsAttsPower;
00536   POSITION m_position;
00537   STRING_POOL m_tempPool;
00538   STRING_POOL m_temp2Pool;
00539   char *m_groupConnector;
00540   unsigned int m_groupSize;
00541   XML_Char m_namespaceSeparator;
00542   XML_Parser m_parentParser;
00543   XML_ParsingStatus m_parsingStatus;
00544 #ifdef XML_DTD
00545   XML_Bool m_isParamEntity;
00546   XML_Bool m_useForeignDTD;
00547   enum XML_ParamEntityParsing m_paramEntityParsing;
00548 #endif
00549 };
00550 
00551 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
00552 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
00553 #define FREE(p) (parser->m_mem.free_fcn((p)))
00554 
00555 #define userData (parser->m_userData)
00556 #define handlerArg (parser->m_handlerArg)
00557 #define startElementHandler (parser->m_startElementHandler)
00558 #define endElementHandler (parser->m_endElementHandler)
00559 #define characterDataHandler (parser->m_characterDataHandler)
00560 #define processingInstructionHandler \
00561         (parser->m_processingInstructionHandler)
00562 #define commentHandler (parser->m_commentHandler)
00563 #define startCdataSectionHandler \
00564         (parser->m_startCdataSectionHandler)
00565 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
00566 #define defaultHandler (parser->m_defaultHandler)
00567 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
00568 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
00569 #define unparsedEntityDeclHandler \
00570         (parser->m_unparsedEntityDeclHandler)
00571 #define notationDeclHandler (parser->m_notationDeclHandler)
00572 #define startNamespaceDeclHandler \
00573         (parser->m_startNamespaceDeclHandler)
00574 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
00575 #define notStandaloneHandler (parser->m_notStandaloneHandler)
00576 #define externalEntityRefHandler \
00577         (parser->m_externalEntityRefHandler)
00578 #define externalEntityRefHandlerArg \
00579         (parser->m_externalEntityRefHandlerArg)
00580 #define internalEntityRefHandler \
00581         (parser->m_internalEntityRefHandler)
00582 #define skippedEntityHandler (parser->m_skippedEntityHandler)
00583 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
00584 #define elementDeclHandler (parser->m_elementDeclHandler)
00585 #define attlistDeclHandler (parser->m_attlistDeclHandler)
00586 #define entityDeclHandler (parser->m_entityDeclHandler)
00587 #define xmlDeclHandler (parser->m_xmlDeclHandler)
00588 #define encoding (parser->m_encoding)
00589 #define initEncoding (parser->m_initEncoding)
00590 #define internalEncoding (parser->m_internalEncoding)
00591 #define unknownEncodingMem (parser->m_unknownEncodingMem)
00592 #define unknownEncodingData (parser->m_unknownEncodingData)
00593 #define unknownEncodingHandlerData \
00594   (parser->m_unknownEncodingHandlerData)
00595 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
00596 #define protocolEncodingName (parser->m_protocolEncodingName)
00597 #define ns (parser->m_ns)
00598 #define ns_triplets (parser->m_ns_triplets)
00599 #define prologState (parser->m_prologState)
00600 #define processor (parser->m_processor)
00601 #define errorCode (parser->m_errorCode)
00602 #define eventPtr (parser->m_eventPtr)
00603 #define eventEndPtr (parser->m_eventEndPtr)
00604 #define positionPtr (parser->m_positionPtr)
00605 #define position (parser->m_position)
00606 #define openInternalEntities (parser->m_openInternalEntities)
00607 #define freeInternalEntities (parser->m_freeInternalEntities)
00608 #define defaultExpandInternalEntities \
00609         (parser->m_defaultExpandInternalEntities)
00610 #define tagLevel (parser->m_tagLevel)
00611 #define buffer (parser->m_buffer)
00612 #define bufferPtr (parser->m_bufferPtr)
00613 #define bufferEnd (parser->m_bufferEnd)
00614 #define parseEndByteIndex (parser->m_parseEndByteIndex)
00615 #define parseEndPtr (parser->m_parseEndPtr)
00616 #define bufferLim (parser->m_bufferLim)
00617 #define dataBuf (parser->m_dataBuf)
00618 #define dataBufEnd (parser->m_dataBufEnd)
00619 #define _dtd (parser->m_dtd)
00620 #define curBase (parser->m_curBase)
00621 #define declEntity (parser->m_declEntity)
00622 #define doctypeName (parser->m_doctypeName)
00623 #define doctypeSysid (parser->m_doctypeSysid)
00624 #define doctypePubid (parser->m_doctypePubid)
00625 #define declAttributeType (parser->m_declAttributeType)
00626 #define declNotationName (parser->m_declNotationName)
00627 #define declNotationPublicId (parser->m_declNotationPublicId)
00628 #define declElementType (parser->m_declElementType)
00629 #define declAttributeId (parser->m_declAttributeId)
00630 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
00631 #define declAttributeIsId (parser->m_declAttributeIsId)
00632 #define freeTagList (parser->m_freeTagList)
00633 #define freeBindingList (parser->m_freeBindingList)
00634 #define inheritedBindings (parser->m_inheritedBindings)
00635 #define tagStack (parser->m_tagStack)
00636 #define atts (parser->m_atts)
00637 #define attsSize (parser->m_attsSize)
00638 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
00639 #define idAttIndex (parser->m_idAttIndex)
00640 #define nsAtts (parser->m_nsAtts)
00641 #define nsAttsVersion (parser->m_nsAttsVersion)
00642 #define nsAttsPower (parser->m_nsAttsPower)
00643 #define tempPool (parser->m_tempPool)
00644 #define temp2Pool (parser->m_temp2Pool)
00645 #define groupConnector (parser->m_groupConnector)
00646 #define groupSize (parser->m_groupSize)
00647 #define namespaceSeparator (parser->m_namespaceSeparator)
00648 #define parentParser (parser->m_parentParser)
00649 #define ps_parsing (parser->m_parsingStatus.parsing)
00650 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
00651 #ifdef XML_DTD
00652 #define isParamEntity (parser->m_isParamEntity)
00653 #define useForeignDTD (parser->m_useForeignDTD)
00654 #define paramEntityParsing (parser->m_paramEntityParsing)
00655 #endif /* XML_DTD */
00656 
00657 XML_Parser XMLCALL
00658 XML_ParserCreate(const XML_Char *encodingName)
00659 {
00660   return XML_ParserCreate_MM(encodingName, NULL, NULL);
00661 }
00662 
00663 XML_Parser XMLCALL
00664 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
00665 {
00666   XML_Char tmp[2];
00667   *tmp = nsSep;
00668   return XML_ParserCreate_MM(encodingName, NULL, tmp);
00669 }
00670 
00671 static const XML_Char implicitContext[] = {
00672   ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
00673   ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, 
00674   ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
00675   ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
00676   ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
00677   ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
00678 };
00679 
00680 XML_Parser XMLCALL
00681 XML_ParserCreate_MM(const XML_Char *encodingName,
00682                     const XML_Memory_Handling_Suite *memsuite,
00683                     const XML_Char *nameSep)
00684 {
00685   XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
00686   if (parser != NULL && ns) {
00687     /* implicit context only set for root parser, since child
00688        parsers (i.e. external entity parsers) will inherit it
00689     */
00690     if (!setContext(parser, implicitContext)) {
00691       XML_ParserFree(parser);
00692       return NULL;
00693     }
00694   }
00695   return parser;
00696 }
00697 
00698 static XML_Parser
00699 parserCreate(const XML_Char *encodingName,
00700              const XML_Memory_Handling_Suite *memsuite,
00701              const XML_Char *nameSep,
00702              DTD *dtd)
00703 {
00704   XML_Parser parser;
00705 
00706   if (memsuite) {
00707     XML_Memory_Handling_Suite *mtemp;
00708     parser = (XML_Parser)
00709       memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
00710     if (parser != NULL) {
00711       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
00712       mtemp->malloc_fcn = memsuite->malloc_fcn;
00713       mtemp->realloc_fcn = memsuite->realloc_fcn;
00714       mtemp->free_fcn = memsuite->free_fcn;
00715     }
00716   }
00717   else {
00718     XML_Memory_Handling_Suite *mtemp;
00719     parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
00720     if (parser != NULL) {
00721       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
00722       mtemp->malloc_fcn = malloc;
00723       mtemp->realloc_fcn = realloc;
00724       mtemp->free_fcn = free;
00725     }
00726   }
00727 
00728   if (!parser)
00729     return parser;
00730 
00731   buffer = NULL;
00732   bufferLim = NULL;
00733 
00734   attsSize = INIT_ATTS_SIZE;
00735   atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
00736   if (atts == NULL) {
00737     FREE(parser);
00738     return NULL;
00739   }
00740   dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
00741   if (dataBuf == NULL) {
00742     FREE(atts);
00743     FREE(parser);
00744     return NULL;
00745   }
00746   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
00747 
00748   if (dtd)
00749     _dtd = dtd;
00750   else {
00751     _dtd = dtdCreate(&parser->m_mem);
00752     if (_dtd == NULL) {
00753       FREE(dataBuf);
00754       FREE(atts);
00755       FREE(parser);
00756       return NULL;
00757     }
00758   }
00759 
00760   freeBindingList = NULL;
00761   freeTagList = NULL;
00762   freeInternalEntities = NULL;
00763 
00764   groupSize = 0;
00765   groupConnector = NULL;
00766 
00767   unknownEncodingHandler = NULL;
00768   unknownEncodingHandlerData = NULL;
00769 
00770   namespaceSeparator = ASCII_EXCL;
00771   ns = XML_FALSE;
00772   ns_triplets = XML_FALSE;
00773 
00774   nsAtts = NULL;
00775   nsAttsVersion = 0;
00776   nsAttsPower = 0;
00777 
00778   poolInit(&tempPool, &(parser->m_mem));
00779   poolInit(&temp2Pool, &(parser->m_mem));
00780   parserInit(parser, encodingName);
00781 
00782   if (encodingName && !protocolEncodingName) {
00783     XML_ParserFree(parser);
00784     return NULL;
00785   }
00786 
00787   if (nameSep) {
00788     ns = XML_TRUE;
00789     internalEncoding = XmlGetInternalEncodingNS();
00790     namespaceSeparator = *nameSep;
00791   }
00792   else {
00793     internalEncoding = XmlGetInternalEncoding();
00794   }
00795 
00796   return parser;
00797 }
00798 
00799 static void
00800 parserInit(XML_Parser parser, const XML_Char *encodingName)
00801 {
00802   processor = prologInitProcessor;
00803   XmlPrologStateInit(&prologState);
00804   protocolEncodingName = (encodingName != NULL
00805                           ? poolCopyString(&tempPool, encodingName)
00806                           : NULL);
00807   curBase = NULL;
00808   XmlInitEncoding(&initEncoding, &encoding, 0);
00809   userData = NULL;
00810   handlerArg = NULL;
00811   startElementHandler = NULL;
00812   endElementHandler = NULL;
00813   characterDataHandler = NULL;
00814   processingInstructionHandler = NULL;
00815   commentHandler = NULL;
00816   startCdataSectionHandler = NULL;
00817   endCdataSectionHandler = NULL;
00818   defaultHandler = NULL;
00819   startDoctypeDeclHandler = NULL;
00820   endDoctypeDeclHandler = NULL;
00821   unparsedEntityDeclHandler = NULL;
00822   notationDeclHandler = NULL;
00823   startNamespaceDeclHandler = NULL;
00824   endNamespaceDeclHandler = NULL;
00825   notStandaloneHandler = NULL;
00826   externalEntityRefHandler = NULL;
00827   externalEntityRefHandlerArg = parser;
00828   skippedEntityHandler = NULL;
00829   elementDeclHandler = NULL;
00830   attlistDeclHandler = NULL;
00831   entityDeclHandler = NULL;
00832   xmlDeclHandler = NULL;
00833   bufferPtr = buffer;
00834   bufferEnd = buffer;
00835   parseEndByteIndex = 0;
00836   parseEndPtr = NULL;
00837   declElementType = NULL;
00838   declAttributeId = NULL;
00839   declEntity = NULL;
00840   doctypeName = NULL;
00841   doctypeSysid = NULL;
00842   doctypePubid = NULL;
00843   declAttributeType = NULL;
00844   declNotationName = NULL;
00845   declNotationPublicId = NULL;
00846   declAttributeIsCdata = XML_FALSE;
00847   declAttributeIsId = XML_FALSE;
00848   memset(&position, 0, sizeof(POSITION));
00849   errorCode = XML_ERROR_NONE;
00850   eventPtr = NULL;
00851   eventEndPtr = NULL;
00852   positionPtr = NULL;
00853   openInternalEntities = NULL;
00854   defaultExpandInternalEntities = XML_TRUE;
00855   tagLevel = 0;
00856   tagStack = NULL;
00857   inheritedBindings = NULL;
00858   nSpecifiedAtts = 0;
00859   unknownEncodingMem = NULL;
00860   unknownEncodingRelease = NULL;
00861   unknownEncodingData = NULL;
00862   parentParser = NULL;
00863   ps_parsing = XML_INITIALIZED;
00864 #ifdef XML_DTD
00865   isParamEntity = XML_FALSE;
00866   useForeignDTD = XML_FALSE;
00867   paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
00868 #endif
00869 }
00870 
00871 /* moves list of bindings to freeBindingList */
00872 static void FASTCALL
00873 moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
00874 {
00875   while (bindings) {
00876     BINDING *b = bindings;
00877     bindings = bindings->nextTagBinding;
00878     b->nextTagBinding = freeBindingList;
00879     freeBindingList = b;
00880   }
00881 }
00882 
00883 XML_Bool XMLCALL
00884 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
00885 {
00886   TAG *tStk;
00887   OPEN_INTERNAL_ENTITY *openEntityList;
00888   if (parentParser)
00889     return XML_FALSE;
00890   /* move tagStack to freeTagList */
00891   tStk = tagStack;
00892   while (tStk) {
00893     TAG *tag = tStk;
00894     tStk = tStk->parent;
00895     tag->parent = freeTagList;
00896     moveToFreeBindingList(parser, tag->bindings);
00897     tag->bindings = NULL;
00898     freeTagList = tag;
00899   }
00900   /* move openInternalEntities to freeInternalEntities */
00901   openEntityList = openInternalEntities;
00902   while (openEntityList) {
00903     OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
00904     openEntityList = openEntity->next;
00905     openEntity->next = freeInternalEntities;
00906     freeInternalEntities = openEntity;
00907   }
00908   moveToFreeBindingList(parser, inheritedBindings);
00909   FREE(unknownEncodingMem);
00910   if (unknownEncodingRelease)
00911     unknownEncodingRelease(unknownEncodingData);
00912   poolClear(&tempPool);
00913   poolClear(&temp2Pool);
00914   parserInit(parser, encodingName);
00915   dtdReset(_dtd, &parser->m_mem);
00916   return setContext(parser, implicitContext);
00917 }
00918 
00919 enum XML_Status XMLCALL
00920 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
00921 {
00922   /* Block after XML_Parse()/XML_ParseBuffer() has been called.
00923      XXX There's no way for the caller to determine which of the
00924      XXX possible error cases caused the XML_STATUS_ERROR return.
00925   */
00926   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
00927     return XML_STATUS_ERROR;
00928   if (encodingName == NULL)
00929     protocolEncodingName = NULL;
00930   else {
00931     protocolEncodingName = poolCopyString(&tempPool, encodingName);
00932     if (!protocolEncodingName)
00933       return XML_STATUS_ERROR;
00934   }
00935   return XML_STATUS_OK;
00936 }
00937 
00938 XML_Parser XMLCALL
00939 XML_ExternalEntityParserCreate(XML_Parser oldParser,
00940                                const XML_Char *context,
00941                                const XML_Char *encodingName)
00942 {
00943   XML_Parser parser = oldParser;
00944   DTD *newDtd = NULL;
00945   DTD *oldDtd = _dtd;
00946   XML_StartElementHandler oldStartElementHandler = startElementHandler;
00947   XML_EndElementHandler oldEndElementHandler = endElementHandler;
00948   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
00949   XML_ProcessingInstructionHandler oldProcessingInstructionHandler
00950       = processingInstructionHandler;
00951   XML_CommentHandler oldCommentHandler = commentHandler;
00952   XML_StartCdataSectionHandler oldStartCdataSectionHandler
00953       = startCdataSectionHandler;
00954   XML_EndCdataSectionHandler oldEndCdataSectionHandler
00955       = endCdataSectionHandler;
00956   XML_DefaultHandler oldDefaultHandler = defaultHandler;
00957   XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
00958       = unparsedEntityDeclHandler;
00959   XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
00960   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
00961       = startNamespaceDeclHandler;
00962   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
00963       = endNamespaceDeclHandler;
00964   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
00965   XML_ExternalEntityRefHandler oldExternalEntityRefHandler
00966       = externalEntityRefHandler;
00967   XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
00968   XML_UnknownEncodingHandler oldUnknownEncodingHandler
00969       = unknownEncodingHandler;
00970   XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
00971   XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
00972   XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
00973   XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
00974   ELEMENT_TYPE * oldDeclElementType = declElementType;
00975 
00976   void *oldUserData = userData;
00977   void *oldHandlerArg = handlerArg;
00978   XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
00979   XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
00980 #ifdef XML_DTD
00981   enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
00982   int oldInEntityValue = prologState.inEntityValue;
00983 #endif
00984   XML_Bool oldns_triplets = ns_triplets;
00985 
00986 #ifdef XML_DTD
00987   if (!context)
00988     newDtd = oldDtd;
00989 #endif /* XML_DTD */
00990 
00991   /* Note that the magical uses of the pre-processor to make field
00992      access look more like C++ require that `parser' be overwritten
00993      here.  This makes this function more painful to follow than it
00994      would be otherwise.
00995   */
00996   if (ns) {
00997     XML_Char tmp[2];
00998     *tmp = namespaceSeparator;
00999     parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
01000   }
01001   else {
01002     parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
01003   }
01004 
01005   if (!parser)
01006     return NULL;
01007 
01008   startElementHandler = oldStartElementHandler;
01009   endElementHandler = oldEndElementHandler;
01010   characterDataHandler = oldCharacterDataHandler;
01011   processingInstructionHandler = oldProcessingInstructionHandler;
01012   commentHandler = oldCommentHandler;
01013   startCdataSectionHandler = oldStartCdataSectionHandler;
01014   endCdataSectionHandler = oldEndCdataSectionHandler;
01015   defaultHandler = oldDefaultHandler;
01016   unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
01017   notationDeclHandler = oldNotationDeclHandler;
01018   startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
01019   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
01020   notStandaloneHandler = oldNotStandaloneHandler;
01021   externalEntityRefHandler = oldExternalEntityRefHandler;
01022   skippedEntityHandler = oldSkippedEntityHandler;
01023   unknownEncodingHandler = oldUnknownEncodingHandler;
01024   elementDeclHandler = oldElementDeclHandler;
01025   attlistDeclHandler = oldAttlistDeclHandler;
01026   entityDeclHandler = oldEntityDeclHandler;
01027   xmlDeclHandler = oldXmlDeclHandler;
01028   declElementType = oldDeclElementType;
01029   userData = oldUserData;
01030   if (oldUserData == oldHandlerArg)
01031     handlerArg = userData;
01032   else
01033     handlerArg = parser;
01034   if (oldExternalEntityRefHandlerArg != oldParser)
01035     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
01036   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
01037   ns_triplets = oldns_triplets;
01038   parentParser = oldParser;
01039 #ifdef XML_DTD
01040   paramEntityParsing = oldParamEntityParsing;
01041   prologState.inEntityValue = oldInEntityValue;
01042   if (context) {
01043 #endif /* XML_DTD */
01044     if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
01045       || !setContext(parser, context)) {
01046       XML_ParserFree(parser);
01047       return NULL;
01048     }
01049     processor = externalEntityInitProcessor;
01050 #ifdef XML_DTD
01051   }
01052   else {
01053     /* The DTD instance referenced by _dtd is shared between the document's
01054        root parser and external PE parsers, therefore one does not need to
01055        call setContext. In addition, one also *must* not call setContext,
01056        because this would overwrite existing prefix->binding pointers in
01057        _dtd with ones that get destroyed with the external PE parser.
01058        This would leave those prefixes with dangling pointers.
01059     */
01060     isParamEntity = XML_TRUE;
01061     XmlPrologStateInitExternalEntity(&prologState);
01062     processor = externalParEntInitProcessor;
01063   }
01064 #endif /* XML_DTD */
01065   return parser;
01066 }
01067 
01068 static void FASTCALL
01069 destroyBindings(BINDING *bindings, XML_Parser parser)
01070 {
01071   for (;;) {
01072     BINDING *b = bindings;
01073     if (!b)
01074       break;
01075     bindings = b->nextTagBinding;
01076     FREE(b->uri);
01077     FREE(b);
01078   }
01079 }
01080 
01081 void XMLCALL
01082 XML_ParserFree(XML_Parser parser)
01083 {
01084   TAG *tagList;
01085   OPEN_INTERNAL_ENTITY *entityList;
01086   if (parser == NULL)
01087     return;
01088   /* free tagStack and freeTagList */
01089   tagList = tagStack;
01090   for (;;) {
01091     TAG *p;
01092     if (tagList == NULL) {
01093       if (freeTagList == NULL)
01094         break;
01095       tagList = freeTagList;
01096       freeTagList = NULL;
01097     }
01098     p = tagList;
01099     tagList = tagList->parent;
01100     FREE(p->buf);
01101     destroyBindings(p->bindings, parser);
01102     FREE(p);
01103   }
01104   /* free openInternalEntities and freeInternalEntities */
01105   entityList = openInternalEntities;
01106   for (;;) {
01107     OPEN_INTERNAL_ENTITY *openEntity;
01108     if (entityList == NULL) {
01109       if (freeInternalEntities == NULL)
01110         break;
01111       entityList = freeInternalEntities;
01112       freeInternalEntities = NULL;
01113     }
01114     openEntity = entityList;
01115     entityList = entityList->next;
01116     FREE(openEntity);
01117   }
01118 
01119   destroyBindings(freeBindingList, parser);
01120   destroyBindings(inheritedBindings, parser);
01121   poolDestroy(&tempPool);
01122   poolDestroy(&temp2Pool);
01123 #ifdef XML_DTD
01124   /* external parameter entity parsers share the DTD structure
01125      parser->m_dtd with the root parser, so we must not destroy it
01126   */
01127   if (!isParamEntity && _dtd)
01128 #else
01129   if (_dtd)
01130 #endif /* XML_DTD */
01131     dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
01132   FREE((void *)atts);
01133   FREE(groupConnector);
01134   FREE(buffer);
01135   FREE(dataBuf);
01136   FREE(nsAtts);
01137   FREE(unknownEncodingMem);
01138   if (unknownEncodingRelease)
01139     unknownEncodingRelease(unknownEncodingData);
01140   FREE(parser);
01141 }
01142 
01143 void XMLCALL
01144 XML_UseParserAsHandlerArg(XML_Parser parser)
01145 {
01146   handlerArg = parser;
01147 }
01148 
01149 enum XML_Error XMLCALL
01150 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
01151 {
01152 #ifdef XML_DTD
01153   /* block after XML_Parse()/XML_ParseBuffer() has been called */
01154   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
01155     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
01156   useForeignDTD = useDTD;
01157   return XML_ERROR_NONE;
01158 #else
01159   return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
01160 #endif
01161 }
01162 
01163 void XMLCALL
01164 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
01165 {
01166   /* block after XML_Parse()/XML_ParseBuffer() has been called */
01167   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
01168     return;
01169   ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
01170 }
01171 
01172 void XMLCALL
01173 XML_SetUserData(XML_Parser parser, void *p)
01174 {
01175   if (handlerArg == userData)
01176     handlerArg = userData = p;
01177   else
01178     userData = p;
01179 }
01180 
01181 enum XML_Status XMLCALL
01182 XML_SetBase(XML_Parser parser, const XML_Char *p)
01183 {
01184   if (p) {
01185     p = poolCopyString(&_dtd->pool, p);
01186     if (!p)
01187       return XML_STATUS_ERROR;
01188     curBase = p;
01189   }
01190   else
01191     curBase = NULL;
01192   return XML_STATUS_OK;
01193 }
01194 
01195 const XML_Char * XMLCALL
01196 XML_GetBase(XML_Parser parser)
01197 {
01198   return curBase;
01199 }
01200 
01201 int XMLCALL
01202 XML_GetSpecifiedAttributeCount(XML_Parser parser)
01203 {
01204   return nSpecifiedAtts;
01205 }
01206 
01207 int XMLCALL
01208 XML_GetIdAttributeIndex(XML_Parser parser)
01209 {
01210   return idAttIndex;
01211 }
01212 
01213 void XMLCALL
01214 XML_SetElementHandler(XML_Parser parser,
01215                       XML_StartElementHandler start,
01216                       XML_EndElementHandler end)
01217 {
01218   startElementHandler = start;
01219   endElementHandler = end;
01220 }
01221 
01222 void XMLCALL
01223 XML_SetStartElementHandler(XML_Parser parser,
01224                            XML_StartElementHandler start) {
01225   startElementHandler = start;
01226 }
01227 
01228 void XMLCALL
01229 XML_SetEndElementHandler(XML_Parser parser,
01230                          XML_EndElementHandler end) {
01231   endElementHandler = end;
01232 }
01233 
01234 void XMLCALL
01235 XML_SetCharacterDataHandler(XML_Parser parser,
01236                             XML_CharacterDataHandler handler)
01237 {
01238   characterDataHandler = handler;
01239 }
01240 
01241 void XMLCALL
01242 XML_SetProcessingInstructionHandler(XML_Parser parser,
01243                                     XML_ProcessingInstructionHandler handler)
01244 {
01245   processingInstructionHandler = handler;
01246 }
01247 
01248 void XMLCALL
01249 XML_SetCommentHandler(XML_Parser parser,
01250                       XML_CommentHandler handler)
01251 {
01252   commentHandler = handler;
01253 }
01254 
01255 void XMLCALL
01256 XML_SetCdataSectionHandler(XML_Parser parser,
01257                            XML_StartCdataSectionHandler start,
01258                            XML_EndCdataSectionHandler end)
01259 {
01260   startCdataSectionHandler = start;
01261   endCdataSectionHandler = end;
01262 }
01263 
01264 void XMLCALL
01265 XML_SetStartCdataSectionHandler(XML_Parser parser,
01266                                 XML_StartCdataSectionHandler start) {
01267   startCdataSectionHandler = start;
01268 }
01269 
01270 void XMLCALL
01271 XML_SetEndCdataSectionHandler(XML_Parser parser,
01272                               XML_EndCdataSectionHandler end) {
01273   endCdataSectionHandler = end;
01274 }
01275 
01276 void XMLCALL
01277 XML_SetDefaultHandler(XML_Parser parser,
01278                       XML_DefaultHandler handler)
01279 {
01280   defaultHandler = handler;
01281   defaultExpandInternalEntities = XML_FALSE;
01282 }
01283 
01284 void XMLCALL
01285 XML_SetDefaultHandlerExpand(XML_Parser parser,
01286                             XML_DefaultHandler handler)
01287 {
01288   defaultHandler = handler;
01289   defaultExpandInternalEntities = XML_TRUE;
01290 }
01291 
01292 void XMLCALL
01293 XML_SetDoctypeDeclHandler(XML_Parser parser,
01294                           XML_StartDoctypeDeclHandler start,
01295                           XML_EndDoctypeDeclHandler end)
01296 {
01297   startDoctypeDeclHandler = start;
01298   endDoctypeDeclHandler = end;
01299 }
01300 
01301 void XMLCALL
01302 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
01303                                XML_StartDoctypeDeclHandler start) {
01304   startDoctypeDeclHandler = start;
01305 }
01306 
01307 void XMLCALL
01308 XML_SetEndDoctypeDeclHandler(XML_Parser parser,
01309                              XML_EndDoctypeDeclHandler end) {
01310   endDoctypeDeclHandler = end;
01311 }
01312 
01313 void XMLCALL
01314 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
01315                                  XML_UnparsedEntityDeclHandler handler)
01316 {
01317   unparsedEntityDeclHandler = handler;
01318 }
01319 
01320 void XMLCALL
01321 XML_SetNotationDeclHandler(XML_Parser parser,
01322                            XML_NotationDeclHandler handler)
01323 {
01324   notationDeclHandler = handler;
01325 }
01326 
01327 void XMLCALL
01328 XML_SetNamespaceDeclHandler(XML_Parser parser,
01329                             XML_StartNamespaceDeclHandler start,
01330                             XML_EndNamespaceDeclHandler end)
01331 {
01332   startNamespaceDeclHandler = start;
01333   endNamespaceDeclHandler = end;
01334 }
01335 
01336 void XMLCALL
01337 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
01338                                  XML_StartNamespaceDeclHandler start) {
01339   startNamespaceDeclHandler = start;
01340 }
01341 
01342 void XMLCALL
01343 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
01344                                XML_EndNamespaceDeclHandler end) {
01345   endNamespaceDeclHandler = end;
01346 }
01347 
01348 void XMLCALL
01349 XML_SetNotStandaloneHandler(XML_Parser parser,
01350                             XML_NotStandaloneHandler handler)
01351 {
01352   notStandaloneHandler = handler;
01353 }
01354 
01355 void XMLCALL
01356 XML_SetExternalEntityRefHandler(XML_Parser parser,
01357                                 XML_ExternalEntityRefHandler handler)
01358 {
01359   externalEntityRefHandler = handler;
01360 }
01361 
01362 void XMLCALL
01363 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
01364 {
01365   if (arg)
01366     externalEntityRefHandlerArg = (XML_Parser)arg;
01367   else
01368     externalEntityRefHandlerArg = parser;
01369 }
01370 
01371 void XMLCALL
01372 XML_SetSkippedEntityHandler(XML_Parser parser,
01373                             XML_SkippedEntityHandler handler)
01374 {
01375   skippedEntityHandler = handler;
01376 }
01377 
01378 void XMLCALL
01379 XML_SetUnknownEncodingHandler(XML_Parser parser,
01380                               XML_UnknownEncodingHandler handler,
01381                               void *data)
01382 {
01383   unknownEncodingHandler = handler;
01384   unknownEncodingHandlerData = data;
01385 }
01386 
01387 void XMLCALL
01388 XML_SetElementDeclHandler(XML_Parser parser,
01389                           XML_ElementDeclHandler eldecl)
01390 {
01391   elementDeclHandler = eldecl;
01392 }
01393 
01394 void XMLCALL
01395 XML_SetAttlistDeclHandler(XML_Parser parser,
01396                           XML_AttlistDeclHandler attdecl)
01397 {
01398   attlistDeclHandler = attdecl;
01399 }
01400 
01401 void XMLCALL
01402 XML_SetEntityDeclHandler(XML_Parser parser,
01403                          XML_EntityDeclHandler handler)
01404 {
01405   entityDeclHandler = handler;
01406 }
01407 
01408 void XMLCALL
01409 XML_SetXmlDeclHandler(XML_Parser parser,
01410                       XML_XmlDeclHandler handler) {
01411   xmlDeclHandler = handler;
01412 }
01413 
01414 int XMLCALL
01415 XML_SetParamEntityParsing(XML_Parser parser,
01416                           enum XML_ParamEntityParsing peParsing)
01417 {
01418   /* block after XML_Parse()/XML_ParseBuffer() has been called */
01419   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
01420     return 0;
01421 #ifdef XML_DTD
01422   paramEntityParsing = peParsing;
01423   return 1;
01424 #else
01425   return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
01426 #endif
01427 }
01428 
01429 enum XML_Status XMLCALL
01430 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
01431 {
01432   switch (ps_parsing) {
01433   case XML_SUSPENDED:
01434     errorCode = XML_ERROR_SUSPENDED;
01435     return XML_STATUS_ERROR;
01436   case XML_FINISHED:
01437     errorCode = XML_ERROR_FINISHED;
01438     return XML_STATUS_ERROR;
01439   default:
01440     ps_parsing = XML_PARSING;
01441   }
01442 
01443   if (len == 0) {
01444     ps_finalBuffer = (XML_Bool)isFinal;
01445     if (!isFinal)
01446       return XML_STATUS_OK;
01447     positionPtr = bufferPtr;
01448     parseEndPtr = bufferEnd;
01449 
01450     /* If data are left over from last buffer, and we now know that these
01451        data are the final chunk of input, then we have to check them again
01452        to detect errors based on that fact.
01453     */
01454     errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
01455 
01456     if (errorCode == XML_ERROR_NONE) {
01457       switch (ps_parsing) {
01458       case XML_SUSPENDED:
01459         XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
01460         positionPtr = bufferPtr;
01461         return XML_STATUS_SUSPENDED;
01462       case XML_INITIALIZED: 
01463       case XML_PARSING:
01464         ps_parsing = XML_FINISHED;
01465         /* fall through */
01466       default:
01467         return XML_STATUS_OK;
01468       }
01469     }
01470     eventEndPtr = eventPtr;
01471     processor = errorProcessor;
01472     return XML_STATUS_ERROR;
01473   }
01474 #ifndef XML_CONTEXT_BYTES
01475   else if (bufferPtr == bufferEnd) {
01476     const char *end;
01477     int nLeftOver;
01478     enum XML_Error result;
01479     parseEndByteIndex += len;
01480     positionPtr = s;
01481     ps_finalBuffer = (XML_Bool)isFinal;
01482 
01483     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
01484 
01485     if (errorCode != XML_ERROR_NONE) {
01486       eventEndPtr = eventPtr;
01487       processor = errorProcessor;
01488       return XML_STATUS_ERROR;
01489     }
01490     else {
01491       switch (ps_parsing) {
01492       case XML_SUSPENDED:
01493         result = XML_STATUS_SUSPENDED;
01494         break;
01495       case XML_INITIALIZED:
01496       case XML_PARSING:
01497         result = XML_STATUS_OK;
01498         if (isFinal) {
01499           ps_parsing = XML_FINISHED;
01500           return result;
01501         }
01502       }
01503     }
01504 
01505     XmlUpdatePosition(encoding, positionPtr, end, &position);
01506     nLeftOver = s + len - end;
01507     if (nLeftOver) {
01508       if (buffer == NULL || nLeftOver > bufferLim - buffer) {
01509         /* FIXME avoid integer overflow */
01510         char *temp;
01511         temp = (buffer == NULL
01512                 ? (char *)MALLOC(len * 2)
01513                 : (char *)REALLOC(buffer, len * 2));
01514         if (temp == NULL) {
01515           errorCode = XML_ERROR_NO_MEMORY;
01516           return XML_STATUS_ERROR;
01517         }
01518         buffer = temp;
01519         if (!buffer) {
01520           errorCode = XML_ERROR_NO_MEMORY;
01521           eventPtr = eventEndPtr = NULL;
01522           processor = errorProcessor;
01523           return XML_STATUS_ERROR;
01524         }
01525         bufferLim = buffer + len * 2;
01526       }
01527       memcpy(buffer, end, nLeftOver);
01528     }
01529     bufferPtr = buffer;
01530     bufferEnd = buffer + nLeftOver;
01531     positionPtr = bufferPtr;
01532     parseEndPtr = bufferEnd;
01533     eventPtr = bufferPtr;
01534     eventEndPtr = bufferPtr;
01535     return result;
01536   }
01537 #endif  /* not defined XML_CONTEXT_BYTES */
01538   else {
01539     void *buff = XML_GetBuffer(parser, len);
01540     if (buff == NULL)
01541       return XML_STATUS_ERROR;
01542     else {
01543       memcpy(buff, s, len);
01544       return XML_ParseBuffer(parser, len, isFinal);
01545     }
01546   }
01547 }
01548 
01549 enum XML_Status XMLCALL
01550 XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
01551 {
01552   const char *start;
01553   enum XML_Status result = XML_STATUS_OK;
01554 
01555   switch (ps_parsing) {
01556   case XML_SUSPENDED:
01557     errorCode = XML_ERROR_SUSPENDED;
01558     return XML_STATUS_ERROR;
01559   case XML_FINISHED:
01560     errorCode = XML_ERROR_FINISHED;
01561     return XML_STATUS_ERROR;
01562   default:
01563     ps_parsing = XML_PARSING;
01564   }
01565 
01566   start = bufferPtr;
01567   positionPtr = start;
01568   bufferEnd += len;
01569   parseEndPtr = bufferEnd;
01570   parseEndByteIndex += len;
01571   ps_finalBuffer = (XML_Bool)isFinal;
01572 
01573   errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
01574 
01575   if (errorCode != XML_ERROR_NONE) {
01576     eventEndPtr = eventPtr;
01577     processor = errorProcessor;
01578     return XML_STATUS_ERROR;
01579   }
01580   else {
01581     switch (ps_parsing) {
01582     case XML_SUSPENDED:
01583       result = XML_STATUS_SUSPENDED;
01584       break;
01585     case XML_INITIALIZED: 
01586     case XML_PARSING:
01587       if (isFinal) {
01588         ps_parsing = XML_FINISHED;
01589         return result;
01590       }
01591     default: ;  /* should not happen */
01592     }
01593   }
01594 
01595   XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
01596   positionPtr = bufferPtr;
01597   return result;
01598 }
01599 
01600 void * XMLCALL
01601 XML_GetBuffer(XML_Parser parser, int len)
01602 {
01603   switch (ps_parsing) {
01604   case XML_SUSPENDED:
01605     errorCode = XML_ERROR_SUSPENDED;
01606     return NULL;
01607   case XML_FINISHED:
01608     errorCode = XML_ERROR_FINISHED;
01609     return NULL;
01610   default: ;
01611   }
01612 
01613   if (len > bufferLim - bufferEnd) {
01614     /* FIXME avoid integer overflow */
01615     int neededSize = len + (int)(bufferEnd - bufferPtr);
01616 #ifdef XML_CONTEXT_BYTES
01617     int keep = (int)(bufferPtr - buffer);
01618 
01619     if (keep > XML_CONTEXT_BYTES)
01620       keep = XML_CONTEXT_BYTES;
01621     neededSize += keep;
01622 #endif  /* defined XML_CONTEXT_BYTES */
01623     if (neededSize  <= bufferLim - buffer) {
01624 #ifdef XML_CONTEXT_BYTES
01625       if (keep < bufferPtr - buffer) {
01626         int offset = (int)(bufferPtr - buffer) - keep;
01627         memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
01628         bufferEnd -= offset;
01629         bufferPtr -= offset;
01630       }
01631 #else
01632       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
01633       bufferEnd = buffer + (bufferEnd - bufferPtr);
01634       bufferPtr = buffer;
01635 #endif  /* not defined XML_CONTEXT_BYTES */
01636     }
01637     else {
01638       char *newBuf;
01639       int bufferSize = (int)(bufferLim - bufferPtr);
01640       if (bufferSize == 0)
01641         bufferSize = INIT_BUFFER_SIZE;
01642       do {
01643         bufferSize *= 2;
01644       } while (bufferSize < neededSize);
01645       newBuf = (char *)MALLOC(bufferSize);
01646       if (newBuf == 0) {
01647         errorCode = XML_ERROR_NO_MEMORY;
01648         return NULL;
01649       }
01650       bufferLim = newBuf + bufferSize;
01651 #ifdef XML_CONTEXT_BYTES
01652       if (bufferPtr) {
01653         int keep = (int)(bufferPtr - buffer);
01654         if (keep > XML_CONTEXT_BYTES)
01655           keep = XML_CONTEXT_BYTES;
01656         memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
01657         FREE(buffer);
01658         buffer = newBuf;
01659         bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
01660         bufferPtr = buffer + keep;
01661       }
01662       else {
01663         bufferEnd = newBuf + (bufferEnd - bufferPtr);
01664         bufferPtr = buffer = newBuf;
01665       }
01666 #else
01667       if (bufferPtr) {
01668         memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
01669         FREE(buffer);
01670       }
01671       bufferEnd = newBuf + (bufferEnd - bufferPtr);
01672       bufferPtr = buffer = newBuf;
01673 #endif  /* not defined XML_CONTEXT_BYTES */
01674     }
01675   }
01676   return bufferEnd;
01677 }
01678 
01679 enum XML_Status XMLCALL
01680 XML_StopParser(XML_Parser parser, XML_Bool resumable)
01681 {
01682   switch (ps_parsing) {
01683   case XML_SUSPENDED:
01684     if (resumable) {
01685       errorCode = XML_ERROR_SUSPENDED;
01686       return XML_STATUS_ERROR;
01687     }
01688     ps_parsing = XML_FINISHED;
01689     break;
01690   case XML_FINISHED:
01691     errorCode = XML_ERROR_FINISHED;
01692     return XML_STATUS_ERROR;
01693   default:
01694     if (resumable) {
01695 #ifdef XML_DTD
01696       if (isParamEntity) {
01697         errorCode = XML_ERROR_SUSPEND_PE;
01698         return XML_STATUS_ERROR;
01699       }
01700 #endif
01701       ps_parsing = XML_SUSPENDED;
01702     }
01703     else
01704       ps_parsing = XML_FINISHED;
01705   }
01706   return XML_STATUS_OK;
01707 }
01708 
01709 enum XML_Status XMLCALL
01710 XML_ResumeParser(XML_Parser parser)
01711 {
01712   enum XML_Status result = XML_STATUS_OK;
01713 
01714   if (ps_parsing != XML_SUSPENDED) {
01715     errorCode = XML_ERROR_NOT_SUSPENDED;
01716     return XML_STATUS_ERROR;
01717   }
01718   ps_parsing = XML_PARSING;
01719 
01720   errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
01721 
01722   if (errorCode != XML_ERROR_NONE) {
01723     eventEndPtr = eventPtr;
01724     processor = errorProcessor;
01725     return XML_STATUS_ERROR;
01726   }
01727   else {
01728     switch (ps_parsing) {
01729     case XML_SUSPENDED:
01730       result = XML_STATUS_SUSPENDED;
01731       break;
01732     case XML_INITIALIZED: 
01733     case XML_PARSING:
01734       if (ps_finalBuffer) {
01735         ps_parsing = XML_FINISHED;
01736         return result;
01737       }
01738     default: ;
01739     }
01740   }
01741 
01742   XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
01743   positionPtr = bufferPtr;
01744   return result;
01745 }
01746 
01747 void XMLCALL
01748 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
01749 {
01750   assert(status != NULL);
01751   *status = parser->m_parsingStatus;
01752 }
01753 
01754 enum XML_Error XMLCALL
01755 XML_GetErrorCode(XML_Parser parser)
01756 {
01757   return errorCode;
01758 }
01759 
01760 XML_Index XMLCALL
01761 XML_GetCurrentByteIndex(XML_Parser parser)
01762 {
01763   if (eventPtr)
01764     return parseEndByteIndex - (parseEndPtr - eventPtr);
01765   return -1;
01766 }
01767 
01768 int XMLCALL
01769 XML_GetCurrentByteCount(XML_Parser parser)
01770 {
01771   if (eventEndPtr && eventPtr)
01772     return (int)(eventEndPtr - eventPtr);
01773   return 0;
01774 }
01775 
01776 const char * XMLCALL
01777 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
01778 {
01779 #ifdef XML_CONTEXT_BYTES
01780   if (eventPtr && buffer) {
01781     *offset = (int)(eventPtr - buffer);
01782     *size   = (int)(bufferEnd - buffer);
01783     return buffer;
01784   }
01785 #endif /* defined XML_CONTEXT_BYTES */
01786   return (char *) 0;
01787 }
01788 
01789 XML_Size XMLCALL
01790 XML_GetCurrentLineNumber(XML_Parser parser)
01791 {
01792   if (eventPtr && eventPtr >= positionPtr) {
01793     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
01794     positionPtr = eventPtr;
01795   }
01796   return position.lineNumber + 1;
01797 }
01798 
01799 XML_Size XMLCALL
01800 XML_GetCurrentColumnNumber(XML_Parser parser)
01801 {
01802   if (eventPtr && eventPtr >= positionPtr) {
01803     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
01804     positionPtr = eventPtr;
01805   }
01806   return position.columnNumber;
01807 }
01808 
01809 void XMLCALL
01810 XML_FreeContentModel(XML_Parser parser, XML_Content *model)
01811 {
01812   FREE(model);
01813 }
01814 
01815 void * XMLCALL
01816 XML_MemMalloc(XML_Parser parser, size_t size)
01817 {
01818   return MALLOC(size);
01819 }
01820 
01821 void * XMLCALL
01822 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
01823 {
01824   return REALLOC(ptr, size);
01825 }
01826 
01827 void XMLCALL
01828 XML_MemFree(XML_Parser parser, void *ptr)
01829 {
01830   FREE(ptr);
01831 }
01832 
01833 void XMLCALL
01834 XML_DefaultCurrent(XML_Parser parser)
01835 {
01836   if (defaultHandler) {
01837     if (openInternalEntities)
01838       reportDefault(parser,
01839                     internalEncoding,
01840                     openInternalEntities->internalEventPtr,
01841                     openInternalEntities->internalEventEndPtr);
01842     else
01843       reportDefault(parser, encoding, eventPtr, eventEndPtr);
01844   }
01845 }
01846 
01847 const XML_LChar * XMLCALL
01848 XML_ErrorString(enum XML_Error code)
01849 {
01850   static const XML_LChar* const message[] = {
01851     0,
01852     XML_L("out of memory"),
01853     XML_L("syntax error"),
01854     XML_L("no element found"),
01855     XML_L("not well-formed (invalid token)"),
01856     XML_L("unclosed token"),
01857     XML_L("partial character"),
01858     XML_L("mismatched tag"),
01859     XML_L("duplicate attribute"),
01860     XML_L("junk after document element"),
01861     XML_L("illegal parameter entity reference"),
01862     XML_L("undefined entity"),
01863     XML_L("recursive entity reference"),
01864     XML_L("asynchronous entity"),
01865     XML_L("reference to invalid character number"),
01866     XML_L("reference to binary entity"),
01867     XML_L("reference to external entity in attribute"),
01868     XML_L("XML or text declaration not at start of entity"),
01869     XML_L("unknown encoding"),
01870     XML_L("encoding specified in XML declaration is incorrect"),
01871     XML_L("unclosed CDATA section"),
01872     XML_L("error in processing external entity reference"),
01873     XML_L("document is not standalone"),
01874     XML_L("unexpected parser state - please send a bug report"),
01875     XML_L("entity declared in parameter entity"),
01876     XML_L("requested feature requires XML_DTD support in Expat"),
01877     XML_L("cannot change setting once parsing has begun"),
01878     XML_L("unbound prefix"),
01879     XML_L("must not undeclare prefix"),
01880     XML_L("incomplete markup in parameter entity"),
01881     XML_L("XML declaration not well-formed"),
01882     XML_L("text declaration not well-formed"),
01883     XML_L("illegal character(s) in public id"),
01884     XML_L("parser suspended"),
01885     XML_L("parser not suspended"),
01886     XML_L("parsing aborted"),
01887     XML_L("parsing finished"),
01888     XML_L("cannot suspend in external parameter entity"),
01889     XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
01890     XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
01891     XML_L("prefix must not be bound to one of the reserved namespace names")
01892   };
01893   if (code > 0 && unsigned(code) < sizeof(message)/sizeof(message[0]))
01894     return message[code];
01895   return NULL;
01896 }
01897 
01898 const XML_LChar * XMLCALL
01899 XML_ExpatVersion(void) {
01900 
01901   /* V1 is used to string-ize the version number. However, it would
01902      string-ize the actual version macro *names* unless we get them
01903      substituted before being passed to V1. CPP is defined to expand
01904      a macro, then rescan for more expansions. Thus, we use V2 to expand
01905      the version macros, then CPP will expand the resulting V1() macro
01906      with the correct numerals. */
01907   /* ### I'm assuming cpp is portable in this respect... */
01908 
01909 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
01910 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
01911 
01912   return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
01913 
01914 #undef V1
01915 #undef V2
01916 }
01917 
01918 XML_Expat_Version XMLCALL
01919 XML_ExpatVersionInfo(void)
01920 {
01921   XML_Expat_Version version;
01922 
01923   version.major = XML_MAJOR_VERSION;
01924   version.minor = XML_MINOR_VERSION;
01925   version.micro = XML_MICRO_VERSION;
01926 
01927   return version;
01928 }
01929 
01930 const XML_Feature * XMLCALL
01931 XML_GetFeatureList(void)
01932 {
01933   static const XML_Feature features[] = {
01934     {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),
01935      sizeof(XML_Char)},
01936     {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
01937      sizeof(XML_LChar)},
01938 #ifdef XML_UNICODE
01939     {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
01940 #endif
01941 #ifdef XML_UNICODE_WCHAR_T
01942     {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
01943 #endif
01944 #ifdef XML_DTD
01945     {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
01946 #endif
01947 #ifdef XML_CONTEXT_BYTES
01948     {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
01949      XML_CONTEXT_BYTES},
01950 #endif
01951 #ifdef XML_MIN_SIZE
01952     {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
01953 #endif
01954 #ifdef XML_NS
01955     {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
01956 #endif
01957 #ifdef XML_LARGE_SIZE
01958     {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0},
01959 #endif    
01960     {XML_FEATURE_END,              NULL, 0}
01961   };
01962 
01963   return features;
01964 }
01965 
01966 /* Initially tag->rawName always points into the parse buffer;
01967    for those TAG instances opened while the current parse buffer was
01968    processed, and not yet closed, we need to store tag->rawName in a more
01969    permanent location, since the parse buffer is about to be discarded.
01970 */
01971 static XML_Bool
01972 storeRawNames(XML_Parser parser)
01973 {
01974   TAG *tag = tagStack;
01975   while (tag) {
01976     int bufSize;
01977     int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
01978     char *rawNameBuf = tag->buf + nameLen;
01979     /* Stop if already stored.  Since tagStack is a stack, we can stop
01980        at the first entry that has already been copied; everything
01981        below it in the stack is already been accounted for in a
01982        previous call to this function.
01983     */
01984     if (tag->rawName == rawNameBuf)
01985       break;
01986     /* For re-use purposes we need to ensure that the
01987        size of tag->buf is a multiple of sizeof(XML_Char).
01988     */
01989     bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
01990     if (bufSize > tag->bufEnd - tag->buf) {
01991       char *temp = (char *)REALLOC(tag->buf, bufSize);
01992       if (temp == NULL)
01993         return XML_FALSE;
01994       /* if tag->name.str points to tag->buf (only when namespace
01995          processing is off) then we have to update it
01996       */
01997       if (tag->name.str == (XML_Char *)tag->buf)
01998         tag->name.str = (XML_Char *)temp;
01999       /* if tag->name.localPart is set (when namespace processing is on)
02000          then update it as well, since it will always point into tag->buf
02001       */
02002       if (tag->name.localPart)
02003         tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
02004                                                   (XML_Char *)tag->buf);
02005       tag->buf = temp;
02006       tag->bufEnd = temp + bufSize;
02007       rawNameBuf = temp + nameLen;
02008     }
02009     memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
02010     tag->rawName = rawNameBuf;
02011     tag = tag->parent;
02012   }
02013   return XML_TRUE;
02014 }
02015 
02016 static enum XML_Error PTRCALL
02017 contentProcessor(XML_Parser parser,
02018                  const char *start,
02019                  const char *end,
02020                  const char **endPtr)
02021 {
02022   enum XML_Error result = doContent(parser, 0, encoding, start, end, 
02023                                     endPtr, (XML_Bool)!ps_finalBuffer);
02024   if (result == XML_ERROR_NONE) {
02025     if (!storeRawNames(parser))
02026       return XML_ERROR_NO_MEMORY;
02027   }
02028   return result;
02029 }
02030 
02031 static enum XML_Error PTRCALL
02032 externalEntityInitProcessor(XML_Parser parser,
02033                             const char *start,
02034                             const char *end,
02035                             const char **endPtr)
02036 {
02037   enum XML_Error result = initializeEncoding(parser);
02038   if (result != XML_ERROR_NONE)
02039     return result;
02040   processor = externalEntityInitProcessor2;
02041   return externalEntityInitProcessor2(parser, start, end, endPtr);
02042 }
02043 
02044 static enum XML_Error PTRCALL
02045 externalEntityInitProcessor2(XML_Parser parser,
02046                              const char *start,
02047                              const char *end,
02048                              const char **endPtr)
02049 {
02050   const char *next = start; /* XmlContentTok doesn't always set the last arg */
02051   int tok = XmlContentTok(encoding, start, end, &next);
02052   switch (tok) {
02053   case XML_TOK_BOM:
02054     /* If we are at the end of the buffer, this would cause the next stage,
02055        i.e. externalEntityInitProcessor3, to pass control directly to
02056        doContent (by detecting XML_TOK_NONE) without processing any xml text
02057        declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
02058     */
02059     if (next == end && !ps_finalBuffer) {
02060       *endPtr = next;
02061       return XML_ERROR_NONE;
02062     }
02063     start = next;
02064     break;
02065   case XML_TOK_PARTIAL:
02066     if (!ps_finalBuffer) {
02067       *endPtr = start;
02068       return XML_ERROR_NONE;
02069     }
02070     eventPtr = start;
02071     return XML_ERROR_UNCLOSED_TOKEN;
02072   case XML_TOK_PARTIAL_CHAR:
02073     if (!ps_finalBuffer) {
02074       *endPtr = start;
02075       return XML_ERROR_NONE;
02076     }
02077     eventPtr = start;
02078     return XML_ERROR_PARTIAL_CHAR;
02079   }
02080   processor = externalEntityInitProcessor3;
02081   return externalEntityInitProcessor3(parser, start, end, endPtr);
02082 }
02083 
02084 static enum XML_Error PTRCALL
02085 externalEntityInitProcessor3(XML_Parser parser,
02086                              const char *start,
02087                              const char *end,
02088                              const char **endPtr)
02089 {
02090   int tok;
02091   const char *next = start; /* XmlContentTok doesn't always set the last arg */
02092   eventPtr = start;
02093   tok = XmlContentTok(encoding, start, end, &next);
02094   eventEndPtr = next;
02095 
02096   switch (tok) {
02097   case XML_TOK_XML_DECL:
02098     {
02099       enum XML_Error result;
02100       result = processXmlDecl(parser, 1, start, next);
02101       if (result != XML_ERROR_NONE)
02102         return result;
02103       switch (ps_parsing) {
02104       case XML_SUSPENDED: 
02105         *endPtr = next;
02106         return XML_ERROR_NONE;
02107       case XML_FINISHED:
02108         return XML_ERROR_ABORTED;
02109       default:
02110         start = next;
02111       }
02112     }
02113     break;
02114   case XML_TOK_PARTIAL:
02115     if (!ps_finalBuffer) {
02116       *endPtr = start;
02117       return XML_ERROR_NONE;
02118     }
02119     return XML_ERROR_UNCLOSED_TOKEN;
02120   case XML_TOK_PARTIAL_CHAR:
02121     if (!ps_finalBuffer) {
02122       *endPtr = start;
02123       return XML_ERROR_NONE;
02124     }
02125     return XML_ERROR_PARTIAL_CHAR;
02126   }
02127   processor = externalEntityContentProcessor;
02128   tagLevel = 1;
02129   return externalEntityContentProcessor(parser, start, end, endPtr);
02130 }
02131 
02132 static enum XML_Error PTRCALL
02133 externalEntityContentProcessor(XML_Parser parser,
02134                                const char *start,
02135                                const char *end,
02136                                const char **endPtr)
02137 {
02138   enum XML_Error result = doContent(parser, 1, encoding, start, end, 
02139                                     endPtr, (XML_Bool)!ps_finalBuffer);
02140   if (result == XML_ERROR_NONE) {
02141     if (!storeRawNames(parser))
02142       return XML_ERROR_NO_MEMORY;
02143   }
02144   return result;
02145 }
02146 
02147 static enum XML_Error
02148 doContent(XML_Parser parser,
02149           int startTagLevel,
02150           const ENCODING *enc,
02151           const char *s,
02152           const char *end,
02153           const char **nextPtr,
02154           XML_Bool haveMore)
02155 {
02156   /* save one level of indirection */
02157   DTD * const dtd = _dtd;  
02158 
02159   const char **eventPP;
02160   const char **eventEndPP;
02161   if (enc == encoding) {
02162     eventPP = &eventPtr;
02163     eventEndPP = &eventEndPtr;
02164   }
02165   else {
02166     eventPP = &(openInternalEntities->internalEventPtr);
02167     eventEndPP = &(openInternalEntities->internalEventEndPtr);
02168   }
02169   *eventPP = s;
02170 
02171   for (;;) {
02172     const char *next = s; /* XmlContentTok doesn't always set the last arg */
02173     int tok = XmlContentTok(enc, s, end, &next);
02174     *eventEndPP = next;
02175     switch (tok) {
02176     case XML_TOK_TRAILING_CR:
02177       if (haveMore) {
02178         *nextPtr = s;
02179         return XML_ERROR_NONE;
02180       }
02181       *eventEndPP = end;
02182       if (characterDataHandler) {
02183         XML_Char c = 0xA;
02184         characterDataHandler(handlerArg, &c, 1);
02185       }
02186       else if (defaultHandler)
02187         reportDefault(parser, enc, s, end);
02188       /* We are at the end of the final buffer, should we check for 
02189          XML_SUSPENDED, XML_FINISHED? 
02190       */
02191       if (startTagLevel == 0)
02192         return XML_ERROR_NO_ELEMENTS;
02193       if (tagLevel != startTagLevel)
02194         return XML_ERROR_ASYNC_ENTITY;
02195       *nextPtr = end;
02196       return XML_ERROR_NONE;
02197     case XML_TOK_NONE:
02198       if (haveMore) {
02199         *nextPtr = s;
02200         return XML_ERROR_NONE;
02201       }
02202       if (startTagLevel > 0) {
02203         if (tagLevel != startTagLevel)
02204           return XML_ERROR_ASYNC_ENTITY;
02205         *nextPtr = s;
02206         return XML_ERROR_NONE;
02207       }
02208       return XML_ERROR_NO_ELEMENTS;
02209     case XML_TOK_INVALID:
02210       *eventPP = next;
02211       return XML_ERROR_INVALID_TOKEN;
02212     case XML_TOK_PARTIAL:
02213       if (haveMore) {
02214         *nextPtr = s;
02215         return XML_ERROR_NONE;
02216       }
02217       return XML_ERROR_UNCLOSED_TOKEN;
02218     case XML_TOK_PARTIAL_CHAR:
02219       if (haveMore) {
02220         *nextPtr = s;
02221         return XML_ERROR_NONE;
02222       }
02223       return XML_ERROR_PARTIAL_CHAR;
02224     case XML_TOK_ENTITY_REF:
02225       {
02226         const XML_Char *name;
02227         ENTITY *entity;
02228         XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
02229                                               s + enc->minBytesPerChar,
02230                                               next - enc->minBytesPerChar);
02231         if (ch) {
02232           if (characterDataHandler)
02233             characterDataHandler(handlerArg, &ch, 1);
02234           else if (defaultHandler)
02235             reportDefault(parser, enc, s, next);
02236           break;
02237         }
02238         name = poolStoreString(&dtd->pool, enc,
02239                                 s + enc->minBytesPerChar,
02240                                 next - enc->minBytesPerChar);
02241         if (!name)
02242           return XML_ERROR_NO_MEMORY;
02243         entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
02244         poolDiscard(&dtd->pool);
02245         /* First, determine if a check for an existing declaration is needed;
02246            if yes, check that the entity exists, and that it is internal,
02247            otherwise call the skipped entity or default handler.
02248         */
02249         if (!dtd->hasParamEntityRefs || dtd->standalone) {
02250           if (!entity)
02251             return XML_ERROR_UNDEFINED_ENTITY;
02252           else if (!entity->is_internal)
02253             return XML_ERROR_ENTITY_DECLARED_IN_PE;
02254         }
02255         else if (!entity) {
02256           if (skippedEntityHandler)
02257             skippedEntityHandler(handlerArg, name, 0);
02258           else if (defaultHandler)
02259             reportDefault(parser, enc, s, next);
02260           break;
02261         }
02262         if (entity->open)
02263           return XML_ERROR_RECURSIVE_ENTITY_REF;
02264         if (entity->notation)
02265           return XML_ERROR_BINARY_ENTITY_REF;
02266         if (entity->textPtr) {
02267           enum XML_Error result;
02268           if (!defaultExpandInternalEntities) {
02269             if (skippedEntityHandler)
02270               skippedEntityHandler(handlerArg, entity->name, 0);
02271             else if (defaultHandler)
02272               reportDefault(parser, enc, s, next);
02273             break;
02274           }
02275           result = processInternalEntity(parser, entity, XML_FALSE);
02276           if (result != XML_ERROR_NONE)
02277             return result;
02278         }
02279         else if (externalEntityRefHandler) {
02280           const XML_Char *context;
02281           entity->open = XML_TRUE;
02282           context = getContext(parser);
02283           entity->open = XML_FALSE;
02284           if (!context)
02285             return XML_ERROR_NO_MEMORY;
02286           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
02287                                         context,
02288                                         entity->base,
02289                                         entity->systemId,
02290                                         entity->publicId))
02291             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
02292           poolDiscard(&tempPool);
02293         }
02294         else if (defaultHandler)
02295           reportDefault(parser, enc, s, next);
02296         break;
02297       }
02298     case XML_TOK_START_TAG_NO_ATTS:
02299       /* fall through */
02300     case XML_TOK_START_TAG_WITH_ATTS:
02301       {
02302         TAG *tag;
02303         enum XML_Error result;
02304         XML_Char *toPtr;
02305         if (freeTagList) {
02306           tag = freeTagList;
02307           freeTagList = freeTagList->parent;
02308         }
02309         else {
02310           tag = (TAG *)MALLOC(sizeof(TAG));
02311           if (!tag)
02312             return XML_ERROR_NO_MEMORY;
02313           tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
02314           if (!tag->buf) {
02315             FREE(tag);
02316             return XML_ERROR_NO_MEMORY;
02317           }
02318           tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
02319         }
02320         tag->bindings = NULL;
02321         tag->parent = tagStack;
02322         tagStack = tag;
02323         tag->name.localPart = NULL;
02324         tag->name.prefix = NULL;
02325         tag->rawName = s + enc->minBytesPerChar;
02326         tag->rawNameLength = XmlNameLength(enc, tag->rawName);
02327         ++tagLevel;
02328         {
02329           const char *rawNameEnd = tag->rawName + tag->rawNameLength;
02330           const char *fromPtr = tag->rawName;
02331           toPtr = (XML_Char *)tag->buf;
02332           for (;;) {
02333             int bufSize;
02334             int convLen;
02335             XmlConvert(enc,
02336                        &fromPtr, rawNameEnd,
02337                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
02338             convLen = (int)(toPtr - (XML_Char *)tag->buf);
02339             if (fromPtr == rawNameEnd) {
02340               tag->name.strLen = convLen;
02341               break;
02342             }
02343             bufSize = (int)(tag->bufEnd - tag->buf) << 1;
02344             {
02345               char *temp = (char *)REALLOC(tag->buf, bufSize);
02346               if (temp == NULL)
02347                 return XML_ERROR_NO_MEMORY;
02348               tag->buf = temp;
02349               tag->bufEnd = temp + bufSize;
02350               toPtr = (XML_Char *)temp + convLen;
02351             }
02352           }
02353         }
02354         tag->name.str = (XML_Char *)tag->buf;
02355         *toPtr = XML_T('\0');
02356         result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
02357         if (result)
02358           return result;
02359         if (startElementHandler)
02360           startElementHandler(handlerArg, tag->name.str,
02361                               (const XML_Char **)atts);
02362         else if (defaultHandler)
02363           reportDefault(parser, enc, s, next);
02364         poolClear(&tempPool);
02365         break;
02366       }
02367     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
02368       /* fall through */
02369     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
02370       {
02371         const char *rawName = s + enc->minBytesPerChar;
02372         enum XML_Error result;
02373         BINDING *bindings = NULL;
02374         XML_Bool noElmHandlers = XML_TRUE;
02375         TAG_NAME name;
02376         name.str = poolStoreString(&tempPool, enc, rawName,
02377                                    rawName + XmlNameLength(enc, rawName));
02378         if (!name.str)
02379           return XML_ERROR_NO_MEMORY;
02380         poolFinish(&tempPool);
02381         result = storeAtts(parser, enc, s, &name, &bindings);
02382         if (result)
02383           return result;
02384         poolFinish(&tempPool);
02385         if (startElementHandler) {
02386           startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
02387           noElmHandlers = XML_FALSE;
02388         }
02389         if (endElementHandler) {
02390           if (startElementHandler)
02391             *eventPP = *eventEndPP;
02392           endElementHandler(handlerArg, name.str);
02393           noElmHandlers = XML_FALSE;
02394         }
02395         if (noElmHandlers && defaultHandler)
02396           reportDefault(parser, enc, s, next);
02397         poolClear(&tempPool);
02398         while (bindings) {
02399           BINDING *b = bindings;
02400           if (endNamespaceDeclHandler)
02401             endNamespaceDeclHandler(handlerArg, b->prefix->name);
02402           bindings = bindings->nextTagBinding;
02403           b->nextTagBinding = freeBindingList;
02404           freeBindingList = b;
02405           b->prefix->binding = b->prevPrefixBinding;
02406         }
02407       }
02408       if (tagLevel == 0)
02409         return epilogProcessor(parser, next, end, nextPtr);
02410       break;
02411     case XML_TOK_END_TAG:
02412       if (tagLevel == startTagLevel)
02413         return XML_ERROR_ASYNC_ENTITY;
02414       else {
02415         int len;
02416         const char *rawName;
02417         TAG *tag = tagStack;
02418         tagStack = tag->parent;
02419         tag->parent = freeTagList;
02420         freeTagList = tag;
02421         rawName = s + enc->minBytesPerChar*2;
02422         len = XmlNameLength(enc, rawName);
02423         if (len != tag->rawNameLength
02424             || memcmp(tag->rawName, rawName, len) != 0) {
02425           *eventPP = rawName;
02426           return XML_ERROR_TAG_MISMATCH;
02427         }
02428         --tagLevel;
02429         if (endElementHandler) {
02430           const XML_Char *localPart;
02431           const XML_Char *prefix;
02432           XML_Char *uri;
02433           localPart = tag->name.localPart;
02434           if (ns && localPart) {
02435             /* localPart and prefix may have been overwritten in
02436                tag->name.str, since this points to the binding->uri
02437                buffer which gets re-used; so we have to add them again
02438             */
02439             uri = (XML_Char *)tag->name.str + tag->name.uriLen;
02440             /* don't need to check for space - already done in storeAtts() */
02441             while (*localPart) *uri++ = *localPart++;
02442             prefix = (XML_Char *)tag->name.prefix;
02443             if (ns_triplets && prefix) {
02444               *uri++ = namespaceSeparator;
02445               while (*prefix) *uri++ = *prefix++;
02446              }
02447             *uri = XML_T('\0');
02448           }
02449           endElementHandler(handlerArg, tag->name.str);
02450         }
02451         else if (defaultHandler)
02452           reportDefault(parser, enc, s, next);
02453         while (tag->bindings) {
02454           BINDING *b = tag->bindings;
02455           if (endNamespaceDeclHandler)
02456             endNamespaceDeclHandler(handlerArg, b->prefix->name);
02457           tag->bindings = tag->bindings->nextTagBinding;
02458           b->nextTagBinding = freeBindingList;
02459           freeBindingList = b;
02460           b->prefix->binding = b->prevPrefixBinding;
02461         }
02462         if (tagLevel == 0)
02463           return epilogProcessor(parser, next, end, nextPtr);
02464       }
02465       break;
02466     case XML_TOK_CHAR_REF:
02467       {
02468         int n = XmlCharRefNumber(enc, s);
02469         if (n < 0)
02470           return XML_ERROR_BAD_CHAR_REF;
02471         if (characterDataHandler) {
02472           XML_Char buf[XML_ENCODE_MAX];
02473           characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
02474         }
02475         else if (defaultHandler)
02476           reportDefault(parser, enc, s, next);
02477       }
02478       break;
02479     case XML_TOK_XML_DECL:
02480       return XML_ERROR_MISPLACED_XML_PI;
02481     case XML_TOK_DATA_NEWLINE:
02482       if (characterDataHandler) {
02483         XML_Char c = 0xA;
02484         characterDataHandler(handlerArg, &c, 1);
02485       }
02486       else if (defaultHandler)
02487         reportDefault(parser, enc, s, next);
02488       break;
02489     case XML_TOK_CDATA_SECT_OPEN:
02490       {
02491         enum XML_Error result;
02492         if (startCdataSectionHandler)
02493           startCdataSectionHandler(handlerArg);
02494 #if 0
02495         /* Suppose you doing a transformation on a document that involves
02496            changing only the character data.  You set up a defaultHandler
02497            and a characterDataHandler.  The defaultHandler simply copies
02498            characters through.  The characterDataHandler does the
02499            transformation and writes the characters out escaping them as
02500            necessary.  This case will fail to work if we leave out the
02501            following two lines (because & and < inside CDATA sections will
02502            be incorrectly escaped).
02503 
02504            However, now we have a start/endCdataSectionHandler, so it seems
02505            easier to let the user deal with this.
02506         */
02507         else if (characterDataHandler)
02508           characterDataHandler(handlerArg, dataBuf, 0);
02509 #endif
02510         else if (defaultHandler)
02511           reportDefault(parser, enc, s, next);
02512         result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
02513         if (result != XML_ERROR_NONE)
02514           return result;
02515         else if (!next) {
02516           processor = cdataSectionProcessor;
02517           return result;
02518         }
02519       }
02520       break;
02521     case XML_TOK_TRAILING_RSQB:
02522       if (haveMore) {
02523         *nextPtr = s;
02524         return XML_ERROR_NONE;
02525       }
02526       if (characterDataHandler) {
02527         if (MUST_CONVERT(enc, s)) {
02528           ICHAR *dataPtr = (ICHAR *)dataBuf;
02529           XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
02530           characterDataHandler(handlerArg, dataBuf,
02531                                (int)(dataPtr - (ICHAR *)dataBuf));
02532         }
02533         else
02534           characterDataHandler(handlerArg,
02535                                (XML_Char *)s,
02536                                (int)((XML_Char *)end - (XML_Char *)s));
02537       }
02538       else if (defaultHandler)
02539         reportDefault(parser, enc, s, end);
02540       /* We are at the end of the final buffer, should we check for 
02541          XML_SUSPENDED, XML_FINISHED? 
02542       */
02543       if (startTagLevel == 0) {
02544         *eventPP = end;
02545         return XML_ERROR_NO_ELEMENTS;
02546       }
02547       if (tagLevel != startTagLevel) {
02548         *eventPP = end;
02549         return XML_ERROR_ASYNC_ENTITY;
02550       }
02551       *nextPtr = end;
02552       return XML_ERROR_NONE;
02553     case XML_TOK_DATA_CHARS: 
02554       {
02555         XML_CharacterDataHandler charDataHandler = characterDataHandler;
02556         if (charDataHandler) {
02557           if (MUST_CONVERT(enc, s)) {
02558             for (;;) {
02559               ICHAR *dataPtr = (ICHAR *)dataBuf;
02560               XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
02561               *eventEndPP = s;
02562               charDataHandler(handlerArg, dataBuf,
02563                               (int)(dataPtr - (ICHAR *)dataBuf));
02564               if (s == next)
02565                 break;
02566               *eventPP = s;
02567             }
02568           }
02569           else
02570             charDataHandler(handlerArg,
02571                             (XML_Char *)s,
02572                             (int)((XML_Char *)next - (XML_Char *)s));
02573         }
02574         else if (defaultHandler)
02575           reportDefault(parser, enc, s, next);
02576       }
02577       break;
02578     case XML_TOK_PI:
02579       if (!reportProcessingInstruction(parser, enc, s, next))
02580         return XML_ERROR_NO_MEMORY;
02581       break;
02582     case XML_TOK_COMMENT:
02583       if (!reportComment(parser, enc, s, next))
02584         return XML_ERROR_NO_MEMORY;
02585       break;
02586     default:
02587       if (defaultHandler)
02588         reportDefault(parser, enc, s, next);
02589       break;
02590     }
02591     *eventPP = s = next;
02592     switch (ps_parsing) {
02593     case XML_SUSPENDED: 
02594       *nextPtr = next;
02595       return XML_ERROR_NONE;
02596     case XML_FINISHED:
02597       return XML_ERROR_ABORTED;
02598     default: ;
02599     }
02600   }
02601   /* not reached */
02602 }
02603 
02604 /* Precondition: all arguments must be non-NULL;
02605    Purpose:
02606    - normalize attributes
02607    - check attributes for well-formedness
02608    - generate namespace aware attribute names (URI, prefix)
02609    - build list of attributes for startElementHandler
02610    - default attributes
02611    - process namespace declarations (check and report them)
02612    - generate namespace aware element name (URI, prefix)
02613 */
02614 static enum XML_Error
02615 storeAtts(XML_Parser parser, const ENCODING *enc,
02616           const char *attStr, TAG_NAME *tagNamePtr,
02617           BINDING **bindingsPtr)
02618 {
02619   DTD * const dtd = _dtd;  /* save one level of indirection */
02620   ELEMENT_TYPE *elementType;
02621   int nDefaultAtts;
02622   const XML_Char **appAtts;   /* the attribute list for the application */
02623   int attIndex = 0;
02624   int prefixLen;
02625   int i;
02626   int n;
02627   XML_Char *uri;
02628   int nPrefixes = 0;
02629   BINDING *binding;
02630   const XML_Char *localPart;
02631 
02632   /* lookup the element type name */
02633   elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
02634   if (!elementType) {
02635     const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
02636     if (!name)
02637       return XML_ERROR_NO_MEMORY;
02638     elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
02639                                          sizeof(ELEMENT_TYPE));
02640     if (!elementType)
02641       return XML_ERROR_NO_MEMORY;
02642     if (ns && !setElementTypePrefix(parser, elementType))
02643       return XML_ERROR_NO_MEMORY;
02644   }
02645   nDefaultAtts = elementType->nDefaultAtts;
02646 
02647   /* get the attributes from the tokenizer */
02648   n = XmlGetAttributes(enc, attStr, attsSize, atts);
02649   if (n + nDefaultAtts > attsSize) {
02650     int oldAttsSize = attsSize;
02651     ATTRIBUTE *temp;
02652     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
02653     temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
02654     if (temp == NULL)
02655       return XML_ERROR_NO_MEMORY;
02656     atts = temp;
02657     if (n > oldAttsSize)
02658       XmlGetAttributes(enc, attStr, n, atts);
02659   }
02660 
02661   appAtts = (const XML_Char **)atts;
02662   for (i = 0; i < n; i++) {
02663     /* add the name and value to the attribute list */
02664     ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
02665                                          atts[i].name
02666                                          + XmlNameLength(enc, atts[i].name));
02667     if (!attId)
02668       return XML_ERROR_NO_MEMORY;
02669     /* Detect duplicate attributes by their QNames. This does not work when
02670        namespace processing is turned on and different prefixes for the same
02671        namespace are used. For this case we have a check further down.
02672     */
02673     if ((attId->name)[-1]) {
02674       if (enc == encoding)
02675         eventPtr = atts[i].name;
02676       return XML_ERROR_DUPLICATE_ATTRIBUTE;
02677     }
02678     (attId->name)[-1] = 1;
02679     appAtts[attIndex++] = attId->name;
02680     if (!atts[i].normalized) {
02681       enum XML_Error result;
02682       XML_Bool isCdata = XML_TRUE;
02683 
02684       /* figure out whether declared as other than CDATA */
02685       if (attId->maybeTokenized) {
02686         int j;
02687         for (j = 0; j < nDefaultAtts; j++) {
02688           if (attId == elementType->defaultAtts[j].id) {
02689             isCdata = elementType->defaultAtts[j].isCdata;
02690             break;
02691           }
02692         }
02693       }
02694 
02695       /* normalize the attribute value */
02696       result = storeAttributeValue(parser, enc, isCdata,
02697                                    atts[i].valuePtr, atts[i].valueEnd,
02698                                    &tempPool);
02699       if (result)
02700         return result;
02701       appAtts[attIndex] = poolStart(&tempPool);
02702       poolFinish(&tempPool);
02703     }
02704     else {
02705       /* the value did not need normalizing */
02706       appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
02707                                           atts[i].valueEnd);
02708       if (appAtts[attIndex] == 0)
02709         return XML_ERROR_NO_MEMORY;
02710       poolFinish(&tempPool);
02711     }
02712     /* handle prefixed attribute names */
02713     if (attId->prefix) {
02714       if (attId->xmlns) {
02715         /* deal with namespace declarations here */
02716         enum XML_Error result = addBinding(parser, attId->prefix, attId,
02717                                            appAtts[attIndex], bindingsPtr);
02718         if (result)
02719           return result;
02720         --attIndex;
02721       }
02722       else {
02723         /* deal with other prefixed names later */
02724         attIndex++;
02725         nPrefixes++;
02726         (attId->name)[-1] = 2;
02727       }
02728     }
02729     else
02730       attIndex++;
02731   }
02732 
02733   /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
02734   nSpecifiedAtts = attIndex;
02735   if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
02736     for (i = 0; i < attIndex; i += 2)
02737       if (appAtts[i] == elementType->idAtt->name) {
02738         idAttIndex = i;
02739         break;
02740       }
02741   }
02742   else
02743     idAttIndex = -1;
02744 
02745   /* do attribute defaulting */
02746   for (i = 0; i < nDefaultAtts; i++) {
02747     const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
02748     if (!(da->id->name)[-1] && da->value) {
02749       if (da->id->prefix) {
02750         if (da->id->xmlns) {
02751           enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
02752                                              da->value, bindingsPtr);
02753           if (result)
02754             return result;
02755         }
02756         else {
02757           (da->id->name)[-1] = 2;
02758           nPrefixes++;
02759           appAtts[attIndex++] = da->id->name;
02760           appAtts[attIndex++] = da->value;
02761         }
02762       }
02763       else {
02764         (da->id->name)[-1] = 1;
02765         appAtts[attIndex++] = da->id->name;
02766         appAtts[attIndex++] = da->value;
02767       }
02768     }
02769   }
02770   appAtts[attIndex] = 0;
02771 
02772   /* expand prefixed attribute names, check for duplicates,
02773      and clear flags that say whether attributes were specified */
02774   i = 0;
02775   if (nPrefixes) {
02776     int j;  /* hash table index */
02777     unsigned long version = nsAttsVersion;
02778     int nsAttsSize = (int)1 << nsAttsPower;
02779     /* size of hash table must be at least 2 * (# of prefixed attributes) */
02780     if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
02781       NS_ATT *temp;
02782       /* hash table size must also be a power of 2 and >= 8 */
02783       while (nPrefixes >> nsAttsPower++);
02784       if (nsAttsPower < 3)
02785         nsAttsPower = 3;
02786       nsAttsSize = (int)1 << nsAttsPower;
02787       temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
02788       if (!temp)
02789         return XML_ERROR_NO_MEMORY;
02790       nsAtts = temp;
02791       version = 0;  /* force re-initialization of nsAtts hash table */
02792     }
02793     /* using a version flag saves us from initializing nsAtts every time */
02794     if (!version) {  /* initialize version flags when version wraps around */
02795       version = INIT_ATTS_VERSION;
02796       for (j = nsAttsSize; j != 0; )
02797         nsAtts[--j].version = version;
02798     }
02799     nsAttsVersion = --version;
02800 
02801     /* expand prefixed names and check for duplicates */
02802     for (; i < attIndex; i += 2) {
02803       const XML_Char *s = appAtts[i];
02804       if (s[-1] == 2) {  /* prefixed */
02805         ATTRIBUTE_ID *id;
02806         const BINDING *b;
02807         unsigned long uriHash = 0;
02808         ((XML_Char *)s)[-1] = 0;  /* clear flag */
02809         id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
02810         b = id->prefix->binding;
02811         if (!b)
02812           return XML_ERROR_UNBOUND_PREFIX;
02813 
02814         /* as we expand the name we also calculate its hash value */
02815         for (j = 0; j < b->uriLen; j++) {
02816           const XML_Char c = b->uri[j];
02817           if (!poolAppendChar(&tempPool, c))
02818             return XML_ERROR_NO_MEMORY;
02819           uriHash = CHAR_HASH(uriHash, c);
02820         }
02821         while (*s++ != XML_T(ASCII_COLON))
02822           ;
02823         do {  /* copies null terminator */
02824           const XML_Char c = *s;
02825           if (!poolAppendChar(&tempPool, *s))
02826             return XML_ERROR_NO_MEMORY;
02827           uriHash = CHAR_HASH(uriHash, c);
02828         } while (*s++);
02829 
02830         { /* Check hash table for duplicate of expanded name (uriName).
02831              Derived from code in lookup(HASH_TABLE *table, ...).
02832           */
02833           unsigned char step = 0;
02834           unsigned long mask = nsAttsSize - 1;
02835           j = uriHash & mask;  /* index into hash table */
02836           while (nsAtts[j].version == version) {
02837             /* for speed we compare stored hash values first */
02838             if (uriHash == nsAtts[j].hash) {
02839               const XML_Char *s1 = poolStart(&tempPool);
02840               const XML_Char *s2 = nsAtts[j].uriName;
02841               /* s1 is null terminated, but not s2 */
02842               for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
02843               if (*s1 == 0)
02844                 return XML_ERROR_DUPLICATE_ATTRIBUTE;
02845             }
02846             if (!step)
02847               step = PROBE_STEP(uriHash, mask, nsAttsPower);
02848             j < step ? (j += nsAttsSize - step) : (j -= step);
02849           }
02850         }
02851 
02852         if (ns_triplets) {  /* append namespace separator and prefix */
02853           tempPool.ptr[-1] = namespaceSeparator;
02854           s = b->prefix->name;
02855           do {
02856             if (!poolAppendChar(&tempPool, *s))
02857               return XML_ERROR_NO_MEMORY;
02858           } while (*s++);
02859         }
02860 
02861         /* store expanded name in attribute list */
02862         s = poolStart(&tempPool);
02863         poolFinish(&tempPool);
02864         appAtts[i] = s;
02865 
02866         /* fill empty slot with new version, uriName and hash value */
02867         nsAtts[j].version = version;
02868         nsAtts[j].hash = uriHash;
02869         nsAtts[j].uriName = s;
02870 
02871         if (!--nPrefixes) {
02872           i += 2;
02873           break;
02874         }
02875       }
02876       else  /* not prefixed */
02877         ((XML_Char *)s)[-1] = 0;  /* clear flag */
02878     }
02879   }
02880   /* clear flags for the remaining attributes */
02881   for (; i < attIndex; i += 2)
02882     ((XML_Char *)(appAtts[i]))[-1] = 0;
02883   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
02884     binding->attId->name[-1] = 0;
02885 
02886   if (!ns)
02887     return XML_ERROR_NONE;
02888 
02889   /* expand the element type name */
02890   if (elementType->prefix) {
02891     binding = elementType->prefix->binding;
02892     if (!binding)
02893       return XML_ERROR_UNBOUND_PREFIX;
02894     localPart = tagNamePtr->str;
02895     while (*localPart++ != XML_T(ASCII_COLON))
02896       ;
02897   }
02898   else if (dtd->defaultPrefix.binding) {
02899     binding = dtd->defaultPrefix.binding;
02900     localPart = tagNamePtr->str;
02901   }
02902   else
02903     return XML_ERROR_NONE;
02904   prefixLen = 0;
02905   if (ns_triplets && binding->prefix->name) {
02906     for (; binding->prefix->name[prefixLen++];)
02907       ;  /* prefixLen includes null terminator */
02908   }
02909   tagNamePtr->localPart = localPart;
02910   tagNamePtr->uriLen = binding->uriLen;
02911   tagNamePtr->prefix = binding->prefix->name;
02912   tagNamePtr->prefixLen = prefixLen;
02913   for (i = 0; localPart[i++];)
02914     ;  /* i includes null terminator */
02915   n = i + binding->uriLen + prefixLen;
02916   if (n > binding->uriAlloc) {
02917     TAG *p;
02918     uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
02919     if (!uri)
02920       return XML_ERROR_NO_MEMORY;
02921     binding->uriAlloc = n + EXPAND_SPARE;
02922     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
02923     for (p = tagStack; p; p = p->parent)
02924       if (p->name.str == binding->uri)
02925         p->name.str = uri;
02926     FREE(binding->uri);
02927     binding->uri = uri;
02928   }
02929   /* if namespaceSeparator != '\0' then uri includes it already */
02930   uri = binding->uri + binding->uriLen;
02931   memcpy(uri, localPart, i * sizeof(XML_Char));
02932   /* we always have a namespace separator between localPart and prefix */
02933   if (prefixLen) {
02934     uri += i - 1;
02935     *uri = namespaceSeparator;  /* replace null terminator */
02936     memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
02937   }
02938   tagNamePtr->str = binding->uri;
02939   return XML_ERROR_NONE;
02940 }
02941 
02942 /* addBinding() overwrites the value of prefix->binding without checking.
02943    Therefore one must keep track of the old value outside of addBinding().
02944 */
02945 static enum XML_Error
02946 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
02947            const XML_Char *uri, BINDING **bindingsPtr)
02948 {
02949   static const XML_Char xmlNamespace[] = {
02950     ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
02951     ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
02952     ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, 
02953     ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
02954     ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
02955     ASCII_e, '\0'
02956   };
02957   static const int xmlLen = 
02958     (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
02959   static const XML_Char xmlnsNamespace[] = {
02960     ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
02961     ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
02962     ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, 
02963     ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, 
02964     ASCII_SLASH, '\0'
02965   };
02966   static const int xmlnsLen = 
02967     (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
02968 
02969   XML_Bool mustBeXML = XML_FALSE;
02970   XML_Bool isXML = XML_TRUE;
02971   XML_Bool isXMLNS = XML_TRUE;
02972   
02973   BINDING *b;
02974   int len;
02975 
02976   /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
02977   if (*uri == XML_T('\0') && prefix->name)
02978     return XML_ERROR_UNDECLARING_PREFIX;
02979 
02980   if (prefix->name
02981       && prefix->name[0] == XML_T(ASCII_x)
02982       && prefix->name[1] == XML_T(ASCII_m)
02983       && prefix->name[2] == XML_T(ASCII_l)) {
02984 
02985     /* Not allowed to bind xmlns */
02986     if (prefix->name[3] == XML_T(ASCII_n)
02987         && prefix->name[4] == XML_T(ASCII_s)
02988         && prefix->name[5] == XML_T('\0'))
02989       return XML_ERROR_RESERVED_PREFIX_XMLNS;
02990 
02991     if (prefix->name[3] == XML_T('\0'))
02992       mustBeXML = XML_TRUE;
02993   }
02994 
02995   for (len = 0; uri[len]; len++) {
02996     if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
02997       isXML = XML_FALSE;
02998 
02999     if (!mustBeXML && isXMLNS 
03000         && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
03001       isXMLNS = XML_FALSE;
03002   }
03003   isXML = isXML && len == xmlLen;
03004   isXMLNS = isXMLNS && len == xmlnsLen;
03005 
03006   if (mustBeXML != isXML)
03007     return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
03008                      : XML_ERROR_RESERVED_NAMESPACE_URI;
03009 
03010   if (isXMLNS)
03011     return XML_ERROR_RESERVED_NAMESPACE_URI;
03012 
03013   if (namespaceSeparator)
03014     len++;
03015   if (freeBindingList) {
03016     b = freeBindingList;
03017     if (len > b->uriAlloc) {
03018       XML_Char *temp = (XML_Char *)REALLOC(b->uri,
03019                           sizeof(XML_Char) * (len + EXPAND_SPARE));
03020       if (temp == NULL)
03021         return XML_ERROR_NO_MEMORY;
03022       b->uri = temp;
03023       b->uriAlloc = len + EXPAND_SPARE;
03024     }
03025     freeBindingList = b->nextTagBinding;
03026   }
03027   else {
03028     b = (BINDING *)MALLOC(sizeof(BINDING));
03029     if (!b)
03030       return XML_ERROR_NO_MEMORY;
03031     b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
03032     if (!b->uri) {
03033       FREE(b);
03034       return XML_ERROR_NO_MEMORY;
03035     }
03036     b->uriAlloc = len + EXPAND_SPARE;
03037   }
03038   b->uriLen = len;
03039   memcpy(b->uri, uri, len * sizeof(XML_Char));
03040   if (namespaceSeparator)
03041     b->uri[len - 1] = namespaceSeparator;
03042   b->prefix = prefix;
03043   b->attId = attId;
03044   b->prevPrefixBinding = prefix->binding;
03045   /* NULL binding when default namespace undeclared */
03046   if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
03047     prefix->binding = NULL;
03048   else
03049     prefix->binding = b;
03050   b->nextTagBinding = *bindingsPtr;
03051   *bindingsPtr = b;
03052   /* if attId == NULL then we are not starting a namespace scope */
03053   if (attId && startNamespaceDeclHandler)
03054     startNamespaceDeclHandler(handlerArg, prefix->name,
03055                               prefix->binding ? uri : 0);
03056   return XML_ERROR_NONE;
03057 }
03058 
03059 /* The idea here is to avoid using stack for each CDATA section when
03060    the whole file is parsed with one call.
03061 */
03062 static enum XML_Error PTRCALL
03063 cdataSectionProcessor(XML_Parser parser,
03064                       const char *start,
03065                       const char *end,
03066                       const char **endPtr)
03067 {
03068   enum XML_Error result = doCdataSection(parser, encoding, &start, end,
03069                                          endPtr, (XML_Bool)!ps_finalBuffer);
03070   if (result != XML_ERROR_NONE)
03071     return result;
03072   if (start) {
03073     if (parentParser) {  /* we are parsing an external entity */
03074       processor = externalEntityContentProcessor;
03075       return externalEntityContentProcessor(parser, start, end, endPtr);
03076     }
03077     else {
03078       processor = contentProcessor;
03079       return contentProcessor(parser, start, end, endPtr);
03080     }
03081   }
03082   return result;
03083 }
03084 
03085 /* startPtr gets set to non-null if the section is closed, and to null if
03086    the section is not yet closed.
03087 */
03088 static enum XML_Error
03089 doCdataSection(XML_Parser parser,
03090                const ENCODING *enc,
03091                const char **startPtr,
03092                const char *end,
03093                const char **nextPtr,
03094                XML_Bool haveMore)
03095 {
03096   const char *s = *startPtr;
03097   const char **eventPP;
03098   const char **eventEndPP;
03099   if (enc == encoding) {
03100     eventPP = &eventPtr;
03101     *eventPP = s;
03102     eventEndPP = &eventEndPtr;
03103   }
03104   else {
03105     eventPP = &(openInternalEntities->internalEventPtr);
03106     eventEndPP = &(openInternalEntities->internalEventEndPtr);
03107   }
03108   *eventPP = s;
03109   *startPtr = NULL;
03110 
03111   for (;;) {
03112     const char *next;
03113     int tok = XmlCdataSectionTok(enc, s, end, &next);
03114     *eventEndPP = next;
03115     switch (tok) {
03116     case XML_TOK_CDATA_SECT_CLOSE:
03117       if (endCdataSectionHandler)
03118         endCdataSectionHandler(handlerArg);
03119 #if 0
03120       /* see comment under XML_TOK_CDATA_SECT_OPEN */
03121       else if (characterDataHandler)
03122         characterDataHandler(handlerArg, dataBuf, 0);
03123 #endif
03124       else if (defaultHandler)
03125         reportDefault(parser, enc, s, next);
03126       *startPtr = next;
03127       *nextPtr = next;
03128       if (ps_parsing == XML_FINISHED)
03129         return XML_ERROR_ABORTED;
03130       else
03131         return XML_ERROR_NONE;
03132     case XML_TOK_DATA_NEWLINE:
03133       if (characterDataHandler) {
03134         XML_Char c = 0xA;
03135         characterDataHandler(handlerArg, &c, 1);
03136       }
03137       else if (defaultHandler)
03138         reportDefault(parser, enc, s, next);
03139       break;
03140     case XML_TOK_DATA_CHARS:
03141       {
03142         XML_CharacterDataHandler charDataHandler = characterDataHandler;
03143         if (charDataHandler) {
03144           if (MUST_CONVERT(enc, s)) {
03145             for (;;) {
03146               ICHAR *dataPtr = (ICHAR *)dataBuf;
03147               XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
03148               *eventEndPP = next;
03149               charDataHandler(handlerArg, dataBuf,
03150                               (int)(dataPtr - (ICHAR *)dataBuf));
03151               if (s == next)
03152                 break;
03153               *eventPP = s;
03154             }
03155           }
03156           else
03157             charDataHandler(handlerArg,
03158                             (XML_Char *)s,
03159                             (int)((XML_Char *)next - (XML_Char *)s));
03160         }
03161         else if (defaultHandler)
03162           reportDefault(parser, enc, s, next);
03163       }
03164       break;
03165     case XML_TOK_INVALID:
03166       *eventPP = next;
03167       return XML_ERROR_INVALID_TOKEN;
03168     case XML_TOK_PARTIAL_CHAR:
03169       if (haveMore) {
03170         *nextPtr = s;
03171         return XML_ERROR_NONE;
03172       }
03173       return XML_ERROR_PARTIAL_CHAR;
03174     case XML_TOK_PARTIAL:
03175     case XML_TOK_NONE:
03176       if (haveMore) {
03177         *nextPtr = s;
03178         return XML_ERROR_NONE;
03179       }
03180       return XML_ERROR_UNCLOSED_CDATA_SECTION;
03181     default:
03182       *eventPP = next;
03183       return XML_ERROR_UNEXPECTED_STATE;
03184     }
03185 
03186     *eventPP = s = next;
03187     switch (ps_parsing) {
03188     case XML_SUSPENDED:
03189       *nextPtr = next;
03190       return XML_ERROR_NONE;
03191     case XML_FINISHED:
03192       return XML_ERROR_ABORTED;
03193     default: ;
03194     }
03195   }
03196   /* not reached */
03197 }
03198 
03199 #ifdef XML_DTD
03200 
03201 /* The idea here is to avoid using stack for each IGNORE section when
03202    the whole file is parsed with one call.
03203 */
03204 static enum XML_Error PTRCALL
03205 ignoreSectionProcessor(XML_Parser parser,
03206                        const char *start,
03207                        const char *end,
03208                        const char **endPtr)
03209 {
03210   enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 
03211                                           endPtr, (XML_Bool)!ps_finalBuffer);
03212   if (result != XML_ERROR_NONE)
03213     return result;
03214   if (start) {
03215     processor = prologProcessor;
03216     return prologProcessor(parser, start, end, endPtr);
03217   }
03218   return result;
03219 }
03220 
03221 /* startPtr gets set to non-null is the section is closed, and to null
03222    if the section is not yet closed.
03223 */
03224 static enum XML_Error
03225 doIgnoreSection(XML_Parser parser,
03226                 const ENCODING *enc,
03227                 const char **startPtr,
03228                 const char *end,
03229                 const char **nextPtr,
03230                 XML_Bool haveMore)
03231 {
03232   const char *next;
03233   int tok;
03234   const char *s = *startPtr;
03235   const char **eventPP;
03236   const char **eventEndPP;
03237   if (enc == encoding) {
03238     eventPP = &eventPtr;
03239     *eventPP = s;
03240     eventEndPP = &eventEndPtr;
03241   }
03242   else {
03243     eventPP = &(openInternalEntities->internalEventPtr);
03244     eventEndPP = &(openInternalEntities->internalEventEndPtr);
03245   }
03246   *eventPP = s;
03247   *startPtr = NULL;
03248   tok = XmlIgnoreSectionTok(enc, s, end, &next);
03249   *eventEndPP = next;
03250   switch (tok) {
03251   case XML_TOK_IGNORE_SECT:
03252     if (defaultHandler)
03253       reportDefault(parser, enc, s, next);
03254     *startPtr = next;
03255     *nextPtr = next;
03256     if (ps_parsing == XML_FINISHED)
03257       return XML_ERROR_ABORTED;
03258     else
03259       return XML_ERROR_NONE;
03260   case XML_TOK_INVALID:
03261     *eventPP = next;
03262     return XML_ERROR_INVALID_TOKEN;
03263   case XML_TOK_PARTIAL_CHAR:
03264     if (haveMore) {
03265       *nextPtr = s;
03266       return XML_ERROR_NONE;
03267     }
03268     return XML_ERROR_PARTIAL_CHAR;
03269   case XML_TOK_PARTIAL:
03270   case XML_TOK_NONE:
03271     if (haveMore) {
03272       *nextPtr = s;
03273       return XML_ERROR_NONE;
03274     }
03275     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
03276   default:
03277     *eventPP = next;
03278     return XML_ERROR_UNEXPECTED_STATE;
03279   }
03280   /* not reached */
03281 }
03282 
03283 #endif /* XML_DTD */
03284 
03285 static enum XML_Error
03286 initializeEncoding(XML_Parser parser)
03287 {
03288   const char *s;
03289 #ifdef XML_UNICODE
03290   char encodingBuf[128];
03291   if (!protocolEncodingName)
03292     s = NULL;
03293   else {
03294     int i;
03295     for (i = 0; protocolEncodingName[i]; i++) {
03296       if (i == sizeof(encodingBuf) - 1
03297           || (protocolEncodingName[i] & ~0x7f) != 0) {
03298         encodingBuf[0] = '\0';
03299         break;
03300       }
03301       encodingBuf[i] = (char)protocolEncodingName[i];
03302     }
03303     encodingBuf[i] = '\0';
03304     s = encodingBuf;
03305   }
03306 #else
03307   s = protocolEncodingName;
03308 #endif
03309   if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
03310     return XML_ERROR_NONE;
03311   return handleUnknownEncoding(parser, protocolEncodingName);
03312 }
03313 
03314 static enum XML_Error
03315 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
03316                const char *s, const char *next)
03317 {
03318   const char *encodingName = NULL;
03319   const XML_Char *storedEncName = NULL;
03320   const ENCODING *newEncoding = NULL;
03321   const char *version = NULL;
03322   const char *versionend;
03323   const XML_Char *storedversion = NULL;
03324   int standalone = -1;
03325   if (!(ns
03326         ? XmlParseXmlDeclNS
03327         : XmlParseXmlDecl)(isGeneralTextEntity,
03328                            encoding,
03329                            s,
03330                            next,
03331                            &eventPtr,
03332                            &version,
03333                            &versionend,
03334                            &encodingName,
03335                            &newEncoding,
03336                            &standalone)) {
03337     if (isGeneralTextEntity)
03338       return XML_ERROR_TEXT_DECL;
03339     else
03340       return XML_ERROR_XML_DECL;
03341   }
03342   if (!isGeneralTextEntity && standalone == 1) {
03343     _dtd->standalone = XML_TRUE;
03344 #ifdef XML_DTD
03345     if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
03346       paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
03347 #endif /* XML_DTD */
03348   }
03349   if (xmlDeclHandler) {
03350     if (encodingName != NULL) {
03351       storedEncName = poolStoreString(&temp2Pool,
03352                                       encoding,
03353                                       encodingName,
03354                                       encodingName
03355                                       + XmlNameLength(encoding, encodingName));
03356       if (!storedEncName)
03357               return XML_ERROR_NO_MEMORY;
03358       poolFinish(&temp2Pool);
03359     }
03360     if (version) {
03361       storedversion = poolStoreString(&temp2Pool,
03362                                       encoding,
03363                                       version,
03364                                       versionend - encoding->minBytesPerChar);
03365       if (!storedversion)
03366         return XML_ERROR_NO_MEMORY;
03367     }
03368     xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
03369   }
03370   else if (defaultHandler)
03371     reportDefault(parser, encoding, s, next);
03372   if (protocolEncodingName == NULL) {
03373     if (newEncoding) {
03374       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
03375         eventPtr = encodingName;
03376         return XML_ERROR_INCORRECT_ENCODING;
03377       }
03378       encoding = newEncoding;
03379     }
03380     else if (encodingName) {
03381       enum XML_Error result;
03382       if (!storedEncName) {
03383         storedEncName = poolStoreString(
03384           &temp2Pool, encoding, encodingName,
03385           encodingName + XmlNameLength(encoding, encodingName));
03386         if (!storedEncName)
03387           return XML_ERROR_NO_MEMORY;
03388       }
03389       result = handleUnknownEncoding(parser, storedEncName);
03390       poolClear(&temp2Pool);
03391       if (result == XML_ERROR_UNKNOWN_ENCODING)
03392         eventPtr = encodingName;
03393       return result;
03394     }
03395   }
03396 
03397   if (storedEncName || storedversion)
03398     poolClear(&temp2Pool);
03399 
03400   return XML_ERROR_NONE;
03401 }
03402 
03403 static enum XML_Error
03404 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
03405 {
03406   if (unknownEncodingHandler) {
03407     XML_Encoding info;
03408     int i;
03409     for (i = 0; i < 256; i++)
03410       info.map[i] = -1;
03411     info.convert = NULL;
03412     info.data = NULL;
03413     info.release = NULL;
03414     if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
03415                                &info)) {
03416       ENCODING *enc;
03417       unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
03418       if (!unknownEncodingMem) {
03419         if (info.release)
03420           info.release(info.data);
03421         return XML_ERROR_NO_MEMORY;
03422       }
03423       enc = (ns
03424              ? XmlInitUnknownEncodingNS
03425              : XmlInitUnknownEncoding)(unknownEncodingMem,
03426                                        info.map,
03427                                        info.convert,
03428                                        info.data);
03429       if (enc) {
03430         unknownEncodingData = info.data;
03431         unknownEncodingRelease = info.release;
03432         encoding = enc;
03433         return XML_ERROR_NONE;
03434       }
03435     }
03436     if (info.release != NULL)
03437       info.release(info.data);
03438   }
03439   return XML_ERROR_UNKNOWN_ENCODING;
03440 }
03441 
03442 static enum XML_Error PTRCALL
03443 prologInitProcessor(XML_Parser parser,
03444                     const char *s,
03445                     const char *end,
03446                     const char **nextPtr)
03447 {
03448   enum XML_Error result = initializeEncoding(parser);
03449   if (result != XML_ERROR_NONE)
03450     return result;
03451   processor = prologProcessor;
03452   return prologProcessor(parser, s, end, nextPtr);
03453 }
03454 
03455 #ifdef XML_DTD
03456 
03457 static enum XML_Error PTRCALL
03458 externalParEntInitProcessor(XML_Parser parser,
03459                             const char *s,
03460                             const char *end,
03461                             const char **nextPtr)
03462 {
03463   enum XML_Error result = initializeEncoding(parser);
03464   if (result != XML_ERROR_NONE)
03465     return result;
03466 
03467   /* we know now that XML_Parse(Buffer) has been called,
03468      so we consider the external parameter entity read */
03469   _dtd->paramEntityRead = XML_TRUE;
03470 
03471   if (prologState.inEntityValue) {
03472     processor = entityValueInitProcessor;
03473     return entityValueInitProcessor(parser, s, end, nextPtr);
03474   }
03475   else {
03476     processor = externalParEntProcessor;
03477     return externalParEntProcessor(parser, s, end, nextPtr);
03478   }
03479 }
03480 
03481 static enum XML_Error PTRCALL
03482 entityValueInitProcessor(XML_Parser parser,
03483                          const char *s,
03484                          const char *end,
03485                          const char **nextPtr)
03486 {
03487   int tok;
03488   const char *start = s;
03489   const char *next = start;
03490   eventPtr = start;
03491 
03492   for (;;) {  
03493     tok = XmlPrologTok(encoding, start, end, &next);
03494     eventEndPtr = next;
03495     if (tok <= 0) {
03496       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
03497         *nextPtr = s;
03498         return XML_ERROR_NONE;
03499       }
03500       switch (tok) {
03501       case XML_TOK_INVALID:
03502         return XML_ERROR_INVALID_TOKEN;
03503       case XML_TOK_PARTIAL:
03504         return XML_ERROR_UNCLOSED_TOKEN;
03505       case XML_TOK_PARTIAL_CHAR:
03506         return XML_ERROR_PARTIAL_CHAR;
03507       case XML_TOK_NONE:   /* start == end */
03508       default:
03509         break;
03510       }
03511       /* found end of entity value - can store it now */
03512       return storeEntityValue(parser, encoding, s, end);
03513     }
03514     else if (tok == XML_TOK_XML_DECL) {
03515       enum XML_Error result;
03516       result = processXmlDecl(parser, 0, start, next);
03517       if (result != XML_ERROR_NONE)
03518         return result;
03519       switch (ps_parsing) {
03520       case XML_SUSPENDED: 
03521         *nextPtr = next;
03522         return XML_ERROR_NONE;
03523       case XML_FINISHED:
03524         return XML_ERROR_ABORTED;
03525       default:
03526         *nextPtr = next;
03527       }
03528       /* stop scanning for text declaration - we found one */
03529       processor = entityValueProcessor;
03530       return entityValueProcessor(parser, next, end, nextPtr);
03531     }
03532     /* If we are at the end of the buffer, this would cause XmlPrologTok to
03533        return XML_TOK_NONE on the next call, which would then cause the
03534        function to exit with *nextPtr set to s - that is what we want for other
03535        tokens, but not for the BOM - we would rather like to skip it;
03536        then, when this routine is entered the next time, XmlPrologTok will
03537        return XML_TOK_INVALID, since the BOM is still in the buffer
03538     */
03539     else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
03540       *nextPtr = next;
03541       return XML_ERROR_NONE;
03542     }
03543     start = next;
03544     eventPtr = start;
03545   }
03546 }
03547 
03548 static enum XML_Error PTRCALL
03549 externalParEntProcessor(XML_Parser parser,
03550                         const char *s,
03551                         const char *end,
03552                         const char **nextPtr)
03553 {
03554   const char *next = s;
03555   int tok;
03556 
03557   tok = XmlPrologTok(encoding, s, end, &next);
03558   if (tok <= 0) {
03559     if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
03560       *nextPtr = s;
03561       return XML_ERROR_NONE;
03562     }
03563     switch (tok) {
03564     case XML_TOK_INVALID:
03565       return XML_ERROR_INVALID_TOKEN;
03566     case XML_TOK_PARTIAL:
03567       return XML_ERROR_UNCLOSED_TOKEN;
03568     case XML_TOK_PARTIAL_CHAR:
03569       return XML_ERROR_PARTIAL_CHAR;
03570     case XML_TOK_NONE:   /* start == end */
03571     default:
03572       break;
03573     }
03574   }
03575   /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
03576      However, when parsing an external subset, doProlog will not accept a BOM
03577      as valid, and report a syntax error, so we have to skip the BOM
03578   */
03579   else if (tok == XML_TOK_BOM) {
03580     s = next;
03581     tok = XmlPrologTok(encoding, s, end, &next);
03582   }
03583 
03584   processor = prologProcessor;
03585   return doProlog(parser, encoding, s, end, tok, next, 
03586                   nextPtr, (XML_Bool)!ps_finalBuffer);
03587 }
03588 
03589 static enum XML_Error PTRCALL
03590 entityValueProcessor(XML_Parser parser,
03591                      const char *s,
03592                      const char *end,
03593                      const char **nextPtr)
03594 {
03595   const char *start = s;
03596   const char *next = s;
03597   const ENCODING *enc = encoding;
03598   int tok;
03599 
03600   for (;;) {
03601     tok = XmlPrologTok(enc, start, end, &next);
03602     if (tok <= 0) {
03603       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
03604         *nextPtr = s;
03605         return XML_ERROR_NONE;
03606       }
03607       switch (tok) {
03608       case XML_TOK_INVALID:
03609         return XML_ERROR_INVALID_TOKEN;
03610       case XML_TOK_PARTIAL:
03611         return XML_ERROR_UNCLOSED_TOKEN;
03612       case XML_TOK_PARTIAL_CHAR:
03613         return XML_ERROR_PARTIAL_CHAR;
03614       case XML_TOK_NONE:   /* start == end */
03615       default:
03616         break;
03617       }
03618       /* found end of entity value - can store it now */
03619       return storeEntityValue(parser, enc, s, end);
03620     }
03621     start = next;
03622   }
03623 }
03624 
03625 #endif /* XML_DTD */
03626 
03627 static enum XML_Error PTRCALL
03628 prologProcessor(XML_Parser parser,
03629                 const char *s,
03630                 const char *end,
03631                 const char **nextPtr)
03632 {
03633   const char *next = s;
03634   int tok = XmlPrologTok(encoding, s, end, &next);
03635   return doProlog(parser, encoding, s, end, tok, next, 
03636                   nextPtr, (XML_Bool)!ps_finalBuffer);
03637 }
03638 
03639 static enum XML_Error
03640 doProlog(XML_Parser parser,
03641          const ENCODING *enc,
03642          const char *s,
03643          const char *end,
03644          int tok,
03645          const char *next,
03646          const char **nextPtr,
03647          XML_Bool haveMore)
03648 {
03649 #ifdef XML_DTD
03650   static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
03651 #endif /* XML_DTD */
03652   static const XML_Char atypeCDATA[] = 
03653       { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
03654   static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
03655   static const XML_Char atypeIDREF[] =
03656       { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
03657   static const XML_Char atypeIDREFS[] =
03658       { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
03659   static const XML_Char atypeENTITY[] =
03660       { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
03661   static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
03662       ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
03663   static const XML_Char atypeNMTOKEN[] = {
03664       ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
03665   static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
03666       ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
03667   static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
03668       ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
03669   static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
03670   static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
03671 
03672   /* save one level of indirection */
03673   DTD * const dtd = _dtd; 
03674 
03675   const char **eventPP;
03676   const char **eventEndPP;
03677   enum XML_Content_Quant quant;
03678 
03679   if (enc == encoding) {
03680     eventPP = &eventPtr;
03681     eventEndPP = &eventEndPtr;
03682   }
03683   else {
03684     eventPP = &(openInternalEntities->internalEventPtr);
03685     eventEndPP = &(openInternalEntities->internalEventEndPtr);
03686   }
03687 
03688   for (;;) {
03689     int role;
03690     XML_Bool handleDefault = XML_TRUE;
03691     *eventPP = s;
03692     *eventEndPP = next;
03693     if (tok <= 0) {
03694       if (haveMore && tok != XML_TOK_INVALID) {
03695         *nextPtr = s;
03696         return XML_ERROR_NONE;
03697       }
03698       switch (tok) {
03699       case XML_TOK_INVALID:
03700         *eventPP = next;
03701         return XML_ERROR_INVALID_TOKEN;
03702       case XML_TOK_PARTIAL:
03703         return XML_ERROR_UNCLOSED_TOKEN;
03704       case XML_TOK_PARTIAL_CHAR:
03705         return XML_ERROR_PARTIAL_CHAR;
03706       case XML_TOK_NONE:
03707 #ifdef XML_DTD
03708         /* for internal PE NOT referenced between declarations */
03709         if (enc != encoding && !openInternalEntities->betweenDecl) {
03710           *nextPtr = s;
03711           return XML_ERROR_NONE;
03712         }
03713         /* WFC: PE Between Declarations - must check that PE contains
03714            complete markup, not only for external PEs, but also for
03715            internal PEs if the reference occurs between declarations.
03716         */
03717         if (isParamEntity || enc != encoding) {
03718           if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
03719               == XML_ROLE_ERROR)
03720             return XML_ERROR_INCOMPLETE_PE;
03721           *nextPtr = s;
03722           return XML_ERROR_NONE;
03723         }
03724 #endif /* XML_DTD */
03725         return XML_ERROR_NO_ELEMENTS;
03726       default:
03727         tok = -tok;
03728         next = end;
03729         break;
03730       }
03731     }
03732     role = XmlTokenRole(&prologState, tok, s, next, enc);
03733     switch (role) {
03734     case XML_ROLE_XML_DECL:
03735       {
03736         enum XML_Error result = processXmlDecl(parser, 0, s, next);
03737         if (result != XML_ERROR_NONE)
03738           return result;
03739         enc = encoding;
03740         handleDefault = XML_FALSE;
03741       }
03742       break;
03743     case XML_ROLE_DOCTYPE_NAME:
03744       if (startDoctypeDeclHandler) {
03745         doctypeName = poolStoreString(&tempPool, enc, s, next);
03746         if (!doctypeName)
03747           return XML_ERROR_NO_MEMORY;
03748         poolFinish(&tempPool);
03749         doctypePubid = NULL;
03750         handleDefault = XML_FALSE;
03751       }
03752       doctypeSysid = NULL; /* always initialize to NULL */
03753       break;
03754     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
03755       if (startDoctypeDeclHandler) {
03756         startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
03757                                 doctypePubid, 1);
03758         doctypeName = NULL;
03759         poolClear(&tempPool);
03760         handleDefault = XML_FALSE;
03761       }
03762       break;
03763 #ifdef XML_DTD
03764     case XML_ROLE_TEXT_DECL:
03765       {
03766         enum XML_Error result = processXmlDecl(parser, 1, s, next);
03767         if (result != XML_ERROR_NONE)
03768           return result;
03769         enc = encoding;
03770         handleDefault = XML_FALSE;
03771       }
03772       break;
03773 #endif /* XML_DTD */
03774     case XML_ROLE_DOCTYPE_PUBLIC_ID:
03775 #ifdef XML_DTD
03776       useForeignDTD = XML_FALSE;
03777       declEntity = (ENTITY *)lookup(&dtd->paramEntities,
03778                                     externalSubsetName,
03779                                     sizeof(ENTITY));
03780       if (!declEntity)
03781         return XML_ERROR_NO_MEMORY;
03782 #endif /* XML_DTD */
03783       dtd->hasParamEntityRefs = XML_TRUE;
03784       if (startDoctypeDeclHandler) {
03785         if (!XmlIsPublicId(enc, s, next, eventPP))
03786           return XML_ERROR_PUBLICID;
03787         doctypePubid = poolStoreString(&tempPool, enc,
03788                                        s + enc->minBytesPerChar,
03789                                        next - enc->minBytesPerChar);
03790         if (!doctypePubid)
03791           return XML_ERROR_NO_MEMORY;
03792         normalizePublicId((XML_Char *)doctypePubid);
03793         poolFinish(&tempPool);
03794         handleDefault = XML_FALSE;
03795         goto alreadyChecked;
03796       }
03797       /* fall through */
03798     case XML_ROLE_ENTITY_PUBLIC_ID:
03799       if (!XmlIsPublicId(enc, s, next, eventPP))
03800         return XML_ERROR_PUBLICID;
03801     alreadyChecked:
03802       if (dtd->keepProcessing && declEntity) {
03803         XML_Char *tem = poolStoreString(&dtd->pool,
03804                                         enc,
03805                                         s + enc->minBytesPerChar,
03806                                         next - enc->minBytesPerChar);
03807         if (!tem)
03808           return XML_ERROR_NO_MEMORY;
03809         normalizePublicId(tem);
03810         declEntity->publicId = tem;
03811         poolFinish(&dtd->pool);
03812         if (entityDeclHandler)
03813           handleDefault = XML_FALSE;
03814       }
03815       break;
03816     case XML_ROLE_DOCTYPE_CLOSE:
03817       if (doctypeName) {
03818         startDoctypeDeclHandler(handlerArg, doctypeName,
03819                                 doctypeSysid, doctypePubid, 0);
03820         poolClear(&tempPool);
03821         handleDefault = XML_FALSE;
03822       }
03823       /* doctypeSysid will be non-NULL in the case of a previous
03824          XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
03825          was not set, indicating an external subset
03826       */
03827 #ifdef XML_DTD
03828       if (doctypeSysid || useForeignDTD) {
03829         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
03830         dtd->hasParamEntityRefs = XML_TRUE;
03831         if (paramEntityParsing && externalEntityRefHandler) {
03832           ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
03833                                             externalSubsetName,
03834                                             sizeof(ENTITY));
03835           if (!entity)
03836             return XML_ERROR_NO_MEMORY;
03837           if (useForeignDTD)
03838             entity->base = curBase;
03839           dtd->paramEntityRead = XML_FALSE;
03840           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
03841                                         0,
03842                                         entity->base,
03843                                         entity->systemId,
03844                                         entity->publicId))
03845             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
03846           if (dtd->paramEntityRead) {
03847             if (!dtd->standalone && 
03848                 notStandaloneHandler && 
03849                 !notStandaloneHandler(handlerArg))
03850               return XML_ERROR_NOT_STANDALONE;
03851           }
03852           /* if we didn't read the foreign DTD then this means that there
03853              is no external subset and we must reset dtd->hasParamEntityRefs
03854           */
03855           else if (!doctypeSysid)
03856             dtd->hasParamEntityRefs = hadParamEntityRefs;
03857           /* end of DTD - no need to update dtd->keepProcessing */
03858         }
03859         useForeignDTD = XML_FALSE;
03860       }
03861 #endif /* XML_DTD */
03862       if (endDoctypeDeclHandler) {
03863         endDoctypeDeclHandler(handlerArg);
03864         handleDefault = XML_FALSE;
03865       }
03866       break;
03867     case XML_ROLE_INSTANCE_START:
03868 #ifdef XML_DTD
03869       /* if there is no DOCTYPE declaration then now is the
03870          last chance to read the foreign DTD
03871       */
03872       if (useForeignDTD) {
03873         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
03874         dtd->hasParamEntityRefs = XML_TRUE;
03875         if (paramEntityParsing && externalEntityRefHandler) {
03876           ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
03877                                             externalSubsetName,
03878                                             sizeof(ENTITY));
03879           if (!entity)
03880             return XML_ERROR_NO_MEMORY;
03881           entity->base = curBase;
03882           dtd->paramEntityRead = XML_FALSE;
03883           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
03884                                         0,
03885                                         entity->base,
03886                                         entity->systemId,
03887                                         entity->publicId))
03888             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
03889           if (dtd->paramEntityRead) {
03890             if (!dtd->standalone &&
03891                 notStandaloneHandler &&
03892                 !notStandaloneHandler(handlerArg))
03893               return XML_ERROR_NOT_STANDALONE;
03894           }
03895           /* if we didn't read the foreign DTD then this means that there
03896              is no external subset and we must reset dtd->hasParamEntityRefs
03897           */
03898           else
03899             dtd->hasParamEntityRefs = hadParamEntityRefs;
03900           /* end of DTD - no need to update dtd->keepProcessing */
03901         }
03902       }
03903 #endif /* XML_DTD */
03904       processor = contentProcessor;
03905       return contentProcessor(parser, s, end, nextPtr);
03906     case XML_ROLE_ATTLIST_ELEMENT_NAME:
03907       declElementType = getElementType(parser, enc, s, next);
03908       if (!declElementType)
03909         return XML_ERROR_NO_MEMORY;
03910       goto checkAttListDeclHandler;
03911     case XML_ROLE_ATTRIBUTE_NAME:
03912       declAttributeId = getAttributeId(parser, enc, s, next);
03913       if (!declAttributeId)
03914         return XML_ERROR_NO_MEMORY;
03915       declAttributeIsCdata = XML_FALSE;
03916       declAttributeType = NULL;
03917       declAttributeIsId = XML_FALSE;
03918       goto checkAttListDeclHandler;
03919     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
03920       declAttributeIsCdata = XML_TRUE;
03921       declAttributeType = atypeCDATA;
03922       goto checkAttListDeclHandler;
03923     case XML_ROLE_ATTRIBUTE_TYPE_ID:
03924       declAttributeIsId = XML_TRUE;
03925       declAttributeType = atypeID;
03926       goto checkAttListDeclHandler;
03927     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
03928       declAttributeType = atypeIDREF;
03929       goto checkAttListDeclHandler;
03930     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
03931       declAttributeType = atypeIDREFS;
03932       goto checkAttListDeclHandler;
03933     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
03934       declAttributeType = atypeENTITY;
03935       goto checkAttListDeclHandler;
03936     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
03937       declAttributeType = atypeENTITIES;
03938       goto checkAttListDeclHandler;
03939     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
03940       declAttributeType = atypeNMTOKEN;
03941       goto checkAttListDeclHandler;
03942     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
03943       declAttributeType = atypeNMTOKENS;
03944     checkAttListDeclHandler:
03945       if (dtd->keepProcessing && attlistDeclHandler)
03946         handleDefault = XML_FALSE;
03947       break;
03948     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
03949     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
03950       if (dtd->keepProcessing && attlistDeclHandler) {
03951         const XML_Char *prefix;
03952         if (declAttributeType) {
03953           prefix = enumValueSep;
03954         }
03955         else {
03956           prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
03957                     ? notationPrefix
03958                     : enumValueStart);
03959         }
03960         if (!poolAppendString(&tempPool, prefix))
03961           return XML_ERROR_NO_MEMORY;
03962         if (!poolAppend(&tempPool, enc, s, next))
03963           return XML_ERROR_NO_MEMORY;
03964         declAttributeType = tempPool.start;
03965         handleDefault = XML_FALSE;
03966       }
03967       break;
03968     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
03969     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
03970       if (dtd->keepProcessing) {
03971         if (!defineAttribute(declElementType, declAttributeId,
03972                              declAttributeIsCdata, declAttributeIsId,
03973                              0, parser))
03974           return XML_ERROR_NO_MEMORY;
03975         if (attlistDeclHandler && declAttributeType) {
03976           if (*declAttributeType == XML_T(ASCII_LPAREN)
03977               || (*declAttributeType == XML_T(ASCII_N)
03978                   && declAttributeType[1] == XML_T(ASCII_O))) {
03979             /* Enumerated or Notation type */
03980             if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
03981                 || !poolAppendChar(&tempPool, XML_T('\0')))
03982               return XML_ERROR_NO_MEMORY;
03983             declAttributeType = tempPool.start;
03984             poolFinish(&tempPool);
03985           }
03986           *eventEndPP = s;
03987           attlistDeclHandler(handlerArg, declElementType->name,
03988                              declAttributeId->name, declAttributeType,
03989                              0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
03990           poolClear(&tempPool);
03991           handleDefault = XML_FALSE;
03992         }
03993       }
03994       break;
03995     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
03996     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
03997       if (dtd->keepProcessing) {
03998         const XML_Char *attVal;
03999         enum XML_Error result =
04000           storeAttributeValue(parser, enc, declAttributeIsCdata,
04001                               s + enc->minBytesPerChar,
04002                               next - enc->minBytesPerChar,
04003                               &dtd->pool);
04004         if (result)
04005           return result;
04006         attVal = poolStart(&dtd->pool);
04007         poolFinish(&dtd->pool);
04008         /* ID attributes aren't allowed to have a default */
04009         if (!defineAttribute(declElementType, declAttributeId,
04010                              declAttributeIsCdata, XML_FALSE, attVal, parser))
04011           return XML_ERROR_NO_MEMORY;
04012         if (attlistDeclHandler && declAttributeType) {
04013           if (*declAttributeType == XML_T(ASCII_LPAREN)
04014               || (*declAttributeType == XML_T(ASCII_N)
04015                   && declAttributeType[1] == XML_T(ASCII_O))) {
04016             /* Enumerated or Notation type */
04017             if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
04018                 || !poolAppendChar(&tempPool, XML_T('\0')))
04019               return XML_ERROR_NO_MEMORY;
04020             declAttributeType = tempPool.start;
04021             poolFinish(&tempPool);
04022           }
04023           *eventEndPP = s;
04024           attlistDeclHandler(handlerArg, declElementType->name,
04025                              declAttributeId->name, declAttributeType,
04026                              attVal,
04027                              role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
04028           poolClear(&tempPool);
04029           handleDefault = XML_FALSE;
04030         }
04031       }
04032       break;
04033     case XML_ROLE_ENTITY_VALUE:
04034       if (dtd->keepProcessing) {
04035         enum XML_Error result = storeEntityValue(parser, enc,
04036                                             s + enc->minBytesPerChar,
04037                                             next - enc->minBytesPerChar);
04038         if (declEntity) {
04039           declEntity->textPtr = poolStart(&dtd->entityValuePool);
04040           declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
04041           poolFinish(&dtd->entityValuePool);
04042           if (entityDeclHandler) {
04043             *eventEndPP = s;
04044             entityDeclHandler(handlerArg,
04045                               declEntity->name,
04046                               declEntity->is_param,
04047                               declEntity->textPtr,
04048                               declEntity->textLen,
04049                               curBase, 0, 0, 0);
04050             handleDefault = XML_FALSE;
04051           }
04052         }
04053         else
04054           poolDiscard(&dtd->entityValuePool);
04055         if (result != XML_ERROR_NONE)
04056           return result;
04057       }
04058       break;
04059     case XML_ROLE_DOCTYPE_SYSTEM_ID:
04060 #ifdef XML_DTD
04061       useForeignDTD = XML_FALSE;
04062 #endif /* XML_DTD */
04063       dtd->hasParamEntityRefs = XML_TRUE;
04064       if (startDoctypeDeclHandler) {
04065         doctypeSysid = poolStoreString(&tempPool, enc,
04066                                        s + enc->minBytesPerChar,
04067                                        next - enc->minBytesPerChar);
04068         if (doctypeSysid == NULL)
04069           return XML_ERROR_NO_MEMORY;
04070         poolFinish(&tempPool);
04071         handleDefault = XML_FALSE;
04072       }
04073 #ifdef XML_DTD
04074       else
04075         /* use externalSubsetName to make doctypeSysid non-NULL
04076            for the case where no startDoctypeDeclHandler is set */
04077         doctypeSysid = externalSubsetName;
04078 #endif /* XML_DTD */
04079       if (!dtd->standalone
04080 #ifdef XML_DTD
04081           && !paramEntityParsing
04082 #endif /* XML_DTD */
04083           && notStandaloneHandler
04084           && !notStandaloneHandler(handlerArg))
04085         return XML_ERROR_NOT_STANDALONE;
04086 #ifndef XML_DTD
04087       break;
04088 #else /* XML_DTD */
04089       if (!declEntity) {
04090         declEntity = (ENTITY *)lookup(&dtd->paramEntities,
04091                                       externalSubsetName,
04092                                       sizeof(ENTITY));
04093         if (!declEntity)
04094           return XML_ERROR_NO_MEMORY;
04095         declEntity->publicId = NULL;
04096       }
04097       /* fall through */
04098 #endif /* XML_DTD */
04099     case XML_ROLE_ENTITY_SYSTEM_ID:
04100       if (dtd->keepProcessing && declEntity) {
04101         declEntity->systemId = poolStoreString(&dtd->pool, enc,
04102                                                s + enc->minBytesPerChar,
04103                                                next - enc->minBytesPerChar);
04104         if (!declEntity->systemId)
04105           return XML_ERROR_NO_MEMORY;
04106         declEntity->base = curBase;
04107         poolFinish(&dtd->pool);
04108         if (entityDeclHandler)
04109           handleDefault = XML_FALSE;
04110       }
04111       break;
04112     case XML_ROLE_ENTITY_COMPLETE:
04113       if (dtd->keepProcessing && declEntity && entityDeclHandler) {
04114         *eventEndPP = s;
04115         entityDeclHandler(handlerArg,
04116                           declEntity->name,
04117                           declEntity->is_param,
04118                           0,0,
04119                           declEntity->base,
04120                           declEntity->systemId,
04121                           declEntity->publicId,
04122                           0);
04123         handleDefault = XML_FALSE;
04124       }
04125       break;
04126     case XML_ROLE_ENTITY_NOTATION_NAME:
04127       if (dtd->keepProcessing && declEntity) {
04128         declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
04129         if (!declEntity->notation)
04130           return XML_ERROR_NO_MEMORY;
04131         poolFinish(&dtd->pool);
04132         if (unparsedEntityDeclHandler) {
04133           *eventEndPP = s;
04134           unparsedEntityDeclHandler(handlerArg,
04135                                     declEntity->name,
04136                                     declEntity->base,
04137                                     declEntity->systemId,
04138                                     declEntity->publicId,
04139                                     declEntity->notation);
04140           handleDefault = XML_FALSE;
04141         }
04142         else if (entityDeclHandler) {
04143           *eventEndPP = s;
04144           entityDeclHandler(handlerArg,
04145                             declEntity->name,
04146                             0,0,0,
04147                             declEntity->base,
04148                             declEntity->systemId,
04149                             declEntity->publicId,
04150                             declEntity->notation);
04151           handleDefault = XML_FALSE;
04152         }
04153       }
04154       break;
04155     case XML_ROLE_GENERAL_ENTITY_NAME:
04156       {
04157         if (XmlPredefinedEntityName(enc, s, next)) {
04158           declEntity = NULL;
04159           break;
04160         }
04161         if (dtd->keepProcessing) {
04162           const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
04163           if (!name)
04164             return XML_ERROR_NO_MEMORY;
04165           declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
04166                                         sizeof(ENTITY));
04167           if (!declEntity)
04168             return XML_ERROR_NO_MEMORY;
04169           if (declEntity->name != name) {
04170             poolDiscard(&dtd->pool);
04171             declEntity = NULL;
04172           }
04173           else {
04174             poolFinish(&dtd->pool);
04175             declEntity->publicId = NULL;
04176             declEntity->is_param = XML_FALSE;
04177             /* if we have a parent parser or are reading an internal parameter
04178                entity, then the entity declaration is not considered "internal"
04179             */
04180             declEntity->is_internal = !(parentParser || openInternalEntities);
04181             if (entityDeclHandler)
04182               handleDefault = XML_FALSE;
04183           }
04184         }
04185         else {
04186           poolDiscard(&dtd->pool);
04187           declEntity = NULL;
04188         }
04189       }
04190       break;
04191     case XML_ROLE_PARAM_ENTITY_NAME:
04192 #ifdef XML_DTD
04193       if (dtd->keepProcessing) {
04194         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
04195         if (!name)
04196           return XML_ERROR_NO_MEMORY;
04197         declEntity = (ENTITY *)lookup(&dtd->paramEntities,
04198                                            name, sizeof(ENTITY));
04199         if (!declEntity)
04200           return XML_ERROR_NO_MEMORY;
04201         if (declEntity->name != name) {
04202           poolDiscard(&dtd->pool);
04203           declEntity = NULL;
04204         }
04205         else {
04206           poolFinish(&dtd->pool);
04207           declEntity->publicId = NULL;
04208           declEntity->is_param = XML_TRUE;
04209           /* if we have a parent parser or are reading an internal parameter
04210              entity, then the entity declaration is not considered "internal"
04211           */
04212           declEntity->is_internal = !(parentParser || openInternalEntities);
04213           if (entityDeclHandler)
04214             handleDefault = XML_FALSE;
04215         }
04216       }
04217       else {
04218         poolDiscard(&dtd->pool);
04219         declEntity = NULL;
04220       }
04221 #else /* not XML_DTD */
04222       declEntity = NULL;
04223 #endif /* XML_DTD */
04224       break;
04225     case XML_ROLE_NOTATION_NAME:
04226       declNotationPublicId = NULL;
04227       declNotationName = NULL;
04228       if (notationDeclHandler) {
04229         declNotationName = poolStoreString(&tempPool, enc, s, next);
04230         if (!declNotationName)
04231           return XML_ERROR_NO_MEMORY;
04232         poolFinish(&tempPool);
04233         handleDefault = XML_FALSE;
04234       }
04235       break;
04236     case XML_ROLE_NOTATION_PUBLIC_ID:
04237       if (!XmlIsPublicId(enc, s, next, eventPP))
04238         return XML_ERROR_PUBLICID;
04239       if (declNotationName) {  /* means notationDeclHandler != NULL */
04240         XML_Char *tem = poolStoreString(&tempPool,
04241                                         enc,
04242                                         s + enc->minBytesPerChar,
04243                                         next - enc->minBytesPerChar);
04244         if (!tem)
04245           return XML_ERROR_NO_MEMORY;
04246         normalizePublicId(tem);
04247         declNotationPublicId = tem;
04248         poolFinish(&tempPool);
04249         handleDefault = XML_FALSE;
04250       }
04251       break;
04252     case XML_ROLE_NOTATION_SYSTEM_ID:
04253       if (declNotationName && notationDeclHandler) {
04254         const XML_Char *systemId
04255           = poolStoreString(&tempPool, enc,
04256                             s + enc->minBytesPerChar,
04257                             next - enc->minBytesPerChar);
04258         if (!systemId)
04259           return XML_ERROR_NO_MEMORY;
04260         *eventEndPP = s;
04261         notationDeclHandler(handlerArg,
04262                             declNotationName,
04263                             curBase,
04264                             systemId,
04265                             declNotationPublicId);
04266         handleDefault = XML_FALSE;
04267       }
04268       poolClear(&tempPool);
04269       break;
04270     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
04271       if (declNotationPublicId && notationDeclHandler) {
04272         *eventEndPP = s;
04273         notationDeclHandler(handlerArg,
04274                             declNotationName,
04275                             curBase,
04276                             0,
04277                             declNotationPublicId);
04278         handleDefault = XML_FALSE;
04279       }
04280       poolClear(&tempPool);
04281       break;
04282     case XML_ROLE_ERROR:
04283       switch (tok) {
04284       case XML_TOK_PARAM_ENTITY_REF:
04285         /* PE references in internal subset are
04286            not allowed within declarations. */  
04287         return XML_ERROR_PARAM_ENTITY_REF;
04288       case XML_TOK_XML_DECL:
04289         return XML_ERROR_MISPLACED_XML_PI;
04290       default:
04291         return XML_ERROR_SYNTAX;
04292       }
04293 #ifdef XML_DTD
04294     case XML_ROLE_IGNORE_SECT:
04295       {
04296         enum XML_Error result;
04297         if (defaultHandler)
04298           reportDefault(parser, enc, s, next);
04299         handleDefault = XML_FALSE;
04300         result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
04301         if (result != XML_ERROR_NONE)
04302           return result;
04303         else if (!next) {
04304           processor = ignoreSectionProcessor;
04305           return result;
04306         }
04307       }
04308       break;
04309 #endif /* XML_DTD */
04310     case XML_ROLE_GROUP_OPEN:
04311       if (prologState.level >= groupSize) {
04312         if (groupSize) {
04313           char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
04314           if (temp == NULL)
04315             return XML_ERROR_NO_MEMORY;
04316           groupConnector = temp;
04317           if (dtd->scaffIndex) {
04318             int *temp = (int *)REALLOC(dtd->scaffIndex,
04319                           groupSize * sizeof(int));
04320             if (temp == NULL)
04321               return XML_ERROR_NO_MEMORY;
04322             dtd->scaffIndex = temp;
04323           }
04324         }
04325         else {
04326           groupConnector = (char *)MALLOC(groupSize = 32);
04327           if (!groupConnector)
04328             return XML_ERROR_NO_MEMORY;
04329         }
04330       }
04331       groupConnector[prologState.level] = 0;
04332       if (dtd->in_eldecl) {
04333         int myindex = nextScaffoldPart(parser);
04334         if (myindex < 0)
04335           return XML_ERROR_NO_MEMORY;
04336         dtd->scaffIndex[dtd->scaffLevel] = myindex;
04337         dtd->scaffLevel++;
04338         dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
04339         if (elementDeclHandler)
04340           handleDefault = XML_FALSE;
04341       }
04342       break;
04343     case XML_ROLE_GROUP_SEQUENCE:
04344       if (groupConnector[prologState.level] == ASCII_PIPE)
04345         return XML_ERROR_SYNTAX;
04346       groupConnector[prologState.level] = ASCII_COMMA;
04347       if (dtd->in_eldecl && elementDeclHandler)
04348         handleDefault = XML_FALSE;
04349       break;
04350     case XML_ROLE_GROUP_CHOICE:
04351       if (groupConnector[prologState.level] == ASCII_COMMA)
04352         return XML_ERROR_SYNTAX;
04353       if (dtd->in_eldecl
04354           && !groupConnector[prologState.level]
04355           && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
04356               != XML_CTYPE_MIXED)
04357           ) {
04358         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
04359             = XML_CTYPE_CHOICE;
04360         if (elementDeclHandler)
04361           handleDefault = XML_FALSE;
04362       }
04363       groupConnector[prologState.level] = ASCII_PIPE;
04364       break;
04365     case XML_ROLE_PARAM_ENTITY_REF:
04366 #ifdef XML_DTD
04367     case XML_ROLE_INNER_PARAM_ENTITY_REF:
04368       dtd->hasParamEntityRefs = XML_TRUE;
04369       if (!paramEntityParsing)
04370         dtd->keepProcessing = dtd->standalone;
04371       else {
04372         const XML_Char *name;
04373         ENTITY *entity;
04374         name = poolStoreString(&dtd->pool, enc,
04375                                 s + enc->minBytesPerChar,
04376                                 next - enc->minBytesPerChar);
04377         if (!name)
04378           return XML_ERROR_NO_MEMORY;
04379         entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
04380         poolDiscard(&dtd->pool);
04381         /* first, determine if a check for an existing declaration is needed;
04382            if yes, check that the entity exists, and that it is internal,
04383            otherwise call the skipped entity handler
04384         */
04385         if (prologState.documentEntity &&
04386             (dtd->standalone
04387              ? !openInternalEntities
04388              : !dtd->hasParamEntityRefs)) {
04389           if (!entity)
04390             return XML_ERROR_UNDEFINED_ENTITY;
04391           else if (!entity->is_internal)
04392             return XML_ERROR_ENTITY_DECLARED_IN_PE;
04393         }
04394         else if (!entity) {
04395           dtd->keepProcessing = dtd->standalone;
04396           /* cannot report skipped entities in declarations */
04397           if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
04398             skippedEntityHandler(handlerArg, name, 1);
04399             handleDefault = XML_FALSE;
04400           }
04401           break;
04402         }
04403         if (entity->open)
04404           return XML_ERROR_RECURSIVE_ENTITY_REF;
04405         if (entity->textPtr) {
04406           enum XML_Error result;
04407           XML_Bool betweenDecl = 
04408             (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
04409           result = processInternalEntity(parser, entity, betweenDecl);
04410           if (result != XML_ERROR_NONE)
04411             return result;
04412           handleDefault = XML_FALSE;
04413           break;
04414         }
04415         if (externalEntityRefHandler) {
04416           dtd->paramEntityRead = XML_FALSE;
04417           entity->open = XML_TRUE;
04418           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
04419                                         0,
04420                                         entity->base,
04421                                         entity->systemId,
04422                                         entity->publicId)) {
04423             entity->open = XML_FALSE;
04424             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
04425           }
04426           entity->open = XML_FALSE;
04427           handleDefault = XML_FALSE;
04428           if (!dtd->paramEntityRead) {
04429             dtd->keepProcessing = dtd->standalone;
04430             break;
04431           }
04432         }
04433         else {
04434           dtd->keepProcessing = dtd->standalone;
04435           break;
04436         }
04437       }
04438 #endif /* XML_DTD */
04439       if (!dtd->standalone &&
04440           notStandaloneHandler &&
04441           !notStandaloneHandler(handlerArg))
04442         return XML_ERROR_NOT_STANDALONE;
04443       break;
04444 
04445     /* Element declaration stuff */
04446 
04447     case XML_ROLE_ELEMENT_NAME:
04448       if (elementDeclHandler) {
04449         declElementType = getElementType(parser, enc, s, next);
04450         if (!declElementType)
04451           return XML_ERROR_NO_MEMORY;
04452         dtd->scaffLevel = 0;
04453         dtd->scaffCount = 0;
04454         dtd->in_eldecl = XML_TRUE;
04455         handleDefault = XML_FALSE;
04456       }
04457       break;
04458 
04459     case XML_ROLE_CONTENT_ANY:
04460     case XML_ROLE_CONTENT_EMPTY:
04461       if (dtd->in_eldecl) {
04462         if (elementDeclHandler) {
04463           XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
04464           if (!content)
04465             return XML_ERROR_NO_MEMORY;
04466           content->quant = XML_CQUANT_NONE;
04467           content->name = NULL;
04468           content->numchildren = 0;
04469           content->children = NULL;
04470           content->type = ((role == XML_ROLE_CONTENT_ANY) ?
04471                            XML_CTYPE_ANY :
04472                            XML_CTYPE_EMPTY);
04473           *eventEndPP = s;
04474           elementDeclHandler(handlerArg, declElementType->name, content);
04475           handleDefault = XML_FALSE;
04476         }
04477         dtd->in_eldecl = XML_FALSE;
04478       }
04479       break;
04480 
04481     case XML_ROLE_CONTENT_PCDATA:
04482       if (dtd->in_eldecl) {
04483         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
04484             = XML_CTYPE_MIXED;
04485         if (elementDeclHandler)
04486           handleDefault = XML_FALSE;
04487       }
04488       break;
04489 
04490     case XML_ROLE_CONTENT_ELEMENT:
04491       quant = XML_CQUANT_NONE;
04492       goto elementContent;
04493     case XML_ROLE_CONTENT_ELEMENT_OPT:
04494       quant = XML_CQUANT_OPT;
04495       goto elementContent;
04496     case XML_ROLE_CONTENT_ELEMENT_REP:
04497       quant = XML_CQUANT_REP;
04498       goto elementContent;
04499     case XML_ROLE_CONTENT_ELEMENT_PLUS:
04500       quant = XML_CQUANT_PLUS;
04501     elementContent:
04502       if (dtd->in_eldecl) {
04503         ELEMENT_TYPE *el;
04504         const XML_Char *name;
04505         int nameLen;
04506         const char *nxt = (quant == XML_CQUANT_NONE
04507                            ? next
04508                            : next - enc->minBytesPerChar);
04509         int myindex = nextScaffoldPart(parser);
04510         if (myindex < 0)
04511           return XML_ERROR_NO_MEMORY;
04512         dtd->scaffold[myindex].type = XML_CTYPE_NAME;
04513         dtd->scaffold[myindex].quant = quant;
04514         el = getElementType(parser, enc, s, nxt);
04515         if (!el)
04516           return XML_ERROR_NO_MEMORY;
04517         name = el->name;
04518         dtd->scaffold[myindex].name = name;
04519         nameLen = 0;
04520         for (; name[nameLen++]; );
04521         dtd->contentStringLen +=  nameLen;
04522         if (elementDeclHandler)
04523           handleDefault = XML_FALSE;
04524       }
04525       break;
04526 
04527     case XML_ROLE_GROUP_CLOSE:
04528       quant = XML_CQUANT_NONE;
04529       goto closeGroup;
04530     case XML_ROLE_GROUP_CLOSE_OPT:
04531       quant = XML_CQUANT_OPT;
04532       goto closeGroup;
04533     case XML_ROLE_GROUP_CLOSE_REP:
04534       quant = XML_CQUANT_REP;
04535       goto closeGroup;
04536     case XML_ROLE_GROUP_CLOSE_PLUS:
04537       quant = XML_CQUANT_PLUS;
04538     closeGroup:
04539       if (dtd->in_eldecl) {
04540         if (elementDeclHandler)
04541           handleDefault = XML_FALSE;
04542         dtd->scaffLevel--;
04543         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
04544         if (dtd->scaffLevel == 0) {
04545           if (!handleDefault) {
04546             XML_Content *model = build_model(parser);
04547             if (!model)
04548               return XML_ERROR_NO_MEMORY;
04549             *eventEndPP = s;
04550             elementDeclHandler(handlerArg, declElementType->name, model);
04551           }
04552           dtd->in_eldecl = XML_FALSE;
04553           dtd->contentStringLen = 0;
04554         }
04555       }
04556       break;
04557       /* End element declaration stuff */
04558 
04559     case XML_ROLE_PI:
04560       if (!reportProcessingInstruction(parser, enc, s, next))
04561         return XML_ERROR_NO_MEMORY;
04562       handleDefault = XML_FALSE;
04563       break;
04564     case XML_ROLE_COMMENT:
04565       if (!reportComment(parser, enc, s, next))
04566         return XML_ERROR_NO_MEMORY;
04567       handleDefault = XML_FALSE;
04568       break;
04569     case XML_ROLE_NONE:
04570       switch (tok) {
04571       case XML_TOK_BOM:
04572         handleDefault = XML_FALSE;
04573         break;
04574       }
04575       break;
04576     case XML_ROLE_DOCTYPE_NONE:
04577       if (startDoctypeDeclHandler)
04578         handleDefault = XML_FALSE;
04579       break;
04580     case XML_ROLE_ENTITY_NONE:
04581       if (dtd->keepProcessing && entityDeclHandler)
04582         handleDefault = XML_FALSE;
04583       break;
04584     case XML_ROLE_NOTATION_NONE:
04585       if (notationDeclHandler)
04586         handleDefault = XML_FALSE;
04587       break;
04588     case XML_ROLE_ATTLIST_NONE:
04589       if (dtd->keepProcessing && attlistDeclHandler)
04590         handleDefault = XML_FALSE;
04591       break;
04592     case XML_ROLE_ELEMENT_NONE:
04593       if (elementDeclHandler)
04594         handleDefault = XML_FALSE;
04595       break;
04596     } /* end of big switch */
04597 
04598     if (handleDefault && defaultHandler)
04599       reportDefault(parser, enc, s, next);
04600 
04601     switch (ps_parsing) {
04602     case XML_SUSPENDED: 
04603       *nextPtr = next;
04604       return XML_ERROR_NONE;
04605     case XML_FINISHED:
04606       return XML_ERROR_ABORTED;
04607     default:
04608       s = next;
04609       tok = XmlPrologTok(enc, s, end, &next);
04610     }
04611   }
04612   /* not reached */
04613 }
04614 
04615 static enum XML_Error PTRCALL
04616 epilogProcessor(XML_Parser parser,
04617                 const char *s,
04618                 const char *end,
04619                 const char **nextPtr)
04620 {
04621   processor = epilogProcessor;
04622   eventPtr = s;
04623   for (;;) {
04624     const char *next = NULL;
04625     int tok = XmlPrologTok(encoding, s, end, &next);
04626     eventEndPtr = next;
04627     switch (tok) {
04628     /* report partial linebreak - it might be the last token */
04629     case -XML_TOK_PROLOG_S:
04630       if (defaultHandler) {
04631         reportDefault(parser, encoding, s, next);
04632         if (ps_parsing == XML_FINISHED)
04633           return XML_ERROR_ABORTED;
04634       }
04635       *nextPtr = next;
04636       return XML_ERROR_NONE;
04637     case XML_TOK_NONE:
04638       *nextPtr = s;
04639       return XML_ERROR_NONE;
04640     case XML_TOK_PROLOG_S:
04641       if (defaultHandler)
04642         reportDefault(parser, encoding, s, next);
04643       break;
04644     case XML_TOK_PI:
04645       if (!reportProcessingInstruction(parser, encoding, s, next))
04646         return XML_ERROR_NO_MEMORY;
04647       break;
04648     case XML_TOK_COMMENT:
04649       if (!reportComment(parser, encoding, s, next))
04650         return XML_ERROR_NO_MEMORY;
04651       break;
04652     case XML_TOK_INVALID:
04653       eventPtr = next;
04654       return XML_ERROR_INVALID_TOKEN;
04655     case XML_TOK_PARTIAL:
04656       if (!ps_finalBuffer) {
04657         *nextPtr = s;
04658         return XML_ERROR_NONE;
04659       }
04660       return XML_ERROR_UNCLOSED_TOKEN;
04661     case XML_TOK_PARTIAL_CHAR:
04662       if (!ps_finalBuffer) {
04663         *nextPtr = s;
04664         return XML_ERROR_NONE;
04665       }
04666       return XML_ERROR_PARTIAL_CHAR;
04667     default:
04668       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
04669     }
04670     eventPtr = s = next;
04671     switch (ps_parsing) {
04672     case XML_SUSPENDED: 
04673       *nextPtr = next;
04674       return XML_ERROR_NONE;
04675     case XML_FINISHED:
04676       return XML_ERROR_ABORTED;
04677     default: ;
04678     }
04679   }
04680 }
04681 
04682 static enum XML_Error
04683 processInternalEntity(XML_Parser parser, ENTITY *entity,
04684                       XML_Bool betweenDecl)
04685 {
04686   const char *textStart, *textEnd;
04687   const char *next;
04688   enum XML_Error result;
04689   OPEN_INTERNAL_ENTITY *openEntity;
04690 
04691   if (freeInternalEntities) {
04692     openEntity = freeInternalEntities;
04693     freeInternalEntities = openEntity->next;
04694   }
04695   else {
04696     openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
04697     if (!openEntity)
04698       return XML_ERROR_NO_MEMORY;
04699   }
04700   entity->open = XML_TRUE;
04701   entity->processed = 0;
04702   openEntity->next = openInternalEntities;
04703   openInternalEntities = openEntity;
04704   openEntity->entity = entity;
04705   openEntity->startTagLevel = tagLevel;
04706   openEntity->betweenDecl = betweenDecl;
04707   openEntity->internalEventPtr = NULL;
04708   openEntity->internalEventEndPtr = NULL;
04709   textStart = (char *)entity->textPtr;
04710   textEnd = (char *)(entity->textPtr + entity->textLen);
04711 
04712 #ifdef XML_DTD
04713   if (entity->is_param) {
04714     int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
04715     result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
04716                       next, &next, XML_FALSE);
04717   }
04718   else 
04719 #endif /* XML_DTD */
04720     result = doContent(parser, tagLevel, internalEncoding, textStart, 
04721                        textEnd, &next, XML_FALSE);
04722 
04723   if (result == XML_ERROR_NONE) {
04724     if (textEnd != next && ps_parsing == XML_SUSPENDED) {
04725       entity->processed = (int)(next - textStart);
04726       processor = internalEntityProcessor;
04727     }
04728     else {
04729       entity->open = XML_FALSE;
04730       openInternalEntities = openEntity->next;
04731       /* put openEntity back in list of free instances */
04732       openEntity->next = freeInternalEntities;
04733       freeInternalEntities = openEntity;
04734     }
04735   }
04736   return result;
04737 }
04738 
04739 static enum XML_Error PTRCALL
04740 internalEntityProcessor(XML_Parser parser,
04741                         const char *s,
04742                         const char *end,
04743                         const char **nextPtr)
04744 {
04745   ENTITY *entity;
04746   const char *textStart, *textEnd;
04747   const char *next;
04748   enum XML_Error result;
04749   OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
04750   if (!openEntity)
04751     return XML_ERROR_UNEXPECTED_STATE;
04752 
04753   entity = openEntity->entity;
04754   textStart = ((char *)entity->textPtr) + entity->processed;
04755   textEnd = (char *)(entity->textPtr + entity->textLen);
04756 
04757 #ifdef XML_DTD
04758   if (entity->is_param) {
04759     int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
04760     result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
04761                       next, &next, XML_FALSE);
04762   }
04763   else
04764 #endif /* XML_DTD */
04765     result = doContent(parser, openEntity->startTagLevel, internalEncoding, 
04766                        textStart, textEnd, &next, XML_FALSE);  
04767 
04768   if (result != XML_ERROR_NONE)
04769     return result;
04770   else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
04771     entity->processed = (int)(next - (char *)entity->textPtr);
04772     return result;
04773   }
04774   else {
04775     entity->open = XML_FALSE;
04776     openInternalEntities = openEntity->next;
04777     /* put openEntity back in list of free instances */
04778     openEntity->next = freeInternalEntities;
04779     freeInternalEntities = openEntity;
04780   }
04781 
04782 #ifdef XML_DTD
04783   if (entity->is_param) {
04784     int tok;
04785     processor = prologProcessor;
04786     tok = XmlPrologTok(encoding, s, end, &next);
04787     return doProlog(parser, encoding, s, end, tok, next, nextPtr, 
04788                     (XML_Bool)!ps_finalBuffer);
04789   }
04790   else
04791 #endif /* XML_DTD */
04792   {
04793     processor = contentProcessor;
04794     /* see externalEntityContentProcessor vs contentProcessor */
04795     return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
04796                      nextPtr, (XML_Bool)!ps_finalBuffer); 
04797   }  
04798 }
04799 
04800 static enum XML_Error PTRCALL
04801 errorProcessor(XML_Parser parser,
04802                const char *s,
04803                const char *end,
04804                const char **nextPtr)
04805 {
04806   return errorCode;
04807 }
04808 
04809 static enum XML_Error
04810 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
04811                     const char *ptr, const char *end,
04812                     STRING_POOL *pool)
04813 {
04814   enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
04815                                                end, pool);
04816   if (result)
04817     return result;
04818   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
04819     poolChop(pool);
04820   if (!poolAppendChar(pool, XML_T('\0')))
04821     return XML_ERROR_NO_MEMORY;
04822   return XML_ERROR_NONE;
04823 }
04824 
04825 static enum XML_Error
04826 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
04827                      const char *ptr, const char *end,
04828                      STRING_POOL *pool)
04829 {
04830   DTD * const dtd = _dtd;  /* save one level of indirection */
04831   for (;;) {
04832     const char *next;
04833     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
04834     switch (tok) {
04835     case XML_TOK_NONE:
04836       return XML_ERROR_NONE;
04837     case XML_TOK_INVALID:
04838       if (enc == encoding)
04839         eventPtr = next;
04840       return XML_ERROR_INVALID_TOKEN;
04841     case XML_TOK_PARTIAL:
04842       if (enc == encoding)
04843         eventPtr = ptr;
04844       return XML_ERROR_INVALID_TOKEN;
04845     case XML_TOK_CHAR_REF:
04846       {
04847         XML_Char buf[XML_ENCODE_MAX];
04848         int i;
04849         int n = XmlCharRefNumber(enc, ptr);
04850         if (n < 0) {
04851           if (enc == encoding)
04852             eventPtr = ptr;
04853           return XML_ERROR_BAD_CHAR_REF;
04854         }
04855         if (!isCdata
04856             && n == 0x20 /* space */
04857             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
04858           break;
04859         n = XmlEncode(n, (ICHAR *)buf);
04860         if (!n) {
04861           if (enc == encoding)
04862             eventPtr = ptr;
04863           return XML_ERROR_BAD_CHAR_REF;
04864         }
04865         for (i = 0; i < n; i++) {
04866           if (!poolAppendChar(pool, buf[i]))
04867             return XML_ERROR_NO_MEMORY;
04868         }
04869       }
04870       break;
04871     case XML_TOK_DATA_CHARS:
04872       if (!poolAppend(pool, enc, ptr, next))
04873         return XML_ERROR_NO_MEMORY;
04874       break;
04875     case XML_TOK_TRAILING_CR:
04876       next = ptr + enc->minBytesPerChar;
04877       /* fall through */
04878     case XML_TOK_ATTRIBUTE_VALUE_S:
04879     case XML_TOK_DATA_NEWLINE:
04880       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
04881         break;
04882       if (!poolAppendChar(pool, 0x20))
04883         return XML_ERROR_NO_MEMORY;
04884       break;
04885     case XML_TOK_ENTITY_REF:
04886       {
04887         const XML_Char *name;
04888         ENTITY *entity;
04889         char checkEntityDecl;
04890         XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
04891                                               ptr + enc->minBytesPerChar,
04892                                               next - enc->minBytesPerChar);
04893         if (ch) {
04894           if (!poolAppendChar(pool, ch))
04895                 return XML_ERROR_NO_MEMORY;
04896           break;
04897         }
04898         name = poolStoreString(&temp2Pool, enc,
04899                                ptr + enc->minBytesPerChar,
04900                                next - enc->minBytesPerChar);
04901         if (!name)
04902           return XML_ERROR_NO_MEMORY;
04903         entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
04904         poolDiscard(&temp2Pool);
04905         /* First, determine if a check for an existing declaration is needed;
04906            if yes, check that the entity exists, and that it is internal.
04907         */
04908         if (pool == &dtd->pool)  /* are we called from prolog? */
04909           checkEntityDecl =
04910 #ifdef XML_DTD
04911               prologState.documentEntity &&
04912 #endif /* XML_DTD */
04913               (dtd->standalone
04914                ? !openInternalEntities
04915                : !dtd->hasParamEntityRefs);
04916         else /* if (pool == &tempPool): we are called from content */
04917           checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
04918         if (checkEntityDecl) {
04919           if (!entity)
04920             return XML_ERROR_UNDEFINED_ENTITY;
04921           else if (!entity->is_internal)
04922             return XML_ERROR_ENTITY_DECLARED_IN_PE;
04923         }
04924         else if (!entity) {
04925           /* Cannot report skipped entity here - see comments on
04926              skippedEntityHandler.
04927           if (skippedEntityHandler)
04928             skippedEntityHandler(handlerArg, name, 0);
04929           */
04930           /* Cannot call the default handler because this would be
04931              out of sync with the call to the startElementHandler.
04932           if ((pool == &tempPool) && defaultHandler)
04933             reportDefault(parser, enc, ptr, next);
04934           */
04935           break;
04936         }
04937         if (entity->open) {
04938           if (enc == encoding)
04939             eventPtr = ptr;
04940           return XML_ERROR_RECURSIVE_ENTITY_REF;
04941         }
04942         if (entity->notation) {
04943           if (enc == encoding)
04944             eventPtr = ptr;
04945           return XML_ERROR_BINARY_ENTITY_REF;
04946         }
04947         if (!entity->textPtr) {
04948           if (enc == encoding)
04949             eventPtr = ptr;
04950               return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
04951         }
04952         else {
04953           enum XML_Error result;
04954           const XML_Char *textEnd = entity->textPtr + entity->textLen;
04955           entity->open = XML_TRUE;
04956           result = appendAttributeValue(parser, internalEncoding, isCdata,
04957                                         (char *)entity->textPtr,
04958                                         (char *)textEnd, pool);
04959           entity->open = XML_FALSE;
04960           if (result)
04961             return result;
04962         }
04963       }
04964       break;
04965     default:
04966       if (enc == encoding)
04967         eventPtr = ptr;
04968       return XML_ERROR_UNEXPECTED_STATE;
04969     }
04970     ptr = next;
04971   }
04972   /* not reached */
04973 }
04974 
04975 static enum XML_Error
04976 storeEntityValue(XML_Parser parser,
04977                  const ENCODING *enc,
04978                  const char *entityTextPtr,
04979                  const char *entityTextEnd)
04980 {
04981   DTD * const dtd = _dtd;  /* save one level of indirection */
04982   STRING_POOL *pool = &(dtd->entityValuePool);
04983   enum XML_Error result = XML_ERROR_NONE;
04984 #ifdef XML_DTD
04985   int oldInEntityValue = prologState.inEntityValue;
04986   prologState.inEntityValue = 1;
04987 #endif /* XML_DTD */
04988   /* never return Null for the value argument in EntityDeclHandler,
04989      since this would indicate an external entity; therefore we
04990      have to make sure that entityValuePool.start is not null */
04991   if (!pool->blocks) {
04992     if (!poolGrow(pool))
04993       return XML_ERROR_NO_MEMORY;
04994   }
04995 
04996   for (;;) {
04997     const char *next;
04998     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
04999     switch (tok) {
05000     case XML_TOK_PARAM_ENTITY_REF:
05001 #ifdef XML_DTD
05002       if (isParamEntity || enc != encoding) {
05003         const XML_Char *name;
05004         ENTITY *entity;
05005         name = poolStoreString(&tempPool, enc,
05006                                entityTextPtr + enc->minBytesPerChar,
05007                                next - enc->minBytesPerChar);
05008         if (!name) {
05009           result = XML_ERROR_NO_MEMORY;
05010           goto endEntityValue;
05011         }
05012         entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
05013         poolDiscard(&tempPool);
05014         if (!entity) {
05015           /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
05016           /* cannot report skipped entity here - see comments on
05017              skippedEntityHandler
05018           if (skippedEntityHandler)
05019             skippedEntityHandler(handlerArg, name, 0);
05020           */
05021           dtd->keepProcessing = dtd->standalone;
05022           goto endEntityValue;
05023         }
05024         if (entity->open) {
05025           if (enc == encoding)
05026             eventPtr = entityTextPtr;
05027           result = XML_ERROR_RECURSIVE_ENTITY_REF;
05028           goto endEntityValue;
05029         }
05030         if (entity->systemId) {
05031           if (externalEntityRefHandler) {
05032             dtd->paramEntityRead = XML_FALSE;
05033             entity->open = XML_TRUE;
05034             if (!externalEntityRefHandler(externalEntityRefHandlerArg,
05035                                           0,
05036                                           entity->base,
05037                                           entity->systemId,
05038                                           entity->publicId)) {
05039               entity->open = XML_FALSE;
05040               result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
05041               goto endEntityValue;
05042             }
05043             entity->open = XML_FALSE;
05044             if (!dtd->paramEntityRead)
05045               dtd->keepProcessing = dtd->standalone;
05046           }
05047           else
05048             dtd->keepProcessing = dtd->standalone;
05049         }
05050         else {
05051           entity->open = XML_TRUE;
05052           result = storeEntityValue(parser,
05053                                     internalEncoding,
05054                                     (char *)entity->textPtr,
05055                                     (char *)(entity->textPtr
05056                                              + entity->textLen));
05057           entity->open = XML_FALSE;
05058           if (result)
05059             goto endEntityValue;
05060         }
05061         break;
05062       }
05063 #endif /* XML_DTD */
05064       /* In the internal subset, PE references are not legal
05065          within markup declarations, e.g entity values in this case. */
05066       eventPtr = entityTextPtr;
05067       result = XML_ERROR_PARAM_ENTITY_REF;
05068       goto endEntityValue;
05069     case XML_TOK_NONE:
05070       result = XML_ERROR_NONE;
05071       goto endEntityValue;
05072     case XML_TOK_ENTITY_REF:
05073     case XML_TOK_DATA_CHARS:
05074       if (!poolAppend(pool, enc, entityTextPtr, next)) {
05075         result = XML_ERROR_NO_MEMORY;
05076         goto endEntityValue;
05077       }
05078       break;
05079     case XML_TOK_TRAILING_CR:
05080       next = entityTextPtr + enc->minBytesPerChar;
05081       /* fall through */
05082     case XML_TOK_DATA_NEWLINE:
05083       if (pool->end == pool->ptr && !poolGrow(pool)) {
05084               result = XML_ERROR_NO_MEMORY;
05085         goto endEntityValue;
05086       }
05087       *(pool->ptr)++ = 0xA;
05088       break;
05089     case XML_TOK_CHAR_REF:
05090       {
05091         XML_Char buf[XML_ENCODE_MAX];
05092         int i;
05093         int n = XmlCharRefNumber(enc, entityTextPtr);
05094         if (n < 0) {
05095           if (enc == encoding)
05096             eventPtr = entityTextPtr;
05097           result = XML_ERROR_BAD_CHAR_REF;
05098           goto endEntityValue;
05099         }
05100         n = XmlEncode(n, (ICHAR *)buf);
05101         if (!n) {
05102           if (enc == encoding)
05103             eventPtr = entityTextPtr;
05104           result = XML_ERROR_BAD_CHAR_REF;
05105           goto endEntityValue;
05106         }
05107         for (i = 0; i < n; i++) {
05108           if (pool->end == pool->ptr && !poolGrow(pool)) {
05109             result = XML_ERROR_NO_MEMORY;
05110             goto endEntityValue;
05111           }
05112           *(pool->ptr)++ = buf[i];
05113         }
05114       }
05115       break;
05116     case XML_TOK_PARTIAL:
05117       if (enc == encoding)
05118         eventPtr = entityTextPtr;
05119       result = XML_ERROR_INVALID_TOKEN;
05120       goto endEntityValue;
05121     case XML_TOK_INVALID:
05122       if (enc == encoding)
05123         eventPtr = next;
05124       result = XML_ERROR_INVALID_TOKEN;
05125       goto endEntityValue;
05126     default:
05127       if (enc == encoding)
05128         eventPtr = entityTextPtr;
05129       result = XML_ERROR_UNEXPECTED_STATE;
05130       goto endEntityValue;
05131     }
05132     entityTextPtr = next;
05133   }
05134 endEntityValue:
05135 #ifdef XML_DTD
05136   prologState.inEntityValue = oldInEntityValue;
05137 #endif /* XML_DTD */
05138   return result;
05139 }
05140 
05141 static void FASTCALL
05142 normalizeLines(XML_Char *s)
05143 {
05144   XML_Char *p;
05145   for (;; s++) {
05146     if (*s == XML_T('\0'))
05147       return;
05148     if (*s == 0xD)
05149       break;
05150   }
05151   p = s;
05152   do {
05153     if (*s == 0xD) {
05154       *p++ = 0xA;
05155       if (*++s == 0xA)
05156         s++;
05157     }
05158     else
05159       *p++ = *s++;
05160   } while (*s);
05161   *p = XML_T('\0');
05162 }
05163 
05164 static int
05165 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
05166                             const char *start, const char *end)
05167 {
05168   const XML_Char *target;
05169   XML_Char *data;
05170   const char *tem;
05171   if (!processingInstructionHandler) {
05172     if (defaultHandler)
05173       reportDefault(parser, enc, start, end);
05174     return 1;
05175   }
05176   start += enc->minBytesPerChar * 2;
05177   tem = start + XmlNameLength(enc, start);
05178   target = poolStoreString(&tempPool, enc, start, tem);
05179   if (!target)
05180     return 0;
05181   poolFinish(&tempPool);
05182   data = poolStoreString(&tempPool, enc,
05183                         XmlSkipS(enc, tem),
05184                         end - enc->minBytesPerChar*2);
05185   if (!data)
05186     return 0;
05187   normalizeLines(data);
05188   processingInstructionHandler(handlerArg, target, data);
05189   poolClear(&tempPool);
05190   return 1;
05191 }
05192 
05193 static int
05194 reportComment(XML_Parser parser, const ENCODING *enc,
05195               const char *start, const char *end)
05196 {
05197   XML_Char *data;
05198   if (!commentHandler) {
05199     if (defaultHandler)
05200       reportDefault(parser, enc, start, end);
05201     return 1;
05202   }
05203   data = poolStoreString(&tempPool,
05204                          enc,
05205                          start + enc->minBytesPerChar * 4,
05206                          end - enc->minBytesPerChar * 3);
05207   if (!data)
05208     return 0;
05209   normalizeLines(data);
05210   commentHandler(handlerArg, data);
05211   poolClear(&tempPool);
05212   return 1;
05213 }
05214 
05215 static void
05216 reportDefault(XML_Parser parser, const ENCODING *enc,
05217               const char *s, const char *end)
05218 {
05219   if (MUST_CONVERT(enc, s)) {
05220     const char **eventPP;
05221     const char **eventEndPP;
05222     if (enc == encoding) {
05223       eventPP = &eventPtr;
05224       eventEndPP = &eventEndPtr;
05225     }
05226     else {
05227       eventPP = &(openInternalEntities->internalEventPtr);
05228       eventEndPP = &(openInternalEntities->internalEventEndPtr);
05229     }
05230     do {
05231       ICHAR *dataPtr = (ICHAR *)dataBuf;
05232       XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
05233       *eventEndPP = s;
05234       defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
05235       *eventPP = s;
05236     } while (s != end);
05237   }
05238   else
05239     defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
05240 }
05241 
05242 
05243 static int
05244 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
05245                 XML_Bool isId, const XML_Char *value, XML_Parser parser)
05246 {
05247   DEFAULT_ATTRIBUTE *att;
05248   if (value || isId) {
05249     /* The handling of default attributes gets messed up if we have
05250        a default which duplicates a non-default. */
05251     int i;
05252     for (i = 0; i < type->nDefaultAtts; i++)
05253       if (attId == type->defaultAtts[i].id)
05254         return 1;
05255     if (isId && !type->idAtt && !attId->xmlns)
05256       type->idAtt = attId;
05257   }
05258   if (type->nDefaultAtts == type->allocDefaultAtts) {
05259     if (type->allocDefaultAtts == 0) {
05260       type->allocDefaultAtts = 8;
05261       type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
05262                             * sizeof(DEFAULT_ATTRIBUTE));
05263       if (!type->defaultAtts)
05264         return 0;
05265     }
05266     else {
05267       DEFAULT_ATTRIBUTE *temp;
05268       int count = type->allocDefaultAtts * 2;
05269       temp = (DEFAULT_ATTRIBUTE *)
05270         REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
05271       if (temp == NULL)
05272         return 0;
05273       type->allocDefaultAtts = count;
05274       type->defaultAtts = temp;
05275     }
05276   }
05277   att = type->defaultAtts + type->nDefaultAtts;
05278   att->id = attId;
05279   att->value = value;
05280   att->isCdata = isCdata;
05281   if (!isCdata)
05282     attId->maybeTokenized = XML_TRUE;
05283   type->nDefaultAtts += 1;
05284   return 1;
05285 }
05286 
05287 static int
05288 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
05289 {
05290   DTD * const dtd = _dtd;  /* save one level of indirection */
05291   const XML_Char *name;
05292   for (name = elementType->name; *name; name++) {
05293     if (*name == XML_T(ASCII_COLON)) {
05294       PREFIX *prefix;
05295       const XML_Char *s;
05296       for (s = elementType->name; s != name; s++) {
05297         if (!poolAppendChar(&dtd->pool, *s))
05298           return 0;
05299       }
05300       if (!poolAppendChar(&dtd->pool, XML_T('\0')))
05301         return 0;
05302       prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
05303                                 sizeof(PREFIX));
05304       if (!prefix)
05305         return 0;
05306       if (prefix->name == poolStart(&dtd->pool))
05307         poolFinish(&dtd->pool);
05308       else
05309         poolDiscard(&dtd->pool);
05310       elementType->prefix = prefix;
05311 
05312     }
05313   }
05314   return 1;
05315 }
05316 
05317 static ATTRIBUTE_ID *
05318 getAttributeId(XML_Parser parser, const ENCODING *enc,
05319                const char *start, const char *end)
05320 {
05321   DTD * const dtd = _dtd;  /* save one level of indirection */
05322   ATTRIBUTE_ID *id;
05323   const XML_Char *name;
05324   if (!poolAppendChar(&dtd->pool, XML_T('\0')))
05325     return NULL;
05326   name = poolStoreString(&dtd->pool, enc, start, end);
05327   if (!name)
05328     return NULL;
05329   /* skip quotation mark - its storage will be re-used (like in name[-1]) */
05330   ++name;
05331   id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
05332   if (!id)
05333     return NULL;
05334   if (id->name != name)
05335     poolDiscard(&dtd->pool);
05336   else {
05337     poolFinish(&dtd->pool);
05338     if (!ns)
05339       ;
05340     else if (name[0] == XML_T(ASCII_x)
05341         && name[1] == XML_T(ASCII_m)
05342         && name[2] == XML_T(ASCII_l)
05343         && name[3] == XML_T(ASCII_n)
05344         && name[4] == XML_T(ASCII_s)
05345         && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
05346       if (name[5] == XML_T('\0'))
05347         id->prefix = &dtd->defaultPrefix;
05348       else
05349         id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
05350       id->xmlns = XML_TRUE;
05351     }
05352     else {
05353       int i;
05354       for (i = 0; name[i]; i++) {
05355         /* attributes without prefix are *not* in the default namespace */
05356         if (name[i] == XML_T(ASCII_COLON)) {
05357           int j;
05358           for (j = 0; j < i; j++) {
05359             if (!poolAppendChar(&dtd->pool, name[j]))
05360               return NULL;
05361           }
05362           if (!poolAppendChar(&dtd->pool, XML_T('\0')))
05363             return NULL;
05364           id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
05365                                         sizeof(PREFIX));
05366           if (id->prefix->name == poolStart(&dtd->pool))
05367             poolFinish(&dtd->pool);
05368           else
05369             poolDiscard(&dtd->pool);
05370           break;
05371         }
05372       }
05373     }
05374   }
05375   return id;
05376 }
05377 
05378 #define CONTEXT_SEP XML_T(ASCII_FF)
05379 
05380 static const XML_Char *
05381 getContext(XML_Parser parser)
05382 {
05383   DTD * const dtd = _dtd;  /* save one level of indirection */
05384   HASH_TABLE_ITER iter;
05385   XML_Bool needSep = XML_FALSE;
05386 
05387   if (dtd->defaultPrefix.binding) {
05388     int i;
05389     int len;
05390     if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
05391       return NULL;
05392     len = dtd->defaultPrefix.binding->uriLen;
05393     if (namespaceSeparator)
05394       len--;
05395     for (i = 0; i < len; i++)
05396       if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
05397         return NULL;
05398     needSep = XML_TRUE;
05399   }
05400 
05401   hashTableIterInit(&iter, &(dtd->prefixes));
05402   for (;;) {
05403     int i;
05404     int len;
05405     const XML_Char *s;
05406     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
05407     if (!prefix)
05408       break;
05409     if (!prefix->binding)
05410       continue;
05411     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
05412       return NULL;
05413     for (s = prefix->name; *s; s++)
05414       if (!poolAppendChar(&tempPool, *s))
05415         return NULL;
05416     if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
05417       return NULL;
05418     len = prefix->binding->uriLen;
05419     if (namespaceSeparator)
05420       len--;
05421     for (i = 0; i < len; i++)
05422       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
05423         return NULL;
05424     needSep = XML_TRUE;
05425   }
05426 
05427 
05428   hashTableIterInit(&iter, &(dtd->generalEntities));
05429   for (;;) {
05430     const XML_Char *s;
05431     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
05432     if (!e)
05433       break;
05434     if (!e->open)
05435       continue;
05436     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
05437       return NULL;
05438     for (s = e->name; *s; s++)
05439       if (!poolAppendChar(&tempPool, *s))
05440         return 0;
05441     needSep = XML_TRUE;
05442   }
05443 
05444   if (!poolAppendChar(&tempPool, XML_T('\0')))
05445     return NULL;
05446   return tempPool.start;
05447 }
05448 
05449 static XML_Bool
05450 setContext(XML_Parser parser, const XML_Char *context)
05451 {
05452   DTD * const dtd = _dtd;  /* save one level of indirection */
05453   const XML_Char *s = context;
05454 
05455   while (*context != XML_T('\0')) {
05456     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
05457       ENTITY *e;
05458       if (!poolAppendChar(&tempPool, XML_T('\0')))
05459         return XML_FALSE;
05460       e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
05461       if (e)
05462         e->open = XML_TRUE;
05463       if (*s != XML_T('\0'))
05464         s++;
05465       context = s;
05466       poolDiscard(&tempPool);
05467     }
05468     else if (*s == XML_T(ASCII_EQUALS)) {
05469       PREFIX *prefix;
05470       if (poolLength(&tempPool) == 0)
05471         prefix = &dtd->defaultPrefix;
05472       else {
05473         if (!poolAppendChar(&tempPool, XML_T('\0')))
05474           return XML_FALSE;
05475         prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
05476                                   sizeof(PREFIX));
05477         if (!prefix)
05478           return XML_FALSE;
05479         if (prefix->name == poolStart(&tempPool)) {
05480           prefix->name = poolCopyString(&dtd->pool, prefix->name);
05481           if (!prefix->name)
05482             return XML_FALSE;
05483         }
05484         poolDiscard(&tempPool);
05485       }
05486       for (context = s + 1;
05487            *context != CONTEXT_SEP && *context != XML_T('\0');
05488            context++)
05489         if (!poolAppendChar(&tempPool, *context))
05490           return XML_FALSE;
05491       if (!poolAppendChar(&tempPool, XML_T('\0')))
05492         return XML_FALSE;
05493       if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
05494                      &inheritedBindings) != XML_ERROR_NONE)
05495         return XML_FALSE;
05496       poolDiscard(&tempPool);
05497       if (*context != XML_T('\0'))
05498         ++context;
05499       s = context;
05500     }
05501     else {
05502       if (!poolAppendChar(&tempPool, *s))
05503         return XML_FALSE;
05504       s++;
05505     }
05506   }
05507   return XML_TRUE;
05508 }
05509 
05510 static void FASTCALL
05511 normalizePublicId(XML_Char *publicId)
05512 {
05513   XML_Char *p = publicId;
05514   XML_Char *s;
05515   for (s = publicId; *s; s++) {
05516     switch (*s) {
05517     case 0x20:
05518     case 0xD:
05519     case 0xA:
05520       if (p != publicId && p[-1] != 0x20)
05521         *p++ = 0x20;
05522       break;
05523     default:
05524       *p++ = *s;
05525     }
05526   }
05527   if (p != publicId && p[-1] == 0x20)
05528     --p;
05529   *p = XML_T('\0');
05530 }
05531 
05532 static DTD *
05533 dtdCreate(const XML_Memory_Handling_Suite *ms)
05534 {
05535   DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
05536   if (p == NULL)
05537     return p;
05538   poolInit(&(p->pool), ms);
05539   poolInit(&(p->entityValuePool), ms);
05540   hashTableInit(&(p->generalEntities), ms);
05541   hashTableInit(&(p->elementTypes), ms);
05542   hashTableInit(&(p->attributeIds), ms);
05543   hashTableInit(&(p->prefixes), ms);
05544 #ifdef XML_DTD
05545   p->paramEntityRead = XML_FALSE;
05546   hashTableInit(&(p->paramEntities), ms);
05547 #endif /* XML_DTD */
05548   p->defaultPrefix.name = NULL;
05549   p->defaultPrefix.binding = NULL;
05550 
05551   p->in_eldecl = XML_FALSE;
05552   p->scaffIndex = NULL;
05553   p->scaffold = NULL;
05554   p->scaffLevel = 0;
05555   p->scaffSize = 0;
05556   p->scaffCount = 0;
05557   p->contentStringLen = 0;
05558 
05559   p->keepProcessing = XML_TRUE;
05560   p->hasParamEntityRefs = XML_FALSE;
05561   p->standalone = XML_FALSE;
05562   return p;
05563 }
05564 
05565 static void
05566 dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
05567 {
05568   HASH_TABLE_ITER iter;
05569   hashTableIterInit(&iter, &(p->elementTypes));
05570   for (;;) {
05571     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
05572     if (!e)
05573       break;
05574     if (e->allocDefaultAtts != 0)
05575       ms->free_fcn(e->defaultAtts);
05576   }
05577   hashTableClear(&(p->generalEntities));
05578 #ifdef XML_DTD
05579   p->paramEntityRead = XML_FALSE;
05580   hashTableClear(&(p->paramEntities));
05581 #endif /* XML_DTD */
05582   hashTableClear(&(p->elementTypes));
05583   hashTableClear(&(p->attributeIds));
05584   hashTableClear(&(p->prefixes));
05585   poolClear(&(p->pool));
05586   poolClear(&(p->entityValuePool));
05587   p->defaultPrefix.name = NULL;
05588   p->defaultPrefix.binding = NULL;
05589 
05590   p->in_eldecl = XML_FALSE;
05591 
05592   ms->free_fcn(p->scaffIndex);
05593   p->scaffIndex = NULL;
05594   ms->free_fcn(p->scaffold);
05595   p->scaffold = NULL;
05596 
05597   p->scaffLevel = 0;
05598   p->scaffSize = 0;
05599   p->scaffCount = 0;
05600   p->contentStringLen = 0;
05601 
05602   p->keepProcessing = XML_TRUE;
05603   p->hasParamEntityRefs = XML_FALSE;
05604   p->standalone = XML_FALSE;
05605 }
05606 
05607 static void
05608 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
05609 {
05610   HASH_TABLE_ITER iter;
05611   hashTableIterInit(&iter, &(p->elementTypes));
05612   for (;;) {
05613     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
05614     if (!e)
05615       break;
05616     if (e->allocDefaultAtts != 0)
05617       ms->free_fcn(e->defaultAtts);
05618   }
05619   hashTableDestroy(&(p->generalEntities));
05620 #ifdef XML_DTD
05621   hashTableDestroy(&(p->paramEntities));
05622 #endif /* XML_DTD */
05623   hashTableDestroy(&(p->elementTypes));
05624   hashTableDestroy(&(p->attributeIds));
05625   hashTableDestroy(&(p->prefixes));
05626   poolDestroy(&(p->pool));
05627   poolDestroy(&(p->entityValuePool));
05628   if (isDocEntity) {
05629     ms->free_fcn(p->scaffIndex);
05630     ms->free_fcn(p->scaffold);
05631   }
05632   ms->free_fcn(p);
05633 }
05634 
05635 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
05636    The new DTD has already been initialized.
05637 */
05638 static int
05639 dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
05640 {
05641   HASH_TABLE_ITER iter;
05642 
05643   /* Copy the prefix table. */
05644 
05645   hashTableIterInit(&iter, &(oldDtd->prefixes));
05646   for (;;) {
05647     const XML_Char *name;
05648     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
05649     if (!oldP)
05650       break;
05651     name = poolCopyString(&(newDtd->pool), oldP->name);
05652     if (!name)
05653       return 0;
05654     if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
05655       return 0;
05656   }
05657 
05658   hashTableIterInit(&iter, &(oldDtd->attributeIds));
05659 
05660   /* Copy the attribute id table. */
05661 
05662   for (;;) {
05663     ATTRIBUTE_ID *newA;
05664     const XML_Char *name;
05665     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
05666 
05667     if (!oldA)
05668       break;
05669     /* Remember to allocate the scratch byte before the name. */
05670     if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
05671       return 0;
05672     name = poolCopyString(&(newDtd->pool), oldA->name);
05673     if (!name)
05674       return 0;
05675     ++name;
05676     newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
05677                                   sizeof(ATTRIBUTE_ID));
05678     if (!newA)
05679       return 0;
05680     newA->maybeTokenized = oldA->maybeTokenized;
05681     if (oldA->prefix) {
05682       newA->xmlns = oldA->xmlns;
05683       if (oldA->prefix == &oldDtd->defaultPrefix)
05684         newA->prefix = &newDtd->defaultPrefix;
05685       else
05686         newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
05687                                         oldA->prefix->name, 0);
05688     }
05689   }
05690 
05691   /* Copy the element type table. */
05692 
05693   hashTableIterInit(&iter, &(oldDtd->elementTypes));
05694 
05695   for (;;) {
05696     int i;
05697     ELEMENT_TYPE *newE;
05698     const XML_Char *name;
05699     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
05700     if (!oldE)
05701       break;
05702     name = poolCopyString(&(newDtd->pool), oldE->name);
05703     if (!name)
05704       return 0;
05705     newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
05706                                   sizeof(ELEMENT_TYPE));
05707     if (!newE)
05708       return 0;
05709     if (oldE->nDefaultAtts) {
05710       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
05711           ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
05712       if (!newE->defaultAtts) {
05713         ms->free_fcn(newE);
05714         return 0;
05715       }
05716     }
05717     if (oldE->idAtt)
05718       newE->idAtt = (ATTRIBUTE_ID *)
05719           lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
05720     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
05721     if (oldE->prefix)
05722       newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
05723                                       oldE->prefix->name, 0);
05724     for (i = 0; i < newE->nDefaultAtts; i++) {
05725       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
05726           lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
05727       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
05728       if (oldE->defaultAtts[i].value) {
05729         newE->defaultAtts[i].value
05730             = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
05731         if (!newE->defaultAtts[i].value)
05732           return 0;
05733       }
05734       else
05735         newE->defaultAtts[i].value = NULL;
05736     }
05737   }
05738 
05739   /* Copy the entity tables. */
05740   if (!copyEntityTable(&(newDtd->generalEntities),
05741                        &(newDtd->pool),
05742                        &(oldDtd->generalEntities)))
05743       return 0;
05744 
05745 #ifdef XML_DTD
05746   if (!copyEntityTable(&(newDtd->paramEntities),
05747                        &(newDtd->pool),
05748                        &(oldDtd->paramEntities)))
05749       return 0;
05750   newDtd->paramEntityRead = oldDtd->paramEntityRead;
05751 #endif /* XML_DTD */
05752 
05753   newDtd->keepProcessing = oldDtd->keepProcessing;
05754   newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
05755   newDtd->standalone = oldDtd->standalone;
05756 
05757   /* Don't want deep copying for scaffolding */
05758   newDtd->in_eldecl = oldDtd->in_eldecl;
05759   newDtd->scaffold = oldDtd->scaffold;
05760   newDtd->contentStringLen = oldDtd->contentStringLen;
05761   newDtd->scaffSize = oldDtd->scaffSize;
05762   newDtd->scaffLevel = oldDtd->scaffLevel;
05763   newDtd->scaffIndex = oldDtd->scaffIndex;
05764 
05765   return 1;
05766 }  /* End dtdCopy */
05767 
05768 static int
05769 copyEntityTable(HASH_TABLE *newTable,
05770                 STRING_POOL *newPool,
05771                 const HASH_TABLE *oldTable)
05772 {
05773   HASH_TABLE_ITER iter;
05774   const XML_Char *cachedOldBase = NULL;
05775   const XML_Char *cachedNewBase = NULL;
05776 
05777   hashTableIterInit(&iter, oldTable);
05778 
05779   for (;;) {
05780     ENTITY *newE;
05781     const XML_Char *name;
05782     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
05783     if (!oldE)
05784       break;
05785     name = poolCopyString(newPool, oldE->name);
05786     if (!name)
05787       return 0;
05788     newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
05789     if (!newE)
05790       return 0;
05791     if (oldE->systemId) {
05792       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
05793       if (!tem)
05794         return 0;
05795       newE->systemId = tem;
05796       if (oldE->base) {
05797         if (oldE->base == cachedOldBase)
05798           newE->base = cachedNewBase;
05799         else {
05800           cachedOldBase = oldE->base;
05801           tem = poolCopyString(newPool, cachedOldBase);
05802           if (!tem)
05803             return 0;
05804           cachedNewBase = newE->base = tem;
05805         }
05806       }
05807       if (oldE->publicId) {
05808         tem = poolCopyString(newPool, oldE->publicId);
05809         if (!tem)
05810           return 0;
05811         newE->publicId = tem;
05812       }
05813     }
05814     else {
05815       const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
05816                                             oldE->textLen);
05817       if (!tem)
05818         return 0;
05819       newE->textPtr = tem;
05820       newE->textLen = oldE->textLen;
05821     }
05822     if (oldE->notation) {
05823       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
05824       if (!tem)
05825         return 0;
05826       newE->notation = tem;
05827     }
05828     newE->is_param = oldE->is_param;
05829     newE->is_internal = oldE->is_internal;
05830   }
05831   return 1;
05832 }
05833 
05834 #define INIT_POWER 6
05835 
05836 static XML_Bool FASTCALL
05837 keyeq(KEY s1, KEY s2)
05838 {
05839   for (; *s1 == *s2; s1++, s2++)
05840     if (*s1 == 0)
05841       return XML_TRUE;
05842   return XML_FALSE;
05843 }
05844 
05845 static unsigned long FASTCALL
05846 hash(KEY s)
05847 {
05848   unsigned long h = 0;
05849   while (*s)
05850     h = CHAR_HASH(h, *s++);
05851   return h;
05852 }
05853 
05854 static NAMED *
05855 lookup(HASH_TABLE *table, KEY name, size_t createSize)
05856 {
05857   size_t i;
05858   if (table->size == 0) {
05859     size_t tsize;
05860     if (!createSize)
05861       return NULL;
05862     table->power = INIT_POWER;
05863     /* table->size is a power of 2 */
05864     table->size = (size_t)1 << INIT_POWER;
05865     tsize = table->size * sizeof(NAMED *);
05866     table->v = (NAMED **)table->mem->malloc_fcn(tsize);
05867     if (!table->v) {
05868       table->size = 0;
05869       return NULL;
05870     }
05871     memset(table->v, 0, tsize);
05872     i = hash(name) & ((unsigned long)table->size - 1);
05873   }
05874   else {
05875     unsigned long h = hash(name);
05876     unsigned long mask = (unsigned long)table->size - 1;
05877     unsigned char step = 0;
05878     i = h & mask;
05879     while (table->v[i]) {
05880       if (keyeq(name, table->v[i]->name))
05881         return table->v[i];
05882       if (!step)
05883         step = PROBE_STEP(h, mask, table->power);
05884       i < step ? (i += table->size - step) : (i -= step);
05885     }
05886     if (!createSize)
05887       return NULL;
05888 
05889     /* check for overflow (table is half full) */
05890     if (table->used >> (table->power - 1)) {
05891       unsigned char newPower = table->power + 1;
05892       size_t newSize = (size_t)1 << newPower;
05893       unsigned long newMask = (unsigned long)newSize - 1;
05894       size_t tsize = newSize * sizeof(NAMED *);
05895       NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
05896       if (!newV)
05897         return NULL;
05898       memset(newV, 0, tsize);
05899       for (i = 0; i < table->size; i++)
05900         if (table->v[i]) {
05901           unsigned long newHash = hash(table->v[i]->name);
05902           size_t j = newHash & newMask;
05903           step = 0;
05904           while (newV[j]) {
05905             if (!step)
05906               step = PROBE_STEP(newHash, newMask, newPower);
05907             j < step ? (j += newSize - step) : (j -= step);
05908           }
05909           newV[j] = table->v[i];
05910         }
05911       table->mem->free_fcn(table->v);
05912       table->v = newV;
05913       table->power = newPower;
05914       table->size = newSize;
05915       i = h & newMask;
05916       step = 0;
05917       while (table->v[i]) {
05918         if (!step)
05919           step = PROBE_STEP(h, newMask, newPower);
05920         i < step ? (i += newSize - step) : (i -= step);
05921       }
05922     }
05923   }
05924   table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
05925   if (!table->v[i])
05926     return NULL;
05927   memset(table->v[i], 0, createSize);
05928   table->v[i]->name = name;
05929   (table->used)++;
05930   return table->v[i];
05931 }
05932 
05933 static void FASTCALL
05934 hashTableClear(HASH_TABLE *table)
05935 {
05936   size_t i;
05937   for (i = 0; i < table->size; i++) {
05938     table->mem->free_fcn(table->v[i]);
05939     table->v[i] = NULL;
05940   }
05941   table->used = 0;
05942 }
05943 
05944 static void FASTCALL
05945 hashTableDestroy(HASH_TABLE *table)
05946 {
05947   size_t i;
05948   for (i = 0; i < table->size; i++)
05949     table->mem->free_fcn(table->v[i]);
05950   table->mem->free_fcn(table->v);
05951 }
05952 
05953 static void FASTCALL
05954 hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
05955 {
05956   p->power = 0;
05957   p->size = 0;
05958   p->used = 0;
05959   p->v = NULL;
05960   p->mem = ms;
05961 }
05962 
05963 static void FASTCALL
05964 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
05965 {
05966   iter->p = table->v;
05967   iter->end = iter->p + table->size;
05968 }
05969 
05970 static NAMED * FASTCALL
05971 hashTableIterNext(HASH_TABLE_ITER *iter)
05972 {
05973   while (iter->p != iter->end) {
05974     NAMED *tem = *(iter->p)++;
05975     if (tem)
05976       return tem;
05977   }
05978   return NULL;
05979 }
05980 
05981 static void FASTCALL
05982 poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
05983 {
05984   pool->blocks = NULL;
05985   pool->freeBlocks = NULL;
05986   pool->start = NULL;
05987   pool->ptr = NULL;
05988   pool->end = NULL;
05989   pool->mem = ms;
05990 }
05991 
05992 static void FASTCALL
05993 poolClear(STRING_POOL *pool)
05994 {
05995   if (!pool->freeBlocks)
05996     pool->freeBlocks = pool->blocks;
05997   else {
05998     BLOCK *p = pool->blocks;
05999     while (p) {
06000       BLOCK *tem = p->next;
06001       p->next = pool->freeBlocks;
06002       pool->freeBlocks = p;
06003       p = tem;
06004     }
06005   }
06006   pool->blocks = NULL;
06007   pool->start = NULL;
06008   pool->ptr = NULL;
06009   pool->end = NULL;
06010 }
06011 
06012 static void FASTCALL
06013 poolDestroy(STRING_POOL *pool)
06014 {
06015   BLOCK *p = pool->blocks;
06016   while (p) {
06017     BLOCK *tem = p->next;
06018     pool->mem->free_fcn(p);
06019     p = tem;
06020   }
06021   p = pool->freeBlocks;
06022   while (p) {
06023     BLOCK *tem = p->next;
06024     pool->mem->free_fcn(p);
06025     p = tem;
06026   }
06027 }
06028 
06029 static XML_Char *
06030 poolAppend(STRING_POOL *pool, const ENCODING *enc,
06031            const char *ptr, const char *end)
06032 {
06033   if (!pool->ptr && !poolGrow(pool))
06034     return NULL;
06035   for (;;) {
06036     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
06037     if (ptr == end)
06038       break;
06039     if (!poolGrow(pool))
06040       return NULL;
06041   }
06042   return pool->start;
06043 }
06044 
06045 static const XML_Char * FASTCALL
06046 poolCopyString(STRING_POOL *pool, const XML_Char *s)
06047 {
06048   do {
06049     if (!poolAppendChar(pool, *s))
06050       return NULL;
06051   } while (*s++);
06052   s = pool->start;
06053   poolFinish(pool);
06054   return s;
06055 }
06056 
06057 static const XML_Char *
06058 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
06059 {
06060   if (!pool->ptr && !poolGrow(pool))
06061     return NULL;
06062   for (; n > 0; --n, s++) {
06063     if (!poolAppendChar(pool, *s))
06064       return NULL;
06065   }
06066   s = pool->start;
06067   poolFinish(pool);
06068   return s;
06069 }
06070 
06071 static const XML_Char * FASTCALL
06072 poolAppendString(STRING_POOL *pool, const XML_Char *s)
06073 {
06074   while (*s) {
06075     if (!poolAppendChar(pool, *s))
06076       return NULL;
06077     s++;
06078   }
06079   return pool->start;
06080 }
06081 
06082 static XML_Char *
06083 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
06084                 const char *ptr, const char *end)
06085 {
06086   if (!poolAppend(pool, enc, ptr, end))
06087     return NULL;
06088   if (pool->ptr == pool->end && !poolGrow(pool))
06089     return NULL;
06090   *(pool->ptr)++ = 0;
06091   return pool->start;
06092 }
06093 
06094 static XML_Bool FASTCALL
06095 poolGrow(STRING_POOL *pool)
06096 {
06097   if (pool->freeBlocks) {
06098     if (pool->start == 0) {
06099       pool->blocks = pool->freeBlocks;
06100       pool->freeBlocks = pool->freeBlocks->next;
06101       pool->blocks->next = NULL;
06102       pool->start = pool->blocks->s;
06103       pool->end = pool->start + pool->blocks->size;
06104       pool->ptr = pool->start;
06105       return XML_TRUE;
06106     }
06107     if (pool->end - pool->start < pool->freeBlocks->size) {
06108       BLOCK *tem = pool->freeBlocks->next;
06109       pool->freeBlocks->next = pool->blocks;
06110       pool->blocks = pool->freeBlocks;
06111       pool->freeBlocks = tem;
06112       memcpy(pool->blocks->s, pool->start,
06113              (pool->end - pool->start) * sizeof(XML_Char));
06114       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
06115       pool->start = pool->blocks->s;
06116       pool->end = pool->start + pool->blocks->size;
06117       return XML_TRUE;
06118     }
06119   }
06120   if (pool->blocks && pool->start == pool->blocks->s) {
06121     int blockSize = (int)(pool->end - pool->start)*2;
06122     pool->blocks = (BLOCK *)
06123       pool->mem->realloc_fcn(pool->blocks,
06124                              (offsetof(BLOCK, s)
06125                               + blockSize * sizeof(XML_Char)));
06126     if (pool->blocks == NULL)
06127       return XML_FALSE;
06128     pool->blocks->size = blockSize;
06129     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
06130     pool->start = pool->blocks->s;
06131     pool->end = pool->start + blockSize;
06132   }
06133   else {
06134     BLOCK *tem;
06135     int blockSize = (int)(pool->end - pool->start);
06136     if (blockSize < INIT_BLOCK_SIZE)
06137       blockSize = INIT_BLOCK_SIZE;
06138     else
06139       blockSize *= 2;
06140     tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
06141                                         + blockSize * sizeof(XML_Char));
06142     if (!tem)
06143       return XML_FALSE;
06144     tem->size = blockSize;
06145     tem->next = pool->blocks;
06146     pool->blocks = tem;
06147     if (pool->ptr != pool->start)
06148       memcpy(tem->s, pool->start,
06149              (pool->ptr - pool->start) * sizeof(XML_Char));
06150     pool->ptr = tem->s + (pool->ptr - pool->start);
06151     pool->start = tem->s;
06152     pool->end = tem->s + blockSize;
06153   }
06154   return XML_TRUE;
06155 }
06156 
06157 static int FASTCALL
06158 nextScaffoldPart(XML_Parser parser)
06159 {
06160   DTD * const dtd = _dtd;  /* save one level of indirection */
06161   CONTENT_SCAFFOLD * me;
06162   int next;
06163 
06164   if (!dtd->scaffIndex) {
06165     dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
06166     if (!dtd->scaffIndex)
06167       return -1;
06168     dtd->scaffIndex[0] = 0;
06169   }
06170 
06171   if (dtd->scaffCount >= dtd->scaffSize) {
06172     CONTENT_SCAFFOLD *temp;
06173     if (dtd->scaffold) {
06174       temp = (CONTENT_SCAFFOLD *)
06175         REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
06176       if (temp == NULL)
06177         return -1;
06178       dtd->scaffSize *= 2;
06179     }
06180     else {
06181       temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
06182                                         * sizeof(CONTENT_SCAFFOLD));
06183       if (temp == NULL)
06184         return -1;
06185       dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
06186     }
06187     dtd->scaffold = temp;
06188   }
06189   next = dtd->scaffCount++;
06190   me = &dtd->scaffold[next];
06191   if (dtd->scaffLevel) {
06192     CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
06193     if (parent->lastchild) {
06194       dtd->scaffold[parent->lastchild].nextsib = next;
06195     }
06196     if (!parent->childcnt)
06197       parent->firstchild = next;
06198     parent->lastchild = next;
06199     parent->childcnt++;
06200   }
06201   me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
06202   return next;
06203 }
06204 
06205 static void
06206 build_node(XML_Parser parser,
06207            int src_node,
06208            XML_Content *dest,
06209            XML_Content **contpos,
06210            XML_Char **strpos)
06211 {
06212   DTD * const dtd = _dtd;  /* save one level of indirection */
06213   dest->type = dtd->scaffold[src_node].type;
06214   dest->quant = dtd->scaffold[src_node].quant;
06215   if (dest->type == XML_CTYPE_NAME) {
06216     const XML_Char *src;
06217     dest->name = *strpos;
06218     src = dtd->scaffold[src_node].name;
06219     for (;;) {
06220       *(*strpos)++ = *src;
06221       if (!*src)
06222         break;
06223       src++;
06224     }
06225     dest->numchildren = 0;
06226     dest->children = NULL;
06227   }
06228   else {
06229     unsigned int i;
06230     int cn;
06231     dest->numchildren = dtd->scaffold[src_node].childcnt;
06232     dest->children = *contpos;
06233     *contpos += dest->numchildren;
06234     for (i = 0, cn = dtd->scaffold[src_node].firstchild;
06235          i < dest->numchildren;
06236          i++, cn = dtd->scaffold[cn].nextsib) {
06237       build_node(parser, cn, &(dest->children[i]), contpos, strpos);
06238     }
06239     dest->name = NULL;
06240   }
06241 }
06242 
06243 static XML_Content *
06244 build_model (XML_Parser parser)
06245 {
06246   DTD * const dtd = _dtd;  /* save one level of indirection */
06247   XML_Content *ret;
06248   XML_Content *cpos;
06249   XML_Char * str;
06250   int allocsize = (dtd->scaffCount * sizeof(XML_Content)
06251                    + (dtd->contentStringLen * sizeof(XML_Char)));
06252 
06253   ret = (XML_Content *)MALLOC(allocsize);
06254   if (!ret)
06255     return NULL;
06256 
06257   str =  (XML_Char *) (&ret[dtd->scaffCount]);
06258   cpos = &ret[1];
06259 
06260   build_node(parser, 0, ret, &cpos, &str);
06261   return ret;
06262 }
06263 
06264 static ELEMENT_TYPE *
06265 getElementType(XML_Parser parser,
06266                const ENCODING *enc,
06267                const char *ptr,
06268                const char *end)
06269 {
06270   DTD * const dtd = _dtd;  /* save one level of indirection */
06271   const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
06272   ELEMENT_TYPE *ret;
06273 
06274   if (!name)
06275     return NULL;
06276   ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
06277   if (!ret)
06278     return NULL;
06279   if (ret->name != name)
06280     poolDiscard(&dtd->pool);
06281   else {
06282     poolFinish(&dtd->pool);
06283     if (!setElementTypePrefix(parser, ret))
06284       return NULL;
06285   }
06286   return ret;
06287 }

Generated on Mon May 27 17:50:36 2013 for Geant4 by  doxygen 1.4.7