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

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

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