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