File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / expat / lib / xmlparse.c
Revision 1.1.1.1.2.1: download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 01:14:39 2013 UTC (10 years, 11 months ago) by misho
Branches: v2_0_1p0
Diff to: branchpoint 1.1.1.1: preferred, unified
patch0

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

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