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