ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

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

Generated on Sat May 26 2012 04:32:24 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.