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