Annotation of embedaddon/expat/lib/xmlparse.c, revision 1.1.1.1.2.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;
1.1.1.1.2.1! misho    3706:       case -XML_TOK_PROLOG_S:
        !          3707:         tok = -tok;
        !          3708:         break;
1.1       misho    3709:       case XML_TOK_NONE:
                   3710: #ifdef XML_DTD
                   3711:         /* for internal PE NOT referenced between declarations */
                   3712:         if (enc != encoding && !openInternalEntities->betweenDecl) {
                   3713:           *nextPtr = s;
                   3714:           return XML_ERROR_NONE;
                   3715:         }
                   3716:         /* WFC: PE Between Declarations - must check that PE contains
                   3717:            complete markup, not only for external PEs, but also for
                   3718:            internal PEs if the reference occurs between declarations.
                   3719:         */
                   3720:         if (isParamEntity || enc != encoding) {
                   3721:           if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
                   3722:               == XML_ROLE_ERROR)
                   3723:             return XML_ERROR_INCOMPLETE_PE;
                   3724:           *nextPtr = s;
                   3725:           return XML_ERROR_NONE;
                   3726:         }
                   3727: #endif /* XML_DTD */
                   3728:         return XML_ERROR_NO_ELEMENTS;
                   3729:       default:
                   3730:         tok = -tok;
                   3731:         next = end;
                   3732:         break;
                   3733:       }
                   3734:     }
                   3735:     role = XmlTokenRole(&prologState, tok, s, next, enc);
                   3736:     switch (role) {
                   3737:     case XML_ROLE_XML_DECL:
                   3738:       {
                   3739:         enum XML_Error result = processXmlDecl(parser, 0, s, next);
                   3740:         if (result != XML_ERROR_NONE)
                   3741:           return result;
                   3742:         enc = encoding;
                   3743:         handleDefault = XML_FALSE;
                   3744:       }
                   3745:       break;
                   3746:     case XML_ROLE_DOCTYPE_NAME:
                   3747:       if (startDoctypeDeclHandler) {
                   3748:         doctypeName = poolStoreString(&tempPool, enc, s, next);
                   3749:         if (!doctypeName)
                   3750:           return XML_ERROR_NO_MEMORY;
                   3751:         poolFinish(&tempPool);
                   3752:         doctypePubid = NULL;
                   3753:         handleDefault = XML_FALSE;
                   3754:       }
                   3755:       doctypeSysid = NULL; /* always initialize to NULL */
                   3756:       break;
                   3757:     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
                   3758:       if (startDoctypeDeclHandler) {
                   3759:         startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
                   3760:                                 doctypePubid, 1);
                   3761:         doctypeName = NULL;
                   3762:         poolClear(&tempPool);
                   3763:         handleDefault = XML_FALSE;
                   3764:       }
                   3765:       break;
                   3766: #ifdef XML_DTD
                   3767:     case XML_ROLE_TEXT_DECL:
                   3768:       {
                   3769:         enum XML_Error result = processXmlDecl(parser, 1, s, next);
                   3770:         if (result != XML_ERROR_NONE)
                   3771:           return result;
                   3772:         enc = encoding;
                   3773:         handleDefault = XML_FALSE;
                   3774:       }
                   3775:       break;
                   3776: #endif /* XML_DTD */
                   3777:     case XML_ROLE_DOCTYPE_PUBLIC_ID:
                   3778: #ifdef XML_DTD
                   3779:       useForeignDTD = XML_FALSE;
                   3780:       declEntity = (ENTITY *)lookup(&dtd->paramEntities,
                   3781:                                     externalSubsetName,
                   3782:                                     sizeof(ENTITY));
                   3783:       if (!declEntity)
                   3784:         return XML_ERROR_NO_MEMORY;
                   3785: #endif /* XML_DTD */
                   3786:       dtd->hasParamEntityRefs = XML_TRUE;
                   3787:       if (startDoctypeDeclHandler) {
                   3788:         if (!XmlIsPublicId(enc, s, next, eventPP))
                   3789:           return XML_ERROR_PUBLICID;
                   3790:         doctypePubid = poolStoreString(&tempPool, enc,
                   3791:                                        s + enc->minBytesPerChar,
                   3792:                                        next - enc->minBytesPerChar);
                   3793:         if (!doctypePubid)
                   3794:           return XML_ERROR_NO_MEMORY;
                   3795:         normalizePublicId((XML_Char *)doctypePubid);
                   3796:         poolFinish(&tempPool);
                   3797:         handleDefault = XML_FALSE;
                   3798:         goto alreadyChecked;
                   3799:       }
                   3800:       /* fall through */
                   3801:     case XML_ROLE_ENTITY_PUBLIC_ID:
                   3802:       if (!XmlIsPublicId(enc, s, next, eventPP))
                   3803:         return XML_ERROR_PUBLICID;
                   3804:     alreadyChecked:
                   3805:       if (dtd->keepProcessing && declEntity) {
                   3806:         XML_Char *tem = poolStoreString(&dtd->pool,
                   3807:                                         enc,
                   3808:                                         s + enc->minBytesPerChar,
                   3809:                                         next - enc->minBytesPerChar);
                   3810:         if (!tem)
                   3811:           return XML_ERROR_NO_MEMORY;
                   3812:         normalizePublicId(tem);
                   3813:         declEntity->publicId = tem;
                   3814:         poolFinish(&dtd->pool);
                   3815:         if (entityDeclHandler)
                   3816:           handleDefault = XML_FALSE;
                   3817:       }
                   3818:       break;
                   3819:     case XML_ROLE_DOCTYPE_CLOSE:
                   3820:       if (doctypeName) {
                   3821:         startDoctypeDeclHandler(handlerArg, doctypeName,
                   3822:                                 doctypeSysid, doctypePubid, 0);
                   3823:         poolClear(&tempPool);
                   3824:         handleDefault = XML_FALSE;
                   3825:       }
                   3826:       /* doctypeSysid will be non-NULL in the case of a previous
                   3827:          XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
                   3828:          was not set, indicating an external subset
                   3829:       */
                   3830: #ifdef XML_DTD
                   3831:       if (doctypeSysid || useForeignDTD) {
                   3832:         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
                   3833:         dtd->hasParamEntityRefs = XML_TRUE;
                   3834:         if (paramEntityParsing && externalEntityRefHandler) {
                   3835:           ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
                   3836:                                             externalSubsetName,
                   3837:                                             sizeof(ENTITY));
                   3838:           if (!entity)
                   3839:             return XML_ERROR_NO_MEMORY;
                   3840:           if (useForeignDTD)
                   3841:             entity->base = curBase;
                   3842:           dtd->paramEntityRead = XML_FALSE;
                   3843:           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
                   3844:                                         0,
                   3845:                                         entity->base,
                   3846:                                         entity->systemId,
                   3847:                                         entity->publicId))
                   3848:             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
                   3849:           if (dtd->paramEntityRead) {
                   3850:             if (!dtd->standalone && 
                   3851:                 notStandaloneHandler && 
                   3852:                 !notStandaloneHandler(handlerArg))
                   3853:               return XML_ERROR_NOT_STANDALONE;
                   3854:           }
                   3855:           /* if we didn't read the foreign DTD then this means that there
                   3856:              is no external subset and we must reset dtd->hasParamEntityRefs
                   3857:           */
                   3858:           else if (!doctypeSysid)
                   3859:             dtd->hasParamEntityRefs = hadParamEntityRefs;
                   3860:           /* end of DTD - no need to update dtd->keepProcessing */
                   3861:         }
                   3862:         useForeignDTD = XML_FALSE;
                   3863:       }
                   3864: #endif /* XML_DTD */
                   3865:       if (endDoctypeDeclHandler) {
                   3866:         endDoctypeDeclHandler(handlerArg);
                   3867:         handleDefault = XML_FALSE;
                   3868:       }
                   3869:       break;
                   3870:     case XML_ROLE_INSTANCE_START:
                   3871: #ifdef XML_DTD
                   3872:       /* if there is no DOCTYPE declaration then now is the
                   3873:          last chance to read the foreign DTD
                   3874:       */
                   3875:       if (useForeignDTD) {
                   3876:         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
                   3877:         dtd->hasParamEntityRefs = XML_TRUE;
                   3878:         if (paramEntityParsing && externalEntityRefHandler) {
                   3879:           ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
                   3880:                                             externalSubsetName,
                   3881:                                             sizeof(ENTITY));
                   3882:           if (!entity)
                   3883:             return XML_ERROR_NO_MEMORY;
                   3884:           entity->base = curBase;
                   3885:           dtd->paramEntityRead = XML_FALSE;
                   3886:           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
                   3887:                                         0,
                   3888:                                         entity->base,
                   3889:                                         entity->systemId,
                   3890:                                         entity->publicId))
                   3891:             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
                   3892:           if (dtd->paramEntityRead) {
                   3893:             if (!dtd->standalone &&
                   3894:                 notStandaloneHandler &&
                   3895:                 !notStandaloneHandler(handlerArg))
                   3896:               return XML_ERROR_NOT_STANDALONE;
                   3897:           }
                   3898:           /* if we didn't read the foreign DTD then this means that there
                   3899:              is no external subset and we must reset dtd->hasParamEntityRefs
                   3900:           */
                   3901:           else
                   3902:             dtd->hasParamEntityRefs = hadParamEntityRefs;
                   3903:           /* end of DTD - no need to update dtd->keepProcessing */
                   3904:         }
                   3905:       }
                   3906: #endif /* XML_DTD */
                   3907:       processor = contentProcessor;
                   3908:       return contentProcessor(parser, s, end, nextPtr);
                   3909:     case XML_ROLE_ATTLIST_ELEMENT_NAME:
                   3910:       declElementType = getElementType(parser, enc, s, next);
                   3911:       if (!declElementType)
                   3912:         return XML_ERROR_NO_MEMORY;
                   3913:       goto checkAttListDeclHandler;
                   3914:     case XML_ROLE_ATTRIBUTE_NAME:
                   3915:       declAttributeId = getAttributeId(parser, enc, s, next);
                   3916:       if (!declAttributeId)
                   3917:         return XML_ERROR_NO_MEMORY;
                   3918:       declAttributeIsCdata = XML_FALSE;
                   3919:       declAttributeType = NULL;
                   3920:       declAttributeIsId = XML_FALSE;
                   3921:       goto checkAttListDeclHandler;
                   3922:     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
                   3923:       declAttributeIsCdata = XML_TRUE;
                   3924:       declAttributeType = atypeCDATA;
                   3925:       goto checkAttListDeclHandler;
                   3926:     case XML_ROLE_ATTRIBUTE_TYPE_ID:
                   3927:       declAttributeIsId = XML_TRUE;
                   3928:       declAttributeType = atypeID;
                   3929:       goto checkAttListDeclHandler;
                   3930:     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
                   3931:       declAttributeType = atypeIDREF;
                   3932:       goto checkAttListDeclHandler;
                   3933:     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
                   3934:       declAttributeType = atypeIDREFS;
                   3935:       goto checkAttListDeclHandler;
                   3936:     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
                   3937:       declAttributeType = atypeENTITY;
                   3938:       goto checkAttListDeclHandler;
                   3939:     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
                   3940:       declAttributeType = atypeENTITIES;
                   3941:       goto checkAttListDeclHandler;
                   3942:     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
                   3943:       declAttributeType = atypeNMTOKEN;
                   3944:       goto checkAttListDeclHandler;
                   3945:     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
                   3946:       declAttributeType = atypeNMTOKENS;
                   3947:     checkAttListDeclHandler:
                   3948:       if (dtd->keepProcessing && attlistDeclHandler)
                   3949:         handleDefault = XML_FALSE;
                   3950:       break;
                   3951:     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
                   3952:     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
                   3953:       if (dtd->keepProcessing && attlistDeclHandler) {
                   3954:         const XML_Char *prefix;
                   3955:         if (declAttributeType) {
                   3956:           prefix = enumValueSep;
                   3957:         }
                   3958:         else {
                   3959:           prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
                   3960:                     ? notationPrefix
                   3961:                     : enumValueStart);
                   3962:         }
                   3963:         if (!poolAppendString(&tempPool, prefix))
                   3964:           return XML_ERROR_NO_MEMORY;
                   3965:         if (!poolAppend(&tempPool, enc, s, next))
                   3966:           return XML_ERROR_NO_MEMORY;
                   3967:         declAttributeType = tempPool.start;
                   3968:         handleDefault = XML_FALSE;
                   3969:       }
                   3970:       break;
                   3971:     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
                   3972:     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
                   3973:       if (dtd->keepProcessing) {
                   3974:         if (!defineAttribute(declElementType, declAttributeId,
                   3975:                              declAttributeIsCdata, declAttributeIsId,
                   3976:                              0, parser))
                   3977:           return XML_ERROR_NO_MEMORY;
                   3978:         if (attlistDeclHandler && declAttributeType) {
                   3979:           if (*declAttributeType == XML_T(ASCII_LPAREN)
                   3980:               || (*declAttributeType == XML_T(ASCII_N)
                   3981:                   && declAttributeType[1] == XML_T(ASCII_O))) {
                   3982:             /* Enumerated or Notation type */
                   3983:             if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
                   3984:                 || !poolAppendChar(&tempPool, XML_T('\0')))
                   3985:               return XML_ERROR_NO_MEMORY;
                   3986:             declAttributeType = tempPool.start;
                   3987:             poolFinish(&tempPool);
                   3988:           }
                   3989:           *eventEndPP = s;
                   3990:           attlistDeclHandler(handlerArg, declElementType->name,
                   3991:                              declAttributeId->name, declAttributeType,
                   3992:                              0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
                   3993:           poolClear(&tempPool);
                   3994:           handleDefault = XML_FALSE;
                   3995:         }
                   3996:       }
                   3997:       break;
                   3998:     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
                   3999:     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
                   4000:       if (dtd->keepProcessing) {
                   4001:         const XML_Char *attVal;
                   4002:         enum XML_Error result =
                   4003:           storeAttributeValue(parser, enc, declAttributeIsCdata,
                   4004:                               s + enc->minBytesPerChar,
                   4005:                               next - enc->minBytesPerChar,
                   4006:                               &dtd->pool);
                   4007:         if (result)
                   4008:           return result;
                   4009:         attVal = poolStart(&dtd->pool);
                   4010:         poolFinish(&dtd->pool);
                   4011:         /* ID attributes aren't allowed to have a default */
                   4012:         if (!defineAttribute(declElementType, declAttributeId,
                   4013:                              declAttributeIsCdata, XML_FALSE, attVal, parser))
                   4014:           return XML_ERROR_NO_MEMORY;
                   4015:         if (attlistDeclHandler && declAttributeType) {
                   4016:           if (*declAttributeType == XML_T(ASCII_LPAREN)
                   4017:               || (*declAttributeType == XML_T(ASCII_N)
                   4018:                   && declAttributeType[1] == XML_T(ASCII_O))) {
                   4019:             /* Enumerated or Notation type */
                   4020:             if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
                   4021:                 || !poolAppendChar(&tempPool, XML_T('\0')))
                   4022:               return XML_ERROR_NO_MEMORY;
                   4023:             declAttributeType = tempPool.start;
                   4024:             poolFinish(&tempPool);
                   4025:           }
                   4026:           *eventEndPP = s;
                   4027:           attlistDeclHandler(handlerArg, declElementType->name,
                   4028:                              declAttributeId->name, declAttributeType,
                   4029:                              attVal,
                   4030:                              role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
                   4031:           poolClear(&tempPool);
                   4032:           handleDefault = XML_FALSE;
                   4033:         }
                   4034:       }
                   4035:       break;
                   4036:     case XML_ROLE_ENTITY_VALUE:
                   4037:       if (dtd->keepProcessing) {
                   4038:         enum XML_Error result = storeEntityValue(parser, enc,
                   4039:                                             s + enc->minBytesPerChar,
                   4040:                                             next - enc->minBytesPerChar);
                   4041:         if (declEntity) {
                   4042:           declEntity->textPtr = poolStart(&dtd->entityValuePool);
                   4043:           declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
                   4044:           poolFinish(&dtd->entityValuePool);
                   4045:           if (entityDeclHandler) {
                   4046:             *eventEndPP = s;
                   4047:             entityDeclHandler(handlerArg,
                   4048:                               declEntity->name,
                   4049:                               declEntity->is_param,
                   4050:                               declEntity->textPtr,
                   4051:                               declEntity->textLen,
                   4052:                               curBase, 0, 0, 0);
                   4053:             handleDefault = XML_FALSE;
                   4054:           }
                   4055:         }
                   4056:         else
                   4057:           poolDiscard(&dtd->entityValuePool);
                   4058:         if (result != XML_ERROR_NONE)
                   4059:           return result;
                   4060:       }
                   4061:       break;
                   4062:     case XML_ROLE_DOCTYPE_SYSTEM_ID:
                   4063: #ifdef XML_DTD
                   4064:       useForeignDTD = XML_FALSE;
                   4065: #endif /* XML_DTD */
                   4066:       dtd->hasParamEntityRefs = XML_TRUE;
                   4067:       if (startDoctypeDeclHandler) {
                   4068:         doctypeSysid = poolStoreString(&tempPool, enc,
                   4069:                                        s + enc->minBytesPerChar,
                   4070:                                        next - enc->minBytesPerChar);
                   4071:         if (doctypeSysid == NULL)
                   4072:           return XML_ERROR_NO_MEMORY;
                   4073:         poolFinish(&tempPool);
                   4074:         handleDefault = XML_FALSE;
                   4075:       }
                   4076: #ifdef XML_DTD
                   4077:       else
                   4078:         /* use externalSubsetName to make doctypeSysid non-NULL
                   4079:            for the case where no startDoctypeDeclHandler is set */
                   4080:         doctypeSysid = externalSubsetName;
                   4081: #endif /* XML_DTD */
                   4082:       if (!dtd->standalone
                   4083: #ifdef XML_DTD
                   4084:           && !paramEntityParsing
                   4085: #endif /* XML_DTD */
                   4086:           && notStandaloneHandler
                   4087:           && !notStandaloneHandler(handlerArg))
                   4088:         return XML_ERROR_NOT_STANDALONE;
                   4089: #ifndef XML_DTD
                   4090:       break;
                   4091: #else /* XML_DTD */
                   4092:       if (!declEntity) {
                   4093:         declEntity = (ENTITY *)lookup(&dtd->paramEntities,
                   4094:                                       externalSubsetName,
                   4095:                                       sizeof(ENTITY));
                   4096:         if (!declEntity)
                   4097:           return XML_ERROR_NO_MEMORY;
                   4098:         declEntity->publicId = NULL;
                   4099:       }
                   4100:       /* fall through */
                   4101: #endif /* XML_DTD */
                   4102:     case XML_ROLE_ENTITY_SYSTEM_ID:
                   4103:       if (dtd->keepProcessing && declEntity) {
                   4104:         declEntity->systemId = poolStoreString(&dtd->pool, enc,
                   4105:                                                s + enc->minBytesPerChar,
                   4106:                                                next - enc->minBytesPerChar);
                   4107:         if (!declEntity->systemId)
                   4108:           return XML_ERROR_NO_MEMORY;
                   4109:         declEntity->base = curBase;
                   4110:         poolFinish(&dtd->pool);
                   4111:         if (entityDeclHandler)
                   4112:           handleDefault = XML_FALSE;
                   4113:       }
                   4114:       break;
                   4115:     case XML_ROLE_ENTITY_COMPLETE:
                   4116:       if (dtd->keepProcessing && declEntity && entityDeclHandler) {
                   4117:         *eventEndPP = s;
                   4118:         entityDeclHandler(handlerArg,
                   4119:                           declEntity->name,
                   4120:                           declEntity->is_param,
                   4121:                           0,0,
                   4122:                           declEntity->base,
                   4123:                           declEntity->systemId,
                   4124:                           declEntity->publicId,
                   4125:                           0);
                   4126:         handleDefault = XML_FALSE;
                   4127:       }
                   4128:       break;
                   4129:     case XML_ROLE_ENTITY_NOTATION_NAME:
                   4130:       if (dtd->keepProcessing && declEntity) {
                   4131:         declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
                   4132:         if (!declEntity->notation)
                   4133:           return XML_ERROR_NO_MEMORY;
                   4134:         poolFinish(&dtd->pool);
                   4135:         if (unparsedEntityDeclHandler) {
                   4136:           *eventEndPP = s;
                   4137:           unparsedEntityDeclHandler(handlerArg,
                   4138:                                     declEntity->name,
                   4139:                                     declEntity->base,
                   4140:                                     declEntity->systemId,
                   4141:                                     declEntity->publicId,
                   4142:                                     declEntity->notation);
                   4143:           handleDefault = XML_FALSE;
                   4144:         }
                   4145:         else if (entityDeclHandler) {
                   4146:           *eventEndPP = s;
                   4147:           entityDeclHandler(handlerArg,
                   4148:                             declEntity->name,
                   4149:                             0,0,0,
                   4150:                             declEntity->base,
                   4151:                             declEntity->systemId,
                   4152:                             declEntity->publicId,
                   4153:                             declEntity->notation);
                   4154:           handleDefault = XML_FALSE;
                   4155:         }
                   4156:       }
                   4157:       break;
                   4158:     case XML_ROLE_GENERAL_ENTITY_NAME:
                   4159:       {
                   4160:         if (XmlPredefinedEntityName(enc, s, next)) {
                   4161:           declEntity = NULL;
                   4162:           break;
                   4163:         }
                   4164:         if (dtd->keepProcessing) {
                   4165:           const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
                   4166:           if (!name)
                   4167:             return XML_ERROR_NO_MEMORY;
                   4168:           declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
                   4169:                                         sizeof(ENTITY));
                   4170:           if (!declEntity)
                   4171:             return XML_ERROR_NO_MEMORY;
                   4172:           if (declEntity->name != name) {
                   4173:             poolDiscard(&dtd->pool);
                   4174:             declEntity = NULL;
                   4175:           }
                   4176:           else {
                   4177:             poolFinish(&dtd->pool);
                   4178:             declEntity->publicId = NULL;
                   4179:             declEntity->is_param = XML_FALSE;
                   4180:             /* if we have a parent parser or are reading an internal parameter
                   4181:                entity, then the entity declaration is not considered "internal"
                   4182:             */
                   4183:             declEntity->is_internal = !(parentParser || openInternalEntities);
                   4184:             if (entityDeclHandler)
                   4185:               handleDefault = XML_FALSE;
                   4186:           }
                   4187:         }
                   4188:         else {
                   4189:           poolDiscard(&dtd->pool);
                   4190:           declEntity = NULL;
                   4191:         }
                   4192:       }
                   4193:       break;
                   4194:     case XML_ROLE_PARAM_ENTITY_NAME:
                   4195: #ifdef XML_DTD
                   4196:       if (dtd->keepProcessing) {
                   4197:         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
                   4198:         if (!name)
                   4199:           return XML_ERROR_NO_MEMORY;
                   4200:         declEntity = (ENTITY *)lookup(&dtd->paramEntities,
                   4201:                                            name, sizeof(ENTITY));
                   4202:         if (!declEntity)
                   4203:           return XML_ERROR_NO_MEMORY;
                   4204:         if (declEntity->name != name) {
                   4205:           poolDiscard(&dtd->pool);
                   4206:           declEntity = NULL;
                   4207:         }
                   4208:         else {
                   4209:           poolFinish(&dtd->pool);
                   4210:           declEntity->publicId = NULL;
                   4211:           declEntity->is_param = XML_TRUE;
                   4212:           /* if we have a parent parser or are reading an internal parameter
                   4213:              entity, then the entity declaration is not considered "internal"
                   4214:           */
                   4215:           declEntity->is_internal = !(parentParser || openInternalEntities);
                   4216:           if (entityDeclHandler)
                   4217:             handleDefault = XML_FALSE;
                   4218:         }
                   4219:       }
                   4220:       else {
                   4221:         poolDiscard(&dtd->pool);
                   4222:         declEntity = NULL;
                   4223:       }
                   4224: #else /* not XML_DTD */
                   4225:       declEntity = NULL;
                   4226: #endif /* XML_DTD */
                   4227:       break;
                   4228:     case XML_ROLE_NOTATION_NAME:
                   4229:       declNotationPublicId = NULL;
                   4230:       declNotationName = NULL;
                   4231:       if (notationDeclHandler) {
                   4232:         declNotationName = poolStoreString(&tempPool, enc, s, next);
                   4233:         if (!declNotationName)
                   4234:           return XML_ERROR_NO_MEMORY;
                   4235:         poolFinish(&tempPool);
                   4236:         handleDefault = XML_FALSE;
                   4237:       }
                   4238:       break;
                   4239:     case XML_ROLE_NOTATION_PUBLIC_ID:
                   4240:       if (!XmlIsPublicId(enc, s, next, eventPP))
                   4241:         return XML_ERROR_PUBLICID;
                   4242:       if (declNotationName) {  /* means notationDeclHandler != NULL */
                   4243:         XML_Char *tem = poolStoreString(&tempPool,
                   4244:                                         enc,
                   4245:                                         s + enc->minBytesPerChar,
                   4246:                                         next - enc->minBytesPerChar);
                   4247:         if (!tem)
                   4248:           return XML_ERROR_NO_MEMORY;
                   4249:         normalizePublicId(tem);
                   4250:         declNotationPublicId = tem;
                   4251:         poolFinish(&tempPool);
                   4252:         handleDefault = XML_FALSE;
                   4253:       }
                   4254:       break;
                   4255:     case XML_ROLE_NOTATION_SYSTEM_ID:
                   4256:       if (declNotationName && notationDeclHandler) {
                   4257:         const XML_Char *systemId
                   4258:           = poolStoreString(&tempPool, enc,
                   4259:                             s + enc->minBytesPerChar,
                   4260:                             next - enc->minBytesPerChar);
                   4261:         if (!systemId)
                   4262:           return XML_ERROR_NO_MEMORY;
                   4263:         *eventEndPP = s;
                   4264:         notationDeclHandler(handlerArg,
                   4265:                             declNotationName,
                   4266:                             curBase,
                   4267:                             systemId,
                   4268:                             declNotationPublicId);
                   4269:         handleDefault = XML_FALSE;
                   4270:       }
                   4271:       poolClear(&tempPool);
                   4272:       break;
                   4273:     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
                   4274:       if (declNotationPublicId && notationDeclHandler) {
                   4275:         *eventEndPP = s;
                   4276:         notationDeclHandler(handlerArg,
                   4277:                             declNotationName,
                   4278:                             curBase,
                   4279:                             0,
                   4280:                             declNotationPublicId);
                   4281:         handleDefault = XML_FALSE;
                   4282:       }
                   4283:       poolClear(&tempPool);
                   4284:       break;
                   4285:     case XML_ROLE_ERROR:
                   4286:       switch (tok) {
                   4287:       case XML_TOK_PARAM_ENTITY_REF:
                   4288:         /* PE references in internal subset are
                   4289:            not allowed within declarations. */  
                   4290:         return XML_ERROR_PARAM_ENTITY_REF;
                   4291:       case XML_TOK_XML_DECL:
                   4292:         return XML_ERROR_MISPLACED_XML_PI;
                   4293:       default:
                   4294:         return XML_ERROR_SYNTAX;
                   4295:       }
                   4296: #ifdef XML_DTD
                   4297:     case XML_ROLE_IGNORE_SECT:
                   4298:       {
                   4299:         enum XML_Error result;
                   4300:         if (defaultHandler)
                   4301:           reportDefault(parser, enc, s, next);
                   4302:         handleDefault = XML_FALSE;
                   4303:         result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
                   4304:         if (result != XML_ERROR_NONE)
                   4305:           return result;
                   4306:         else if (!next) {
                   4307:           processor = ignoreSectionProcessor;
                   4308:           return result;
                   4309:         }
                   4310:       }
                   4311:       break;
                   4312: #endif /* XML_DTD */
                   4313:     case XML_ROLE_GROUP_OPEN:
                   4314:       if (prologState.level >= groupSize) {
                   4315:         if (groupSize) {
                   4316:           char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
                   4317:           if (temp == NULL)
                   4318:             return XML_ERROR_NO_MEMORY;
                   4319:           groupConnector = temp;
                   4320:           if (dtd->scaffIndex) {
                   4321:             int *temp = (int *)REALLOC(dtd->scaffIndex,
                   4322:                           groupSize * sizeof(int));
                   4323:             if (temp == NULL)
                   4324:               return XML_ERROR_NO_MEMORY;
                   4325:             dtd->scaffIndex = temp;
                   4326:           }
                   4327:         }
                   4328:         else {
                   4329:           groupConnector = (char *)MALLOC(groupSize = 32);
                   4330:           if (!groupConnector)
                   4331:             return XML_ERROR_NO_MEMORY;
                   4332:         }
                   4333:       }
                   4334:       groupConnector[prologState.level] = 0;
                   4335:       if (dtd->in_eldecl) {
                   4336:         int myindex = nextScaffoldPart(parser);
                   4337:         if (myindex < 0)
                   4338:           return XML_ERROR_NO_MEMORY;
                   4339:         dtd->scaffIndex[dtd->scaffLevel] = myindex;
                   4340:         dtd->scaffLevel++;
                   4341:         dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
                   4342:         if (elementDeclHandler)
                   4343:           handleDefault = XML_FALSE;
                   4344:       }
                   4345:       break;
                   4346:     case XML_ROLE_GROUP_SEQUENCE:
                   4347:       if (groupConnector[prologState.level] == ASCII_PIPE)
                   4348:         return XML_ERROR_SYNTAX;
                   4349:       groupConnector[prologState.level] = ASCII_COMMA;
                   4350:       if (dtd->in_eldecl && elementDeclHandler)
                   4351:         handleDefault = XML_FALSE;
                   4352:       break;
                   4353:     case XML_ROLE_GROUP_CHOICE:
                   4354:       if (groupConnector[prologState.level] == ASCII_COMMA)
                   4355:         return XML_ERROR_SYNTAX;
                   4356:       if (dtd->in_eldecl
                   4357:           && !groupConnector[prologState.level]
                   4358:           && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
                   4359:               != XML_CTYPE_MIXED)
                   4360:           ) {
                   4361:         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
                   4362:             = XML_CTYPE_CHOICE;
                   4363:         if (elementDeclHandler)
                   4364:           handleDefault = XML_FALSE;
                   4365:       }
                   4366:       groupConnector[prologState.level] = ASCII_PIPE;
                   4367:       break;
                   4368:     case XML_ROLE_PARAM_ENTITY_REF:
                   4369: #ifdef XML_DTD
                   4370:     case XML_ROLE_INNER_PARAM_ENTITY_REF:
                   4371:       dtd->hasParamEntityRefs = XML_TRUE;
                   4372:       if (!paramEntityParsing)
                   4373:         dtd->keepProcessing = dtd->standalone;
                   4374:       else {
                   4375:         const XML_Char *name;
                   4376:         ENTITY *entity;
                   4377:         name = poolStoreString(&dtd->pool, enc,
                   4378:                                 s + enc->minBytesPerChar,
                   4379:                                 next - enc->minBytesPerChar);
                   4380:         if (!name)
                   4381:           return XML_ERROR_NO_MEMORY;
                   4382:         entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
                   4383:         poolDiscard(&dtd->pool);
                   4384:         /* first, determine if a check for an existing declaration is needed;
                   4385:            if yes, check that the entity exists, and that it is internal,
                   4386:            otherwise call the skipped entity handler
                   4387:         */
                   4388:         if (prologState.documentEntity &&
                   4389:             (dtd->standalone
                   4390:              ? !openInternalEntities
                   4391:              : !dtd->hasParamEntityRefs)) {
                   4392:           if (!entity)
                   4393:             return XML_ERROR_UNDEFINED_ENTITY;
                   4394:           else if (!entity->is_internal)
                   4395:             return XML_ERROR_ENTITY_DECLARED_IN_PE;
                   4396:         }
                   4397:         else if (!entity) {
                   4398:           dtd->keepProcessing = dtd->standalone;
                   4399:           /* cannot report skipped entities in declarations */
                   4400:           if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
                   4401:             skippedEntityHandler(handlerArg, name, 1);
                   4402:             handleDefault = XML_FALSE;
                   4403:           }
                   4404:           break;
                   4405:         }
                   4406:         if (entity->open)
                   4407:           return XML_ERROR_RECURSIVE_ENTITY_REF;
                   4408:         if (entity->textPtr) {
                   4409:           enum XML_Error result;
                   4410:           XML_Bool betweenDecl = 
                   4411:             (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
                   4412:           result = processInternalEntity(parser, entity, betweenDecl);
                   4413:           if (result != XML_ERROR_NONE)
                   4414:             return result;
                   4415:           handleDefault = XML_FALSE;
                   4416:           break;
                   4417:         }
                   4418:         if (externalEntityRefHandler) {
                   4419:           dtd->paramEntityRead = XML_FALSE;
                   4420:           entity->open = XML_TRUE;
                   4421:           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
                   4422:                                         0,
                   4423:                                         entity->base,
                   4424:                                         entity->systemId,
                   4425:                                         entity->publicId)) {
                   4426:             entity->open = XML_FALSE;
                   4427:             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
                   4428:           }
                   4429:           entity->open = XML_FALSE;
                   4430:           handleDefault = XML_FALSE;
                   4431:           if (!dtd->paramEntityRead) {
                   4432:             dtd->keepProcessing = dtd->standalone;
                   4433:             break;
                   4434:           }
                   4435:         }
                   4436:         else {
                   4437:           dtd->keepProcessing = dtd->standalone;
                   4438:           break;
                   4439:         }
                   4440:       }
                   4441: #endif /* XML_DTD */
                   4442:       if (!dtd->standalone &&
                   4443:           notStandaloneHandler &&
                   4444:           !notStandaloneHandler(handlerArg))
                   4445:         return XML_ERROR_NOT_STANDALONE;
                   4446:       break;
                   4447: 
                   4448:     /* Element declaration stuff */
                   4449: 
                   4450:     case XML_ROLE_ELEMENT_NAME:
                   4451:       if (elementDeclHandler) {
                   4452:         declElementType = getElementType(parser, enc, s, next);
                   4453:         if (!declElementType)
                   4454:           return XML_ERROR_NO_MEMORY;
                   4455:         dtd->scaffLevel = 0;
                   4456:         dtd->scaffCount = 0;
                   4457:         dtd->in_eldecl = XML_TRUE;
                   4458:         handleDefault = XML_FALSE;
                   4459:       }
                   4460:       break;
                   4461: 
                   4462:     case XML_ROLE_CONTENT_ANY:
                   4463:     case XML_ROLE_CONTENT_EMPTY:
                   4464:       if (dtd->in_eldecl) {
                   4465:         if (elementDeclHandler) {
                   4466:           XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
                   4467:           if (!content)
                   4468:             return XML_ERROR_NO_MEMORY;
                   4469:           content->quant = XML_CQUANT_NONE;
                   4470:           content->name = NULL;
                   4471:           content->numchildren = 0;
                   4472:           content->children = NULL;
                   4473:           content->type = ((role == XML_ROLE_CONTENT_ANY) ?
                   4474:                            XML_CTYPE_ANY :
                   4475:                            XML_CTYPE_EMPTY);
                   4476:           *eventEndPP = s;
                   4477:           elementDeclHandler(handlerArg, declElementType->name, content);
                   4478:           handleDefault = XML_FALSE;
                   4479:         }
                   4480:         dtd->in_eldecl = XML_FALSE;
                   4481:       }
                   4482:       break;
                   4483: 
                   4484:     case XML_ROLE_CONTENT_PCDATA:
                   4485:       if (dtd->in_eldecl) {
                   4486:         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
                   4487:             = XML_CTYPE_MIXED;
                   4488:         if (elementDeclHandler)
                   4489:           handleDefault = XML_FALSE;
                   4490:       }
                   4491:       break;
                   4492: 
                   4493:     case XML_ROLE_CONTENT_ELEMENT:
                   4494:       quant = XML_CQUANT_NONE;
                   4495:       goto elementContent;
                   4496:     case XML_ROLE_CONTENT_ELEMENT_OPT:
                   4497:       quant = XML_CQUANT_OPT;
                   4498:       goto elementContent;
                   4499:     case XML_ROLE_CONTENT_ELEMENT_REP:
                   4500:       quant = XML_CQUANT_REP;
                   4501:       goto elementContent;
                   4502:     case XML_ROLE_CONTENT_ELEMENT_PLUS:
                   4503:       quant = XML_CQUANT_PLUS;
                   4504:     elementContent:
                   4505:       if (dtd->in_eldecl) {
                   4506:         ELEMENT_TYPE *el;
                   4507:         const XML_Char *name;
                   4508:         int nameLen;
                   4509:         const char *nxt = (quant == XML_CQUANT_NONE
                   4510:                            ? next
                   4511:                            : next - enc->minBytesPerChar);
                   4512:         int myindex = nextScaffoldPart(parser);
                   4513:         if (myindex < 0)
                   4514:           return XML_ERROR_NO_MEMORY;
                   4515:         dtd->scaffold[myindex].type = XML_CTYPE_NAME;
                   4516:         dtd->scaffold[myindex].quant = quant;
                   4517:         el = getElementType(parser, enc, s, nxt);
                   4518:         if (!el)
                   4519:           return XML_ERROR_NO_MEMORY;
                   4520:         name = el->name;
                   4521:         dtd->scaffold[myindex].name = name;
                   4522:         nameLen = 0;
                   4523:         for (; name[nameLen++]; );
                   4524:         dtd->contentStringLen +=  nameLen;
                   4525:         if (elementDeclHandler)
                   4526:           handleDefault = XML_FALSE;
                   4527:       }
                   4528:       break;
                   4529: 
                   4530:     case XML_ROLE_GROUP_CLOSE:
                   4531:       quant = XML_CQUANT_NONE;
                   4532:       goto closeGroup;
                   4533:     case XML_ROLE_GROUP_CLOSE_OPT:
                   4534:       quant = XML_CQUANT_OPT;
                   4535:       goto closeGroup;
                   4536:     case XML_ROLE_GROUP_CLOSE_REP:
                   4537:       quant = XML_CQUANT_REP;
                   4538:       goto closeGroup;
                   4539:     case XML_ROLE_GROUP_CLOSE_PLUS:
                   4540:       quant = XML_CQUANT_PLUS;
                   4541:     closeGroup:
                   4542:       if (dtd->in_eldecl) {
                   4543:         if (elementDeclHandler)
                   4544:           handleDefault = XML_FALSE;
                   4545:         dtd->scaffLevel--;
                   4546:         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
                   4547:         if (dtd->scaffLevel == 0) {
                   4548:           if (!handleDefault) {
                   4549:             XML_Content *model = build_model(parser);
                   4550:             if (!model)
                   4551:               return XML_ERROR_NO_MEMORY;
                   4552:             *eventEndPP = s;
                   4553:             elementDeclHandler(handlerArg, declElementType->name, model);
                   4554:           }
                   4555:           dtd->in_eldecl = XML_FALSE;
                   4556:           dtd->contentStringLen = 0;
                   4557:         }
                   4558:       }
                   4559:       break;
                   4560:       /* End element declaration stuff */
                   4561: 
                   4562:     case XML_ROLE_PI:
                   4563:       if (!reportProcessingInstruction(parser, enc, s, next))
                   4564:         return XML_ERROR_NO_MEMORY;
                   4565:       handleDefault = XML_FALSE;
                   4566:       break;
                   4567:     case XML_ROLE_COMMENT:
                   4568:       if (!reportComment(parser, enc, s, next))
                   4569:         return XML_ERROR_NO_MEMORY;
                   4570:       handleDefault = XML_FALSE;
                   4571:       break;
                   4572:     case XML_ROLE_NONE:
                   4573:       switch (tok) {
                   4574:       case XML_TOK_BOM:
                   4575:         handleDefault = XML_FALSE;
                   4576:         break;
                   4577:       }
                   4578:       break;
                   4579:     case XML_ROLE_DOCTYPE_NONE:
                   4580:       if (startDoctypeDeclHandler)
                   4581:         handleDefault = XML_FALSE;
                   4582:       break;
                   4583:     case XML_ROLE_ENTITY_NONE:
                   4584:       if (dtd->keepProcessing && entityDeclHandler)
                   4585:         handleDefault = XML_FALSE;
                   4586:       break;
                   4587:     case XML_ROLE_NOTATION_NONE:
                   4588:       if (notationDeclHandler)
                   4589:         handleDefault = XML_FALSE;
                   4590:       break;
                   4591:     case XML_ROLE_ATTLIST_NONE:
                   4592:       if (dtd->keepProcessing && attlistDeclHandler)
                   4593:         handleDefault = XML_FALSE;
                   4594:       break;
                   4595:     case XML_ROLE_ELEMENT_NONE:
                   4596:       if (elementDeclHandler)
                   4597:         handleDefault = XML_FALSE;
                   4598:       break;
                   4599:     } /* end of big switch */
                   4600: 
                   4601:     if (handleDefault && defaultHandler)
                   4602:       reportDefault(parser, enc, s, next);
                   4603: 
                   4604:     switch (ps_parsing) {
                   4605:     case XML_SUSPENDED: 
                   4606:       *nextPtr = next;
                   4607:       return XML_ERROR_NONE;
                   4608:     case XML_FINISHED:
                   4609:       return XML_ERROR_ABORTED;
                   4610:     default:
                   4611:       s = next;
                   4612:       tok = XmlPrologTok(enc, s, end, &next);
                   4613:     }
                   4614:   }
                   4615:   /* not reached */
                   4616: }
                   4617: 
                   4618: static enum XML_Error PTRCALL
                   4619: epilogProcessor(XML_Parser parser,
                   4620:                 const char *s,
                   4621:                 const char *end,
                   4622:                 const char **nextPtr)
                   4623: {
                   4624:   processor = epilogProcessor;
                   4625:   eventPtr = s;
                   4626:   for (;;) {
                   4627:     const char *next = NULL;
                   4628:     int tok = XmlPrologTok(encoding, s, end, &next);
                   4629:     eventEndPtr = next;
                   4630:     switch (tok) {
                   4631:     /* report partial linebreak - it might be the last token */
                   4632:     case -XML_TOK_PROLOG_S:
                   4633:       if (defaultHandler) {
                   4634:         reportDefault(parser, encoding, s, next);
                   4635:         if (ps_parsing == XML_FINISHED)
                   4636:           return XML_ERROR_ABORTED;
                   4637:       }
                   4638:       *nextPtr = next;
                   4639:       return XML_ERROR_NONE;
                   4640:     case XML_TOK_NONE:
                   4641:       *nextPtr = s;
                   4642:       return XML_ERROR_NONE;
                   4643:     case XML_TOK_PROLOG_S:
                   4644:       if (defaultHandler)
                   4645:         reportDefault(parser, encoding, s, next);
                   4646:       break;
                   4647:     case XML_TOK_PI:
                   4648:       if (!reportProcessingInstruction(parser, encoding, s, next))
                   4649:         return XML_ERROR_NO_MEMORY;
                   4650:       break;
                   4651:     case XML_TOK_COMMENT:
                   4652:       if (!reportComment(parser, encoding, s, next))
                   4653:         return XML_ERROR_NO_MEMORY;
                   4654:       break;
                   4655:     case XML_TOK_INVALID:
                   4656:       eventPtr = next;
                   4657:       return XML_ERROR_INVALID_TOKEN;
                   4658:     case XML_TOK_PARTIAL:
                   4659:       if (!ps_finalBuffer) {
                   4660:         *nextPtr = s;
                   4661:         return XML_ERROR_NONE;
                   4662:       }
                   4663:       return XML_ERROR_UNCLOSED_TOKEN;
                   4664:     case XML_TOK_PARTIAL_CHAR:
                   4665:       if (!ps_finalBuffer) {
                   4666:         *nextPtr = s;
                   4667:         return XML_ERROR_NONE;
                   4668:       }
                   4669:       return XML_ERROR_PARTIAL_CHAR;
                   4670:     default:
                   4671:       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
                   4672:     }
                   4673:     eventPtr = s = next;
                   4674:     switch (ps_parsing) {
                   4675:     case XML_SUSPENDED: 
                   4676:       *nextPtr = next;
                   4677:       return XML_ERROR_NONE;
                   4678:     case XML_FINISHED:
                   4679:       return XML_ERROR_ABORTED;
                   4680:     default: ;
                   4681:     }
                   4682:   }
                   4683: }
                   4684: 
                   4685: static enum XML_Error
                   4686: processInternalEntity(XML_Parser parser, ENTITY *entity,
                   4687:                       XML_Bool betweenDecl)
                   4688: {
                   4689:   const char *textStart, *textEnd;
                   4690:   const char *next;
                   4691:   enum XML_Error result;
                   4692:   OPEN_INTERNAL_ENTITY *openEntity;
                   4693: 
                   4694:   if (freeInternalEntities) {
                   4695:     openEntity = freeInternalEntities;
                   4696:     freeInternalEntities = openEntity->next;
                   4697:   }
                   4698:   else {
                   4699:     openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
                   4700:     if (!openEntity)
                   4701:       return XML_ERROR_NO_MEMORY;
                   4702:   }
                   4703:   entity->open = XML_TRUE;
                   4704:   entity->processed = 0;
                   4705:   openEntity->next = openInternalEntities;
                   4706:   openInternalEntities = openEntity;
                   4707:   openEntity->entity = entity;
                   4708:   openEntity->startTagLevel = tagLevel;
                   4709:   openEntity->betweenDecl = betweenDecl;
                   4710:   openEntity->internalEventPtr = NULL;
                   4711:   openEntity->internalEventEndPtr = NULL;
                   4712:   textStart = (char *)entity->textPtr;
                   4713:   textEnd = (char *)(entity->textPtr + entity->textLen);
                   4714: 
                   4715: #ifdef XML_DTD
                   4716:   if (entity->is_param) {
                   4717:     int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
                   4718:     result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
                   4719:                       next, &next, XML_FALSE);
                   4720:   }
                   4721:   else 
                   4722: #endif /* XML_DTD */
                   4723:     result = doContent(parser, tagLevel, internalEncoding, textStart, 
                   4724:                        textEnd, &next, XML_FALSE);
                   4725: 
                   4726:   if (result == XML_ERROR_NONE) {
                   4727:     if (textEnd != next && ps_parsing == XML_SUSPENDED) {
                   4728:       entity->processed = (int)(next - textStart);
                   4729:       processor = internalEntityProcessor;
                   4730:     }
                   4731:     else {
                   4732:       entity->open = XML_FALSE;
                   4733:       openInternalEntities = openEntity->next;
                   4734:       /* put openEntity back in list of free instances */
                   4735:       openEntity->next = freeInternalEntities;
                   4736:       freeInternalEntities = openEntity;
                   4737:     }
                   4738:   }
                   4739:   return result;
                   4740: }
                   4741: 
                   4742: static enum XML_Error PTRCALL
                   4743: internalEntityProcessor(XML_Parser parser,
                   4744:                         const char *s,
                   4745:                         const char *end,
                   4746:                         const char **nextPtr)
                   4747: {
                   4748:   ENTITY *entity;
                   4749:   const char *textStart, *textEnd;
                   4750:   const char *next;
                   4751:   enum XML_Error result;
                   4752:   OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
                   4753:   if (!openEntity)
                   4754:     return XML_ERROR_UNEXPECTED_STATE;
                   4755: 
                   4756:   entity = openEntity->entity;
                   4757:   textStart = ((char *)entity->textPtr) + entity->processed;
                   4758:   textEnd = (char *)(entity->textPtr + entity->textLen);
                   4759: 
                   4760: #ifdef XML_DTD
                   4761:   if (entity->is_param) {
                   4762:     int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
                   4763:     result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
                   4764:                       next, &next, XML_FALSE);
                   4765:   }
                   4766:   else
                   4767: #endif /* XML_DTD */
                   4768:     result = doContent(parser, openEntity->startTagLevel, internalEncoding, 
                   4769:                        textStart, textEnd, &next, XML_FALSE);  
                   4770: 
                   4771:   if (result != XML_ERROR_NONE)
                   4772:     return result;
                   4773:   else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
                   4774:     entity->processed = (int)(next - (char *)entity->textPtr);
                   4775:     return result;
                   4776:   }
                   4777:   else {
                   4778:     entity->open = XML_FALSE;
                   4779:     openInternalEntities = openEntity->next;
                   4780:     /* put openEntity back in list of free instances */
                   4781:     openEntity->next = freeInternalEntities;
                   4782:     freeInternalEntities = openEntity;
                   4783:   }
                   4784: 
                   4785: #ifdef XML_DTD
                   4786:   if (entity->is_param) {
                   4787:     int tok;
                   4788:     processor = prologProcessor;
                   4789:     tok = XmlPrologTok(encoding, s, end, &next);
                   4790:     return doProlog(parser, encoding, s, end, tok, next, nextPtr, 
                   4791:                     (XML_Bool)!ps_finalBuffer);
                   4792:   }
                   4793:   else
                   4794: #endif /* XML_DTD */
                   4795:   {
                   4796:     processor = contentProcessor;
                   4797:     /* see externalEntityContentProcessor vs contentProcessor */
                   4798:     return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
                   4799:                      nextPtr, (XML_Bool)!ps_finalBuffer); 
                   4800:   }  
                   4801: }
                   4802: 
                   4803: static enum XML_Error PTRCALL
                   4804: errorProcessor(XML_Parser parser,
                   4805:                const char *s,
                   4806:                const char *end,
                   4807:                const char **nextPtr)
                   4808: {
                   4809:   return errorCode;
                   4810: }
                   4811: 
                   4812: static enum XML_Error
                   4813: storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
                   4814:                     const char *ptr, const char *end,
                   4815:                     STRING_POOL *pool)
                   4816: {
                   4817:   enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
                   4818:                                                end, pool);
                   4819:   if (result)
                   4820:     return result;
                   4821:   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
                   4822:     poolChop(pool);
                   4823:   if (!poolAppendChar(pool, XML_T('\0')))
                   4824:     return XML_ERROR_NO_MEMORY;
                   4825:   return XML_ERROR_NONE;
                   4826: }
                   4827: 
                   4828: static enum XML_Error
                   4829: appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
                   4830:                      const char *ptr, const char *end,
                   4831:                      STRING_POOL *pool)
                   4832: {
                   4833:   DTD * const dtd = _dtd;  /* save one level of indirection */
                   4834:   for (;;) {
                   4835:     const char *next;
                   4836:     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
                   4837:     switch (tok) {
                   4838:     case XML_TOK_NONE:
                   4839:       return XML_ERROR_NONE;
                   4840:     case XML_TOK_INVALID:
                   4841:       if (enc == encoding)
                   4842:         eventPtr = next;
                   4843:       return XML_ERROR_INVALID_TOKEN;
                   4844:     case XML_TOK_PARTIAL:
                   4845:       if (enc == encoding)
                   4846:         eventPtr = ptr;
                   4847:       return XML_ERROR_INVALID_TOKEN;
                   4848:     case XML_TOK_CHAR_REF:
                   4849:       {
                   4850:         XML_Char buf[XML_ENCODE_MAX];
                   4851:         int i;
                   4852:         int n = XmlCharRefNumber(enc, ptr);
                   4853:         if (n < 0) {
                   4854:           if (enc == encoding)
                   4855:             eventPtr = ptr;
                   4856:           return XML_ERROR_BAD_CHAR_REF;
                   4857:         }
                   4858:         if (!isCdata
                   4859:             && n == 0x20 /* space */
                   4860:             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
                   4861:           break;
                   4862:         n = XmlEncode(n, (ICHAR *)buf);
                   4863:         if (!n) {
                   4864:           if (enc == encoding)
                   4865:             eventPtr = ptr;
                   4866:           return XML_ERROR_BAD_CHAR_REF;
                   4867:         }
                   4868:         for (i = 0; i < n; i++) {
                   4869:           if (!poolAppendChar(pool, buf[i]))
                   4870:             return XML_ERROR_NO_MEMORY;
                   4871:         }
                   4872:       }
                   4873:       break;
                   4874:     case XML_TOK_DATA_CHARS:
                   4875:       if (!poolAppend(pool, enc, ptr, next))
                   4876:         return XML_ERROR_NO_MEMORY;
                   4877:       break;
                   4878:     case XML_TOK_TRAILING_CR:
                   4879:       next = ptr + enc->minBytesPerChar;
                   4880:       /* fall through */
                   4881:     case XML_TOK_ATTRIBUTE_VALUE_S:
                   4882:     case XML_TOK_DATA_NEWLINE:
                   4883:       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
                   4884:         break;
                   4885:       if (!poolAppendChar(pool, 0x20))
                   4886:         return XML_ERROR_NO_MEMORY;
                   4887:       break;
                   4888:     case XML_TOK_ENTITY_REF:
                   4889:       {
                   4890:         const XML_Char *name;
                   4891:         ENTITY *entity;
                   4892:         char checkEntityDecl;
                   4893:         XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
                   4894:                                               ptr + enc->minBytesPerChar,
                   4895:                                               next - enc->minBytesPerChar);
                   4896:         if (ch) {
                   4897:           if (!poolAppendChar(pool, ch))
                   4898:                 return XML_ERROR_NO_MEMORY;
                   4899:           break;
                   4900:         }
                   4901:         name = poolStoreString(&temp2Pool, enc,
                   4902:                                ptr + enc->minBytesPerChar,
                   4903:                                next - enc->minBytesPerChar);
                   4904:         if (!name)
                   4905:           return XML_ERROR_NO_MEMORY;
                   4906:         entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
                   4907:         poolDiscard(&temp2Pool);
                   4908:         /* First, determine if a check for an existing declaration is needed;
                   4909:            if yes, check that the entity exists, and that it is internal.
                   4910:         */
                   4911:         if (pool == &dtd->pool)  /* are we called from prolog? */
                   4912:           checkEntityDecl =
                   4913: #ifdef XML_DTD
                   4914:               prologState.documentEntity &&
                   4915: #endif /* XML_DTD */
                   4916:               (dtd->standalone
                   4917:                ? !openInternalEntities
                   4918:                : !dtd->hasParamEntityRefs);
                   4919:         else /* if (pool == &tempPool): we are called from content */
                   4920:           checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
                   4921:         if (checkEntityDecl) {
                   4922:           if (!entity)
                   4923:             return XML_ERROR_UNDEFINED_ENTITY;
                   4924:           else if (!entity->is_internal)
                   4925:             return XML_ERROR_ENTITY_DECLARED_IN_PE;
                   4926:         }
                   4927:         else if (!entity) {
                   4928:           /* Cannot report skipped entity here - see comments on
                   4929:              skippedEntityHandler.
                   4930:           if (skippedEntityHandler)
                   4931:             skippedEntityHandler(handlerArg, name, 0);
                   4932:           */
                   4933:           /* Cannot call the default handler because this would be
                   4934:              out of sync with the call to the startElementHandler.
                   4935:           if ((pool == &tempPool) && defaultHandler)
                   4936:             reportDefault(parser, enc, ptr, next);
                   4937:           */
                   4938:           break;
                   4939:         }
                   4940:         if (entity->open) {
                   4941:           if (enc == encoding)
                   4942:             eventPtr = ptr;
                   4943:           return XML_ERROR_RECURSIVE_ENTITY_REF;
                   4944:         }
                   4945:         if (entity->notation) {
                   4946:           if (enc == encoding)
                   4947:             eventPtr = ptr;
                   4948:           return XML_ERROR_BINARY_ENTITY_REF;
                   4949:         }
                   4950:         if (!entity->textPtr) {
                   4951:           if (enc == encoding)
                   4952:             eventPtr = ptr;
                   4953:               return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
                   4954:         }
                   4955:         else {
                   4956:           enum XML_Error result;
                   4957:           const XML_Char *textEnd = entity->textPtr + entity->textLen;
                   4958:           entity->open = XML_TRUE;
                   4959:           result = appendAttributeValue(parser, internalEncoding, isCdata,
                   4960:                                         (char *)entity->textPtr,
                   4961:                                         (char *)textEnd, pool);
                   4962:           entity->open = XML_FALSE;
                   4963:           if (result)
                   4964:             return result;
                   4965:         }
                   4966:       }
                   4967:       break;
                   4968:     default:
                   4969:       if (enc == encoding)
                   4970:         eventPtr = ptr;
                   4971:       return XML_ERROR_UNEXPECTED_STATE;
                   4972:     }
                   4973:     ptr = next;
                   4974:   }
                   4975:   /* not reached */
                   4976: }
                   4977: 
                   4978: static enum XML_Error
                   4979: storeEntityValue(XML_Parser parser,
                   4980:                  const ENCODING *enc,
                   4981:                  const char *entityTextPtr,
                   4982:                  const char *entityTextEnd)
                   4983: {
                   4984:   DTD * const dtd = _dtd;  /* save one level of indirection */
                   4985:   STRING_POOL *pool = &(dtd->entityValuePool);
                   4986:   enum XML_Error result = XML_ERROR_NONE;
                   4987: #ifdef XML_DTD
                   4988:   int oldInEntityValue = prologState.inEntityValue;
                   4989:   prologState.inEntityValue = 1;
                   4990: #endif /* XML_DTD */
                   4991:   /* never return Null for the value argument in EntityDeclHandler,
                   4992:      since this would indicate an external entity; therefore we
                   4993:      have to make sure that entityValuePool.start is not null */
                   4994:   if (!pool->blocks) {
                   4995:     if (!poolGrow(pool))
                   4996:       return XML_ERROR_NO_MEMORY;
                   4997:   }
                   4998: 
                   4999:   for (;;) {
                   5000:     const char *next;
                   5001:     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
                   5002:     switch (tok) {
                   5003:     case XML_TOK_PARAM_ENTITY_REF:
                   5004: #ifdef XML_DTD
                   5005:       if (isParamEntity || enc != encoding) {
                   5006:         const XML_Char *name;
                   5007:         ENTITY *entity;
                   5008:         name = poolStoreString(&tempPool, enc,
                   5009:                                entityTextPtr + enc->minBytesPerChar,
                   5010:                                next - enc->minBytesPerChar);
                   5011:         if (!name) {
                   5012:           result = XML_ERROR_NO_MEMORY;
                   5013:           goto endEntityValue;
                   5014:         }
                   5015:         entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
                   5016:         poolDiscard(&tempPool);
                   5017:         if (!entity) {
                   5018:           /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
                   5019:           /* cannot report skipped entity here - see comments on
                   5020:              skippedEntityHandler
                   5021:           if (skippedEntityHandler)
                   5022:             skippedEntityHandler(handlerArg, name, 0);
                   5023:           */
                   5024:           dtd->keepProcessing = dtd->standalone;
                   5025:           goto endEntityValue;
                   5026:         }
                   5027:         if (entity->open) {
                   5028:           if (enc == encoding)
                   5029:             eventPtr = entityTextPtr;
                   5030:           result = XML_ERROR_RECURSIVE_ENTITY_REF;
                   5031:           goto endEntityValue;
                   5032:         }
                   5033:         if (entity->systemId) {
                   5034:           if (externalEntityRefHandler) {
                   5035:             dtd->paramEntityRead = XML_FALSE;
                   5036:             entity->open = XML_TRUE;
                   5037:             if (!externalEntityRefHandler(externalEntityRefHandlerArg,
                   5038:                                           0,
                   5039:                                           entity->base,
                   5040:                                           entity->systemId,
                   5041:                                           entity->publicId)) {
                   5042:               entity->open = XML_FALSE;
                   5043:               result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
                   5044:               goto endEntityValue;
                   5045:             }
                   5046:             entity->open = XML_FALSE;
                   5047:             if (!dtd->paramEntityRead)
                   5048:               dtd->keepProcessing = dtd->standalone;
                   5049:           }
                   5050:           else
                   5051:             dtd->keepProcessing = dtd->standalone;
                   5052:         }
                   5053:         else {
                   5054:           entity->open = XML_TRUE;
                   5055:           result = storeEntityValue(parser,
                   5056:                                     internalEncoding,
                   5057:                                     (char *)entity->textPtr,
                   5058:                                     (char *)(entity->textPtr
                   5059:                                              + entity->textLen));
                   5060:           entity->open = XML_FALSE;
                   5061:           if (result)
                   5062:             goto endEntityValue;
                   5063:         }
                   5064:         break;
                   5065:       }
                   5066: #endif /* XML_DTD */
                   5067:       /* In the internal subset, PE references are not legal
                   5068:          within markup declarations, e.g entity values in this case. */
                   5069:       eventPtr = entityTextPtr;
                   5070:       result = XML_ERROR_PARAM_ENTITY_REF;
                   5071:       goto endEntityValue;
                   5072:     case XML_TOK_NONE:
                   5073:       result = XML_ERROR_NONE;
                   5074:       goto endEntityValue;
                   5075:     case XML_TOK_ENTITY_REF:
                   5076:     case XML_TOK_DATA_CHARS:
                   5077:       if (!poolAppend(pool, enc, entityTextPtr, next)) {
                   5078:         result = XML_ERROR_NO_MEMORY;
                   5079:         goto endEntityValue;
                   5080:       }
                   5081:       break;
                   5082:     case XML_TOK_TRAILING_CR:
                   5083:       next = entityTextPtr + enc->minBytesPerChar;
                   5084:       /* fall through */
                   5085:     case XML_TOK_DATA_NEWLINE:
                   5086:       if (pool->end == pool->ptr && !poolGrow(pool)) {
                   5087:               result = XML_ERROR_NO_MEMORY;
                   5088:         goto endEntityValue;
                   5089:       }
                   5090:       *(pool->ptr)++ = 0xA;
                   5091:       break;
                   5092:     case XML_TOK_CHAR_REF:
                   5093:       {
                   5094:         XML_Char buf[XML_ENCODE_MAX];
                   5095:         int i;
                   5096:         int n = XmlCharRefNumber(enc, entityTextPtr);
                   5097:         if (n < 0) {
                   5098:           if (enc == encoding)
                   5099:             eventPtr = entityTextPtr;
                   5100:           result = XML_ERROR_BAD_CHAR_REF;
                   5101:           goto endEntityValue;
                   5102:         }
                   5103:         n = XmlEncode(n, (ICHAR *)buf);
                   5104:         if (!n) {
                   5105:           if (enc == encoding)
                   5106:             eventPtr = entityTextPtr;
                   5107:           result = XML_ERROR_BAD_CHAR_REF;
                   5108:           goto endEntityValue;
                   5109:         }
                   5110:         for (i = 0; i < n; i++) {
                   5111:           if (pool->end == pool->ptr && !poolGrow(pool)) {
                   5112:             result = XML_ERROR_NO_MEMORY;
                   5113:             goto endEntityValue;
                   5114:           }
                   5115:           *(pool->ptr)++ = buf[i];
                   5116:         }
                   5117:       }
                   5118:       break;
                   5119:     case XML_TOK_PARTIAL:
                   5120:       if (enc == encoding)
                   5121:         eventPtr = entityTextPtr;
                   5122:       result = XML_ERROR_INVALID_TOKEN;
                   5123:       goto endEntityValue;
                   5124:     case XML_TOK_INVALID:
                   5125:       if (enc == encoding)
                   5126:         eventPtr = next;
                   5127:       result = XML_ERROR_INVALID_TOKEN;
                   5128:       goto endEntityValue;
                   5129:     default:
                   5130:       if (enc == encoding)
                   5131:         eventPtr = entityTextPtr;
                   5132:       result = XML_ERROR_UNEXPECTED_STATE;
                   5133:       goto endEntityValue;
                   5134:     }
                   5135:     entityTextPtr = next;
                   5136:   }
                   5137: endEntityValue:
                   5138: #ifdef XML_DTD
                   5139:   prologState.inEntityValue = oldInEntityValue;
                   5140: #endif /* XML_DTD */
                   5141:   return result;
                   5142: }
                   5143: 
                   5144: static void FASTCALL
                   5145: normalizeLines(XML_Char *s)
                   5146: {
                   5147:   XML_Char *p;
                   5148:   for (;; s++) {
                   5149:     if (*s == XML_T('\0'))
                   5150:       return;
                   5151:     if (*s == 0xD)
                   5152:       break;
                   5153:   }
                   5154:   p = s;
                   5155:   do {
                   5156:     if (*s == 0xD) {
                   5157:       *p++ = 0xA;
                   5158:       if (*++s == 0xA)
                   5159:         s++;
                   5160:     }
                   5161:     else
                   5162:       *p++ = *s++;
                   5163:   } while (*s);
                   5164:   *p = XML_T('\0');
                   5165: }
                   5166: 
                   5167: static int
                   5168: reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
                   5169:                             const char *start, const char *end)
                   5170: {
                   5171:   const XML_Char *target;
                   5172:   XML_Char *data;
                   5173:   const char *tem;
                   5174:   if (!processingInstructionHandler) {
                   5175:     if (defaultHandler)
                   5176:       reportDefault(parser, enc, start, end);
                   5177:     return 1;
                   5178:   }
                   5179:   start += enc->minBytesPerChar * 2;
                   5180:   tem = start + XmlNameLength(enc, start);
                   5181:   target = poolStoreString(&tempPool, enc, start, tem);
                   5182:   if (!target)
                   5183:     return 0;
                   5184:   poolFinish(&tempPool);
                   5185:   data = poolStoreString(&tempPool, enc,
                   5186:                         XmlSkipS(enc, tem),
                   5187:                         end - enc->minBytesPerChar*2);
                   5188:   if (!data)
                   5189:     return 0;
                   5190:   normalizeLines(data);
                   5191:   processingInstructionHandler(handlerArg, target, data);
                   5192:   poolClear(&tempPool);
                   5193:   return 1;
                   5194: }
                   5195: 
                   5196: static int
                   5197: reportComment(XML_Parser parser, const ENCODING *enc,
                   5198:               const char *start, const char *end)
                   5199: {
                   5200:   XML_Char *data;
                   5201:   if (!commentHandler) {
                   5202:     if (defaultHandler)
                   5203:       reportDefault(parser, enc, start, end);
                   5204:     return 1;
                   5205:   }
                   5206:   data = poolStoreString(&tempPool,
                   5207:                          enc,
                   5208:                          start + enc->minBytesPerChar * 4,
                   5209:                          end - enc->minBytesPerChar * 3);
                   5210:   if (!data)
                   5211:     return 0;
                   5212:   normalizeLines(data);
                   5213:   commentHandler(handlerArg, data);
                   5214:   poolClear(&tempPool);
                   5215:   return 1;
                   5216: }
                   5217: 
                   5218: static void
                   5219: reportDefault(XML_Parser parser, const ENCODING *enc,
                   5220:               const char *s, const char *end)
                   5221: {
                   5222:   if (MUST_CONVERT(enc, s)) {
                   5223:     const char **eventPP;
                   5224:     const char **eventEndPP;
                   5225:     if (enc == encoding) {
                   5226:       eventPP = &eventPtr;
                   5227:       eventEndPP = &eventEndPtr;
                   5228:     }
                   5229:     else {
                   5230:       eventPP = &(openInternalEntities->internalEventPtr);
                   5231:       eventEndPP = &(openInternalEntities->internalEventEndPtr);
                   5232:     }
                   5233:     do {
                   5234:       ICHAR *dataPtr = (ICHAR *)dataBuf;
                   5235:       XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
                   5236:       *eventEndPP = s;
                   5237:       defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
                   5238:       *eventPP = s;
                   5239:     } while (s != end);
                   5240:   }
                   5241:   else
                   5242:     defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
                   5243: }
                   5244: 
                   5245: 
                   5246: static int
                   5247: defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
                   5248:                 XML_Bool isId, const XML_Char *value, XML_Parser parser)
                   5249: {
                   5250:   DEFAULT_ATTRIBUTE *att;
                   5251:   if (value || isId) {
                   5252:     /* The handling of default attributes gets messed up if we have
                   5253:        a default which duplicates a non-default. */
                   5254:     int i;
                   5255:     for (i = 0; i < type->nDefaultAtts; i++)
                   5256:       if (attId == type->defaultAtts[i].id)
                   5257:         return 1;
                   5258:     if (isId && !type->idAtt && !attId->xmlns)
                   5259:       type->idAtt = attId;
                   5260:   }
                   5261:   if (type->nDefaultAtts == type->allocDefaultAtts) {
                   5262:     if (type->allocDefaultAtts == 0) {
                   5263:       type->allocDefaultAtts = 8;
                   5264:       type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
                   5265:                             * sizeof(DEFAULT_ATTRIBUTE));
                   5266:       if (!type->defaultAtts)
                   5267:         return 0;
                   5268:     }
                   5269:     else {
                   5270:       DEFAULT_ATTRIBUTE *temp;
                   5271:       int count = type->allocDefaultAtts * 2;
                   5272:       temp = (DEFAULT_ATTRIBUTE *)
                   5273:         REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
                   5274:       if (temp == NULL)
                   5275:         return 0;
                   5276:       type->allocDefaultAtts = count;
                   5277:       type->defaultAtts = temp;
                   5278:     }
                   5279:   }
                   5280:   att = type->defaultAtts + type->nDefaultAtts;
                   5281:   att->id = attId;
                   5282:   att->value = value;
                   5283:   att->isCdata = isCdata;
                   5284:   if (!isCdata)
                   5285:     attId->maybeTokenized = XML_TRUE;
                   5286:   type->nDefaultAtts += 1;
                   5287:   return 1;
                   5288: }
                   5289: 
                   5290: static int
                   5291: setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
                   5292: {
                   5293:   DTD * const dtd = _dtd;  /* save one level of indirection */
                   5294:   const XML_Char *name;
                   5295:   for (name = elementType->name; *name; name++) {
                   5296:     if (*name == XML_T(ASCII_COLON)) {
                   5297:       PREFIX *prefix;
                   5298:       const XML_Char *s;
                   5299:       for (s = elementType->name; s != name; s++) {
                   5300:         if (!poolAppendChar(&dtd->pool, *s))
                   5301:           return 0;
                   5302:       }
                   5303:       if (!poolAppendChar(&dtd->pool, XML_T('\0')))
                   5304:         return 0;
                   5305:       prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
                   5306:                                 sizeof(PREFIX));
                   5307:       if (!prefix)
                   5308:         return 0;
                   5309:       if (prefix->name == poolStart(&dtd->pool))
                   5310:         poolFinish(&dtd->pool);
                   5311:       else
                   5312:         poolDiscard(&dtd->pool);
                   5313:       elementType->prefix = prefix;
                   5314: 
                   5315:     }
                   5316:   }
                   5317:   return 1;
                   5318: }
                   5319: 
                   5320: static ATTRIBUTE_ID *
                   5321: getAttributeId(XML_Parser parser, const ENCODING *enc,
                   5322:                const char *start, const char *end)
                   5323: {
                   5324:   DTD * const dtd = _dtd;  /* save one level of indirection */
                   5325:   ATTRIBUTE_ID *id;
                   5326:   const XML_Char *name;
                   5327:   if (!poolAppendChar(&dtd->pool, XML_T('\0')))
                   5328:     return NULL;
                   5329:   name = poolStoreString(&dtd->pool, enc, start, end);
                   5330:   if (!name)
                   5331:     return NULL;
                   5332:   /* skip quotation mark - its storage will be re-used (like in name[-1]) */
                   5333:   ++name;
                   5334:   id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
                   5335:   if (!id)
                   5336:     return NULL;
                   5337:   if (id->name != name)
                   5338:     poolDiscard(&dtd->pool);
                   5339:   else {
                   5340:     poolFinish(&dtd->pool);
                   5341:     if (!ns)
                   5342:       ;
                   5343:     else if (name[0] == XML_T(ASCII_x)
                   5344:         && name[1] == XML_T(ASCII_m)
                   5345:         && name[2] == XML_T(ASCII_l)
                   5346:         && name[3] == XML_T(ASCII_n)
                   5347:         && name[4] == XML_T(ASCII_s)
                   5348:         && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
                   5349:       if (name[5] == XML_T('\0'))
                   5350:         id->prefix = &dtd->defaultPrefix;
                   5351:       else
                   5352:         id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
                   5353:       id->xmlns = XML_TRUE;
                   5354:     }
                   5355:     else {
                   5356:       int i;
                   5357:       for (i = 0; name[i]; i++) {
                   5358:         /* attributes without prefix are *not* in the default namespace */
                   5359:         if (name[i] == XML_T(ASCII_COLON)) {
                   5360:           int j;
                   5361:           for (j = 0; j < i; j++) {
                   5362:             if (!poolAppendChar(&dtd->pool, name[j]))
                   5363:               return NULL;
                   5364:           }
                   5365:           if (!poolAppendChar(&dtd->pool, XML_T('\0')))
                   5366:             return NULL;
                   5367:           id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
                   5368:                                         sizeof(PREFIX));
                   5369:           if (id->prefix->name == poolStart(&dtd->pool))
                   5370:             poolFinish(&dtd->pool);
                   5371:           else
                   5372:             poolDiscard(&dtd->pool);
                   5373:           break;
                   5374:         }
                   5375:       }
                   5376:     }
                   5377:   }
                   5378:   return id;
                   5379: }
                   5380: 
                   5381: #define CONTEXT_SEP XML_T(ASCII_FF)
                   5382: 
                   5383: static const XML_Char *
                   5384: getContext(XML_Parser parser)
                   5385: {
                   5386:   DTD * const dtd = _dtd;  /* save one level of indirection */
                   5387:   HASH_TABLE_ITER iter;
                   5388:   XML_Bool needSep = XML_FALSE;
                   5389: 
                   5390:   if (dtd->defaultPrefix.binding) {
                   5391:     int i;
                   5392:     int len;
                   5393:     if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
                   5394:       return NULL;
                   5395:     len = dtd->defaultPrefix.binding->uriLen;
                   5396:     if (namespaceSeparator)
                   5397:       len--;
                   5398:     for (i = 0; i < len; i++)
                   5399:       if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
                   5400:         return NULL;
                   5401:     needSep = XML_TRUE;
                   5402:   }
                   5403: 
                   5404:   hashTableIterInit(&iter, &(dtd->prefixes));
                   5405:   for (;;) {
                   5406:     int i;
                   5407:     int len;
                   5408:     const XML_Char *s;
                   5409:     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
                   5410:     if (!prefix)
                   5411:       break;
                   5412:     if (!prefix->binding)
                   5413:       continue;
                   5414:     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
                   5415:       return NULL;
                   5416:     for (s = prefix->name; *s; s++)
                   5417:       if (!poolAppendChar(&tempPool, *s))
                   5418:         return NULL;
                   5419:     if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
                   5420:       return NULL;
                   5421:     len = prefix->binding->uriLen;
                   5422:     if (namespaceSeparator)
                   5423:       len--;
                   5424:     for (i = 0; i < len; i++)
                   5425:       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
                   5426:         return NULL;
                   5427:     needSep = XML_TRUE;
                   5428:   }
                   5429: 
                   5430: 
                   5431:   hashTableIterInit(&iter, &(dtd->generalEntities));
                   5432:   for (;;) {
                   5433:     const XML_Char *s;
                   5434:     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
                   5435:     if (!e)
                   5436:       break;
                   5437:     if (!e->open)
                   5438:       continue;
                   5439:     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
                   5440:       return NULL;
                   5441:     for (s = e->name; *s; s++)
                   5442:       if (!poolAppendChar(&tempPool, *s))
                   5443:         return 0;
                   5444:     needSep = XML_TRUE;
                   5445:   }
                   5446: 
                   5447:   if (!poolAppendChar(&tempPool, XML_T('\0')))
                   5448:     return NULL;
                   5449:   return tempPool.start;
                   5450: }
                   5451: 
                   5452: static XML_Bool
                   5453: setContext(XML_Parser parser, const XML_Char *context)
                   5454: {
                   5455:   DTD * const dtd = _dtd;  /* save one level of indirection */
                   5456:   const XML_Char *s = context;
                   5457: 
                   5458:   while (*context != XML_T('\0')) {
                   5459:     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
                   5460:       ENTITY *e;
                   5461:       if (!poolAppendChar(&tempPool, XML_T('\0')))
                   5462:         return XML_FALSE;
                   5463:       e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
                   5464:       if (e)
                   5465:         e->open = XML_TRUE;
                   5466:       if (*s != XML_T('\0'))
                   5467:         s++;
                   5468:       context = s;
                   5469:       poolDiscard(&tempPool);
                   5470:     }
                   5471:     else if (*s == XML_T(ASCII_EQUALS)) {
                   5472:       PREFIX *prefix;
                   5473:       if (poolLength(&tempPool) == 0)
                   5474:         prefix = &dtd->defaultPrefix;
                   5475:       else {
                   5476:         if (!poolAppendChar(&tempPool, XML_T('\0')))
                   5477:           return XML_FALSE;
                   5478:         prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
                   5479:                                   sizeof(PREFIX));
                   5480:         if (!prefix)
                   5481:           return XML_FALSE;
                   5482:         if (prefix->name == poolStart(&tempPool)) {
                   5483:           prefix->name = poolCopyString(&dtd->pool, prefix->name);
                   5484:           if (!prefix->name)
                   5485:             return XML_FALSE;
                   5486:         }
                   5487:         poolDiscard(&tempPool);
                   5488:       }
                   5489:       for (context = s + 1;
                   5490:            *context != CONTEXT_SEP && *context != XML_T('\0');
                   5491:            context++)
                   5492:         if (!poolAppendChar(&tempPool, *context))
                   5493:           return XML_FALSE;
                   5494:       if (!poolAppendChar(&tempPool, XML_T('\0')))
                   5495:         return XML_FALSE;
                   5496:       if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
                   5497:                      &inheritedBindings) != XML_ERROR_NONE)
                   5498:         return XML_FALSE;
                   5499:       poolDiscard(&tempPool);
                   5500:       if (*context != XML_T('\0'))
                   5501:         ++context;
                   5502:       s = context;
                   5503:     }
                   5504:     else {
                   5505:       if (!poolAppendChar(&tempPool, *s))
                   5506:         return XML_FALSE;
                   5507:       s++;
                   5508:     }
                   5509:   }
                   5510:   return XML_TRUE;
                   5511: }
                   5512: 
                   5513: static void FASTCALL
                   5514: normalizePublicId(XML_Char *publicId)
                   5515: {
                   5516:   XML_Char *p = publicId;
                   5517:   XML_Char *s;
                   5518:   for (s = publicId; *s; s++) {
                   5519:     switch (*s) {
                   5520:     case 0x20:
                   5521:     case 0xD:
                   5522:     case 0xA:
                   5523:       if (p != publicId && p[-1] != 0x20)
                   5524:         *p++ = 0x20;
                   5525:       break;
                   5526:     default:
                   5527:       *p++ = *s;
                   5528:     }
                   5529:   }
                   5530:   if (p != publicId && p[-1] == 0x20)
                   5531:     --p;
                   5532:   *p = XML_T('\0');
                   5533: }
                   5534: 
                   5535: static DTD *
                   5536: dtdCreate(const XML_Memory_Handling_Suite *ms)
                   5537: {
                   5538:   DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
                   5539:   if (p == NULL)
                   5540:     return p;
                   5541:   poolInit(&(p->pool), ms);
                   5542:   poolInit(&(p->entityValuePool), ms);
                   5543:   hashTableInit(&(p->generalEntities), ms);
                   5544:   hashTableInit(&(p->elementTypes), ms);
                   5545:   hashTableInit(&(p->attributeIds), ms);
                   5546:   hashTableInit(&(p->prefixes), ms);
                   5547: #ifdef XML_DTD
                   5548:   p->paramEntityRead = XML_FALSE;
                   5549:   hashTableInit(&(p->paramEntities), ms);
                   5550: #endif /* XML_DTD */
                   5551:   p->defaultPrefix.name = NULL;
                   5552:   p->defaultPrefix.binding = NULL;
                   5553: 
                   5554:   p->in_eldecl = XML_FALSE;
                   5555:   p->scaffIndex = NULL;
                   5556:   p->scaffold = NULL;
                   5557:   p->scaffLevel = 0;
                   5558:   p->scaffSize = 0;
                   5559:   p->scaffCount = 0;
                   5560:   p->contentStringLen = 0;
                   5561: 
                   5562:   p->keepProcessing = XML_TRUE;
                   5563:   p->hasParamEntityRefs = XML_FALSE;
                   5564:   p->standalone = XML_FALSE;
                   5565:   return p;
                   5566: }
                   5567: 
                   5568: static void
                   5569: dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
                   5570: {
                   5571:   HASH_TABLE_ITER iter;
                   5572:   hashTableIterInit(&iter, &(p->elementTypes));
                   5573:   for (;;) {
                   5574:     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
                   5575:     if (!e)
                   5576:       break;
                   5577:     if (e->allocDefaultAtts != 0)
                   5578:       ms->free_fcn(e->defaultAtts);
                   5579:   }
                   5580:   hashTableClear(&(p->generalEntities));
                   5581: #ifdef XML_DTD
                   5582:   p->paramEntityRead = XML_FALSE;
                   5583:   hashTableClear(&(p->paramEntities));
                   5584: #endif /* XML_DTD */
                   5585:   hashTableClear(&(p->elementTypes));
                   5586:   hashTableClear(&(p->attributeIds));
                   5587:   hashTableClear(&(p->prefixes));
                   5588:   poolClear(&(p->pool));
                   5589:   poolClear(&(p->entityValuePool));
                   5590:   p->defaultPrefix.name = NULL;
                   5591:   p->defaultPrefix.binding = NULL;
                   5592: 
                   5593:   p->in_eldecl = XML_FALSE;
                   5594: 
                   5595:   ms->free_fcn(p->scaffIndex);
                   5596:   p->scaffIndex = NULL;
                   5597:   ms->free_fcn(p->scaffold);
                   5598:   p->scaffold = NULL;
                   5599: 
                   5600:   p->scaffLevel = 0;
                   5601:   p->scaffSize = 0;
                   5602:   p->scaffCount = 0;
                   5603:   p->contentStringLen = 0;
                   5604: 
                   5605:   p->keepProcessing = XML_TRUE;
                   5606:   p->hasParamEntityRefs = XML_FALSE;
                   5607:   p->standalone = XML_FALSE;
                   5608: }
                   5609: 
                   5610: static void
                   5611: dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
                   5612: {
                   5613:   HASH_TABLE_ITER iter;
                   5614:   hashTableIterInit(&iter, &(p->elementTypes));
                   5615:   for (;;) {
                   5616:     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
                   5617:     if (!e)
                   5618:       break;
                   5619:     if (e->allocDefaultAtts != 0)
                   5620:       ms->free_fcn(e->defaultAtts);
                   5621:   }
                   5622:   hashTableDestroy(&(p->generalEntities));
                   5623: #ifdef XML_DTD
                   5624:   hashTableDestroy(&(p->paramEntities));
                   5625: #endif /* XML_DTD */
                   5626:   hashTableDestroy(&(p->elementTypes));
                   5627:   hashTableDestroy(&(p->attributeIds));
                   5628:   hashTableDestroy(&(p->prefixes));
                   5629:   poolDestroy(&(p->pool));
                   5630:   poolDestroy(&(p->entityValuePool));
                   5631:   if (isDocEntity) {
                   5632:     ms->free_fcn(p->scaffIndex);
                   5633:     ms->free_fcn(p->scaffold);
                   5634:   }
                   5635:   ms->free_fcn(p);
                   5636: }
                   5637: 
                   5638: /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
                   5639:    The new DTD has already been initialized.
                   5640: */
                   5641: static int
                   5642: dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
                   5643: {
                   5644:   HASH_TABLE_ITER iter;
                   5645: 
                   5646:   /* Copy the prefix table. */
                   5647: 
                   5648:   hashTableIterInit(&iter, &(oldDtd->prefixes));
                   5649:   for (;;) {
                   5650:     const XML_Char *name;
                   5651:     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
                   5652:     if (!oldP)
                   5653:       break;
                   5654:     name = poolCopyString(&(newDtd->pool), oldP->name);
                   5655:     if (!name)
                   5656:       return 0;
                   5657:     if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
                   5658:       return 0;
                   5659:   }
                   5660: 
                   5661:   hashTableIterInit(&iter, &(oldDtd->attributeIds));
                   5662: 
                   5663:   /* Copy the attribute id table. */
                   5664: 
                   5665:   for (;;) {
                   5666:     ATTRIBUTE_ID *newA;
                   5667:     const XML_Char *name;
                   5668:     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
                   5669: 
                   5670:     if (!oldA)
                   5671:       break;
                   5672:     /* Remember to allocate the scratch byte before the name. */
                   5673:     if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
                   5674:       return 0;
                   5675:     name = poolCopyString(&(newDtd->pool), oldA->name);
                   5676:     if (!name)
                   5677:       return 0;
                   5678:     ++name;
                   5679:     newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
                   5680:                                   sizeof(ATTRIBUTE_ID));
                   5681:     if (!newA)
                   5682:       return 0;
                   5683:     newA->maybeTokenized = oldA->maybeTokenized;
                   5684:     if (oldA->prefix) {
                   5685:       newA->xmlns = oldA->xmlns;
                   5686:       if (oldA->prefix == &oldDtd->defaultPrefix)
                   5687:         newA->prefix = &newDtd->defaultPrefix;
                   5688:       else
                   5689:         newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
                   5690:                                         oldA->prefix->name, 0);
                   5691:     }
                   5692:   }
                   5693: 
                   5694:   /* Copy the element type table. */
                   5695: 
                   5696:   hashTableIterInit(&iter, &(oldDtd->elementTypes));
                   5697: 
                   5698:   for (;;) {
                   5699:     int i;
                   5700:     ELEMENT_TYPE *newE;
                   5701:     const XML_Char *name;
                   5702:     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
                   5703:     if (!oldE)
                   5704:       break;
                   5705:     name = poolCopyString(&(newDtd->pool), oldE->name);
                   5706:     if (!name)
                   5707:       return 0;
                   5708:     newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
                   5709:                                   sizeof(ELEMENT_TYPE));
                   5710:     if (!newE)
                   5711:       return 0;
                   5712:     if (oldE->nDefaultAtts) {
                   5713:       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
                   5714:           ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
                   5715:       if (!newE->defaultAtts) {
                   5716:         ms->free_fcn(newE);
                   5717:         return 0;
                   5718:       }
                   5719:     }
                   5720:     if (oldE->idAtt)
                   5721:       newE->idAtt = (ATTRIBUTE_ID *)
                   5722:           lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
                   5723:     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
                   5724:     if (oldE->prefix)
                   5725:       newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
                   5726:                                       oldE->prefix->name, 0);
                   5727:     for (i = 0; i < newE->nDefaultAtts; i++) {
                   5728:       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
                   5729:           lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
                   5730:       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
                   5731:       if (oldE->defaultAtts[i].value) {
                   5732:         newE->defaultAtts[i].value
                   5733:             = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
                   5734:         if (!newE->defaultAtts[i].value)
                   5735:           return 0;
                   5736:       }
                   5737:       else
                   5738:         newE->defaultAtts[i].value = NULL;
                   5739:     }
                   5740:   }
                   5741: 
                   5742:   /* Copy the entity tables. */
                   5743:   if (!copyEntityTable(&(newDtd->generalEntities),
                   5744:                        &(newDtd->pool),
                   5745:                        &(oldDtd->generalEntities)))
                   5746:       return 0;
                   5747: 
                   5748: #ifdef XML_DTD
                   5749:   if (!copyEntityTable(&(newDtd->paramEntities),
                   5750:                        &(newDtd->pool),
                   5751:                        &(oldDtd->paramEntities)))
                   5752:       return 0;
                   5753:   newDtd->paramEntityRead = oldDtd->paramEntityRead;
                   5754: #endif /* XML_DTD */
                   5755: 
                   5756:   newDtd->keepProcessing = oldDtd->keepProcessing;
                   5757:   newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
                   5758:   newDtd->standalone = oldDtd->standalone;
                   5759: 
                   5760:   /* Don't want deep copying for scaffolding */
                   5761:   newDtd->in_eldecl = oldDtd->in_eldecl;
                   5762:   newDtd->scaffold = oldDtd->scaffold;
                   5763:   newDtd->contentStringLen = oldDtd->contentStringLen;
                   5764:   newDtd->scaffSize = oldDtd->scaffSize;
                   5765:   newDtd->scaffLevel = oldDtd->scaffLevel;
                   5766:   newDtd->scaffIndex = oldDtd->scaffIndex;
                   5767: 
                   5768:   return 1;
                   5769: }  /* End dtdCopy */
                   5770: 
                   5771: static int
                   5772: copyEntityTable(HASH_TABLE *newTable,
                   5773:                 STRING_POOL *newPool,
                   5774:                 const HASH_TABLE *oldTable)
                   5775: {
                   5776:   HASH_TABLE_ITER iter;
                   5777:   const XML_Char *cachedOldBase = NULL;
                   5778:   const XML_Char *cachedNewBase = NULL;
                   5779: 
                   5780:   hashTableIterInit(&iter, oldTable);
                   5781: 
                   5782:   for (;;) {
                   5783:     ENTITY *newE;
                   5784:     const XML_Char *name;
                   5785:     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
                   5786:     if (!oldE)
                   5787:       break;
                   5788:     name = poolCopyString(newPool, oldE->name);
                   5789:     if (!name)
                   5790:       return 0;
                   5791:     newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
                   5792:     if (!newE)
                   5793:       return 0;
                   5794:     if (oldE->systemId) {
                   5795:       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
                   5796:       if (!tem)
                   5797:         return 0;
                   5798:       newE->systemId = tem;
                   5799:       if (oldE->base) {
                   5800:         if (oldE->base == cachedOldBase)
                   5801:           newE->base = cachedNewBase;
                   5802:         else {
                   5803:           cachedOldBase = oldE->base;
                   5804:           tem = poolCopyString(newPool, cachedOldBase);
                   5805:           if (!tem)
                   5806:             return 0;
                   5807:           cachedNewBase = newE->base = tem;
                   5808:         }
                   5809:       }
                   5810:       if (oldE->publicId) {
                   5811:         tem = poolCopyString(newPool, oldE->publicId);
                   5812:         if (!tem)
                   5813:           return 0;
                   5814:         newE->publicId = tem;
                   5815:       }
                   5816:     }
                   5817:     else {
                   5818:       const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
                   5819:                                             oldE->textLen);
                   5820:       if (!tem)
                   5821:         return 0;
                   5822:       newE->textPtr = tem;
                   5823:       newE->textLen = oldE->textLen;
                   5824:     }
                   5825:     if (oldE->notation) {
                   5826:       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
                   5827:       if (!tem)
                   5828:         return 0;
                   5829:       newE->notation = tem;
                   5830:     }
                   5831:     newE->is_param = oldE->is_param;
                   5832:     newE->is_internal = oldE->is_internal;
                   5833:   }
                   5834:   return 1;
                   5835: }
                   5836: 
                   5837: #define INIT_POWER 6
                   5838: 
                   5839: static XML_Bool FASTCALL
                   5840: keyeq(KEY s1, KEY s2)
                   5841: {
                   5842:   for (; *s1 == *s2; s1++, s2++)
                   5843:     if (*s1 == 0)
                   5844:       return XML_TRUE;
                   5845:   return XML_FALSE;
                   5846: }
                   5847: 
                   5848: static unsigned long FASTCALL
                   5849: hash(KEY s)
                   5850: {
                   5851:   unsigned long h = 0;
                   5852:   while (*s)
                   5853:     h = CHAR_HASH(h, *s++);
                   5854:   return h;
                   5855: }
                   5856: 
                   5857: static NAMED *
                   5858: lookup(HASH_TABLE *table, KEY name, size_t createSize)
                   5859: {
                   5860:   size_t i;
                   5861:   if (table->size == 0) {
                   5862:     size_t tsize;
                   5863:     if (!createSize)
                   5864:       return NULL;
                   5865:     table->power = INIT_POWER;
                   5866:     /* table->size is a power of 2 */
                   5867:     table->size = (size_t)1 << INIT_POWER;
                   5868:     tsize = table->size * sizeof(NAMED *);
                   5869:     table->v = (NAMED **)table->mem->malloc_fcn(tsize);
                   5870:     if (!table->v) {
                   5871:       table->size = 0;
                   5872:       return NULL;
                   5873:     }
                   5874:     memset(table->v, 0, tsize);
                   5875:     i = hash(name) & ((unsigned long)table->size - 1);
                   5876:   }
                   5877:   else {
                   5878:     unsigned long h = hash(name);
                   5879:     unsigned long mask = (unsigned long)table->size - 1;
                   5880:     unsigned char step = 0;
                   5881:     i = h & mask;
                   5882:     while (table->v[i]) {
                   5883:       if (keyeq(name, table->v[i]->name))
                   5884:         return table->v[i];
                   5885:       if (!step)
                   5886:         step = PROBE_STEP(h, mask, table->power);
                   5887:       i < step ? (i += table->size - step) : (i -= step);
                   5888:     }
                   5889:     if (!createSize)
                   5890:       return NULL;
                   5891: 
                   5892:     /* check for overflow (table is half full) */
                   5893:     if (table->used >> (table->power - 1)) {
                   5894:       unsigned char newPower = table->power + 1;
                   5895:       size_t newSize = (size_t)1 << newPower;
                   5896:       unsigned long newMask = (unsigned long)newSize - 1;
                   5897:       size_t tsize = newSize * sizeof(NAMED *);
                   5898:       NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
                   5899:       if (!newV)
                   5900:         return NULL;
                   5901:       memset(newV, 0, tsize);
                   5902:       for (i = 0; i < table->size; i++)
                   5903:         if (table->v[i]) {
                   5904:           unsigned long newHash = hash(table->v[i]->name);
                   5905:           size_t j = newHash & newMask;
                   5906:           step = 0;
                   5907:           while (newV[j]) {
                   5908:             if (!step)
                   5909:               step = PROBE_STEP(newHash, newMask, newPower);
                   5910:             j < step ? (j += newSize - step) : (j -= step);
                   5911:           }
                   5912:           newV[j] = table->v[i];
                   5913:         }
                   5914:       table->mem->free_fcn(table->v);
                   5915:       table->v = newV;
                   5916:       table->power = newPower;
                   5917:       table->size = newSize;
                   5918:       i = h & newMask;
                   5919:       step = 0;
                   5920:       while (table->v[i]) {
                   5921:         if (!step)
                   5922:           step = PROBE_STEP(h, newMask, newPower);
                   5923:         i < step ? (i += newSize - step) : (i -= step);
                   5924:       }
                   5925:     }
                   5926:   }
                   5927:   table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
                   5928:   if (!table->v[i])
                   5929:     return NULL;
                   5930:   memset(table->v[i], 0, createSize);
                   5931:   table->v[i]->name = name;
                   5932:   (table->used)++;
                   5933:   return table->v[i];
                   5934: }
                   5935: 
                   5936: static void FASTCALL
                   5937: hashTableClear(HASH_TABLE *table)
                   5938: {
                   5939:   size_t i;
                   5940:   for (i = 0; i < table->size; i++) {
                   5941:     table->mem->free_fcn(table->v[i]);
                   5942:     table->v[i] = NULL;
                   5943:   }
                   5944:   table->used = 0;
                   5945: }
                   5946: 
                   5947: static void FASTCALL
                   5948: hashTableDestroy(HASH_TABLE *table)
                   5949: {
                   5950:   size_t i;
                   5951:   for (i = 0; i < table->size; i++)
                   5952:     table->mem->free_fcn(table->v[i]);
                   5953:   table->mem->free_fcn(table->v);
                   5954: }
                   5955: 
                   5956: static void FASTCALL
                   5957: hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
                   5958: {
                   5959:   p->power = 0;
                   5960:   p->size = 0;
                   5961:   p->used = 0;
                   5962:   p->v = NULL;
                   5963:   p->mem = ms;
                   5964: }
                   5965: 
                   5966: static void FASTCALL
                   5967: hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
                   5968: {
                   5969:   iter->p = table->v;
                   5970:   iter->end = iter->p + table->size;
                   5971: }
                   5972: 
                   5973: static NAMED * FASTCALL
                   5974: hashTableIterNext(HASH_TABLE_ITER *iter)
                   5975: {
                   5976:   while (iter->p != iter->end) {
                   5977:     NAMED *tem = *(iter->p)++;
                   5978:     if (tem)
                   5979:       return tem;
                   5980:   }
                   5981:   return NULL;
                   5982: }
                   5983: 
                   5984: static void FASTCALL
                   5985: poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
                   5986: {
                   5987:   pool->blocks = NULL;
                   5988:   pool->freeBlocks = NULL;
                   5989:   pool->start = NULL;
                   5990:   pool->ptr = NULL;
                   5991:   pool->end = NULL;
                   5992:   pool->mem = ms;
                   5993: }
                   5994: 
                   5995: static void FASTCALL
                   5996: poolClear(STRING_POOL *pool)
                   5997: {
                   5998:   if (!pool->freeBlocks)
                   5999:     pool->freeBlocks = pool->blocks;
                   6000:   else {
                   6001:     BLOCK *p = pool->blocks;
                   6002:     while (p) {
                   6003:       BLOCK *tem = p->next;
                   6004:       p->next = pool->freeBlocks;
                   6005:       pool->freeBlocks = p;
                   6006:       p = tem;
                   6007:     }
                   6008:   }
                   6009:   pool->blocks = NULL;
                   6010:   pool->start = NULL;
                   6011:   pool->ptr = NULL;
                   6012:   pool->end = NULL;
                   6013: }
                   6014: 
                   6015: static void FASTCALL
                   6016: poolDestroy(STRING_POOL *pool)
                   6017: {
                   6018:   BLOCK *p = pool->blocks;
                   6019:   while (p) {
                   6020:     BLOCK *tem = p->next;
                   6021:     pool->mem->free_fcn(p);
                   6022:     p = tem;
                   6023:   }
                   6024:   p = pool->freeBlocks;
                   6025:   while (p) {
                   6026:     BLOCK *tem = p->next;
                   6027:     pool->mem->free_fcn(p);
                   6028:     p = tem;
                   6029:   }
                   6030: }
                   6031: 
                   6032: static XML_Char *
                   6033: poolAppend(STRING_POOL *pool, const ENCODING *enc,
                   6034:            const char *ptr, const char *end)
                   6035: {
                   6036:   if (!pool->ptr && !poolGrow(pool))
                   6037:     return NULL;
                   6038:   for (;;) {
                   6039:     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
                   6040:     if (ptr == end)
                   6041:       break;
                   6042:     if (!poolGrow(pool))
                   6043:       return NULL;
                   6044:   }
                   6045:   return pool->start;
                   6046: }
                   6047: 
                   6048: static const XML_Char * FASTCALL
                   6049: poolCopyString(STRING_POOL *pool, const XML_Char *s)
                   6050: {
                   6051:   do {
                   6052:     if (!poolAppendChar(pool, *s))
                   6053:       return NULL;
                   6054:   } while (*s++);
                   6055:   s = pool->start;
                   6056:   poolFinish(pool);
                   6057:   return s;
                   6058: }
                   6059: 
                   6060: static const XML_Char *
                   6061: poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
                   6062: {
                   6063:   if (!pool->ptr && !poolGrow(pool))
                   6064:     return NULL;
                   6065:   for (; n > 0; --n, s++) {
                   6066:     if (!poolAppendChar(pool, *s))
                   6067:       return NULL;
                   6068:   }
                   6069:   s = pool->start;
                   6070:   poolFinish(pool);
                   6071:   return s;
                   6072: }
                   6073: 
                   6074: static const XML_Char * FASTCALL
                   6075: poolAppendString(STRING_POOL *pool, const XML_Char *s)
                   6076: {
                   6077:   while (*s) {
                   6078:     if (!poolAppendChar(pool, *s))
                   6079:       return NULL;
                   6080:     s++;
                   6081:   }
                   6082:   return pool->start;
                   6083: }
                   6084: 
                   6085: static XML_Char *
                   6086: poolStoreString(STRING_POOL *pool, const ENCODING *enc,
                   6087:                 const char *ptr, const char *end)
                   6088: {
                   6089:   if (!poolAppend(pool, enc, ptr, end))
                   6090:     return NULL;
                   6091:   if (pool->ptr == pool->end && !poolGrow(pool))
                   6092:     return NULL;
                   6093:   *(pool->ptr)++ = 0;
                   6094:   return pool->start;
                   6095: }
                   6096: 
                   6097: static XML_Bool FASTCALL
                   6098: poolGrow(STRING_POOL *pool)
                   6099: {
                   6100:   if (pool->freeBlocks) {
                   6101:     if (pool->start == 0) {
                   6102:       pool->blocks = pool->freeBlocks;
                   6103:       pool->freeBlocks = pool->freeBlocks->next;
                   6104:       pool->blocks->next = NULL;
                   6105:       pool->start = pool->blocks->s;
                   6106:       pool->end = pool->start + pool->blocks->size;
                   6107:       pool->ptr = pool->start;
                   6108:       return XML_TRUE;
                   6109:     }
                   6110:     if (pool->end - pool->start < pool->freeBlocks->size) {
                   6111:       BLOCK *tem = pool->freeBlocks->next;
                   6112:       pool->freeBlocks->next = pool->blocks;
                   6113:       pool->blocks = pool->freeBlocks;
                   6114:       pool->freeBlocks = tem;
                   6115:       memcpy(pool->blocks->s, pool->start,
                   6116:              (pool->end - pool->start) * sizeof(XML_Char));
                   6117:       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
                   6118:       pool->start = pool->blocks->s;
                   6119:       pool->end = pool->start + pool->blocks->size;
                   6120:       return XML_TRUE;
                   6121:     }
                   6122:   }
                   6123:   if (pool->blocks && pool->start == pool->blocks->s) {
                   6124:     int blockSize = (int)(pool->end - pool->start)*2;
                   6125:     pool->blocks = (BLOCK *)
                   6126:       pool->mem->realloc_fcn(pool->blocks,
                   6127:                              (offsetof(BLOCK, s)
                   6128:                               + blockSize * sizeof(XML_Char)));
                   6129:     if (pool->blocks == NULL)
                   6130:       return XML_FALSE;
                   6131:     pool->blocks->size = blockSize;
                   6132:     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
                   6133:     pool->start = pool->blocks->s;
                   6134:     pool->end = pool->start + blockSize;
                   6135:   }
                   6136:   else {
                   6137:     BLOCK *tem;
                   6138:     int blockSize = (int)(pool->end - pool->start);
                   6139:     if (blockSize < INIT_BLOCK_SIZE)
                   6140:       blockSize = INIT_BLOCK_SIZE;
                   6141:     else
                   6142:       blockSize *= 2;
                   6143:     tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
                   6144:                                         + blockSize * sizeof(XML_Char));
                   6145:     if (!tem)
                   6146:       return XML_FALSE;
                   6147:     tem->size = blockSize;
                   6148:     tem->next = pool->blocks;
                   6149:     pool->blocks = tem;
                   6150:     if (pool->ptr != pool->start)
                   6151:       memcpy(tem->s, pool->start,
                   6152:              (pool->ptr - pool->start) * sizeof(XML_Char));
                   6153:     pool->ptr = tem->s + (pool->ptr - pool->start);
                   6154:     pool->start = tem->s;
                   6155:     pool->end = tem->s + blockSize;
                   6156:   }
                   6157:   return XML_TRUE;
                   6158: }
                   6159: 
                   6160: static int FASTCALL
                   6161: nextScaffoldPart(XML_Parser parser)
                   6162: {
                   6163:   DTD * const dtd = _dtd;  /* save one level of indirection */
                   6164:   CONTENT_SCAFFOLD * me;
                   6165:   int next;
                   6166: 
                   6167:   if (!dtd->scaffIndex) {
                   6168:     dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
                   6169:     if (!dtd->scaffIndex)
                   6170:       return -1;
                   6171:     dtd->scaffIndex[0] = 0;
                   6172:   }
                   6173: 
                   6174:   if (dtd->scaffCount >= dtd->scaffSize) {
                   6175:     CONTENT_SCAFFOLD *temp;
                   6176:     if (dtd->scaffold) {
                   6177:       temp = (CONTENT_SCAFFOLD *)
                   6178:         REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
                   6179:       if (temp == NULL)
                   6180:         return -1;
                   6181:       dtd->scaffSize *= 2;
                   6182:     }
                   6183:     else {
                   6184:       temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
                   6185:                                         * sizeof(CONTENT_SCAFFOLD));
                   6186:       if (temp == NULL)
                   6187:         return -1;
                   6188:       dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
                   6189:     }
                   6190:     dtd->scaffold = temp;
                   6191:   }
                   6192:   next = dtd->scaffCount++;
                   6193:   me = &dtd->scaffold[next];
                   6194:   if (dtd->scaffLevel) {
                   6195:     CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
                   6196:     if (parent->lastchild) {
                   6197:       dtd->scaffold[parent->lastchild].nextsib = next;
                   6198:     }
                   6199:     if (!parent->childcnt)
                   6200:       parent->firstchild = next;
                   6201:     parent->lastchild = next;
                   6202:     parent->childcnt++;
                   6203:   }
                   6204:   me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
                   6205:   return next;
                   6206: }
                   6207: 
                   6208: static void
                   6209: build_node(XML_Parser parser,
                   6210:            int src_node,
                   6211:            XML_Content *dest,
                   6212:            XML_Content **contpos,
                   6213:            XML_Char **strpos)
                   6214: {
                   6215:   DTD * const dtd = _dtd;  /* save one level of indirection */
                   6216:   dest->type = dtd->scaffold[src_node].type;
                   6217:   dest->quant = dtd->scaffold[src_node].quant;
                   6218:   if (dest->type == XML_CTYPE_NAME) {
                   6219:     const XML_Char *src;
                   6220:     dest->name = *strpos;
                   6221:     src = dtd->scaffold[src_node].name;
                   6222:     for (;;) {
                   6223:       *(*strpos)++ = *src;
                   6224:       if (!*src)
                   6225:         break;
                   6226:       src++;
                   6227:     }
                   6228:     dest->numchildren = 0;
                   6229:     dest->children = NULL;
                   6230:   }
                   6231:   else {
                   6232:     unsigned int i;
                   6233:     int cn;
                   6234:     dest->numchildren = dtd->scaffold[src_node].childcnt;
                   6235:     dest->children = *contpos;
                   6236:     *contpos += dest->numchildren;
                   6237:     for (i = 0, cn = dtd->scaffold[src_node].firstchild;
                   6238:          i < dest->numchildren;
                   6239:          i++, cn = dtd->scaffold[cn].nextsib) {
                   6240:       build_node(parser, cn, &(dest->children[i]), contpos, strpos);
                   6241:     }
                   6242:     dest->name = NULL;
                   6243:   }
                   6244: }
                   6245: 
                   6246: static XML_Content *
                   6247: build_model (XML_Parser parser)
                   6248: {
                   6249:   DTD * const dtd = _dtd;  /* save one level of indirection */
                   6250:   XML_Content *ret;
                   6251:   XML_Content *cpos;
                   6252:   XML_Char * str;
                   6253:   int allocsize = (dtd->scaffCount * sizeof(XML_Content)
                   6254:                    + (dtd->contentStringLen * sizeof(XML_Char)));
                   6255: 
                   6256:   ret = (XML_Content *)MALLOC(allocsize);
                   6257:   if (!ret)
                   6258:     return NULL;
                   6259: 
                   6260:   str =  (XML_Char *) (&ret[dtd->scaffCount]);
                   6261:   cpos = &ret[1];
                   6262: 
                   6263:   build_node(parser, 0, ret, &cpos, &str);
                   6264:   return ret;
                   6265: }
                   6266: 
                   6267: static ELEMENT_TYPE *
                   6268: getElementType(XML_Parser parser,
                   6269:                const ENCODING *enc,
                   6270:                const char *ptr,
                   6271:                const char *end)
                   6272: {
                   6273:   DTD * const dtd = _dtd;  /* save one level of indirection */
                   6274:   const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
                   6275:   ELEMENT_TYPE *ret;
                   6276: 
                   6277:   if (!name)
                   6278:     return NULL;
                   6279:   ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
                   6280:   if (!ret)
                   6281:     return NULL;
                   6282:   if (ret->name != name)
                   6283:     poolDiscard(&dtd->pool);
                   6284:   else {
                   6285:     poolFinish(&dtd->pool);
                   6286:     if (!setElementTypePrefix(parser, ret))
                   6287:       return NULL;
                   6288:   }
                   6289:   return ret;
                   6290: }

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