Annotation of embedaddon/expat/lib/xmlparse.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>