blob: fc4adbb020183957b227637684fe8b85e1c4c549 [file] [log] [blame]
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003*/
4
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005#include <stddef.h>
6#include <string.h> /* memset(), memcpy() */
7
Fred Drake08317ae2003-10-21 15:38:55 +00008#define XML_BUILDING_EXPAT 1
9
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000010#ifdef COMPILED_FROM_DSP
Martin v. Löwisfc03a942003-01-25 22:41:29 +000011#include "winconfig.h"
Martin v. Löwisfc03a942003-01-25 22:41:29 +000012#elif defined(MACOS_CLASSIC)
Martin v. Löwisfc03a942003-01-25 22:41:29 +000013#include "macconfig.h"
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000014#else
Fred Drake08317ae2003-10-21 15:38:55 +000015#ifdef HAVE_EXPAT_CONFIG_H
Martin v. Löwisfc03a942003-01-25 22:41:29 +000016#include <expat_config.h>
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000017#endif
18#endif /* ndef COMPILED_FROM_DSP */
19
Fred Drake08317ae2003-10-21 15:38:55 +000020#include "expat.h"
21
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000022#ifdef XML_UNICODE
23#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
24#define XmlConvert XmlUtf16Convert
25#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
26#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
27#define XmlEncode XmlUtf16Encode
28#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
29typedef unsigned short ICHAR;
30#else
31#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
32#define XmlConvert XmlUtf8Convert
33#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
34#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
35#define XmlEncode XmlUtf8Encode
36#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
37typedef char ICHAR;
38#endif
39
40
41#ifndef XML_NS
42
43#define XmlInitEncodingNS XmlInitEncoding
44#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
45#undef XmlGetInternalEncodingNS
46#define XmlGetInternalEncodingNS XmlGetInternalEncoding
47#define XmlParseXmlDeclNS XmlParseXmlDecl
48
49#endif
50
Martin v. Löwisfc03a942003-01-25 22:41:29 +000051#ifdef XML_UNICODE
52
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000053#ifdef XML_UNICODE_WCHAR_T
Martin v. Löwisfc03a942003-01-25 22:41:29 +000054#define XML_T(x) (const wchar_t)x
55#define XML_L(x) L ## x
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000056#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +000057#define XML_T(x) (const unsigned short)x
58#define XML_L(x) x
59#endif
60
61#else
62
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000063#define XML_T(x) x
Martin v. Löwisfc03a942003-01-25 22:41:29 +000064#define XML_L(x) x
65
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000066#endif
67
68/* Round up n to be a multiple of sz, where sz is a power of 2. */
69#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
70
Fred Drake08317ae2003-10-21 15:38:55 +000071/* Handle the case where memmove() doesn't exist. */
72#ifndef HAVE_MEMMOVE
73#ifdef HAVE_BCOPY
74#define memmove(d,s,l) bcopy((s),(d),(l))
75#else
76#error memmove does not exist on this platform, nor is a substitute available
77#endif /* HAVE_BCOPY */
78#endif /* HAVE_MEMMOVE */
79
Martin v. Löwisfc03a942003-01-25 22:41:29 +000080#include "internal.h"
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000081#include "xmltok.h"
82#include "xmlrole.h"
83
84typedef const XML_Char *KEY;
85
86typedef struct {
87 KEY name;
88} NAMED;
89
90typedef struct {
91 NAMED **v;
Fred Drake08317ae2003-10-21 15:38:55 +000092 unsigned char power;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000093 size_t size;
94 size_t used;
Martin v. Löwisfc03a942003-01-25 22:41:29 +000095 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000096} HASH_TABLE;
97
Fred Drake08317ae2003-10-21 15:38:55 +000098/* Basic character hash algorithm, taken from Python's string hash:
99 h = h * 1000003 ^ character, the constant being a prime number.
100
101*/
102#ifdef XML_UNICODE
103#define CHAR_HASH(h, c) \
104 (((h) * 0xF4243) ^ (unsigned short)(c))
105#else
106#define CHAR_HASH(h, c) \
107 (((h) * 0xF4243) ^ (unsigned char)(c))
108#endif
109
110/* For probing (after a collision) we need a step size relative prime
111 to the hash table size, which is a power of 2. We use double-hashing,
112 since we can calculate a second hash value cheaply by taking those bits
113 of the first hash value that were discarded (masked out) when the table
114 index was calculated: index = hash & mask, where mask = table->size - 1.
115 We limit the maximum step size to table->size / 4 (mask >> 2) and make
116 it odd, since odd numbers are always relative prime to a power of 2.
117*/
118#define SECOND_HASH(hash, mask, power) \
119 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
120#define PROBE_STEP(hash, mask, power) \
121 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
122
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000123typedef struct {
124 NAMED **p;
125 NAMED **end;
126} HASH_TABLE_ITER;
127
128#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
129#define INIT_DATA_BUF_SIZE 1024
130#define INIT_ATTS_SIZE 16
Fred Drake08317ae2003-10-21 15:38:55 +0000131#define INIT_ATTS_VERSION 0xFFFFFFFF
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000132#define INIT_BLOCK_SIZE 1024
133#define INIT_BUFFER_SIZE 1024
134
135#define EXPAND_SPARE 24
136
137typedef struct binding {
138 struct prefix *prefix;
139 struct binding *nextTagBinding;
140 struct binding *prevPrefixBinding;
141 const struct attribute_id *attId;
142 XML_Char *uri;
143 int uriLen;
144 int uriAlloc;
145} BINDING;
146
147typedef struct prefix {
148 const XML_Char *name;
149 BINDING *binding;
150} PREFIX;
151
152typedef struct {
153 const XML_Char *str;
154 const XML_Char *localPart;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000155 const XML_Char *prefix;
156 int strLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000157 int uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000158 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000159} TAG_NAME;
160
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000161/* TAG represents an open element.
162 The name of the element is stored in both the document and API
163 encodings. The memory buffer 'buf' is a separately-allocated
164 memory area which stores the name. During the XML_Parse()/
165 XMLParseBuffer() when the element is open, the memory for the 'raw'
166 version of the name (in the document encoding) is shared with the
167 document buffer. If the element is open across calls to
168 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
169 contain the 'raw' name as well.
170
171 A parser re-uses these structures, maintaining a list of allocated
172 TAG objects in a free list.
173*/
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000174typedef struct tag {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000175 struct tag *parent; /* parent of this element */
176 const char *rawName; /* tagName in the original encoding */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000177 int rawNameLength;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000178 TAG_NAME name; /* tagName in the API encoding */
179 char *buf; /* buffer for name components */
180 char *bufEnd; /* end of the buffer */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000181 BINDING *bindings;
182} TAG;
183
184typedef struct {
185 const XML_Char *name;
186 const XML_Char *textPtr;
187 int textLen;
188 const XML_Char *systemId;
189 const XML_Char *base;
190 const XML_Char *publicId;
191 const XML_Char *notation;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000192 XML_Bool open;
193 XML_Bool is_param;
194 XML_Bool is_internal; /* true if declared in internal subset outside PE */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000195} ENTITY;
196
197typedef struct {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000198 enum XML_Content_Type type;
199 enum XML_Content_Quant quant;
200 const XML_Char * name;
201 int firstchild;
202 int lastchild;
203 int childcnt;
204 int nextsib;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000205} CONTENT_SCAFFOLD;
206
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000207#define INIT_SCAFFOLD_ELEMENTS 32
208
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000209typedef struct block {
210 struct block *next;
211 int size;
212 XML_Char s[1];
213} BLOCK;
214
215typedef struct {
216 BLOCK *blocks;
217 BLOCK *freeBlocks;
218 const XML_Char *end;
219 XML_Char *ptr;
220 XML_Char *start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000221 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000222} STRING_POOL;
223
224/* The XML_Char before the name is used to determine whether
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000225 an attribute has been specified. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000226typedef struct attribute_id {
227 XML_Char *name;
228 PREFIX *prefix;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000229 XML_Bool maybeTokenized;
230 XML_Bool xmlns;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000231} ATTRIBUTE_ID;
232
233typedef struct {
234 const ATTRIBUTE_ID *id;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000235 XML_Bool isCdata;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000236 const XML_Char *value;
237} DEFAULT_ATTRIBUTE;
238
239typedef struct {
Fred Drake08317ae2003-10-21 15:38:55 +0000240 unsigned long version;
241 unsigned long hash;
242 const XML_Char *uriName;
243} NS_ATT;
244
245typedef struct {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000246 const XML_Char *name;
247 PREFIX *prefix;
248 const ATTRIBUTE_ID *idAtt;
249 int nDefaultAtts;
250 int allocDefaultAtts;
251 DEFAULT_ATTRIBUTE *defaultAtts;
252} ELEMENT_TYPE;
253
254typedef struct {
255 HASH_TABLE generalEntities;
256 HASH_TABLE elementTypes;
257 HASH_TABLE attributeIds;
258 HASH_TABLE prefixes;
259 STRING_POOL pool;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000260 STRING_POOL entityValuePool;
261 /* false once a parameter entity reference has been skipped */
262 XML_Bool keepProcessing;
263 /* true once an internal or external PE reference has been encountered;
264 this includes the reference to an external subset */
265 XML_Bool hasParamEntityRefs;
266 XML_Bool standalone;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000267#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000268 /* indicates if external PE has been read */
269 XML_Bool paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000270 HASH_TABLE paramEntities;
271#endif /* XML_DTD */
272 PREFIX defaultPrefix;
273 /* === scaffolding for building content model === */
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000274 XML_Bool in_eldecl;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000275 CONTENT_SCAFFOLD *scaffold;
276 unsigned contentStringLen;
277 unsigned scaffSize;
278 unsigned scaffCount;
279 int scaffLevel;
280 int *scaffIndex;
281} DTD;
282
283typedef struct open_internal_entity {
284 const char *internalEventPtr;
285 const char *internalEventEndPtr;
286 struct open_internal_entity *next;
287 ENTITY *entity;
288} OPEN_INTERNAL_ENTITY;
289
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000290typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
291 const char *start,
292 const char *end,
293 const char **endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000294
295static Processor prologProcessor;
296static Processor prologInitProcessor;
297static Processor contentProcessor;
298static Processor cdataSectionProcessor;
299#ifdef XML_DTD
300static Processor ignoreSectionProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000301static Processor externalParEntProcessor;
302static Processor externalParEntInitProcessor;
303static Processor entityValueProcessor;
304static Processor entityValueInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000305#endif /* XML_DTD */
306static Processor epilogProcessor;
307static Processor errorProcessor;
308static Processor externalEntityInitProcessor;
309static Processor externalEntityInitProcessor2;
310static Processor externalEntityInitProcessor3;
311static Processor externalEntityContentProcessor;
312
313static enum XML_Error
314handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
315static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000316processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
317 const char *, const char *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000318static enum XML_Error
319initializeEncoding(XML_Parser parser);
320static enum XML_Error
321doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000322 const char *end, int tok, const char *next, const char **nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000323static enum XML_Error
324processInternalParamEntity(XML_Parser parser, ENTITY *entity);
325static enum XML_Error
326doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000327 const char *start, const char *end, const char **endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000328static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000329doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
330 const char *end, const char **nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000331#ifdef XML_DTD
332static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000333doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
334 const char *end, const char **nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000335#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000336
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000337static enum XML_Error
Fred Drake4faea012003-01-28 06:42:40 +0000338storeAtts(XML_Parser parser, const ENCODING *, const char *s,
339 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000340static enum XML_Error
341addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
342 const XML_Char *uri, BINDING **bindingsPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000343static int
344defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000345 XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue,
346 XML_Parser parser);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000347static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000348storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
349 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000350static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000351appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
352 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000353static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000354getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
355 const char *end);
356static int
357setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000358static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000359storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
360 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000361static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000362reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
363 const char *start, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000364static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000365reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
366 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000367static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000368reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
369 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000370
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000371static const XML_Char * getContext(XML_Parser parser);
372static XML_Bool
373setContext(XML_Parser parser, const XML_Char *context);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000374
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000375static void FASTCALL normalizePublicId(XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000376
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000377static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
378/* do not call if parentParser != NULL */
379static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
380static void
381dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
382static int
383dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
384static int
385copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000386
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000387static NAMED *
388lookup(HASH_TABLE *table, KEY name, size_t createSize);
389static void FASTCALL
390hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
391static void FASTCALL hashTableClear(HASH_TABLE *);
392static void FASTCALL hashTableDestroy(HASH_TABLE *);
393static void FASTCALL
394hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
395static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000396
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000397static void FASTCALL
398poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
399static void FASTCALL poolClear(STRING_POOL *);
400static void FASTCALL poolDestroy(STRING_POOL *);
401static XML_Char *
402poolAppend(STRING_POOL *pool, const ENCODING *enc,
403 const char *ptr, const char *end);
404static XML_Char *
405poolStoreString(STRING_POOL *pool, const ENCODING *enc,
406 const char *ptr, const char *end);
407static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
408static const XML_Char * FASTCALL
409poolCopyString(STRING_POOL *pool, const XML_Char *s);
410static const XML_Char *
411poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
412static const XML_Char * FASTCALL
413poolAppendString(STRING_POOL *pool, const XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000414
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000415static int FASTCALL nextScaffoldPart(XML_Parser parser);
416static XML_Content * build_model(XML_Parser parser);
417static ELEMENT_TYPE *
418getElementType(XML_Parser parser, const ENCODING *enc,
419 const char *ptr, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000420
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000421static XML_Parser
422parserCreate(const XML_Char *encodingName,
423 const XML_Memory_Handling_Suite *memsuite,
424 const XML_Char *nameSep,
425 DTD *dtd);
426static void
427parserInit(XML_Parser parser, const XML_Char *encodingName);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000428
429#define poolStart(pool) ((pool)->start)
430#define poolEnd(pool) ((pool)->ptr)
431#define poolLength(pool) ((pool)->ptr - (pool)->start)
432#define poolChop(pool) ((void)--(pool->ptr))
433#define poolLastChar(pool) (((pool)->ptr)[-1])
434#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
435#define poolFinish(pool) ((pool)->start = (pool)->ptr)
436#define poolAppendChar(pool, c) \
437 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
438 ? 0 \
439 : ((*((pool)->ptr)++ = c), 1))
440
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000441struct XML_ParserStruct {
442 /* The first member must be userData so that the XML_GetUserData
443 macro works. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000444 void *m_userData;
445 void *m_handlerArg;
446 char *m_buffer;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000447 const XML_Memory_Handling_Suite m_mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000448 /* first character to be parsed */
449 const char *m_bufferPtr;
450 /* past last character to be parsed */
451 char *m_bufferEnd;
452 /* allocated end of buffer */
453 const char *m_bufferLim;
454 long m_parseEndByteIndex;
455 const char *m_parseEndPtr;
456 XML_Char *m_dataBuf;
457 XML_Char *m_dataBufEnd;
458 XML_StartElementHandler m_startElementHandler;
459 XML_EndElementHandler m_endElementHandler;
460 XML_CharacterDataHandler m_characterDataHandler;
461 XML_ProcessingInstructionHandler m_processingInstructionHandler;
462 XML_CommentHandler m_commentHandler;
463 XML_StartCdataSectionHandler m_startCdataSectionHandler;
464 XML_EndCdataSectionHandler m_endCdataSectionHandler;
465 XML_DefaultHandler m_defaultHandler;
466 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
467 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
468 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
469 XML_NotationDeclHandler m_notationDeclHandler;
470 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
471 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
472 XML_NotStandaloneHandler m_notStandaloneHandler;
473 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000474 XML_Parser m_externalEntityRefHandlerArg;
475 XML_SkippedEntityHandler m_skippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000476 XML_UnknownEncodingHandler m_unknownEncodingHandler;
477 XML_ElementDeclHandler m_elementDeclHandler;
478 XML_AttlistDeclHandler m_attlistDeclHandler;
479 XML_EntityDeclHandler m_entityDeclHandler;
480 XML_XmlDeclHandler m_xmlDeclHandler;
481 const ENCODING *m_encoding;
482 INIT_ENCODING m_initEncoding;
483 const ENCODING *m_internalEncoding;
484 const XML_Char *m_protocolEncodingName;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000485 XML_Bool m_ns;
486 XML_Bool m_ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000487 void *m_unknownEncodingMem;
488 void *m_unknownEncodingData;
489 void *m_unknownEncodingHandlerData;
490 void (*m_unknownEncodingRelease)(void *);
491 PROLOG_STATE m_prologState;
492 Processor *m_processor;
493 enum XML_Error m_errorCode;
494 const char *m_eventPtr;
495 const char *m_eventEndPtr;
496 const char *m_positionPtr;
497 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000498 XML_Bool m_defaultExpandInternalEntities;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000499 int m_tagLevel;
500 ENTITY *m_declEntity;
501 const XML_Char *m_doctypeName;
502 const XML_Char *m_doctypeSysid;
503 const XML_Char *m_doctypePubid;
504 const XML_Char *m_declAttributeType;
505 const XML_Char *m_declNotationName;
506 const XML_Char *m_declNotationPublicId;
507 ELEMENT_TYPE *m_declElementType;
508 ATTRIBUTE_ID *m_declAttributeId;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000509 XML_Bool m_declAttributeIsCdata;
510 XML_Bool m_declAttributeIsId;
511 DTD *m_dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000512 const XML_Char *m_curBase;
513 TAG *m_tagStack;
514 TAG *m_freeTagList;
515 BINDING *m_inheritedBindings;
516 BINDING *m_freeBindingList;
517 int m_attsSize;
518 int m_nSpecifiedAtts;
519 int m_idAttIndex;
520 ATTRIBUTE *m_atts;
Fred Drake08317ae2003-10-21 15:38:55 +0000521 NS_ATT *m_nsAtts;
522 unsigned long m_nsAttsVersion;
523 unsigned char m_nsAttsPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000524 POSITION m_position;
525 STRING_POOL m_tempPool;
526 STRING_POOL m_temp2Pool;
527 char *m_groupConnector;
Fred Drake08317ae2003-10-21 15:38:55 +0000528 unsigned int m_groupSize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000529 XML_Char m_namespaceSeparator;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000530 XML_Parser m_parentParser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000531#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000532 XML_Bool m_isParamEntity;
533 XML_Bool m_useForeignDTD;
534 enum XML_ParamEntityParsing m_paramEntityParsing;
535#endif
536};
537
538#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
539#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
540#define FREE(p) (parser->m_mem.free_fcn((p)))
541
542#define userData (parser->m_userData)
543#define handlerArg (parser->m_handlerArg)
544#define startElementHandler (parser->m_startElementHandler)
545#define endElementHandler (parser->m_endElementHandler)
546#define characterDataHandler (parser->m_characterDataHandler)
547#define processingInstructionHandler \
548 (parser->m_processingInstructionHandler)
549#define commentHandler (parser->m_commentHandler)
550#define startCdataSectionHandler \
551 (parser->m_startCdataSectionHandler)
552#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
553#define defaultHandler (parser->m_defaultHandler)
554#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
555#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
556#define unparsedEntityDeclHandler \
557 (parser->m_unparsedEntityDeclHandler)
558#define notationDeclHandler (parser->m_notationDeclHandler)
559#define startNamespaceDeclHandler \
560 (parser->m_startNamespaceDeclHandler)
561#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
562#define notStandaloneHandler (parser->m_notStandaloneHandler)
563#define externalEntityRefHandler \
564 (parser->m_externalEntityRefHandler)
565#define externalEntityRefHandlerArg \
566 (parser->m_externalEntityRefHandlerArg)
567#define internalEntityRefHandler \
568 (parser->m_internalEntityRefHandler)
569#define skippedEntityHandler (parser->m_skippedEntityHandler)
570#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
571#define elementDeclHandler (parser->m_elementDeclHandler)
572#define attlistDeclHandler (parser->m_attlistDeclHandler)
573#define entityDeclHandler (parser->m_entityDeclHandler)
574#define xmlDeclHandler (parser->m_xmlDeclHandler)
575#define encoding (parser->m_encoding)
576#define initEncoding (parser->m_initEncoding)
577#define internalEncoding (parser->m_internalEncoding)
578#define unknownEncodingMem (parser->m_unknownEncodingMem)
579#define unknownEncodingData (parser->m_unknownEncodingData)
580#define unknownEncodingHandlerData \
581 (parser->m_unknownEncodingHandlerData)
582#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
583#define protocolEncodingName (parser->m_protocolEncodingName)
584#define ns (parser->m_ns)
585#define ns_triplets (parser->m_ns_triplets)
586#define prologState (parser->m_prologState)
587#define processor (parser->m_processor)
588#define errorCode (parser->m_errorCode)
589#define eventPtr (parser->m_eventPtr)
590#define eventEndPtr (parser->m_eventEndPtr)
591#define positionPtr (parser->m_positionPtr)
592#define position (parser->m_position)
593#define openInternalEntities (parser->m_openInternalEntities)
594#define defaultExpandInternalEntities \
595 (parser->m_defaultExpandInternalEntities)
596#define tagLevel (parser->m_tagLevel)
597#define buffer (parser->m_buffer)
598#define bufferPtr (parser->m_bufferPtr)
599#define bufferEnd (parser->m_bufferEnd)
600#define parseEndByteIndex (parser->m_parseEndByteIndex)
601#define parseEndPtr (parser->m_parseEndPtr)
602#define bufferLim (parser->m_bufferLim)
603#define dataBuf (parser->m_dataBuf)
604#define dataBufEnd (parser->m_dataBufEnd)
605#define _dtd (parser->m_dtd)
606#define curBase (parser->m_curBase)
607#define declEntity (parser->m_declEntity)
608#define doctypeName (parser->m_doctypeName)
609#define doctypeSysid (parser->m_doctypeSysid)
610#define doctypePubid (parser->m_doctypePubid)
611#define declAttributeType (parser->m_declAttributeType)
612#define declNotationName (parser->m_declNotationName)
613#define declNotationPublicId (parser->m_declNotationPublicId)
614#define declElementType (parser->m_declElementType)
615#define declAttributeId (parser->m_declAttributeId)
616#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
617#define declAttributeIsId (parser->m_declAttributeIsId)
618#define freeTagList (parser->m_freeTagList)
619#define freeBindingList (parser->m_freeBindingList)
620#define inheritedBindings (parser->m_inheritedBindings)
621#define tagStack (parser->m_tagStack)
622#define atts (parser->m_atts)
623#define attsSize (parser->m_attsSize)
624#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
625#define idAttIndex (parser->m_idAttIndex)
Fred Drake08317ae2003-10-21 15:38:55 +0000626#define nsAtts (parser->m_nsAtts)
627#define nsAttsVersion (parser->m_nsAttsVersion)
628#define nsAttsPower (parser->m_nsAttsPower)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000629#define tempPool (parser->m_tempPool)
630#define temp2Pool (parser->m_temp2Pool)
631#define groupConnector (parser->m_groupConnector)
632#define groupSize (parser->m_groupSize)
633#define namespaceSeparator (parser->m_namespaceSeparator)
634#define parentParser (parser->m_parentParser)
635#ifdef XML_DTD
636#define isParamEntity (parser->m_isParamEntity)
637#define useForeignDTD (parser->m_useForeignDTD)
638#define paramEntityParsing (parser->m_paramEntityParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000639#endif /* XML_DTD */
640
Fred Drake08317ae2003-10-21 15:38:55 +0000641#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000642#define parsing \
643 (parentParser \
644 ? \
645 (isParamEntity \
646 ? \
647 (processor != externalParEntInitProcessor) \
648 : \
649 (processor != externalEntityInitProcessor)) \
650 : \
651 (processor != prologInitProcessor))
Fred Drake08317ae2003-10-21 15:38:55 +0000652#else
653#define parsing \
654 (parentParser \
655 ? \
656 (processor != externalEntityInitProcessor) \
657 : \
658 (processor != prologInitProcessor))
659#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000660
Fred Drake08317ae2003-10-21 15:38:55 +0000661XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000662XML_ParserCreate(const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000663{
664 return XML_ParserCreate_MM(encodingName, NULL, NULL);
665}
666
Fred Drake08317ae2003-10-21 15:38:55 +0000667XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000668XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000669{
670 XML_Char tmp[2];
671 *tmp = nsSep;
672 return XML_ParserCreate_MM(encodingName, NULL, tmp);
673}
674
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000675static const XML_Char implicitContext[] = {
676 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
677 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
678 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
679 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
680};
681
Fred Drake08317ae2003-10-21 15:38:55 +0000682XML_Parser XMLCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000683XML_ParserCreate_MM(const XML_Char *encodingName,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000684 const XML_Memory_Handling_Suite *memsuite,
685 const XML_Char *nameSep)
686{
687 XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
688 if (parser != NULL && ns) {
689 /* implicit context only set for root parser, since child
690 parsers (i.e. external entity parsers) will inherit it
691 */
692 if (!setContext(parser, implicitContext)) {
693 XML_ParserFree(parser);
694 return NULL;
695 }
696 }
697 return parser;
698}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000699
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000700static XML_Parser
701parserCreate(const XML_Char *encodingName,
702 const XML_Memory_Handling_Suite *memsuite,
703 const XML_Char *nameSep,
704 DTD *dtd)
705{
706 XML_Parser parser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000707
708 if (memsuite) {
709 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000710 parser = (XML_Parser)
711 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
712 if (parser != NULL) {
713 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
714 mtemp->malloc_fcn = memsuite->malloc_fcn;
715 mtemp->realloc_fcn = memsuite->realloc_fcn;
716 mtemp->free_fcn = memsuite->free_fcn;
717 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000718 }
719 else {
720 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000721 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
722 if (parser != NULL) {
723 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
724 mtemp->malloc_fcn = malloc;
725 mtemp->realloc_fcn = realloc;
726 mtemp->free_fcn = free;
727 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000728 }
729
730 if (!parser)
731 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000732
733 buffer = NULL;
734 bufferLim = NULL;
735
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000736 attsSize = INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000737 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
738 if (atts == NULL) {
739 FREE(parser);
740 return NULL;
741 }
742 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
743 if (dataBuf == NULL) {
744 FREE(atts);
745 FREE(parser);
746 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000747 }
748 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
749
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000750 if (dtd)
751 _dtd = dtd;
752 else {
753 _dtd = dtdCreate(&parser->m_mem);
754 if (_dtd == NULL) {
755 FREE(dataBuf);
756 FREE(atts);
757 FREE(parser);
758 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000759 }
760 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000761
762 freeBindingList = NULL;
763 freeTagList = NULL;
764
765 groupSize = 0;
766 groupConnector = NULL;
767
768 unknownEncodingHandler = NULL;
769 unknownEncodingHandlerData = NULL;
770
771 namespaceSeparator = '!';
772 ns = XML_FALSE;
773 ns_triplets = XML_FALSE;
774
Fred Drake08317ae2003-10-21 15:38:55 +0000775 nsAtts = NULL;
776 nsAttsVersion = 0;
777 nsAttsPower = 0;
778
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000779 poolInit(&tempPool, &(parser->m_mem));
780 poolInit(&temp2Pool, &(parser->m_mem));
781 parserInit(parser, encodingName);
782
783 if (encodingName && !protocolEncodingName) {
784 XML_ParserFree(parser);
785 return NULL;
786 }
787
788 if (nameSep) {
789 ns = XML_TRUE;
790 internalEncoding = XmlGetInternalEncodingNS();
791 namespaceSeparator = *nameSep;
792 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000793 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000794 internalEncoding = XmlGetInternalEncoding();
795 }
796
797 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000798}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000799
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000800static void
801parserInit(XML_Parser parser, const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000802{
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000803 processor = prologInitProcessor;
804 XmlPrologStateInit(&prologState);
805 protocolEncodingName = (encodingName != NULL
806 ? poolCopyString(&tempPool, encodingName)
807 : NULL);
808 curBase = NULL;
809 XmlInitEncoding(&initEncoding, &encoding, 0);
810 userData = NULL;
811 handlerArg = NULL;
812 startElementHandler = NULL;
813 endElementHandler = NULL;
814 characterDataHandler = NULL;
815 processingInstructionHandler = NULL;
816 commentHandler = NULL;
817 startCdataSectionHandler = NULL;
818 endCdataSectionHandler = NULL;
819 defaultHandler = NULL;
820 startDoctypeDeclHandler = NULL;
821 endDoctypeDeclHandler = NULL;
822 unparsedEntityDeclHandler = NULL;
823 notationDeclHandler = NULL;
824 startNamespaceDeclHandler = NULL;
825 endNamespaceDeclHandler = NULL;
826 notStandaloneHandler = NULL;
827 externalEntityRefHandler = NULL;
828 externalEntityRefHandlerArg = parser;
829 skippedEntityHandler = NULL;
830 elementDeclHandler = NULL;
831 attlistDeclHandler = NULL;
832 entityDeclHandler = NULL;
833 xmlDeclHandler = NULL;
834 bufferPtr = buffer;
835 bufferEnd = buffer;
836 parseEndByteIndex = 0;
837 parseEndPtr = NULL;
838 declElementType = NULL;
839 declAttributeId = NULL;
840 declEntity = NULL;
841 doctypeName = NULL;
842 doctypeSysid = NULL;
843 doctypePubid = NULL;
844 declAttributeType = NULL;
845 declNotationName = NULL;
846 declNotationPublicId = NULL;
847 declAttributeIsCdata = XML_FALSE;
848 declAttributeIsId = XML_FALSE;
849 memset(&position, 0, sizeof(POSITION));
850 errorCode = XML_ERROR_NONE;
851 eventPtr = NULL;
852 eventEndPtr = NULL;
853 positionPtr = NULL;
854 openInternalEntities = 0;
855 defaultExpandInternalEntities = XML_TRUE;
856 tagLevel = 0;
857 tagStack = NULL;
858 inheritedBindings = NULL;
859 nSpecifiedAtts = 0;
860 unknownEncodingMem = NULL;
861 unknownEncodingRelease = NULL;
862 unknownEncodingData = NULL;
863 parentParser = NULL;
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 */
872static void FASTCALL
873moveToFreeBindingList(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
Fred Drake08317ae2003-10-21 15:38:55 +0000883XML_Bool XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000884XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
885{
886 TAG *tStk;
887 if (parentParser)
888 return XML_FALSE;
889 /* move tagStack to freeTagList */
890 tStk = tagStack;
891 while (tStk) {
892 TAG *tag = tStk;
893 tStk = tStk->parent;
894 tag->parent = freeTagList;
895 moveToFreeBindingList(parser, tag->bindings);
896 tag->bindings = NULL;
897 freeTagList = tag;
898 }
899 moveToFreeBindingList(parser, inheritedBindings);
Fred Drake08317ae2003-10-21 15:38:55 +0000900 FREE(unknownEncodingMem);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000901 if (unknownEncodingRelease)
902 unknownEncodingRelease(unknownEncodingData);
903 poolClear(&tempPool);
904 poolClear(&temp2Pool);
905 parserInit(parser, encodingName);
906 dtdReset(_dtd, &parser->m_mem);
907 return setContext(parser, implicitContext);
908}
909
Fred Drake08317ae2003-10-21 15:38:55 +0000910enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000911XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
912{
913 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
914 XXX There's no way for the caller to determine which of the
915 XXX possible error cases caused the XML_STATUS_ERROR return.
916 */
917 if (parsing)
918 return XML_STATUS_ERROR;
919 if (encodingName == NULL)
920 protocolEncodingName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000921 else {
922 protocolEncodingName = poolCopyString(&tempPool, encodingName);
923 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000924 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000925 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000926 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000927}
928
Fred Drake08317ae2003-10-21 15:38:55 +0000929XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000930XML_ExternalEntityParserCreate(XML_Parser oldParser,
931 const XML_Char *context,
932 const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000933{
934 XML_Parser parser = oldParser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000935 DTD *newDtd = NULL;
936 DTD *oldDtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000937 XML_StartElementHandler oldStartElementHandler = startElementHandler;
938 XML_EndElementHandler oldEndElementHandler = endElementHandler;
939 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000940 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
941 = processingInstructionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000942 XML_CommentHandler oldCommentHandler = commentHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000943 XML_StartCdataSectionHandler oldStartCdataSectionHandler
944 = startCdataSectionHandler;
945 XML_EndCdataSectionHandler oldEndCdataSectionHandler
946 = endCdataSectionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000947 XML_DefaultHandler oldDefaultHandler = defaultHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000948 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
949 = unparsedEntityDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000950 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000951 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
952 = startNamespaceDeclHandler;
953 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
954 = endNamespaceDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000955 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000956 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
957 = externalEntityRefHandler;
958 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
959 XML_UnknownEncodingHandler oldUnknownEncodingHandler
960 = unknownEncodingHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000961 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
962 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
963 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
964 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
965 ELEMENT_TYPE * oldDeclElementType = declElementType;
966
967 void *oldUserData = userData;
968 void *oldHandlerArg = handlerArg;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000969 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
970 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000971#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000972 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
973 int oldInEntityValue = prologState.inEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000974#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000975 XML_Bool oldns_triplets = ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000976
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000977#ifdef XML_DTD
978 if (!context)
979 newDtd = oldDtd;
980#endif /* XML_DTD */
981
982 /* Note that the magical uses of the pre-processor to make field
983 access look more like C++ require that `parser' be overwritten
984 here. This makes this function more painful to follow than it
985 would be otherwise.
986 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000987 if (ns) {
988 XML_Char tmp[2];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000989 *tmp = namespaceSeparator;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000990 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000991 }
992 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000993 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000994 }
995
996 if (!parser)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000997 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000998
999 startElementHandler = oldStartElementHandler;
1000 endElementHandler = oldEndElementHandler;
1001 characterDataHandler = oldCharacterDataHandler;
1002 processingInstructionHandler = oldProcessingInstructionHandler;
1003 commentHandler = oldCommentHandler;
1004 startCdataSectionHandler = oldStartCdataSectionHandler;
1005 endCdataSectionHandler = oldEndCdataSectionHandler;
1006 defaultHandler = oldDefaultHandler;
1007 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1008 notationDeclHandler = oldNotationDeclHandler;
1009 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1010 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1011 notStandaloneHandler = oldNotStandaloneHandler;
1012 externalEntityRefHandler = oldExternalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001013 skippedEntityHandler = oldSkippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001014 unknownEncodingHandler = oldUnknownEncodingHandler;
1015 elementDeclHandler = oldElementDeclHandler;
1016 attlistDeclHandler = oldAttlistDeclHandler;
1017 entityDeclHandler = oldEntityDeclHandler;
1018 xmlDeclHandler = oldXmlDeclHandler;
1019 declElementType = oldDeclElementType;
1020 userData = oldUserData;
1021 if (oldUserData == oldHandlerArg)
1022 handlerArg = userData;
1023 else
1024 handlerArg = parser;
1025 if (oldExternalEntityRefHandlerArg != oldParser)
1026 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1027 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1028 ns_triplets = oldns_triplets;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001029 parentParser = oldParser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001030#ifdef XML_DTD
1031 paramEntityParsing = oldParamEntityParsing;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001032 prologState.inEntityValue = oldInEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001033 if (context) {
1034#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001035 if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
1036 || !setContext(parser, context)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001037 XML_ParserFree(parser);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001038 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001039 }
1040 processor = externalEntityInitProcessor;
1041#ifdef XML_DTD
1042 }
1043 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001044 /* The DTD instance referenced by _dtd is shared between the document's
1045 root parser and external PE parsers, therefore one does not need to
1046 call setContext. In addition, one also *must* not call setContext,
1047 because this would overwrite existing prefix->binding pointers in
1048 _dtd with ones that get destroyed with the external PE parser.
1049 This would leave those prefixes with dangling pointers.
1050 */
1051 isParamEntity = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001052 XmlPrologStateInitExternalEntity(&prologState);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001053 processor = externalParEntInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001054 }
1055#endif /* XML_DTD */
1056 return parser;
1057}
1058
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001059static void FASTCALL
1060destroyBindings(BINDING *bindings, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001061{
1062 for (;;) {
1063 BINDING *b = bindings;
1064 if (!b)
1065 break;
1066 bindings = b->nextTagBinding;
1067 FREE(b->uri);
1068 FREE(b);
1069 }
1070}
1071
Fred Drake08317ae2003-10-21 15:38:55 +00001072void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001073XML_ParserFree(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001074{
1075 for (;;) {
1076 TAG *p;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001077 if (tagStack == NULL) {
1078 if (freeTagList == NULL)
1079 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001080 tagStack = freeTagList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001081 freeTagList = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001082 }
1083 p = tagStack;
1084 tagStack = tagStack->parent;
1085 FREE(p->buf);
1086 destroyBindings(p->bindings, parser);
1087 FREE(p);
1088 }
1089 destroyBindings(freeBindingList, parser);
1090 destroyBindings(inheritedBindings, parser);
1091 poolDestroy(&tempPool);
1092 poolDestroy(&temp2Pool);
1093#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001094 /* external parameter entity parsers share the DTD structure
1095 parser->m_dtd with the root parser, so we must not destroy it
1096 */
1097 if (!isParamEntity && _dtd)
1098#else
1099 if (_dtd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001100#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001101 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001102 FREE((void *)atts);
Fred Drake08317ae2003-10-21 15:38:55 +00001103 FREE(groupConnector);
1104 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001105 FREE(dataBuf);
Fred Drake08317ae2003-10-21 15:38:55 +00001106 FREE(nsAtts);
1107 FREE(unknownEncodingMem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001108 if (unknownEncodingRelease)
1109 unknownEncodingRelease(unknownEncodingData);
1110 FREE(parser);
1111}
1112
Fred Drake08317ae2003-10-21 15:38:55 +00001113void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001114XML_UseParserAsHandlerArg(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001115{
1116 handlerArg = parser;
1117}
1118
Fred Drake08317ae2003-10-21 15:38:55 +00001119enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001120XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1121{
1122#ifdef XML_DTD
1123 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1124 if (parsing)
1125 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1126 useForeignDTD = useDTD;
1127 return XML_ERROR_NONE;
1128#else
1129 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1130#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001131}
1132
Fred Drake08317ae2003-10-21 15:38:55 +00001133void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001134XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1135{
1136 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1137 if (parsing)
1138 return;
1139 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1140}
1141
Fred Drake08317ae2003-10-21 15:38:55 +00001142void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001143XML_SetUserData(XML_Parser parser, void *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001144{
1145 if (handlerArg == userData)
1146 handlerArg = userData = p;
1147 else
1148 userData = p;
1149}
1150
Fred Drake08317ae2003-10-21 15:38:55 +00001151enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001152XML_SetBase(XML_Parser parser, const XML_Char *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001153{
1154 if (p) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001155 p = poolCopyString(&_dtd->pool, p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001156 if (!p)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001157 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001158 curBase = p;
1159 }
1160 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001161 curBase = NULL;
1162 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001163}
1164
Fred Drake08317ae2003-10-21 15:38:55 +00001165const XML_Char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001166XML_GetBase(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001167{
1168 return curBase;
1169}
1170
Fred Drake08317ae2003-10-21 15:38:55 +00001171int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001172XML_GetSpecifiedAttributeCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001173{
1174 return nSpecifiedAtts;
1175}
1176
Fred Drake08317ae2003-10-21 15:38:55 +00001177int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001178XML_GetIdAttributeIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001179{
1180 return idAttIndex;
1181}
1182
Fred Drake08317ae2003-10-21 15:38:55 +00001183void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001184XML_SetElementHandler(XML_Parser parser,
1185 XML_StartElementHandler start,
1186 XML_EndElementHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001187{
1188 startElementHandler = start;
1189 endElementHandler = end;
1190}
1191
Fred Drake08317ae2003-10-21 15:38:55 +00001192void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001193XML_SetStartElementHandler(XML_Parser parser,
1194 XML_StartElementHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001195 startElementHandler = start;
1196}
1197
Fred Drake08317ae2003-10-21 15:38:55 +00001198void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001199XML_SetEndElementHandler(XML_Parser parser,
1200 XML_EndElementHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001201 endElementHandler = end;
1202}
1203
Fred Drake08317ae2003-10-21 15:38:55 +00001204void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001205XML_SetCharacterDataHandler(XML_Parser parser,
1206 XML_CharacterDataHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001207{
1208 characterDataHandler = handler;
1209}
1210
Fred Drake08317ae2003-10-21 15:38:55 +00001211void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001212XML_SetProcessingInstructionHandler(XML_Parser parser,
1213 XML_ProcessingInstructionHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001214{
1215 processingInstructionHandler = handler;
1216}
1217
Fred Drake08317ae2003-10-21 15:38:55 +00001218void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001219XML_SetCommentHandler(XML_Parser parser,
1220 XML_CommentHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001221{
1222 commentHandler = handler;
1223}
1224
Fred Drake08317ae2003-10-21 15:38:55 +00001225void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001226XML_SetCdataSectionHandler(XML_Parser parser,
1227 XML_StartCdataSectionHandler start,
1228 XML_EndCdataSectionHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001229{
1230 startCdataSectionHandler = start;
1231 endCdataSectionHandler = end;
1232}
1233
Fred Drake08317ae2003-10-21 15:38:55 +00001234void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001235XML_SetStartCdataSectionHandler(XML_Parser parser,
1236 XML_StartCdataSectionHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001237 startCdataSectionHandler = start;
1238}
1239
Fred Drake08317ae2003-10-21 15:38:55 +00001240void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001241XML_SetEndCdataSectionHandler(XML_Parser parser,
1242 XML_EndCdataSectionHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001243 endCdataSectionHandler = end;
1244}
1245
Fred Drake08317ae2003-10-21 15:38:55 +00001246void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001247XML_SetDefaultHandler(XML_Parser parser,
1248 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001249{
1250 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001251 defaultExpandInternalEntities = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001252}
1253
Fred Drake08317ae2003-10-21 15:38:55 +00001254void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001255XML_SetDefaultHandlerExpand(XML_Parser parser,
1256 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001257{
1258 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001259 defaultExpandInternalEntities = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001260}
1261
Fred Drake08317ae2003-10-21 15:38:55 +00001262void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001263XML_SetDoctypeDeclHandler(XML_Parser parser,
1264 XML_StartDoctypeDeclHandler start,
1265 XML_EndDoctypeDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001266{
1267 startDoctypeDeclHandler = start;
1268 endDoctypeDeclHandler = end;
1269}
1270
Fred Drake08317ae2003-10-21 15:38:55 +00001271void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001272XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1273 XML_StartDoctypeDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001274 startDoctypeDeclHandler = start;
1275}
1276
Fred Drake08317ae2003-10-21 15:38:55 +00001277void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001278XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1279 XML_EndDoctypeDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001280 endDoctypeDeclHandler = end;
1281}
1282
Fred Drake08317ae2003-10-21 15:38:55 +00001283void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001284XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1285 XML_UnparsedEntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001286{
1287 unparsedEntityDeclHandler = handler;
1288}
1289
Fred Drake08317ae2003-10-21 15:38:55 +00001290void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001291XML_SetNotationDeclHandler(XML_Parser parser,
1292 XML_NotationDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001293{
1294 notationDeclHandler = handler;
1295}
1296
Fred Drake08317ae2003-10-21 15:38:55 +00001297void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001298XML_SetNamespaceDeclHandler(XML_Parser parser,
1299 XML_StartNamespaceDeclHandler start,
1300 XML_EndNamespaceDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001301{
1302 startNamespaceDeclHandler = start;
1303 endNamespaceDeclHandler = end;
1304}
1305
Fred Drake08317ae2003-10-21 15:38:55 +00001306void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001307XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1308 XML_StartNamespaceDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001309 startNamespaceDeclHandler = start;
1310}
1311
Fred Drake08317ae2003-10-21 15:38:55 +00001312void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001313XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1314 XML_EndNamespaceDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001315 endNamespaceDeclHandler = end;
1316}
1317
Fred Drake08317ae2003-10-21 15:38:55 +00001318void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001319XML_SetNotStandaloneHandler(XML_Parser parser,
1320 XML_NotStandaloneHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001321{
1322 notStandaloneHandler = handler;
1323}
1324
Fred Drake08317ae2003-10-21 15:38:55 +00001325void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001326XML_SetExternalEntityRefHandler(XML_Parser parser,
1327 XML_ExternalEntityRefHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001328{
1329 externalEntityRefHandler = handler;
1330}
1331
Fred Drake08317ae2003-10-21 15:38:55 +00001332void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001333XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001334{
1335 if (arg)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001336 externalEntityRefHandlerArg = (XML_Parser)arg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001337 else
1338 externalEntityRefHandlerArg = parser;
1339}
1340
Fred Drake08317ae2003-10-21 15:38:55 +00001341void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001342XML_SetSkippedEntityHandler(XML_Parser parser,
1343 XML_SkippedEntityHandler handler)
1344{
1345 skippedEntityHandler = handler;
1346}
1347
Fred Drake08317ae2003-10-21 15:38:55 +00001348void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001349XML_SetUnknownEncodingHandler(XML_Parser parser,
1350 XML_UnknownEncodingHandler handler,
1351 void *data)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001352{
1353 unknownEncodingHandler = handler;
1354 unknownEncodingHandlerData = data;
1355}
1356
Fred Drake08317ae2003-10-21 15:38:55 +00001357void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001358XML_SetElementDeclHandler(XML_Parser parser,
1359 XML_ElementDeclHandler eldecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001360{
1361 elementDeclHandler = eldecl;
1362}
1363
Fred Drake08317ae2003-10-21 15:38:55 +00001364void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001365XML_SetAttlistDeclHandler(XML_Parser parser,
1366 XML_AttlistDeclHandler attdecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001367{
1368 attlistDeclHandler = attdecl;
1369}
1370
Fred Drake08317ae2003-10-21 15:38:55 +00001371void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001372XML_SetEntityDeclHandler(XML_Parser parser,
1373 XML_EntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001374{
1375 entityDeclHandler = handler;
1376}
1377
Fred Drake08317ae2003-10-21 15:38:55 +00001378void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001379XML_SetXmlDeclHandler(XML_Parser parser,
1380 XML_XmlDeclHandler handler) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001381 xmlDeclHandler = handler;
1382}
1383
Fred Drake08317ae2003-10-21 15:38:55 +00001384int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001385XML_SetParamEntityParsing(XML_Parser parser,
1386 enum XML_ParamEntityParsing peParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001387{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001388 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1389 if (parsing)
1390 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001391#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001392 paramEntityParsing = peParsing;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001393 return 1;
1394#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001395 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001396#endif
1397}
1398
Fred Drake08317ae2003-10-21 15:38:55 +00001399enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001400XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001401{
1402 if (len == 0) {
1403 if (!isFinal)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001404 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001405 positionPtr = bufferPtr;
1406 errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
1407 if (errorCode == XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001408 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001409 eventEndPtr = eventPtr;
1410 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001411 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001412 }
1413#ifndef XML_CONTEXT_BYTES
1414 else if (bufferPtr == bufferEnd) {
1415 const char *end;
1416 int nLeftOver;
1417 parseEndByteIndex += len;
1418 positionPtr = s;
1419 if (isFinal) {
1420 errorCode = processor(parser, s, parseEndPtr = s + len, 0);
1421 if (errorCode == XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001422 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001423 eventEndPtr = eventPtr;
1424 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001425 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001426 }
1427 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1428 if (errorCode != XML_ERROR_NONE) {
1429 eventEndPtr = eventPtr;
1430 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001431 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001432 }
1433 XmlUpdatePosition(encoding, positionPtr, end, &position);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001434 positionPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001435 nLeftOver = s + len - end;
1436 if (nLeftOver) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001437 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1438 /* FIXME avoid integer overflow */
1439 char *temp;
1440 temp = (buffer == NULL
1441 ? (char *)MALLOC(len * 2)
1442 : (char *)REALLOC(buffer, len * 2));
1443 if (temp == NULL) {
1444 errorCode = XML_ERROR_NO_MEMORY;
1445 return XML_STATUS_ERROR;
1446 }
1447 buffer = temp;
1448 if (!buffer) {
1449 errorCode = XML_ERROR_NO_MEMORY;
1450 eventPtr = eventEndPtr = NULL;
1451 processor = errorProcessor;
1452 return XML_STATUS_ERROR;
1453 }
1454 bufferLim = buffer + len * 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001455 }
1456 memcpy(buffer, end, nLeftOver);
1457 bufferPtr = buffer;
1458 bufferEnd = buffer + nLeftOver;
1459 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001460 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001461 }
1462#endif /* not defined XML_CONTEXT_BYTES */
1463 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001464 void *buff = XML_GetBuffer(parser, len);
1465 if (buff == NULL)
1466 return XML_STATUS_ERROR;
1467 else {
1468 memcpy(buff, s, len);
1469 return XML_ParseBuffer(parser, len, isFinal);
1470 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001471 }
1472}
1473
Fred Drake08317ae2003-10-21 15:38:55 +00001474enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001475XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001476{
1477 const char *start = bufferPtr;
1478 positionPtr = start;
1479 bufferEnd += len;
1480 parseEndByteIndex += len;
1481 errorCode = processor(parser, start, parseEndPtr = bufferEnd,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001482 isFinal ? (const char **)NULL : &bufferPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001483 if (errorCode == XML_ERROR_NONE) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001484 if (!isFinal) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001485 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001486 positionPtr = bufferPtr;
1487 }
1488 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001489 }
1490 else {
1491 eventEndPtr = eventPtr;
1492 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001493 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001494 }
1495}
1496
Fred Drake08317ae2003-10-21 15:38:55 +00001497void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001498XML_GetBuffer(XML_Parser parser, int len)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001499{
1500 if (len > bufferLim - bufferEnd) {
1501 /* FIXME avoid integer overflow */
1502 int neededSize = len + (bufferEnd - bufferPtr);
1503#ifdef XML_CONTEXT_BYTES
1504 int keep = bufferPtr - buffer;
1505
1506 if (keep > XML_CONTEXT_BYTES)
1507 keep = XML_CONTEXT_BYTES;
1508 neededSize += keep;
1509#endif /* defined XML_CONTEXT_BYTES */
1510 if (neededSize <= bufferLim - buffer) {
1511#ifdef XML_CONTEXT_BYTES
1512 if (keep < bufferPtr - buffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001513 int offset = (bufferPtr - buffer) - keep;
1514 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1515 bufferEnd -= offset;
1516 bufferPtr -= offset;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001517 }
1518#else
1519 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1520 bufferEnd = buffer + (bufferEnd - bufferPtr);
1521 bufferPtr = buffer;
1522#endif /* not defined XML_CONTEXT_BYTES */
1523 }
1524 else {
1525 char *newBuf;
1526 int bufferSize = bufferLim - bufferPtr;
1527 if (bufferSize == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001528 bufferSize = INIT_BUFFER_SIZE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001529 do {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001530 bufferSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001531 } while (bufferSize < neededSize);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001532 newBuf = (char *)MALLOC(bufferSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001533 if (newBuf == 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001534 errorCode = XML_ERROR_NO_MEMORY;
1535 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001536 }
1537 bufferLim = newBuf + bufferSize;
1538#ifdef XML_CONTEXT_BYTES
1539 if (bufferPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001540 int keep = bufferPtr - buffer;
1541 if (keep > XML_CONTEXT_BYTES)
1542 keep = XML_CONTEXT_BYTES;
1543 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1544 FREE(buffer);
1545 buffer = newBuf;
1546 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1547 bufferPtr = buffer + keep;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001548 }
1549 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001550 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1551 bufferPtr = buffer = newBuf;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001552 }
1553#else
1554 if (bufferPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001555 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1556 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001557 }
1558 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1559 bufferPtr = buffer = newBuf;
1560#endif /* not defined XML_CONTEXT_BYTES */
1561 }
1562 }
1563 return bufferEnd;
1564}
1565
Fred Drake08317ae2003-10-21 15:38:55 +00001566enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001567XML_GetErrorCode(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001568{
1569 return errorCode;
1570}
1571
Fred Drake08317ae2003-10-21 15:38:55 +00001572long XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001573XML_GetCurrentByteIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001574{
1575 if (eventPtr)
1576 return parseEndByteIndex - (parseEndPtr - eventPtr);
1577 return -1;
1578}
1579
Fred Drake08317ae2003-10-21 15:38:55 +00001580int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001581XML_GetCurrentByteCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001582{
1583 if (eventEndPtr && eventPtr)
1584 return eventEndPtr - eventPtr;
1585 return 0;
1586}
1587
Fred Drake08317ae2003-10-21 15:38:55 +00001588const char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001589XML_GetInputContext(XML_Parser parser, int *offset, int *size)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001590{
1591#ifdef XML_CONTEXT_BYTES
1592 if (eventPtr && buffer) {
1593 *offset = eventPtr - buffer;
1594 *size = bufferEnd - buffer;
1595 return buffer;
1596 }
1597#endif /* defined XML_CONTEXT_BYTES */
1598 return (char *) 0;
1599}
1600
Fred Drake08317ae2003-10-21 15:38:55 +00001601int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001602XML_GetCurrentLineNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001603{
1604 if (eventPtr) {
1605 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1606 positionPtr = eventPtr;
1607 }
1608 return position.lineNumber + 1;
1609}
1610
Fred Drake08317ae2003-10-21 15:38:55 +00001611int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001612XML_GetCurrentColumnNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001613{
1614 if (eventPtr) {
1615 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1616 positionPtr = eventPtr;
1617 }
1618 return position.columnNumber;
1619}
1620
Fred Drake08317ae2003-10-21 15:38:55 +00001621void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001622XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1623{
1624 FREE(model);
1625}
1626
Fred Drake08317ae2003-10-21 15:38:55 +00001627void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001628XML_MemMalloc(XML_Parser parser, size_t size)
1629{
1630 return MALLOC(size);
1631}
1632
Fred Drake08317ae2003-10-21 15:38:55 +00001633void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001634XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1635{
1636 return REALLOC(ptr, size);
1637}
1638
Fred Drake08317ae2003-10-21 15:38:55 +00001639void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001640XML_MemFree(XML_Parser parser, void *ptr)
1641{
1642 FREE(ptr);
1643}
1644
Fred Drake08317ae2003-10-21 15:38:55 +00001645void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001646XML_DefaultCurrent(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001647{
1648 if (defaultHandler) {
1649 if (openInternalEntities)
1650 reportDefault(parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001651 internalEncoding,
1652 openInternalEntities->internalEventPtr,
1653 openInternalEntities->internalEventEndPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001654 else
1655 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1656 }
1657}
1658
Fred Drake08317ae2003-10-21 15:38:55 +00001659const XML_LChar * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001660XML_ErrorString(enum XML_Error code)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001661{
1662 static const XML_LChar *message[] = {
1663 0,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001664 XML_L("out of memory"),
1665 XML_L("syntax error"),
1666 XML_L("no element found"),
1667 XML_L("not well-formed (invalid token)"),
1668 XML_L("unclosed token"),
1669 XML_L("partial character"),
1670 XML_L("mismatched tag"),
1671 XML_L("duplicate attribute"),
1672 XML_L("junk after document element"),
1673 XML_L("illegal parameter entity reference"),
1674 XML_L("undefined entity"),
1675 XML_L("recursive entity reference"),
1676 XML_L("asynchronous entity"),
1677 XML_L("reference to invalid character number"),
1678 XML_L("reference to binary entity"),
1679 XML_L("reference to external entity in attribute"),
1680 XML_L("xml declaration not at start of external entity"),
1681 XML_L("unknown encoding"),
1682 XML_L("encoding specified in XML declaration is incorrect"),
1683 XML_L("unclosed CDATA section"),
1684 XML_L("error in processing external entity reference"),
1685 XML_L("document is not standalone"),
1686 XML_L("unexpected parser state - please send a bug report"),
1687 XML_L("entity declared in parameter entity"),
1688 XML_L("requested feature requires XML_DTD support in Expat"),
Fred Drake08317ae2003-10-21 15:38:55 +00001689 XML_L("cannot change setting once parsing has begun"),
1690 XML_L("unbound prefix")
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001691 };
1692 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1693 return message[code];
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001694 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001695}
1696
Fred Drake08317ae2003-10-21 15:38:55 +00001697const XML_LChar * XMLCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001698XML_ExpatVersion(void) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001699
1700 /* V1 is used to string-ize the version number. However, it would
1701 string-ize the actual version macro *names* unless we get them
1702 substituted before being passed to V1. CPP is defined to expand
1703 a macro, then rescan for more expansions. Thus, we use V2 to expand
1704 the version macros, then CPP will expand the resulting V1() macro
1705 with the correct numerals. */
1706 /* ### I'm assuming cpp is portable in this respect... */
1707
1708#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1709#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1710
1711 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1712
1713#undef V1
1714#undef V2
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001715}
1716
Fred Drake08317ae2003-10-21 15:38:55 +00001717XML_Expat_Version XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001718XML_ExpatVersionInfo(void)
1719{
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001720 XML_Expat_Version version;
1721
1722 version.major = XML_MAJOR_VERSION;
1723 version.minor = XML_MINOR_VERSION;
1724 version.micro = XML_MICRO_VERSION;
1725
1726 return version;
1727}
1728
Fred Drake08317ae2003-10-21 15:38:55 +00001729const XML_Feature * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001730XML_GetFeatureList(void)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001731{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001732 static XML_Feature features[] = {
Fred Drake08317ae2003-10-21 15:38:55 +00001733 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), 0},
1734 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001735#ifdef XML_UNICODE
Fred Drake08317ae2003-10-21 15:38:55 +00001736 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001737#endif
1738#ifdef XML_UNICODE_WCHAR_T
Fred Drake08317ae2003-10-21 15:38:55 +00001739 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001740#endif
1741#ifdef XML_DTD
Fred Drake08317ae2003-10-21 15:38:55 +00001742 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001743#endif
1744#ifdef XML_CONTEXT_BYTES
1745 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
1746 XML_CONTEXT_BYTES},
1747#endif
1748#ifdef XML_MIN_SIZE
Fred Drake08317ae2003-10-21 15:38:55 +00001749 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001750#endif
Fred Drake08317ae2003-10-21 15:38:55 +00001751 {XML_FEATURE_END, NULL, 0}
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001752 };
1753
1754 features[0].value = sizeof(XML_Char);
1755 features[1].value = sizeof(XML_LChar);
1756 return features;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001757}
1758
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001759/* Initially tag->rawName always points into the parse buffer;
1760 for those TAG instances opened while the current parse buffer was
1761 processed, and not yet closed, we need to store tag->rawName in a more
1762 permanent location, since the parse buffer is about to be discarded.
1763*/
1764static XML_Bool
1765storeRawNames(XML_Parser parser)
1766{
1767 TAG *tag = tagStack;
1768 while (tag) {
1769 int bufSize;
1770 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
1771 char *rawNameBuf = tag->buf + nameLen;
1772 /* Stop if already stored. Since tagStack is a stack, we can stop
1773 at the first entry that has already been copied; everything
1774 below it in the stack is already been accounted for in a
1775 previous call to this function.
1776 */
1777 if (tag->rawName == rawNameBuf)
1778 break;
1779 /* For re-use purposes we need to ensure that the
1780 size of tag->buf is a multiple of sizeof(XML_Char).
1781 */
1782 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
1783 if (bufSize > tag->bufEnd - tag->buf) {
1784 char *temp = (char *)REALLOC(tag->buf, bufSize);
1785 if (temp == NULL)
1786 return XML_FALSE;
1787 /* if tag->name.str points to tag->buf (only when namespace
1788 processing is off) then we have to update it
1789 */
1790 if (tag->name.str == (XML_Char *)tag->buf)
1791 tag->name.str = (XML_Char *)temp;
1792 /* if tag->name.localPart is set (when namespace processing is on)
1793 then update it as well, since it will always point into tag->buf
1794 */
1795 if (tag->name.localPart)
1796 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
1797 (XML_Char *)tag->buf);
1798 tag->buf = temp;
1799 tag->bufEnd = temp + bufSize;
1800 rawNameBuf = temp + nameLen;
1801 }
1802 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
1803 tag->rawName = rawNameBuf;
1804 tag = tag->parent;
1805 }
1806 return XML_TRUE;
1807}
1808
1809static enum XML_Error PTRCALL
1810contentProcessor(XML_Parser parser,
1811 const char *start,
1812 const char *end,
1813 const char **endPtr)
1814{
1815 enum XML_Error result =
1816 doContent(parser, 0, encoding, start, end, endPtr);
1817 if (result != XML_ERROR_NONE)
1818 return result;
1819 if (!storeRawNames(parser))
1820 return XML_ERROR_NO_MEMORY;
1821 return result;
1822}
1823
1824static enum XML_Error PTRCALL
1825externalEntityInitProcessor(XML_Parser parser,
1826 const char *start,
1827 const char *end,
1828 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001829{
1830 enum XML_Error result = initializeEncoding(parser);
1831 if (result != XML_ERROR_NONE)
1832 return result;
1833 processor = externalEntityInitProcessor2;
1834 return externalEntityInitProcessor2(parser, start, end, endPtr);
1835}
1836
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001837static enum XML_Error PTRCALL
1838externalEntityInitProcessor2(XML_Parser parser,
1839 const char *start,
1840 const char *end,
1841 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001842{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001843 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001844 int tok = XmlContentTok(encoding, start, end, &next);
1845 switch (tok) {
1846 case XML_TOK_BOM:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001847 /* If we are at the end of the buffer, this would cause the next stage,
1848 i.e. externalEntityInitProcessor3, to pass control directly to
1849 doContent (by detecting XML_TOK_NONE) without processing any xml text
1850 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1851 */
1852 if (next == end && endPtr) {
1853 *endPtr = next;
1854 return XML_ERROR_NONE;
1855 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001856 start = next;
1857 break;
1858 case XML_TOK_PARTIAL:
1859 if (endPtr) {
1860 *endPtr = start;
1861 return XML_ERROR_NONE;
1862 }
1863 eventPtr = start;
1864 return XML_ERROR_UNCLOSED_TOKEN;
1865 case XML_TOK_PARTIAL_CHAR:
1866 if (endPtr) {
1867 *endPtr = start;
1868 return XML_ERROR_NONE;
1869 }
1870 eventPtr = start;
1871 return XML_ERROR_PARTIAL_CHAR;
1872 }
1873 processor = externalEntityInitProcessor3;
1874 return externalEntityInitProcessor3(parser, start, end, endPtr);
1875}
1876
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001877static enum XML_Error PTRCALL
1878externalEntityInitProcessor3(XML_Parser parser,
1879 const char *start,
1880 const char *end,
1881 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001882{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001883 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001884 int tok = XmlContentTok(encoding, start, end, &next);
1885 switch (tok) {
1886 case XML_TOK_XML_DECL:
1887 {
1888 enum XML_Error result = processXmlDecl(parser, 1, start, next);
1889 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001890 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001891 start = next;
1892 }
1893 break;
1894 case XML_TOK_PARTIAL:
1895 if (endPtr) {
1896 *endPtr = start;
1897 return XML_ERROR_NONE;
1898 }
1899 eventPtr = start;
1900 return XML_ERROR_UNCLOSED_TOKEN;
1901 case XML_TOK_PARTIAL_CHAR:
1902 if (endPtr) {
1903 *endPtr = start;
1904 return XML_ERROR_NONE;
1905 }
1906 eventPtr = start;
1907 return XML_ERROR_PARTIAL_CHAR;
1908 }
1909 processor = externalEntityContentProcessor;
1910 tagLevel = 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001911 return externalEntityContentProcessor(parser, start, end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001912}
1913
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001914static enum XML_Error PTRCALL
1915externalEntityContentProcessor(XML_Parser parser,
1916 const char *start,
1917 const char *end,
1918 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001919{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001920 enum XML_Error result =
1921 doContent(parser, 1, encoding, start, end, endPtr);
1922 if (result != XML_ERROR_NONE)
1923 return result;
1924 if (!storeRawNames(parser))
1925 return XML_ERROR_NO_MEMORY;
1926 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001927}
1928
1929static enum XML_Error
1930doContent(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001931 int startTagLevel,
1932 const ENCODING *enc,
1933 const char *s,
1934 const char *end,
1935 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001936{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001937 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001938 const char **eventPP;
1939 const char **eventEndPP;
1940 if (enc == encoding) {
1941 eventPP = &eventPtr;
1942 eventEndPP = &eventEndPtr;
1943 }
1944 else {
1945 eventPP = &(openInternalEntities->internalEventPtr);
1946 eventEndPP = &(openInternalEntities->internalEventEndPtr);
1947 }
1948 *eventPP = s;
1949 for (;;) {
1950 const char *next = s; /* XmlContentTok doesn't always set the last arg */
1951 int tok = XmlContentTok(enc, s, end, &next);
1952 *eventEndPP = next;
1953 switch (tok) {
1954 case XML_TOK_TRAILING_CR:
1955 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001956 *nextPtr = s;
1957 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001958 }
1959 *eventEndPP = end;
1960 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001961 XML_Char c = 0xA;
1962 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001963 }
1964 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001965 reportDefault(parser, enc, s, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001966 if (startTagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001967 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001968 if (tagLevel != startTagLevel)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001969 return XML_ERROR_ASYNC_ENTITY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001970 return XML_ERROR_NONE;
1971 case XML_TOK_NONE:
1972 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001973 *nextPtr = s;
1974 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001975 }
1976 if (startTagLevel > 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001977 if (tagLevel != startTagLevel)
1978 return XML_ERROR_ASYNC_ENTITY;
1979 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001980 }
1981 return XML_ERROR_NO_ELEMENTS;
1982 case XML_TOK_INVALID:
1983 *eventPP = next;
1984 return XML_ERROR_INVALID_TOKEN;
1985 case XML_TOK_PARTIAL:
1986 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001987 *nextPtr = s;
1988 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001989 }
1990 return XML_ERROR_UNCLOSED_TOKEN;
1991 case XML_TOK_PARTIAL_CHAR:
1992 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001993 *nextPtr = s;
1994 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001995 }
1996 return XML_ERROR_PARTIAL_CHAR;
1997 case XML_TOK_ENTITY_REF:
1998 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001999 const XML_Char *name;
2000 ENTITY *entity;
2001 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2002 s + enc->minBytesPerChar,
2003 next - enc->minBytesPerChar);
2004 if (ch) {
2005 if (characterDataHandler)
2006 characterDataHandler(handlerArg, &ch, 1);
2007 else if (defaultHandler)
2008 reportDefault(parser, enc, s, next);
2009 break;
2010 }
2011 name = poolStoreString(&dtd->pool, enc,
2012 s + enc->minBytesPerChar,
2013 next - enc->minBytesPerChar);
2014 if (!name)
2015 return XML_ERROR_NO_MEMORY;
2016 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
2017 poolDiscard(&dtd->pool);
2018 /* First, determine if a check for an existing declaration is needed;
2019 if yes, check that the entity exists, and that it is internal,
2020 otherwise call the skipped entity or default handler.
2021 */
2022 if (!dtd->hasParamEntityRefs || dtd->standalone) {
2023 if (!entity)
2024 return XML_ERROR_UNDEFINED_ENTITY;
2025 else if (!entity->is_internal)
2026 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2027 }
2028 else if (!entity) {
2029 if (skippedEntityHandler)
2030 skippedEntityHandler(handlerArg, name, 0);
2031 else if (defaultHandler)
2032 reportDefault(parser, enc, s, next);
2033 break;
2034 }
2035 if (entity->open)
2036 return XML_ERROR_RECURSIVE_ENTITY_REF;
2037 if (entity->notation)
2038 return XML_ERROR_BINARY_ENTITY_REF;
2039 if (entity->textPtr) {
2040 enum XML_Error result;
2041 OPEN_INTERNAL_ENTITY openEntity;
2042 if (!defaultExpandInternalEntities) {
2043 if (skippedEntityHandler)
2044 skippedEntityHandler(handlerArg, entity->name, 0);
2045 else if (defaultHandler)
2046 reportDefault(parser, enc, s, next);
2047 break;
2048 }
2049 entity->open = XML_TRUE;
2050 openEntity.next = openInternalEntities;
2051 openInternalEntities = &openEntity;
2052 openEntity.entity = entity;
2053 openEntity.internalEventPtr = NULL;
2054 openEntity.internalEventEndPtr = NULL;
2055 result = doContent(parser,
2056 tagLevel,
2057 internalEncoding,
2058 (char *)entity->textPtr,
2059 (char *)(entity->textPtr + entity->textLen),
2060 0);
2061 entity->open = XML_FALSE;
2062 openInternalEntities = openEntity.next;
2063 if (result)
2064 return result;
2065 }
2066 else if (externalEntityRefHandler) {
2067 const XML_Char *context;
2068 entity->open = XML_TRUE;
2069 context = getContext(parser);
2070 entity->open = XML_FALSE;
2071 if (!context)
2072 return XML_ERROR_NO_MEMORY;
2073 if (!externalEntityRefHandler((XML_Parser)externalEntityRefHandlerArg,
2074 context,
2075 entity->base,
2076 entity->systemId,
2077 entity->publicId))
2078 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2079 poolDiscard(&tempPool);
2080 }
2081 else if (defaultHandler)
2082 reportDefault(parser, enc, s, next);
2083 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002084 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002085 case XML_TOK_START_TAG_NO_ATTS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002086 /* fall through */
2087 case XML_TOK_START_TAG_WITH_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002088 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002089 TAG *tag;
2090 enum XML_Error result;
2091 XML_Char *toPtr;
2092 if (freeTagList) {
2093 tag = freeTagList;
2094 freeTagList = freeTagList->parent;
2095 }
2096 else {
2097 tag = (TAG *)MALLOC(sizeof(TAG));
2098 if (!tag)
2099 return XML_ERROR_NO_MEMORY;
2100 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2101 if (!tag->buf) {
2102 FREE(tag);
2103 return XML_ERROR_NO_MEMORY;
2104 }
2105 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2106 }
2107 tag->bindings = NULL;
2108 tag->parent = tagStack;
2109 tagStack = tag;
2110 tag->name.localPart = NULL;
2111 tag->name.prefix = NULL;
2112 tag->rawName = s + enc->minBytesPerChar;
2113 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2114 ++tagLevel;
2115 {
2116 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2117 const char *fromPtr = tag->rawName;
2118 toPtr = (XML_Char *)tag->buf;
2119 for (;;) {
2120 int bufSize;
2121 int convLen;
2122 XmlConvert(enc,
2123 &fromPtr, rawNameEnd,
2124 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2125 convLen = toPtr - (XML_Char *)tag->buf;
2126 if (fromPtr == rawNameEnd) {
2127 tag->name.strLen = convLen;
2128 break;
2129 }
2130 bufSize = (tag->bufEnd - tag->buf) << 1;
2131 {
2132 char *temp = (char *)REALLOC(tag->buf, bufSize);
2133 if (temp == NULL)
2134 return XML_ERROR_NO_MEMORY;
2135 tag->buf = temp;
2136 tag->bufEnd = temp + bufSize;
2137 toPtr = (XML_Char *)temp + convLen;
2138 }
2139 }
2140 }
2141 tag->name.str = (XML_Char *)tag->buf;
2142 *toPtr = XML_T('\0');
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002143 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2144 if (result)
2145 return result;
2146 if (startElementHandler)
2147 startElementHandler(handlerArg, tag->name.str,
2148 (const XML_Char **)atts);
2149 else if (defaultHandler)
2150 reportDefault(parser, enc, s, next);
2151 poolClear(&tempPool);
2152 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002153 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002154 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002155 /* fall through */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002156 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2157 {
2158 const char *rawName = s + enc->minBytesPerChar;
2159 enum XML_Error result;
2160 BINDING *bindings = NULL;
2161 XML_Bool noElmHandlers = XML_TRUE;
2162 TAG_NAME name;
2163 name.str = poolStoreString(&tempPool, enc, rawName,
2164 rawName + XmlNameLength(enc, rawName));
2165 if (!name.str)
2166 return XML_ERROR_NO_MEMORY;
2167 poolFinish(&tempPool);
Fred Drake4faea012003-01-28 06:42:40 +00002168 result = storeAtts(parser, enc, s, &name, &bindings);
2169 if (result)
2170 return result;
2171 poolFinish(&tempPool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002172 if (startElementHandler) {
2173 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2174 noElmHandlers = XML_FALSE;
2175 }
2176 if (endElementHandler) {
2177 if (startElementHandler)
2178 *eventPP = *eventEndPP;
2179 endElementHandler(handlerArg, name.str);
2180 noElmHandlers = XML_FALSE;
2181 }
2182 if (noElmHandlers && defaultHandler)
2183 reportDefault(parser, enc, s, next);
2184 poolClear(&tempPool);
2185 while (bindings) {
2186 BINDING *b = bindings;
2187 if (endNamespaceDeclHandler)
2188 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2189 bindings = bindings->nextTagBinding;
2190 b->nextTagBinding = freeBindingList;
2191 freeBindingList = b;
2192 b->prefix->binding = b->prevPrefixBinding;
2193 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002194 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002195 if (tagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002196 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002197 break;
2198 case XML_TOK_END_TAG:
2199 if (tagLevel == startTagLevel)
2200 return XML_ERROR_ASYNC_ENTITY;
2201 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002202 int len;
2203 const char *rawName;
2204 TAG *tag = tagStack;
2205 tagStack = tag->parent;
2206 tag->parent = freeTagList;
2207 freeTagList = tag;
2208 rawName = s + enc->minBytesPerChar*2;
2209 len = XmlNameLength(enc, rawName);
2210 if (len != tag->rawNameLength
2211 || memcmp(tag->rawName, rawName, len) != 0) {
2212 *eventPP = rawName;
2213 return XML_ERROR_TAG_MISMATCH;
2214 }
2215 --tagLevel;
2216 if (endElementHandler) {
2217 const XML_Char *localPart;
2218 const XML_Char *prefix;
2219 XML_Char *uri;
2220 localPart = tag->name.localPart;
2221 if (ns && localPart) {
2222 /* localPart and prefix may have been overwritten in
2223 tag->name.str, since this points to the binding->uri
2224 buffer which gets re-used; so we have to add them again
2225 */
2226 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2227 /* don't need to check for space - already done in storeAtts() */
2228 while (*localPart) *uri++ = *localPart++;
2229 prefix = (XML_Char *)tag->name.prefix;
2230 if (ns_triplets && prefix) {
2231 *uri++ = namespaceSeparator;
2232 while (*prefix) *uri++ = *prefix++;
2233 }
2234 *uri = XML_T('\0');
2235 }
2236 endElementHandler(handlerArg, tag->name.str);
2237 }
2238 else if (defaultHandler)
2239 reportDefault(parser, enc, s, next);
2240 while (tag->bindings) {
2241 BINDING *b = tag->bindings;
2242 if (endNamespaceDeclHandler)
2243 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2244 tag->bindings = tag->bindings->nextTagBinding;
2245 b->nextTagBinding = freeBindingList;
2246 freeBindingList = b;
2247 b->prefix->binding = b->prevPrefixBinding;
2248 }
2249 if (tagLevel == 0)
2250 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002251 }
2252 break;
2253 case XML_TOK_CHAR_REF:
2254 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002255 int n = XmlCharRefNumber(enc, s);
2256 if (n < 0)
2257 return XML_ERROR_BAD_CHAR_REF;
2258 if (characterDataHandler) {
2259 XML_Char buf[XML_ENCODE_MAX];
2260 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2261 }
2262 else if (defaultHandler)
2263 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002264 }
2265 break;
2266 case XML_TOK_XML_DECL:
2267 return XML_ERROR_MISPLACED_XML_PI;
2268 case XML_TOK_DATA_NEWLINE:
2269 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002270 XML_Char c = 0xA;
2271 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002272 }
2273 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002274 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002275 break;
2276 case XML_TOK_CDATA_SECT_OPEN:
2277 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002278 enum XML_Error result;
2279 if (startCdataSectionHandler)
2280 startCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002281#if 0
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002282 /* Suppose you doing a transformation on a document that involves
2283 changing only the character data. You set up a defaultHandler
2284 and a characterDataHandler. The defaultHandler simply copies
2285 characters through. The characterDataHandler does the
2286 transformation and writes the characters out escaping them as
2287 necessary. This case will fail to work if we leave out the
2288 following two lines (because & and < inside CDATA sections will
2289 be incorrectly escaped).
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002290
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002291 However, now we have a start/endCdataSectionHandler, so it seems
2292 easier to let the user deal with this.
2293 */
2294 else if (characterDataHandler)
2295 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002296#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002297 else if (defaultHandler)
2298 reportDefault(parser, enc, s, next);
2299 result = doCdataSection(parser, enc, &next, end, nextPtr);
2300 if (!next) {
2301 processor = cdataSectionProcessor;
2302 return result;
2303 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002304 }
2305 break;
2306 case XML_TOK_TRAILING_RSQB:
2307 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002308 *nextPtr = s;
2309 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002310 }
2311 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002312 if (MUST_CONVERT(enc, s)) {
2313 ICHAR *dataPtr = (ICHAR *)dataBuf;
2314 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2315 characterDataHandler(handlerArg, dataBuf,
2316 dataPtr - (ICHAR *)dataBuf);
2317 }
2318 else
2319 characterDataHandler(handlerArg,
2320 (XML_Char *)s,
2321 (XML_Char *)end - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002322 }
2323 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002324 reportDefault(parser, enc, s, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002325 if (startTagLevel == 0) {
2326 *eventPP = end;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002327 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002328 }
2329 if (tagLevel != startTagLevel) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002330 *eventPP = end;
2331 return XML_ERROR_ASYNC_ENTITY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002332 }
2333 return XML_ERROR_NONE;
2334 case XML_TOK_DATA_CHARS:
2335 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002336 if (MUST_CONVERT(enc, s)) {
2337 for (;;) {
2338 ICHAR *dataPtr = (ICHAR *)dataBuf;
2339 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2340 *eventEndPP = s;
2341 characterDataHandler(handlerArg, dataBuf,
2342 dataPtr - (ICHAR *)dataBuf);
2343 if (s == next)
2344 break;
2345 *eventPP = s;
2346 }
2347 }
2348 else
2349 characterDataHandler(handlerArg,
2350 (XML_Char *)s,
2351 (XML_Char *)next - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002352 }
2353 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002354 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002355 break;
2356 case XML_TOK_PI:
2357 if (!reportProcessingInstruction(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002358 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002359 break;
2360 case XML_TOK_COMMENT:
2361 if (!reportComment(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002362 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002363 break;
2364 default:
2365 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002366 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002367 break;
2368 }
2369 *eventPP = s = next;
2370 }
2371 /* not reached */
2372}
2373
Fred Drake4faea012003-01-28 06:42:40 +00002374/* Precondition: all arguments must be non-NULL;
2375 Purpose:
2376 - normalize attributes
2377 - check attributes for well-formedness
2378 - generate namespace aware attribute names (URI, prefix)
2379 - build list of attributes for startElementHandler
2380 - default attributes
2381 - process namespace declarations (check and report them)
2382 - generate namespace aware element name (URI, prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002383*/
2384static enum XML_Error
2385storeAtts(XML_Parser parser, const ENCODING *enc,
2386 const char *attStr, TAG_NAME *tagNamePtr,
2387 BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002388{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002389 DTD * const dtd = _dtd; /* save one level of indirection */
Fred Drake08317ae2003-10-21 15:38:55 +00002390 ELEMENT_TYPE *elementType;
2391 int nDefaultAtts;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002392 const XML_Char **appAtts; /* the attribute list for the application */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002393 int attIndex = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002394 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002395 int i;
2396 int n;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002397 XML_Char *uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002398 int nPrefixes = 0;
2399 BINDING *binding;
2400 const XML_Char *localPart;
2401
2402 /* lookup the element type name */
Fred Drake4faea012003-01-28 06:42:40 +00002403 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
2404 if (!elementType) {
2405 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2406 if (!name)
2407 return XML_ERROR_NO_MEMORY;
2408 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
2409 sizeof(ELEMENT_TYPE));
2410 if (!elementType)
2411 return XML_ERROR_NO_MEMORY;
2412 if (ns && !setElementTypePrefix(parser, elementType))
2413 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002414 }
Fred Drake4faea012003-01-28 06:42:40 +00002415 nDefaultAtts = elementType->nDefaultAtts;
2416
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002417 /* get the attributes from the tokenizer */
2418 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2419 if (n + nDefaultAtts > attsSize) {
2420 int oldAttsSize = attsSize;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002421 ATTRIBUTE *temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002422 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002423 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2424 if (temp == NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002425 return XML_ERROR_NO_MEMORY;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002426 atts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002427 if (n > oldAttsSize)
2428 XmlGetAttributes(enc, attStr, n, atts);
2429 }
Fred Drake4faea012003-01-28 06:42:40 +00002430
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002431 appAtts = (const XML_Char **)atts;
2432 for (i = 0; i < n; i++) {
2433 /* add the name and value to the attribute list */
2434 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002435 atts[i].name
2436 + XmlNameLength(enc, atts[i].name));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002437 if (!attId)
2438 return XML_ERROR_NO_MEMORY;
Fred Drake08317ae2003-10-21 15:38:55 +00002439 /* Detect duplicate attributes by their QNames. This does not work when
2440 namespace processing is turned on and different prefixes for the same
2441 namespace are used. For this case we have a check further down.
2442 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002443 if ((attId->name)[-1]) {
2444 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002445 eventPtr = atts[i].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002446 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2447 }
2448 (attId->name)[-1] = 1;
2449 appAtts[attIndex++] = attId->name;
2450 if (!atts[i].normalized) {
2451 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002452 XML_Bool isCdata = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002453
2454 /* figure out whether declared as other than CDATA */
2455 if (attId->maybeTokenized) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002456 int j;
2457 for (j = 0; j < nDefaultAtts; j++) {
2458 if (attId == elementType->defaultAtts[j].id) {
2459 isCdata = elementType->defaultAtts[j].isCdata;
2460 break;
2461 }
2462 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002463 }
2464
2465 /* normalize the attribute value */
2466 result = storeAttributeValue(parser, enc, isCdata,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002467 atts[i].valuePtr, atts[i].valueEnd,
2468 &tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002469 if (result)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002470 return result;
Fred Drake4faea012003-01-28 06:42:40 +00002471 appAtts[attIndex] = poolStart(&tempPool);
2472 poolFinish(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002473 }
Fred Drake4faea012003-01-28 06:42:40 +00002474 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002475 /* the value did not need normalizing */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002476 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2477 atts[i].valueEnd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002478 if (appAtts[attIndex] == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002479 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002480 poolFinish(&tempPool);
2481 }
2482 /* handle prefixed attribute names */
Fred Drake4faea012003-01-28 06:42:40 +00002483 if (attId->prefix) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002484 if (attId->xmlns) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002485 /* deal with namespace declarations here */
2486 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2487 appAtts[attIndex], bindingsPtr);
2488 if (result)
2489 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002490 --attIndex;
2491 }
2492 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002493 /* deal with other prefixed names later */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002494 attIndex++;
2495 nPrefixes++;
2496 (attId->name)[-1] = 2;
2497 }
2498 }
2499 else
2500 attIndex++;
2501 }
Fred Drake4faea012003-01-28 06:42:40 +00002502
2503 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2504 nSpecifiedAtts = attIndex;
2505 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2506 for (i = 0; i < attIndex; i += 2)
2507 if (appAtts[i] == elementType->idAtt->name) {
2508 idAttIndex = i;
2509 break;
2510 }
2511 }
2512 else
2513 idAttIndex = -1;
2514
2515 /* do attribute defaulting */
2516 for (i = 0; i < nDefaultAtts; i++) {
2517 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2518 if (!(da->id->name)[-1] && da->value) {
2519 if (da->id->prefix) {
2520 if (da->id->xmlns) {
2521 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2522 da->value, bindingsPtr);
2523 if (result)
2524 return result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002525 }
2526 else {
Fred Drake4faea012003-01-28 06:42:40 +00002527 (da->id->name)[-1] = 2;
2528 nPrefixes++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002529 appAtts[attIndex++] = da->id->name;
2530 appAtts[attIndex++] = da->value;
2531 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002532 }
Fred Drake4faea012003-01-28 06:42:40 +00002533 else {
2534 (da->id->name)[-1] = 1;
2535 appAtts[attIndex++] = da->id->name;
2536 appAtts[attIndex++] = da->value;
2537 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002538 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002539 }
Fred Drake4faea012003-01-28 06:42:40 +00002540 appAtts[attIndex] = 0;
2541
Fred Drake08317ae2003-10-21 15:38:55 +00002542 /* expand prefixed attribute names, check for duplicates,
2543 and clear flags that say whether attributes were specified */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002544 i = 0;
2545 if (nPrefixes) {
Fred Drake08317ae2003-10-21 15:38:55 +00002546 int j; /* hash table index */
2547 unsigned long version = nsAttsVersion;
2548 int nsAttsSize = (int)1 << nsAttsPower;
2549 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2550 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2551 NS_ATT *temp;
2552 /* hash table size must also be a power of 2 and >= 8 */
2553 while (nPrefixes >> nsAttsPower++);
2554 if (nsAttsPower < 3)
2555 nsAttsPower = 3;
2556 nsAttsSize = (int)1 << nsAttsPower;
2557 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2558 if (!temp)
2559 return XML_ERROR_NO_MEMORY;
2560 nsAtts = temp;
2561 version = 0; /* force re-initialization of nsAtts hash table */
2562 }
2563 /* using a version flag saves us from initializing nsAtts every time */
2564 if (!version) { /* initialize version flags when version wraps around */
2565 version = INIT_ATTS_VERSION;
2566 for (j = nsAttsSize; j != 0; )
2567 nsAtts[--j].version = version;
2568 }
2569 nsAttsVersion = --version;
2570
2571 /* expand prefixed names and check for duplicates */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002572 for (; i < attIndex; i += 2) {
Fred Drake08317ae2003-10-21 15:38:55 +00002573 const XML_Char *s = appAtts[i];
2574 if (s[-1] == 2) { /* prefixed */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002575 ATTRIBUTE_ID *id;
Fred Drake08317ae2003-10-21 15:38:55 +00002576 const BINDING *b;
2577 unsigned long uriHash = 0;
2578 ((XML_Char *)s)[-1] = 0; /* clear flag */
2579 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
2580 b = id->prefix->binding;
2581 if (!b)
2582 return XML_ERROR_UNBOUND_PREFIX;
2583
2584 /* as we expand the name we also calculate its hash value */
2585 for (j = 0; j < b->uriLen; j++) {
2586 const XML_Char c = b->uri[j];
2587 if (!poolAppendChar(&tempPool, c))
2588 return XML_ERROR_NO_MEMORY;
2589 uriHash = CHAR_HASH(uriHash, c);
2590 }
2591 while (*s++ != XML_T(':'))
2592 ;
2593 do { /* copies null terminator */
2594 const XML_Char c = *s;
2595 if (!poolAppendChar(&tempPool, *s))
2596 return XML_ERROR_NO_MEMORY;
2597 uriHash = CHAR_HASH(uriHash, c);
2598 } while (*s++);
2599
2600 { /* Check hash table for duplicate of expanded name (uriName).
2601 Derived from code in lookup(HASH_TABLE *table, ...).
2602 */
2603 unsigned char step = 0;
2604 unsigned long mask = nsAttsSize - 1;
2605 j = uriHash & mask; /* index into hash table */
2606 while (nsAtts[j].version == version) {
2607 /* for speed we compare stored hash values first */
2608 if (uriHash == nsAtts[j].hash) {
2609 const XML_Char *s1 = poolStart(&tempPool);
2610 const XML_Char *s2 = nsAtts[j].uriName;
2611 /* s1 is null terminated, but not s2 */
2612 for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2613 if (*s1 == 0)
2614 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2615 }
2616 if (!step)
2617 step = PROBE_STEP(uriHash, mask, nsAttsPower);
2618 j < step ? ( j += nsAttsSize - step) : (j -= step);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002619 }
Fred Drake08317ae2003-10-21 15:38:55 +00002620 }
2621
2622 if (ns_triplets) { /* append namespace separator and prefix */
2623 tempPool.ptr[-1] = namespaceSeparator;
2624 s = b->prefix->name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002625 do {
2626 if (!poolAppendChar(&tempPool, *s))
2627 return XML_ERROR_NO_MEMORY;
2628 } while (*s++);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002629 }
Fred Drake08317ae2003-10-21 15:38:55 +00002630
2631 /* store expanded name in attribute list */
2632 s = poolStart(&tempPool);
2633 poolFinish(&tempPool);
2634 appAtts[i] = s;
2635
2636 /* fill empty slot with new version, uriName and hash value */
2637 nsAtts[j].version = version;
2638 nsAtts[j].hash = uriHash;
2639 nsAtts[j].uriName = s;
2640
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002641 if (!--nPrefixes)
2642 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002643 }
Fred Drake08317ae2003-10-21 15:38:55 +00002644 else /* not prefixed */
2645 ((XML_Char *)s)[-1] = 0; /* clear flag */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002646 }
2647 }
Fred Drake08317ae2003-10-21 15:38:55 +00002648 /* clear flags for the remaining attributes */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002649 for (; i < attIndex; i += 2)
2650 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002651 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2652 binding->attId->name[-1] = 0;
Fred Drake4faea012003-01-28 06:42:40 +00002653
Fred Drake08317ae2003-10-21 15:38:55 +00002654 if (!ns)
2655 return XML_ERROR_NONE;
2656
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002657 /* expand the element type name */
2658 if (elementType->prefix) {
2659 binding = elementType->prefix->binding;
2660 if (!binding)
Fred Drake08317ae2003-10-21 15:38:55 +00002661 return XML_ERROR_UNBOUND_PREFIX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002662 localPart = tagNamePtr->str;
2663 while (*localPart++ != XML_T(':'))
2664 ;
2665 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002666 else if (dtd->defaultPrefix.binding) {
2667 binding = dtd->defaultPrefix.binding;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002668 localPart = tagNamePtr->str;
2669 }
2670 else
2671 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002672 prefixLen = 0;
Fred Drake08317ae2003-10-21 15:38:55 +00002673 if (ns_triplets && binding->prefix->name) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002674 for (; binding->prefix->name[prefixLen++];)
2675 ;
2676 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002677 tagNamePtr->localPart = localPart;
2678 tagNamePtr->uriLen = binding->uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002679 tagNamePtr->prefix = binding->prefix->name;
2680 tagNamePtr->prefixLen = prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002681 for (i = 0; localPart[i++];)
2682 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002683 n = i + binding->uriLen + prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002684 if (n > binding->uriAlloc) {
2685 TAG *p;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002686 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002687 if (!uri)
2688 return XML_ERROR_NO_MEMORY;
2689 binding->uriAlloc = n + EXPAND_SPARE;
2690 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2691 for (p = tagStack; p; p = p->parent)
2692 if (p->name.str == binding->uri)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002693 p->name.str = uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002694 FREE(binding->uri);
2695 binding->uri = uri;
2696 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002697 uri = binding->uri + binding->uriLen;
2698 memcpy(uri, localPart, i * sizeof(XML_Char));
2699 if (prefixLen) {
Fred Drake08317ae2003-10-21 15:38:55 +00002700 uri = uri + (i - 1);
2701 if (namespaceSeparator)
2702 *uri = namespaceSeparator;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002703 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2704 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002705 tagNamePtr->str = binding->uri;
2706 return XML_ERROR_NONE;
2707}
2708
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002709/* addBinding() overwrites the value of prefix->binding without checking.
2710 Therefore one must keep track of the old value outside of addBinding().
2711*/
2712static enum XML_Error
2713addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2714 const XML_Char *uri, BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002715{
2716 BINDING *b;
2717 int len;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002718
2719 /* empty string is only valid when there is no prefix per XML NS 1.0 */
2720 if (*uri == XML_T('\0') && prefix->name)
2721 return XML_ERROR_SYNTAX;
2722
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002723 for (len = 0; uri[len]; len++)
2724 ;
2725 if (namespaceSeparator)
2726 len++;
2727 if (freeBindingList) {
2728 b = freeBindingList;
2729 if (len > b->uriAlloc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002730 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
2731 sizeof(XML_Char) * (len + EXPAND_SPARE));
2732 if (temp == NULL)
2733 return XML_ERROR_NO_MEMORY;
2734 b->uri = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002735 b->uriAlloc = len + EXPAND_SPARE;
2736 }
2737 freeBindingList = b->nextTagBinding;
2738 }
2739 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002740 b = (BINDING *)MALLOC(sizeof(BINDING));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002741 if (!b)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002742 return XML_ERROR_NO_MEMORY;
2743 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002744 if (!b->uri) {
2745 FREE(b);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002746 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002747 }
2748 b->uriAlloc = len + EXPAND_SPARE;
2749 }
2750 b->uriLen = len;
2751 memcpy(b->uri, uri, len * sizeof(XML_Char));
2752 if (namespaceSeparator)
2753 b->uri[len - 1] = namespaceSeparator;
2754 b->prefix = prefix;
2755 b->attId = attId;
2756 b->prevPrefixBinding = prefix->binding;
Fred Drake08317ae2003-10-21 15:38:55 +00002757 /* NULL binding when default namespace undeclared */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002758 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
2759 prefix->binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002760 else
2761 prefix->binding = b;
2762 b->nextTagBinding = *bindingsPtr;
2763 *bindingsPtr = b;
2764 if (startNamespaceDeclHandler)
2765 startNamespaceDeclHandler(handlerArg, prefix->name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002766 prefix->binding ? uri : 0);
2767 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002768}
2769
2770/* The idea here is to avoid using stack for each CDATA section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002771 the whole file is parsed with one call.
2772*/
2773static enum XML_Error PTRCALL
2774cdataSectionProcessor(XML_Parser parser,
2775 const char *start,
2776 const char *end,
2777 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002778{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002779 enum XML_Error result = doCdataSection(parser, encoding, &start,
2780 end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002781 if (start) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002782 if (parentParser) { /* we are parsing an external entity */
2783 processor = externalEntityContentProcessor;
2784 return externalEntityContentProcessor(parser, start, end, endPtr);
2785 }
2786 else {
2787 processor = contentProcessor;
2788 return contentProcessor(parser, start, end, endPtr);
2789 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002790 }
2791 return result;
2792}
2793
2794/* startPtr gets set to non-null is the section is closed, and to null if
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002795 the section is not yet closed.
2796*/
2797static enum XML_Error
2798doCdataSection(XML_Parser parser,
2799 const ENCODING *enc,
2800 const char **startPtr,
2801 const char *end,
2802 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002803{
2804 const char *s = *startPtr;
2805 const char **eventPP;
2806 const char **eventEndPP;
2807 if (enc == encoding) {
2808 eventPP = &eventPtr;
2809 *eventPP = s;
2810 eventEndPP = &eventEndPtr;
2811 }
2812 else {
2813 eventPP = &(openInternalEntities->internalEventPtr);
2814 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2815 }
2816 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002817 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002818 for (;;) {
2819 const char *next;
2820 int tok = XmlCdataSectionTok(enc, s, end, &next);
2821 *eventEndPP = next;
2822 switch (tok) {
2823 case XML_TOK_CDATA_SECT_CLOSE:
2824 if (endCdataSectionHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002825 endCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002826#if 0
2827 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2828 else if (characterDataHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002829 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002830#endif
2831 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002832 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002833 *startPtr = next;
2834 return XML_ERROR_NONE;
2835 case XML_TOK_DATA_NEWLINE:
2836 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002837 XML_Char c = 0xA;
2838 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002839 }
2840 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002841 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002842 break;
2843 case XML_TOK_DATA_CHARS:
2844 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002845 if (MUST_CONVERT(enc, s)) {
2846 for (;;) {
2847 ICHAR *dataPtr = (ICHAR *)dataBuf;
2848 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2849 *eventEndPP = next;
2850 characterDataHandler(handlerArg, dataBuf,
2851 dataPtr - (ICHAR *)dataBuf);
2852 if (s == next)
2853 break;
2854 *eventPP = s;
2855 }
2856 }
2857 else
2858 characterDataHandler(handlerArg,
2859 (XML_Char *)s,
2860 (XML_Char *)next - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002861 }
2862 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002863 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002864 break;
2865 case XML_TOK_INVALID:
2866 *eventPP = next;
2867 return XML_ERROR_INVALID_TOKEN;
2868 case XML_TOK_PARTIAL_CHAR:
2869 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002870 *nextPtr = s;
2871 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002872 }
2873 return XML_ERROR_PARTIAL_CHAR;
2874 case XML_TOK_PARTIAL:
2875 case XML_TOK_NONE:
2876 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002877 *nextPtr = s;
2878 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002879 }
2880 return XML_ERROR_UNCLOSED_CDATA_SECTION;
2881 default:
2882 *eventPP = next;
2883 return XML_ERROR_UNEXPECTED_STATE;
2884 }
2885 *eventPP = s = next;
2886 }
2887 /* not reached */
2888}
2889
2890#ifdef XML_DTD
2891
2892/* The idea here is to avoid using stack for each IGNORE section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002893 the whole file is parsed with one call.
2894*/
2895static enum XML_Error PTRCALL
2896ignoreSectionProcessor(XML_Parser parser,
2897 const char *start,
2898 const char *end,
2899 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002900{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002901 enum XML_Error result = doIgnoreSection(parser, encoding, &start,
2902 end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002903 if (start) {
2904 processor = prologProcessor;
2905 return prologProcessor(parser, start, end, endPtr);
2906 }
2907 return result;
2908}
2909
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002910/* startPtr gets set to non-null is the section is closed, and to null
2911 if the section is not yet closed.
2912*/
2913static enum XML_Error
2914doIgnoreSection(XML_Parser parser,
2915 const ENCODING *enc,
2916 const char **startPtr,
2917 const char *end,
2918 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002919{
2920 const char *next;
2921 int tok;
2922 const char *s = *startPtr;
2923 const char **eventPP;
2924 const char **eventEndPP;
2925 if (enc == encoding) {
2926 eventPP = &eventPtr;
2927 *eventPP = s;
2928 eventEndPP = &eventEndPtr;
2929 }
2930 else {
2931 eventPP = &(openInternalEntities->internalEventPtr);
2932 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2933 }
2934 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002935 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002936 tok = XmlIgnoreSectionTok(enc, s, end, &next);
2937 *eventEndPP = next;
2938 switch (tok) {
2939 case XML_TOK_IGNORE_SECT:
2940 if (defaultHandler)
2941 reportDefault(parser, enc, s, next);
2942 *startPtr = next;
2943 return XML_ERROR_NONE;
2944 case XML_TOK_INVALID:
2945 *eventPP = next;
2946 return XML_ERROR_INVALID_TOKEN;
2947 case XML_TOK_PARTIAL_CHAR:
2948 if (nextPtr) {
2949 *nextPtr = s;
2950 return XML_ERROR_NONE;
2951 }
2952 return XML_ERROR_PARTIAL_CHAR;
2953 case XML_TOK_PARTIAL:
2954 case XML_TOK_NONE:
2955 if (nextPtr) {
2956 *nextPtr = s;
2957 return XML_ERROR_NONE;
2958 }
2959 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2960 default:
2961 *eventPP = next;
2962 return XML_ERROR_UNEXPECTED_STATE;
2963 }
2964 /* not reached */
2965}
2966
2967#endif /* XML_DTD */
2968
2969static enum XML_Error
2970initializeEncoding(XML_Parser parser)
2971{
2972 const char *s;
2973#ifdef XML_UNICODE
2974 char encodingBuf[128];
2975 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002976 s = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002977 else {
2978 int i;
2979 for (i = 0; protocolEncodingName[i]; i++) {
2980 if (i == sizeof(encodingBuf) - 1
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002981 || (protocolEncodingName[i] & ~0x7f) != 0) {
2982 encodingBuf[0] = '\0';
2983 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002984 }
2985 encodingBuf[i] = (char)protocolEncodingName[i];
2986 }
2987 encodingBuf[i] = '\0';
2988 s = encodingBuf;
2989 }
2990#else
2991 s = protocolEncodingName;
2992#endif
2993 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
2994 return XML_ERROR_NONE;
2995 return handleUnknownEncoding(parser, protocolEncodingName);
2996}
2997
2998static enum XML_Error
2999processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003000 const char *s, const char *next)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003001{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003002 const char *encodingName = NULL;
3003 const XML_Char *storedEncName = NULL;
3004 const ENCODING *newEncoding = NULL;
3005 const char *version = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003006 const char *versionend;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003007 const XML_Char *storedversion = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003008 int standalone = -1;
3009 if (!(ns
3010 ? XmlParseXmlDeclNS
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003011 : XmlParseXmlDecl)(isGeneralTextEntity,
3012 encoding,
3013 s,
3014 next,
3015 &eventPtr,
3016 &version,
3017 &versionend,
3018 &encodingName,
3019 &newEncoding,
3020 &standalone))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003021 return XML_ERROR_SYNTAX;
3022 if (!isGeneralTextEntity && standalone == 1) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003023 _dtd->standalone = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003024#ifdef XML_DTD
3025 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3026 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3027#endif /* XML_DTD */
3028 }
3029 if (xmlDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003030 if (encodingName != NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003031 storedEncName = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003032 encoding,
3033 encodingName,
3034 encodingName
3035 + XmlNameLength(encoding, encodingName));
3036 if (!storedEncName)
3037 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003038 poolFinish(&temp2Pool);
3039 }
3040 if (version) {
3041 storedversion = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003042 encoding,
3043 version,
3044 versionend - encoding->minBytesPerChar);
3045 if (!storedversion)
3046 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003047 }
3048 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3049 }
3050 else if (defaultHandler)
3051 reportDefault(parser, encoding, s, next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003052 if (protocolEncodingName == NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003053 if (newEncoding) {
3054 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003055 eventPtr = encodingName;
3056 return XML_ERROR_INCORRECT_ENCODING;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003057 }
3058 encoding = newEncoding;
3059 }
3060 else if (encodingName) {
3061 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003062 if (!storedEncName) {
3063 storedEncName = poolStoreString(
3064 &temp2Pool, encoding, encodingName,
3065 encodingName + XmlNameLength(encoding, encodingName));
3066 if (!storedEncName)
3067 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003068 }
3069 result = handleUnknownEncoding(parser, storedEncName);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003070 poolClear(&temp2Pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003071 if (result == XML_ERROR_UNKNOWN_ENCODING)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003072 eventPtr = encodingName;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003073 return result;
3074 }
3075 }
3076
3077 if (storedEncName || storedversion)
3078 poolClear(&temp2Pool);
3079
3080 return XML_ERROR_NONE;
3081}
3082
3083static enum XML_Error
3084handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3085{
3086 if (unknownEncodingHandler) {
3087 XML_Encoding info;
3088 int i;
3089 for (i = 0; i < 256; i++)
3090 info.map[i] = -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003091 info.convert = NULL;
3092 info.data = NULL;
3093 info.release = NULL;
3094 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3095 &info)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003096 ENCODING *enc;
3097 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3098 if (!unknownEncodingMem) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003099 if (info.release)
3100 info.release(info.data);
3101 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003102 }
3103 enc = (ns
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003104 ? XmlInitUnknownEncodingNS
3105 : XmlInitUnknownEncoding)(unknownEncodingMem,
3106 info.map,
3107 info.convert,
3108 info.data);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003109 if (enc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003110 unknownEncodingData = info.data;
3111 unknownEncodingRelease = info.release;
3112 encoding = enc;
3113 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003114 }
3115 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003116 if (info.release != NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003117 info.release(info.data);
3118 }
3119 return XML_ERROR_UNKNOWN_ENCODING;
3120}
3121
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003122static enum XML_Error PTRCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003123prologInitProcessor(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003124 const char *s,
3125 const char *end,
3126 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003127{
3128 enum XML_Error result = initializeEncoding(parser);
3129 if (result != XML_ERROR_NONE)
3130 return result;
3131 processor = prologProcessor;
3132 return prologProcessor(parser, s, end, nextPtr);
3133}
3134
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003135#ifdef XML_DTD
3136
3137static enum XML_Error PTRCALL
3138externalParEntInitProcessor(XML_Parser parser,
3139 const char *s,
3140 const char *end,
3141 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003142{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003143 enum XML_Error result = initializeEncoding(parser);
3144 if (result != XML_ERROR_NONE)
3145 return result;
3146
3147 /* we know now that XML_Parse(Buffer) has been called,
3148 so we consider the external parameter entity read */
3149 _dtd->paramEntityRead = XML_TRUE;
3150
3151 if (prologState.inEntityValue) {
3152 processor = entityValueInitProcessor;
3153 return entityValueInitProcessor(parser, s, end, nextPtr);
3154 }
3155 else {
3156 processor = externalParEntProcessor;
3157 return externalParEntProcessor(parser, s, end, nextPtr);
3158 }
3159}
3160
3161static enum XML_Error PTRCALL
3162entityValueInitProcessor(XML_Parser parser,
3163 const char *s,
3164 const char *end,
3165 const char **nextPtr)
3166{
3167 const char *start = s;
3168 const char *next = s;
3169 int tok;
3170
3171 for (;;) {
3172 tok = XmlPrologTok(encoding, start, end, &next);
3173 if (tok <= 0) {
3174 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3175 *nextPtr = s;
3176 return XML_ERROR_NONE;
3177 }
3178 switch (tok) {
3179 case XML_TOK_INVALID:
3180 return XML_ERROR_INVALID_TOKEN;
3181 case XML_TOK_PARTIAL:
3182 return XML_ERROR_UNCLOSED_TOKEN;
3183 case XML_TOK_PARTIAL_CHAR:
3184 return XML_ERROR_PARTIAL_CHAR;
3185 case XML_TOK_NONE: /* start == end */
3186 default:
3187 break;
3188 }
3189 return storeEntityValue(parser, encoding, s, end);
3190 }
3191 else if (tok == XML_TOK_XML_DECL) {
3192 enum XML_Error result = processXmlDecl(parser, 0, start, next);
3193 if (result != XML_ERROR_NONE)
3194 return result;
3195 if (nextPtr) *nextPtr = next;
3196 /* stop scanning for text declaration - we found one */
3197 processor = entityValueProcessor;
3198 return entityValueProcessor(parser, next, end, nextPtr);
3199 }
3200 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3201 return XML_TOK_NONE on the next call, which would then cause the
3202 function to exit with *nextPtr set to s - that is what we want for other
3203 tokens, but not for the BOM - we would rather like to skip it;
3204 then, when this routine is entered the next time, XmlPrologTok will
3205 return XML_TOK_INVALID, since the BOM is still in the buffer
3206 */
3207 else if (tok == XML_TOK_BOM && next == end && nextPtr) {
3208 *nextPtr = next;
3209 return XML_ERROR_NONE;
3210 }
3211 start = next;
3212 }
3213}
3214
3215static enum XML_Error PTRCALL
3216externalParEntProcessor(XML_Parser parser,
3217 const char *s,
3218 const char *end,
3219 const char **nextPtr)
3220{
3221 const char *start = s;
3222 const char *next = s;
3223 int tok;
3224
3225 tok = XmlPrologTok(encoding, start, end, &next);
3226 if (tok <= 0) {
3227 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3228 *nextPtr = s;
3229 return XML_ERROR_NONE;
3230 }
3231 switch (tok) {
3232 case XML_TOK_INVALID:
3233 return XML_ERROR_INVALID_TOKEN;
3234 case XML_TOK_PARTIAL:
3235 return XML_ERROR_UNCLOSED_TOKEN;
3236 case XML_TOK_PARTIAL_CHAR:
3237 return XML_ERROR_PARTIAL_CHAR;
3238 case XML_TOK_NONE: /* start == end */
3239 default:
3240 break;
3241 }
3242 }
3243 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3244 However, when parsing an external subset, doProlog will not accept a BOM
3245 as valid, and report a syntax error, so we have to skip the BOM
3246 */
3247 else if (tok == XML_TOK_BOM) {
3248 s = next;
3249 tok = XmlPrologTok(encoding, s, end, &next);
3250 }
3251
3252 processor = prologProcessor;
3253 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3254}
3255
3256static enum XML_Error PTRCALL
3257entityValueProcessor(XML_Parser parser,
3258 const char *s,
3259 const char *end,
3260 const char **nextPtr)
3261{
3262 const char *start = s;
3263 const char *next = s;
3264 const ENCODING *enc = encoding;
3265 int tok;
3266
3267 for (;;) {
3268 tok = XmlPrologTok(enc, start, end, &next);
3269 if (tok <= 0) {
3270 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3271 *nextPtr = s;
3272 return XML_ERROR_NONE;
3273 }
3274 switch (tok) {
3275 case XML_TOK_INVALID:
3276 return XML_ERROR_INVALID_TOKEN;
3277 case XML_TOK_PARTIAL:
3278 return XML_ERROR_UNCLOSED_TOKEN;
3279 case XML_TOK_PARTIAL_CHAR:
3280 return XML_ERROR_PARTIAL_CHAR;
3281 case XML_TOK_NONE: /* start == end */
3282 default:
3283 break;
3284 }
3285 return storeEntityValue(parser, enc, s, end);
3286 }
3287 start = next;
3288 }
3289}
3290
3291#endif /* XML_DTD */
3292
3293static enum XML_Error PTRCALL
3294prologProcessor(XML_Parser parser,
3295 const char *s,
3296 const char *end,
3297 const char **nextPtr)
3298{
3299 const char *next = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003300 int tok = XmlPrologTok(encoding, s, end, &next);
3301 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3302}
3303
3304static enum XML_Error
3305doProlog(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003306 const ENCODING *enc,
3307 const char *s,
3308 const char *end,
3309 int tok,
3310 const char *next,
3311 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003312{
3313#ifdef XML_DTD
3314 static const XML_Char externalSubsetName[] = { '#' , '\0' };
3315#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003316 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3317 static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3318 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3319 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3320 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3321 static const XML_Char atypeENTITIES[] =
3322 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3323 static const XML_Char atypeNMTOKEN[] = {
3324 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3325 static const XML_Char atypeNMTOKENS[] = {
3326 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3327 static const XML_Char notationPrefix[] = {
3328 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3329 static const XML_Char enumValueSep[] = { '|', '\0' };
3330 static const XML_Char enumValueStart[] = { '(', '\0' };
3331
3332 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003333
3334 const char **eventPP;
3335 const char **eventEndPP;
3336 enum XML_Content_Quant quant;
3337
3338 if (enc == encoding) {
3339 eventPP = &eventPtr;
3340 eventEndPP = &eventEndPtr;
3341 }
3342 else {
3343 eventPP = &(openInternalEntities->internalEventPtr);
3344 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3345 }
3346 for (;;) {
3347 int role;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003348 XML_Bool handleDefault = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003349 *eventPP = s;
3350 *eventEndPP = next;
3351 if (tok <= 0) {
3352 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003353 *nextPtr = s;
3354 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003355 }
3356 switch (tok) {
3357 case XML_TOK_INVALID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003358 *eventPP = next;
3359 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003360 case XML_TOK_PARTIAL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003361 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003362 case XML_TOK_PARTIAL_CHAR:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003363 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003364 case XML_TOK_NONE:
3365#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003366 if (enc != encoding)
3367 return XML_ERROR_NONE;
3368 if (isParamEntity) {
3369 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3370 == XML_ROLE_ERROR)
3371 return XML_ERROR_SYNTAX;
3372 return XML_ERROR_NONE;
3373 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003374#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003375 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003376 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003377 tok = -tok;
3378 next = end;
3379 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003380 }
3381 }
3382 role = XmlTokenRole(&prologState, tok, s, next, enc);
3383 switch (role) {
3384 case XML_ROLE_XML_DECL:
3385 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003386 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3387 if (result != XML_ERROR_NONE)
3388 return result;
3389 enc = encoding;
3390 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003391 }
3392 break;
3393 case XML_ROLE_DOCTYPE_NAME:
3394 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003395 doctypeName = poolStoreString(&tempPool, enc, s, next);
3396 if (!doctypeName)
3397 return XML_ERROR_NO_MEMORY;
3398 poolFinish(&tempPool);
3399 doctypePubid = NULL;
3400 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003401 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003402 doctypeSysid = NULL; /* always initialize to NULL */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003403 break;
3404 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3405 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003406 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3407 doctypePubid, 1);
3408 doctypeName = NULL;
3409 poolClear(&tempPool);
3410 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003411 }
3412 break;
3413#ifdef XML_DTD
3414 case XML_ROLE_TEXT_DECL:
3415 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003416 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3417 if (result != XML_ERROR_NONE)
3418 return result;
3419 enc = encoding;
3420 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003421 }
3422 break;
3423#endif /* XML_DTD */
3424 case XML_ROLE_DOCTYPE_PUBLIC_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003425#ifdef XML_DTD
3426 useForeignDTD = XML_FALSE;
3427#endif /* XML_DTD */
3428 dtd->hasParamEntityRefs = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003429 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003430 doctypePubid = poolStoreString(&tempPool, enc,
3431 s + enc->minBytesPerChar,
3432 next - enc->minBytesPerChar);
3433 if (!doctypePubid)
3434 return XML_ERROR_NO_MEMORY;
3435 poolFinish(&tempPool);
3436 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003437 }
3438#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003439 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3440 externalSubsetName,
3441 sizeof(ENTITY));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003442 if (!declEntity)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003443 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003444#endif /* XML_DTD */
3445 /* fall through */
3446 case XML_ROLE_ENTITY_PUBLIC_ID:
3447 if (!XmlIsPublicId(enc, s, next, eventPP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003448 return XML_ERROR_SYNTAX;
3449 if (dtd->keepProcessing && declEntity) {
3450 XML_Char *tem = poolStoreString(&dtd->pool,
3451 enc,
3452 s + enc->minBytesPerChar,
3453 next - enc->minBytesPerChar);
3454 if (!tem)
3455 return XML_ERROR_NO_MEMORY;
3456 normalizePublicId(tem);
3457 declEntity->publicId = tem;
3458 poolFinish(&dtd->pool);
3459 if (entityDeclHandler)
3460 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003461 }
3462 break;
3463 case XML_ROLE_DOCTYPE_CLOSE:
3464 if (doctypeName) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003465 startDoctypeDeclHandler(handlerArg, doctypeName,
3466 doctypeSysid, doctypePubid, 0);
3467 poolClear(&tempPool);
3468 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003469 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003470 /* doctypeSysid will be non-NULL in the case of a previous
3471 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3472 was not set, indicating an external subset
3473 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003474#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003475 if (doctypeSysid || useForeignDTD) {
3476 dtd->hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */
3477 if (paramEntityParsing && externalEntityRefHandler) {
3478 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3479 externalSubsetName,
3480 sizeof(ENTITY));
3481 if (!entity)
3482 return XML_ERROR_NO_MEMORY;
3483 if (useForeignDTD)
3484 entity->base = curBase;
3485 dtd->paramEntityRead = XML_FALSE;
3486 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3487 0,
3488 entity->base,
3489 entity->systemId,
3490 entity->publicId))
3491 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3492 if (dtd->paramEntityRead &&
3493 !dtd->standalone &&
3494 notStandaloneHandler &&
3495 !notStandaloneHandler(handlerArg))
3496 return XML_ERROR_NOT_STANDALONE;
3497 /* end of DTD - no need to update dtd->keepProcessing */
3498 }
3499 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003500 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003501#endif /* XML_DTD */
3502 if (endDoctypeDeclHandler) {
3503 endDoctypeDeclHandler(handlerArg);
3504 handleDefault = XML_FALSE;
3505 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003506 break;
3507 case XML_ROLE_INSTANCE_START:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003508#ifdef XML_DTD
3509 /* if there is no DOCTYPE declaration then now is the
3510 last chance to read the foreign DTD
3511 */
3512 if (useForeignDTD) {
3513 dtd->hasParamEntityRefs = XML_TRUE;
3514 if (paramEntityParsing && externalEntityRefHandler) {
3515 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3516 externalSubsetName,
3517 sizeof(ENTITY));
3518 if (!entity)
3519 return XML_ERROR_NO_MEMORY;
3520 entity->base = curBase;
3521 dtd->paramEntityRead = XML_FALSE;
3522 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3523 0,
3524 entity->base,
3525 entity->systemId,
3526 entity->publicId))
3527 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3528 if (dtd->paramEntityRead &&
3529 !dtd->standalone &&
3530 notStandaloneHandler &&
3531 !notStandaloneHandler(handlerArg))
3532 return XML_ERROR_NOT_STANDALONE;
3533 /* end of DTD - no need to update dtd->keepProcessing */
3534 }
3535 }
3536#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003537 processor = contentProcessor;
3538 return contentProcessor(parser, s, end, nextPtr);
3539 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3540 declElementType = getElementType(parser, enc, s, next);
3541 if (!declElementType)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003542 return XML_ERROR_NO_MEMORY;
3543 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003544 case XML_ROLE_ATTRIBUTE_NAME:
3545 declAttributeId = getAttributeId(parser, enc, s, next);
3546 if (!declAttributeId)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003547 return XML_ERROR_NO_MEMORY;
3548 declAttributeIsCdata = XML_FALSE;
3549 declAttributeType = NULL;
3550 declAttributeIsId = XML_FALSE;
3551 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003552 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003553 declAttributeIsCdata = XML_TRUE;
3554 declAttributeType = atypeCDATA;
3555 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003556 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003557 declAttributeIsId = XML_TRUE;
3558 declAttributeType = atypeID;
3559 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003560 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003561 declAttributeType = atypeIDREF;
3562 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003563 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003564 declAttributeType = atypeIDREFS;
3565 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003566 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003567 declAttributeType = atypeENTITY;
3568 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003569 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003570 declAttributeType = atypeENTITIES;
3571 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003572 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003573 declAttributeType = atypeNMTOKEN;
3574 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003575 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003576 declAttributeType = atypeNMTOKENS;
3577 checkAttListDeclHandler:
3578 if (dtd->keepProcessing && attlistDeclHandler)
3579 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003580 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003581 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3582 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003583 if (dtd->keepProcessing && attlistDeclHandler) {
3584 const XML_Char *prefix;
3585 if (declAttributeType) {
3586 prefix = enumValueSep;
3587 }
3588 else {
3589 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3590 ? notationPrefix
3591 : enumValueStart);
3592 }
3593 if (!poolAppendString(&tempPool, prefix))
3594 return XML_ERROR_NO_MEMORY;
3595 if (!poolAppend(&tempPool, enc, s, next))
3596 return XML_ERROR_NO_MEMORY;
3597 declAttributeType = tempPool.start;
3598 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003599 }
3600 break;
3601 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3602 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003603 if (dtd->keepProcessing) {
3604 if (!defineAttribute(declElementType, declAttributeId,
Fred Drake08317ae2003-10-21 15:38:55 +00003605 declAttributeIsCdata, declAttributeIsId,
3606 0, parser))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003607 return XML_ERROR_NO_MEMORY;
3608 if (attlistDeclHandler && declAttributeType) {
3609 if (*declAttributeType == XML_T('(')
3610 || (*declAttributeType == XML_T('N')
3611 && declAttributeType[1] == XML_T('O'))) {
3612 /* Enumerated or Notation type */
3613 if (!poolAppendChar(&tempPool, XML_T(')'))
3614 || !poolAppendChar(&tempPool, XML_T('\0')))
3615 return XML_ERROR_NO_MEMORY;
3616 declAttributeType = tempPool.start;
3617 poolFinish(&tempPool);
3618 }
3619 *eventEndPP = s;
3620 attlistDeclHandler(handlerArg, declElementType->name,
3621 declAttributeId->name, declAttributeType,
3622 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
3623 poolClear(&tempPool);
3624 handleDefault = XML_FALSE;
3625 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003626 }
3627 break;
3628 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3629 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003630 if (dtd->keepProcessing) {
3631 const XML_Char *attVal;
Fred Drake08317ae2003-10-21 15:38:55 +00003632 enum XML_Error result =
3633 storeAttributeValue(parser, enc, declAttributeIsCdata,
3634 s + enc->minBytesPerChar,
3635 next - enc->minBytesPerChar,
3636 &dtd->pool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003637 if (result)
3638 return result;
3639 attVal = poolStart(&dtd->pool);
3640 poolFinish(&dtd->pool);
3641 /* ID attributes aren't allowed to have a default */
3642 if (!defineAttribute(declElementType, declAttributeId,
3643 declAttributeIsCdata, XML_FALSE, attVal, parser))
3644 return XML_ERROR_NO_MEMORY;
3645 if (attlistDeclHandler && declAttributeType) {
3646 if (*declAttributeType == XML_T('(')
3647 || (*declAttributeType == XML_T('N')
3648 && declAttributeType[1] == XML_T('O'))) {
3649 /* Enumerated or Notation type */
3650 if (!poolAppendChar(&tempPool, XML_T(')'))
3651 || !poolAppendChar(&tempPool, XML_T('\0')))
3652 return XML_ERROR_NO_MEMORY;
3653 declAttributeType = tempPool.start;
3654 poolFinish(&tempPool);
3655 }
3656 *eventEndPP = s;
3657 attlistDeclHandler(handlerArg, declElementType->name,
3658 declAttributeId->name, declAttributeType,
3659 attVal,
3660 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
3661 poolClear(&tempPool);
3662 handleDefault = XML_FALSE;
3663 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003664 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003665 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003666 case XML_ROLE_ENTITY_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003667 if (dtd->keepProcessing) {
3668 enum XML_Error result = storeEntityValue(parser, enc,
3669 s + enc->minBytesPerChar,
3670 next - enc->minBytesPerChar);
3671 if (declEntity) {
3672 declEntity->textPtr = poolStart(&dtd->entityValuePool);
3673 declEntity->textLen = poolLength(&dtd->entityValuePool);
3674 poolFinish(&dtd->entityValuePool);
3675 if (entityDeclHandler) {
3676 *eventEndPP = s;
3677 entityDeclHandler(handlerArg,
3678 declEntity->name,
3679 declEntity->is_param,
3680 declEntity->textPtr,
3681 declEntity->textLen,
3682 curBase, 0, 0, 0);
3683 handleDefault = XML_FALSE;
3684 }
3685 }
3686 else
3687 poolDiscard(&dtd->entityValuePool);
3688 if (result != XML_ERROR_NONE)
3689 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003690 }
3691 break;
3692 case XML_ROLE_DOCTYPE_SYSTEM_ID:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003693#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003694 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003695#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003696 dtd->hasParamEntityRefs = XML_TRUE;
3697 if (startDoctypeDeclHandler) {
3698 doctypeSysid = poolStoreString(&tempPool, enc,
3699 s + enc->minBytesPerChar,
3700 next - enc->minBytesPerChar);
3701 if (doctypeSysid == NULL)
3702 return XML_ERROR_NO_MEMORY;
3703 poolFinish(&tempPool);
3704 handleDefault = XML_FALSE;
3705 }
3706#ifdef XML_DTD
3707 else
3708 /* use externalSubsetName to make doctypeSysid non-NULL
3709 for the case where no startDoctypeDeclHandler is set */
3710 doctypeSysid = externalSubsetName;
3711#endif /* XML_DTD */
3712 if (!dtd->standalone
3713#ifdef XML_DTD
3714 && !paramEntityParsing
3715#endif /* XML_DTD */
3716 && notStandaloneHandler
3717 && !notStandaloneHandler(handlerArg))
3718 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003719#ifndef XML_DTD
3720 break;
3721#else /* XML_DTD */
3722 if (!declEntity) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003723 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3724 externalSubsetName,
3725 sizeof(ENTITY));
3726 if (!declEntity)
3727 return XML_ERROR_NO_MEMORY;
3728 declEntity->publicId = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003729 }
3730 /* fall through */
3731#endif /* XML_DTD */
3732 case XML_ROLE_ENTITY_SYSTEM_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003733 if (dtd->keepProcessing && declEntity) {
3734 declEntity->systemId = poolStoreString(&dtd->pool, enc,
3735 s + enc->minBytesPerChar,
3736 next - enc->minBytesPerChar);
3737 if (!declEntity->systemId)
3738 return XML_ERROR_NO_MEMORY;
3739 declEntity->base = curBase;
3740 poolFinish(&dtd->pool);
3741 if (entityDeclHandler)
3742 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003743 }
3744 break;
3745 case XML_ROLE_ENTITY_COMPLETE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003746 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
3747 *eventEndPP = s;
3748 entityDeclHandler(handlerArg,
3749 declEntity->name,
3750 declEntity->is_param,
3751 0,0,
3752 declEntity->base,
3753 declEntity->systemId,
3754 declEntity->publicId,
3755 0);
3756 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003757 }
3758 break;
3759 case XML_ROLE_ENTITY_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003760 if (dtd->keepProcessing && declEntity) {
3761 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
3762 if (!declEntity->notation)
3763 return XML_ERROR_NO_MEMORY;
3764 poolFinish(&dtd->pool);
3765 if (unparsedEntityDeclHandler) {
3766 *eventEndPP = s;
3767 unparsedEntityDeclHandler(handlerArg,
3768 declEntity->name,
3769 declEntity->base,
3770 declEntity->systemId,
3771 declEntity->publicId,
3772 declEntity->notation);
3773 handleDefault = XML_FALSE;
3774 }
3775 else if (entityDeclHandler) {
3776 *eventEndPP = s;
3777 entityDeclHandler(handlerArg,
3778 declEntity->name,
3779 0,0,0,
3780 declEntity->base,
3781 declEntity->systemId,
3782 declEntity->publicId,
3783 declEntity->notation);
3784 handleDefault = XML_FALSE;
3785 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003786 }
3787 break;
3788 case XML_ROLE_GENERAL_ENTITY_NAME:
3789 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003790 if (XmlPredefinedEntityName(enc, s, next)) {
3791 declEntity = NULL;
3792 break;
3793 }
3794 if (dtd->keepProcessing) {
3795 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
3796 if (!name)
3797 return XML_ERROR_NO_MEMORY;
3798 declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
3799 sizeof(ENTITY));
3800 if (!declEntity)
3801 return XML_ERROR_NO_MEMORY;
3802 if (declEntity->name != name) {
3803 poolDiscard(&dtd->pool);
3804 declEntity = NULL;
3805 }
3806 else {
3807 poolFinish(&dtd->pool);
3808 declEntity->publicId = NULL;
3809 declEntity->is_param = XML_FALSE;
3810 /* if we have a parent parser or are reading an internal parameter
3811 entity, then the entity declaration is not considered "internal"
3812 */
3813 declEntity->is_internal = !(parentParser || openInternalEntities);
3814 if (entityDeclHandler)
3815 handleDefault = XML_FALSE;
3816 }
3817 }
3818 else {
3819 poolDiscard(&dtd->pool);
3820 declEntity = NULL;
3821 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003822 }
3823 break;
3824 case XML_ROLE_PARAM_ENTITY_NAME:
3825#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003826 if (dtd->keepProcessing) {
3827 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
3828 if (!name)
3829 return XML_ERROR_NO_MEMORY;
3830 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3831 name, sizeof(ENTITY));
3832 if (!declEntity)
3833 return XML_ERROR_NO_MEMORY;
3834 if (declEntity->name != name) {
3835 poolDiscard(&dtd->pool);
3836 declEntity = NULL;
3837 }
3838 else {
3839 poolFinish(&dtd->pool);
3840 declEntity->publicId = NULL;
3841 declEntity->is_param = XML_TRUE;
3842 /* if we have a parent parser or are reading an internal parameter
3843 entity, then the entity declaration is not considered "internal"
3844 */
3845 declEntity->is_internal = !(parentParser || openInternalEntities);
3846 if (entityDeclHandler)
3847 handleDefault = XML_FALSE;
3848 }
3849 }
3850 else {
3851 poolDiscard(&dtd->pool);
3852 declEntity = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003853 }
3854#else /* not XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003855 declEntity = NULL;
3856#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003857 break;
3858 case XML_ROLE_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003859 declNotationPublicId = NULL;
3860 declNotationName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003861 if (notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003862 declNotationName = poolStoreString(&tempPool, enc, s, next);
3863 if (!declNotationName)
3864 return XML_ERROR_NO_MEMORY;
3865 poolFinish(&tempPool);
3866 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003867 }
3868 break;
3869 case XML_ROLE_NOTATION_PUBLIC_ID:
3870 if (!XmlIsPublicId(enc, s, next, eventPP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003871 return XML_ERROR_SYNTAX;
3872 if (declNotationName) { /* means notationDeclHandler != NULL */
3873 XML_Char *tem = poolStoreString(&tempPool,
3874 enc,
3875 s + enc->minBytesPerChar,
3876 next - enc->minBytesPerChar);
3877 if (!tem)
3878 return XML_ERROR_NO_MEMORY;
3879 normalizePublicId(tem);
3880 declNotationPublicId = tem;
3881 poolFinish(&tempPool);
3882 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003883 }
3884 break;
3885 case XML_ROLE_NOTATION_SYSTEM_ID:
3886 if (declNotationName && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003887 const XML_Char *systemId
3888 = poolStoreString(&tempPool, enc,
3889 s + enc->minBytesPerChar,
3890 next - enc->minBytesPerChar);
3891 if (!systemId)
3892 return XML_ERROR_NO_MEMORY;
3893 *eventEndPP = s;
3894 notationDeclHandler(handlerArg,
3895 declNotationName,
3896 curBase,
3897 systemId,
3898 declNotationPublicId);
3899 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003900 }
3901 poolClear(&tempPool);
3902 break;
3903 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
3904 if (declNotationPublicId && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003905 *eventEndPP = s;
3906 notationDeclHandler(handlerArg,
3907 declNotationName,
3908 curBase,
3909 0,
3910 declNotationPublicId);
3911 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003912 }
3913 poolClear(&tempPool);
3914 break;
3915 case XML_ROLE_ERROR:
3916 switch (tok) {
3917 case XML_TOK_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003918 return XML_ERROR_PARAM_ENTITY_REF;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003919 case XML_TOK_XML_DECL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003920 return XML_ERROR_MISPLACED_XML_PI;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003921 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003922 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003923 }
3924#ifdef XML_DTD
3925 case XML_ROLE_IGNORE_SECT:
3926 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003927 enum XML_Error result;
3928 if (defaultHandler)
3929 reportDefault(parser, enc, s, next);
3930 handleDefault = XML_FALSE;
3931 result = doIgnoreSection(parser, enc, &next, end, nextPtr);
3932 if (!next) {
3933 processor = ignoreSectionProcessor;
3934 return result;
3935 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003936 }
3937 break;
3938#endif /* XML_DTD */
3939 case XML_ROLE_GROUP_OPEN:
3940 if (prologState.level >= groupSize) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003941 if (groupSize) {
3942 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
3943 if (temp == NULL)
3944 return XML_ERROR_NO_MEMORY;
3945 groupConnector = temp;
3946 if (dtd->scaffIndex) {
3947 int *temp = (int *)REALLOC(dtd->scaffIndex,
3948 groupSize * sizeof(int));
3949 if (temp == NULL)
3950 return XML_ERROR_NO_MEMORY;
3951 dtd->scaffIndex = temp;
3952 }
3953 }
3954 else {
3955 groupConnector = (char *)MALLOC(groupSize = 32);
3956 if (!groupConnector)
3957 return XML_ERROR_NO_MEMORY;
3958 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003959 }
3960 groupConnector[prologState.level] = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003961 if (dtd->in_eldecl) {
3962 int myindex = nextScaffoldPart(parser);
3963 if (myindex < 0)
3964 return XML_ERROR_NO_MEMORY;
3965 dtd->scaffIndex[dtd->scaffLevel] = myindex;
3966 dtd->scaffLevel++;
3967 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
3968 if (elementDeclHandler)
3969 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003970 }
3971 break;
3972 case XML_ROLE_GROUP_SEQUENCE:
3973 if (groupConnector[prologState.level] == '|')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003974 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003975 groupConnector[prologState.level] = ',';
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003976 if (dtd->in_eldecl && elementDeclHandler)
3977 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003978 break;
3979 case XML_ROLE_GROUP_CHOICE:
3980 if (groupConnector[prologState.level] == ',')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003981 return XML_ERROR_SYNTAX;
3982 if (dtd->in_eldecl
3983 && !groupConnector[prologState.level]
3984 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
3985 != XML_CTYPE_MIXED)
3986 ) {
3987 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
3988 = XML_CTYPE_CHOICE;
3989 if (elementDeclHandler)
3990 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003991 }
3992 groupConnector[prologState.level] = '|';
3993 break;
3994 case XML_ROLE_PARAM_ENTITY_REF:
3995#ifdef XML_DTD
3996 case XML_ROLE_INNER_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003997 /* PE references in internal subset are
3998 not allowed within declarations */
3999 if (prologState.documentEntity &&
4000 role == XML_ROLE_INNER_PARAM_ENTITY_REF)
4001 return XML_ERROR_PARAM_ENTITY_REF;
4002 dtd->hasParamEntityRefs = XML_TRUE;
4003 if (!paramEntityParsing)
4004 dtd->keepProcessing = dtd->standalone;
4005 else {
4006 const XML_Char *name;
4007 ENTITY *entity;
4008 name = poolStoreString(&dtd->pool, enc,
4009 s + enc->minBytesPerChar,
4010 next - enc->minBytesPerChar);
4011 if (!name)
4012 return XML_ERROR_NO_MEMORY;
4013 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4014 poolDiscard(&dtd->pool);
4015 /* first, determine if a check for an existing declaration is needed;
4016 if yes, check that the entity exists, and that it is internal,
4017 otherwise call the skipped entity handler
4018 */
4019 if (prologState.documentEntity &&
4020 (dtd->standalone
4021 ? !openInternalEntities
4022 : !dtd->hasParamEntityRefs)) {
4023 if (!entity)
4024 return XML_ERROR_UNDEFINED_ENTITY;
4025 else if (!entity->is_internal)
4026 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4027 }
4028 else if (!entity) {
4029 dtd->keepProcessing = dtd->standalone;
4030 /* cannot report skipped entities in declarations */
4031 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4032 skippedEntityHandler(handlerArg, name, 1);
4033 handleDefault = XML_FALSE;
4034 }
4035 break;
4036 }
4037 if (entity->open)
4038 return XML_ERROR_RECURSIVE_ENTITY_REF;
4039 if (entity->textPtr) {
4040 enum XML_Error result;
4041 result = processInternalParamEntity(parser, entity);
4042 if (result != XML_ERROR_NONE)
4043 return result;
4044 handleDefault = XML_FALSE;
4045 break;
4046 }
4047 if (externalEntityRefHandler) {
4048 dtd->paramEntityRead = XML_FALSE;
4049 entity->open = XML_TRUE;
4050 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4051 0,
4052 entity->base,
4053 entity->systemId,
4054 entity->publicId)) {
4055 entity->open = XML_FALSE;
4056 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4057 }
4058 entity->open = XML_FALSE;
4059 handleDefault = XML_FALSE;
4060 if (!dtd->paramEntityRead) {
4061 dtd->keepProcessing = dtd->standalone;
4062 break;
4063 }
4064 }
4065 else {
4066 dtd->keepProcessing = dtd->standalone;
4067 break;
4068 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004069 }
4070#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004071 if (!dtd->standalone &&
4072 notStandaloneHandler &&
4073 !notStandaloneHandler(handlerArg))
4074 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004075 break;
4076
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004077 /* Element declaration stuff */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004078
4079 case XML_ROLE_ELEMENT_NAME:
4080 if (elementDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004081 declElementType = getElementType(parser, enc, s, next);
4082 if (!declElementType)
4083 return XML_ERROR_NO_MEMORY;
4084 dtd->scaffLevel = 0;
4085 dtd->scaffCount = 0;
4086 dtd->in_eldecl = XML_TRUE;
4087 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004088 }
4089 break;
4090
4091 case XML_ROLE_CONTENT_ANY:
4092 case XML_ROLE_CONTENT_EMPTY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004093 if (dtd->in_eldecl) {
4094 if (elementDeclHandler) {
4095 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4096 if (!content)
4097 return XML_ERROR_NO_MEMORY;
4098 content->quant = XML_CQUANT_NONE;
4099 content->name = NULL;
4100 content->numchildren = 0;
4101 content->children = NULL;
4102 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4103 XML_CTYPE_ANY :
4104 XML_CTYPE_EMPTY);
4105 *eventEndPP = s;
4106 elementDeclHandler(handlerArg, declElementType->name, content);
4107 handleDefault = XML_FALSE;
4108 }
4109 dtd->in_eldecl = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004110 }
4111 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004112
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004113 case XML_ROLE_CONTENT_PCDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004114 if (dtd->in_eldecl) {
4115 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4116 = XML_CTYPE_MIXED;
4117 if (elementDeclHandler)
4118 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004119 }
4120 break;
4121
4122 case XML_ROLE_CONTENT_ELEMENT:
4123 quant = XML_CQUANT_NONE;
4124 goto elementContent;
4125 case XML_ROLE_CONTENT_ELEMENT_OPT:
4126 quant = XML_CQUANT_OPT;
4127 goto elementContent;
4128 case XML_ROLE_CONTENT_ELEMENT_REP:
4129 quant = XML_CQUANT_REP;
4130 goto elementContent;
4131 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4132 quant = XML_CQUANT_PLUS;
4133 elementContent:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004134 if (dtd->in_eldecl) {
4135 ELEMENT_TYPE *el;
4136 const XML_Char *name;
4137 int nameLen;
4138 const char *nxt = (quant == XML_CQUANT_NONE
4139 ? next
4140 : next - enc->minBytesPerChar);
4141 int myindex = nextScaffoldPart(parser);
4142 if (myindex < 0)
4143 return XML_ERROR_NO_MEMORY;
4144 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4145 dtd->scaffold[myindex].quant = quant;
4146 el = getElementType(parser, enc, s, nxt);
4147 if (!el)
4148 return XML_ERROR_NO_MEMORY;
4149 name = el->name;
4150 dtd->scaffold[myindex].name = name;
4151 nameLen = 0;
4152 for (; name[nameLen++]; );
4153 dtd->contentStringLen += nameLen;
4154 if (elementDeclHandler)
4155 handleDefault = XML_FALSE;
4156 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004157 break;
4158
4159 case XML_ROLE_GROUP_CLOSE:
4160 quant = XML_CQUANT_NONE;
4161 goto closeGroup;
4162 case XML_ROLE_GROUP_CLOSE_OPT:
4163 quant = XML_CQUANT_OPT;
4164 goto closeGroup;
4165 case XML_ROLE_GROUP_CLOSE_REP:
4166 quant = XML_CQUANT_REP;
4167 goto closeGroup;
4168 case XML_ROLE_GROUP_CLOSE_PLUS:
4169 quant = XML_CQUANT_PLUS;
4170 closeGroup:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004171 if (dtd->in_eldecl) {
4172 if (elementDeclHandler)
4173 handleDefault = XML_FALSE;
4174 dtd->scaffLevel--;
4175 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4176 if (dtd->scaffLevel == 0) {
4177 if (!handleDefault) {
4178 XML_Content *model = build_model(parser);
4179 if (!model)
4180 return XML_ERROR_NO_MEMORY;
4181 *eventEndPP = s;
4182 elementDeclHandler(handlerArg, declElementType->name, model);
4183 }
4184 dtd->in_eldecl = XML_FALSE;
4185 dtd->contentStringLen = 0;
4186 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004187 }
4188 break;
4189 /* End element declaration stuff */
4190
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004191 case XML_ROLE_PI:
4192 if (!reportProcessingInstruction(parser, enc, s, next))
4193 return XML_ERROR_NO_MEMORY;
4194 handleDefault = XML_FALSE;
4195 break;
4196 case XML_ROLE_COMMENT:
4197 if (!reportComment(parser, enc, s, next))
4198 return XML_ERROR_NO_MEMORY;
4199 handleDefault = XML_FALSE;
4200 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004201 case XML_ROLE_NONE:
4202 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004203 case XML_TOK_BOM:
4204 handleDefault = XML_FALSE;
4205 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004206 }
4207 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004208 case XML_ROLE_DOCTYPE_NONE:
4209 if (startDoctypeDeclHandler)
4210 handleDefault = XML_FALSE;
4211 break;
4212 case XML_ROLE_ENTITY_NONE:
4213 if (dtd->keepProcessing && entityDeclHandler)
4214 handleDefault = XML_FALSE;
4215 break;
4216 case XML_ROLE_NOTATION_NONE:
4217 if (notationDeclHandler)
4218 handleDefault = XML_FALSE;
4219 break;
4220 case XML_ROLE_ATTLIST_NONE:
4221 if (dtd->keepProcessing && attlistDeclHandler)
4222 handleDefault = XML_FALSE;
4223 break;
4224 case XML_ROLE_ELEMENT_NONE:
4225 if (elementDeclHandler)
4226 handleDefault = XML_FALSE;
4227 break;
4228 } /* end of big switch */
4229
4230 if (handleDefault && defaultHandler)
4231 reportDefault(parser, enc, s, next);
4232
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004233 s = next;
4234 tok = XmlPrologTok(enc, s, end, &next);
4235 }
4236 /* not reached */
4237}
4238
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004239static enum XML_Error PTRCALL
4240epilogProcessor(XML_Parser parser,
4241 const char *s,
4242 const char *end,
4243 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004244{
4245 processor = epilogProcessor;
4246 eventPtr = s;
4247 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004248 const char *next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004249 int tok = XmlPrologTok(encoding, s, end, &next);
4250 eventEndPtr = next;
4251 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004252 /* report partial linebreak - it might be the last token */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004253 case -XML_TOK_PROLOG_S:
4254 if (defaultHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004255 eventEndPtr = next;
4256 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004257 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004258 if (nextPtr)
4259 *nextPtr = next;
4260 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004261 case XML_TOK_NONE:
4262 if (nextPtr)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004263 *nextPtr = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004264 return XML_ERROR_NONE;
4265 case XML_TOK_PROLOG_S:
4266 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004267 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004268 break;
4269 case XML_TOK_PI:
4270 if (!reportProcessingInstruction(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004271 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004272 break;
4273 case XML_TOK_COMMENT:
4274 if (!reportComment(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004275 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004276 break;
4277 case XML_TOK_INVALID:
4278 eventPtr = next;
4279 return XML_ERROR_INVALID_TOKEN;
4280 case XML_TOK_PARTIAL:
4281 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004282 *nextPtr = s;
4283 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004284 }
4285 return XML_ERROR_UNCLOSED_TOKEN;
4286 case XML_TOK_PARTIAL_CHAR:
4287 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004288 *nextPtr = s;
4289 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004290 }
4291 return XML_ERROR_PARTIAL_CHAR;
4292 default:
4293 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4294 }
4295 eventPtr = s = next;
4296 }
4297}
4298
4299#ifdef XML_DTD
4300
4301static enum XML_Error
4302processInternalParamEntity(XML_Parser parser, ENTITY *entity)
4303{
4304 const char *s, *end, *next;
4305 int tok;
4306 enum XML_Error result;
4307 OPEN_INTERNAL_ENTITY openEntity;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004308 entity->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004309 openEntity.next = openInternalEntities;
4310 openInternalEntities = &openEntity;
4311 openEntity.entity = entity;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004312 openEntity.internalEventPtr = NULL;
4313 openEntity.internalEventEndPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004314 s = (char *)entity->textPtr;
4315 end = (char *)(entity->textPtr + entity->textLen);
4316 tok = XmlPrologTok(internalEncoding, s, end, &next);
4317 result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004318 entity->open = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004319 openInternalEntities = openEntity.next;
4320 return result;
4321}
4322
4323#endif /* XML_DTD */
4324
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004325static enum XML_Error PTRCALL
4326errorProcessor(XML_Parser parser,
4327 const char *s,
4328 const char *end,
4329 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004330{
4331 return errorCode;
4332}
4333
4334static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004335storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4336 const char *ptr, const char *end,
4337 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004338{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004339 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4340 end, pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004341 if (result)
4342 return result;
4343 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4344 poolChop(pool);
4345 if (!poolAppendChar(pool, XML_T('\0')))
4346 return XML_ERROR_NO_MEMORY;
4347 return XML_ERROR_NONE;
4348}
4349
4350static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004351appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4352 const char *ptr, const char *end,
4353 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004354{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004355 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004356 for (;;) {
4357 const char *next;
4358 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4359 switch (tok) {
4360 case XML_TOK_NONE:
4361 return XML_ERROR_NONE;
4362 case XML_TOK_INVALID:
4363 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004364 eventPtr = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004365 return XML_ERROR_INVALID_TOKEN;
4366 case XML_TOK_PARTIAL:
4367 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004368 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004369 return XML_ERROR_INVALID_TOKEN;
4370 case XML_TOK_CHAR_REF:
4371 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004372 XML_Char buf[XML_ENCODE_MAX];
4373 int i;
4374 int n = XmlCharRefNumber(enc, ptr);
4375 if (n < 0) {
4376 if (enc == encoding)
4377 eventPtr = ptr;
4378 return XML_ERROR_BAD_CHAR_REF;
4379 }
4380 if (!isCdata
4381 && n == 0x20 /* space */
4382 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4383 break;
4384 n = XmlEncode(n, (ICHAR *)buf);
4385 if (!n) {
4386 if (enc == encoding)
4387 eventPtr = ptr;
4388 return XML_ERROR_BAD_CHAR_REF;
4389 }
4390 for (i = 0; i < n; i++) {
4391 if (!poolAppendChar(pool, buf[i]))
4392 return XML_ERROR_NO_MEMORY;
4393 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004394 }
4395 break;
4396 case XML_TOK_DATA_CHARS:
4397 if (!poolAppend(pool, enc, ptr, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004398 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004399 break;
4400 case XML_TOK_TRAILING_CR:
4401 next = ptr + enc->minBytesPerChar;
4402 /* fall through */
4403 case XML_TOK_ATTRIBUTE_VALUE_S:
4404 case XML_TOK_DATA_NEWLINE:
4405 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004406 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004407 if (!poolAppendChar(pool, 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004408 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004409 break;
4410 case XML_TOK_ENTITY_REF:
4411 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004412 const XML_Char *name;
4413 ENTITY *entity;
4414 char checkEntityDecl;
4415 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4416 ptr + enc->minBytesPerChar,
4417 next - enc->minBytesPerChar);
4418 if (ch) {
4419 if (!poolAppendChar(pool, ch))
4420 return XML_ERROR_NO_MEMORY;
4421 break;
4422 }
4423 name = poolStoreString(&temp2Pool, enc,
4424 ptr + enc->minBytesPerChar,
4425 next - enc->minBytesPerChar);
4426 if (!name)
4427 return XML_ERROR_NO_MEMORY;
4428 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
4429 poolDiscard(&temp2Pool);
4430 /* first, determine if a check for an existing declaration is needed;
4431 if yes, check that the entity exists, and that it is internal,
4432 otherwise call the default handler (if called from content)
4433 */
4434 if (pool == &dtd->pool) /* are we called from prolog? */
4435 checkEntityDecl =
4436#ifdef XML_DTD
4437 prologState.documentEntity &&
4438#endif /* XML_DTD */
4439 (dtd->standalone
4440 ? !openInternalEntities
4441 : !dtd->hasParamEntityRefs);
4442 else /* if (pool == &tempPool): we are called from content */
4443 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4444 if (checkEntityDecl) {
4445 if (!entity)
4446 return XML_ERROR_UNDEFINED_ENTITY;
4447 else if (!entity->is_internal)
4448 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4449 }
4450 else if (!entity) {
4451 /* cannot report skipped entity here - see comments on
4452 skippedEntityHandler
4453 if (skippedEntityHandler)
4454 skippedEntityHandler(handlerArg, name, 0);
4455 */
4456 if ((pool == &tempPool) && defaultHandler)
4457 reportDefault(parser, enc, ptr, next);
4458 break;
4459 }
4460 if (entity->open) {
4461 if (enc == encoding)
4462 eventPtr = ptr;
4463 return XML_ERROR_RECURSIVE_ENTITY_REF;
4464 }
4465 if (entity->notation) {
4466 if (enc == encoding)
4467 eventPtr = ptr;
4468 return XML_ERROR_BINARY_ENTITY_REF;
4469 }
4470 if (!entity->textPtr) {
4471 if (enc == encoding)
4472 eventPtr = ptr;
4473 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4474 }
4475 else {
4476 enum XML_Error result;
4477 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4478 entity->open = XML_TRUE;
4479 result = appendAttributeValue(parser, internalEncoding, isCdata,
4480 (char *)entity->textPtr,
4481 (char *)textEnd, pool);
4482 entity->open = XML_FALSE;
4483 if (result)
4484 return result;
4485 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004486 }
4487 break;
4488 default:
4489 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004490 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004491 return XML_ERROR_UNEXPECTED_STATE;
4492 }
4493 ptr = next;
4494 }
4495 /* not reached */
4496}
4497
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004498static enum XML_Error
4499storeEntityValue(XML_Parser parser,
4500 const ENCODING *enc,
4501 const char *entityTextPtr,
4502 const char *entityTextEnd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004503{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004504 DTD * const dtd = _dtd; /* save one level of indirection */
4505 STRING_POOL *pool = &(dtd->entityValuePool);
4506 enum XML_Error result = XML_ERROR_NONE;
4507#ifdef XML_DTD
4508 int oldInEntityValue = prologState.inEntityValue;
4509 prologState.inEntityValue = 1;
4510#endif /* XML_DTD */
4511 /* never return Null for the value argument in EntityDeclHandler,
4512 since this would indicate an external entity; therefore we
4513 have to make sure that entityValuePool.start is not null */
4514 if (!pool->blocks) {
4515 if (!poolGrow(pool))
4516 return XML_ERROR_NO_MEMORY;
4517 }
4518
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004519 for (;;) {
4520 const char *next;
4521 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4522 switch (tok) {
4523 case XML_TOK_PARAM_ENTITY_REF:
4524#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004525 if (isParamEntity || enc != encoding) {
4526 const XML_Char *name;
4527 ENTITY *entity;
4528 name = poolStoreString(&tempPool, enc,
4529 entityTextPtr + enc->minBytesPerChar,
4530 next - enc->minBytesPerChar);
4531 if (!name) {
4532 result = XML_ERROR_NO_MEMORY;
4533 goto endEntityValue;
4534 }
4535 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4536 poolDiscard(&tempPool);
4537 if (!entity) {
4538 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4539 /* cannot report skipped entity here - see comments on
4540 skippedEntityHandler
4541 if (skippedEntityHandler)
4542 skippedEntityHandler(handlerArg, name, 0);
4543 */
4544 dtd->keepProcessing = dtd->standalone;
4545 goto endEntityValue;
4546 }
4547 if (entity->open) {
4548 if (enc == encoding)
4549 eventPtr = entityTextPtr;
4550 result = XML_ERROR_RECURSIVE_ENTITY_REF;
4551 goto endEntityValue;
4552 }
4553 if (entity->systemId) {
4554 if (externalEntityRefHandler) {
4555 dtd->paramEntityRead = XML_FALSE;
4556 entity->open = XML_TRUE;
4557 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4558 0,
4559 entity->base,
4560 entity->systemId,
4561 entity->publicId)) {
4562 entity->open = XML_FALSE;
4563 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4564 goto endEntityValue;
4565 }
4566 entity->open = XML_FALSE;
4567 if (!dtd->paramEntityRead)
4568 dtd->keepProcessing = dtd->standalone;
4569 }
4570 else
4571 dtd->keepProcessing = dtd->standalone;
4572 }
4573 else {
4574 entity->open = XML_TRUE;
4575 result = storeEntityValue(parser,
4576 internalEncoding,
4577 (char *)entity->textPtr,
4578 (char *)(entity->textPtr
4579 + entity->textLen));
4580 entity->open = XML_FALSE;
4581 if (result)
4582 goto endEntityValue;
4583 }
4584 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004585 }
4586#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004587 /* in the internal subset, PE references are not legal
4588 within markup declarations, e.g entity values in this case */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004589 eventPtr = entityTextPtr;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004590 result = XML_ERROR_PARAM_ENTITY_REF;
4591 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004592 case XML_TOK_NONE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004593 result = XML_ERROR_NONE;
4594 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004595 case XML_TOK_ENTITY_REF:
4596 case XML_TOK_DATA_CHARS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004597 if (!poolAppend(pool, enc, entityTextPtr, next)) {
4598 result = XML_ERROR_NO_MEMORY;
4599 goto endEntityValue;
4600 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004601 break;
4602 case XML_TOK_TRAILING_CR:
4603 next = entityTextPtr + enc->minBytesPerChar;
4604 /* fall through */
4605 case XML_TOK_DATA_NEWLINE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004606 if (pool->end == pool->ptr && !poolGrow(pool)) {
4607 result = XML_ERROR_NO_MEMORY;
4608 goto endEntityValue;
4609 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004610 *(pool->ptr)++ = 0xA;
4611 break;
4612 case XML_TOK_CHAR_REF:
4613 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004614 XML_Char buf[XML_ENCODE_MAX];
4615 int i;
4616 int n = XmlCharRefNumber(enc, entityTextPtr);
4617 if (n < 0) {
4618 if (enc == encoding)
4619 eventPtr = entityTextPtr;
4620 result = XML_ERROR_BAD_CHAR_REF;
4621 goto endEntityValue;
4622 }
4623 n = XmlEncode(n, (ICHAR *)buf);
4624 if (!n) {
4625 if (enc == encoding)
4626 eventPtr = entityTextPtr;
4627 result = XML_ERROR_BAD_CHAR_REF;
4628 goto endEntityValue;
4629 }
4630 for (i = 0; i < n; i++) {
4631 if (pool->end == pool->ptr && !poolGrow(pool)) {
4632 result = XML_ERROR_NO_MEMORY;
4633 goto endEntityValue;
4634 }
4635 *(pool->ptr)++ = buf[i];
4636 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004637 }
4638 break;
4639 case XML_TOK_PARTIAL:
4640 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004641 eventPtr = entityTextPtr;
4642 result = XML_ERROR_INVALID_TOKEN;
4643 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004644 case XML_TOK_INVALID:
4645 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004646 eventPtr = next;
4647 result = XML_ERROR_INVALID_TOKEN;
4648 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004649 default:
4650 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004651 eventPtr = entityTextPtr;
4652 result = XML_ERROR_UNEXPECTED_STATE;
4653 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004654 }
4655 entityTextPtr = next;
4656 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004657endEntityValue:
4658#ifdef XML_DTD
4659 prologState.inEntityValue = oldInEntityValue;
4660#endif /* XML_DTD */
4661 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004662}
4663
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004664static void FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004665normalizeLines(XML_Char *s)
4666{
4667 XML_Char *p;
4668 for (;; s++) {
4669 if (*s == XML_T('\0'))
4670 return;
4671 if (*s == 0xD)
4672 break;
4673 }
4674 p = s;
4675 do {
4676 if (*s == 0xD) {
4677 *p++ = 0xA;
4678 if (*++s == 0xA)
4679 s++;
4680 }
4681 else
4682 *p++ = *s++;
4683 } while (*s);
4684 *p = XML_T('\0');
4685}
4686
4687static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004688reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
4689 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004690{
4691 const XML_Char *target;
4692 XML_Char *data;
4693 const char *tem;
4694 if (!processingInstructionHandler) {
4695 if (defaultHandler)
4696 reportDefault(parser, enc, start, end);
4697 return 1;
4698 }
4699 start += enc->minBytesPerChar * 2;
4700 tem = start + XmlNameLength(enc, start);
4701 target = poolStoreString(&tempPool, enc, start, tem);
4702 if (!target)
4703 return 0;
4704 poolFinish(&tempPool);
4705 data = poolStoreString(&tempPool, enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004706 XmlSkipS(enc, tem),
4707 end - enc->minBytesPerChar*2);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004708 if (!data)
4709 return 0;
4710 normalizeLines(data);
4711 processingInstructionHandler(handlerArg, target, data);
4712 poolClear(&tempPool);
4713 return 1;
4714}
4715
4716static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004717reportComment(XML_Parser parser, const ENCODING *enc,
4718 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004719{
4720 XML_Char *data;
4721 if (!commentHandler) {
4722 if (defaultHandler)
4723 reportDefault(parser, enc, start, end);
4724 return 1;
4725 }
4726 data = poolStoreString(&tempPool,
4727 enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004728 start + enc->minBytesPerChar * 4,
4729 end - enc->minBytesPerChar * 3);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004730 if (!data)
4731 return 0;
4732 normalizeLines(data);
4733 commentHandler(handlerArg, data);
4734 poolClear(&tempPool);
4735 return 1;
4736}
4737
4738static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004739reportDefault(XML_Parser parser, const ENCODING *enc,
4740 const char *s, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004741{
4742 if (MUST_CONVERT(enc, s)) {
4743 const char **eventPP;
4744 const char **eventEndPP;
4745 if (enc == encoding) {
4746 eventPP = &eventPtr;
4747 eventEndPP = &eventEndPtr;
4748 }
4749 else {
4750 eventPP = &(openInternalEntities->internalEventPtr);
4751 eventEndPP = &(openInternalEntities->internalEventEndPtr);
4752 }
4753 do {
4754 ICHAR *dataPtr = (ICHAR *)dataBuf;
4755 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
4756 *eventEndPP = s;
4757 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
4758 *eventPP = s;
4759 } while (s != end);
4760 }
4761 else
4762 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
4763}
4764
4765
4766static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004767defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
4768 XML_Bool isId, const XML_Char *value, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004769{
4770 DEFAULT_ATTRIBUTE *att;
4771 if (value || isId) {
4772 /* The handling of default attributes gets messed up if we have
4773 a default which duplicates a non-default. */
4774 int i;
4775 for (i = 0; i < type->nDefaultAtts; i++)
4776 if (attId == type->defaultAtts[i].id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004777 return 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004778 if (isId && !type->idAtt && !attId->xmlns)
4779 type->idAtt = attId;
4780 }
4781 if (type->nDefaultAtts == type->allocDefaultAtts) {
4782 if (type->allocDefaultAtts == 0) {
4783 type->allocDefaultAtts = 8;
Fred Drake08317ae2003-10-21 15:38:55 +00004784 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004785 * sizeof(DEFAULT_ATTRIBUTE));
4786 if (!type->defaultAtts)
4787 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004788 }
4789 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004790 DEFAULT_ATTRIBUTE *temp;
4791 int count = type->allocDefaultAtts * 2;
4792 temp = (DEFAULT_ATTRIBUTE *)
4793 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
4794 if (temp == NULL)
4795 return 0;
4796 type->allocDefaultAtts = count;
4797 type->defaultAtts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004798 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004799 }
4800 att = type->defaultAtts + type->nDefaultAtts;
4801 att->id = attId;
4802 att->value = value;
4803 att->isCdata = isCdata;
4804 if (!isCdata)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004805 attId->maybeTokenized = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004806 type->nDefaultAtts += 1;
4807 return 1;
4808}
4809
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004810static int
4811setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004812{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004813 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004814 const XML_Char *name;
4815 for (name = elementType->name; *name; name++) {
4816 if (*name == XML_T(':')) {
4817 PREFIX *prefix;
4818 const XML_Char *s;
4819 for (s = elementType->name; s != name; s++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004820 if (!poolAppendChar(&dtd->pool, *s))
4821 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004822 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004823 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4824 return 0;
4825 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4826 sizeof(PREFIX));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004827 if (!prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004828 return 0;
4829 if (prefix->name == poolStart(&dtd->pool))
4830 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004831 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004832 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004833 elementType->prefix = prefix;
4834
4835 }
4836 }
4837 return 1;
4838}
4839
4840static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004841getAttributeId(XML_Parser parser, const ENCODING *enc,
4842 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004843{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004844 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004845 ATTRIBUTE_ID *id;
4846 const XML_Char *name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004847 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4848 return NULL;
4849 name = poolStoreString(&dtd->pool, enc, start, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004850 if (!name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004851 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00004852 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004853 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004854 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004855 if (!id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004856 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004857 if (id->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004858 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004859 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004860 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004861 if (!ns)
4862 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004863 else if (name[0] == XML_T('x')
4864 && name[1] == XML_T('m')
4865 && name[2] == XML_T('l')
4866 && name[3] == XML_T('n')
4867 && name[4] == XML_T('s')
4868 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
4869 if (name[5] == XML_T('\0'))
4870 id->prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004871 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004872 id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
4873 id->xmlns = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004874 }
4875 else {
4876 int i;
4877 for (i = 0; name[i]; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00004878 /* attributes without prefix are *not* in the default namespace */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004879 if (name[i] == XML_T(':')) {
4880 int j;
4881 for (j = 0; j < i; j++) {
4882 if (!poolAppendChar(&dtd->pool, name[j]))
4883 return NULL;
4884 }
4885 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4886 return NULL;
4887 id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4888 sizeof(PREFIX));
4889 if (id->prefix->name == poolStart(&dtd->pool))
4890 poolFinish(&dtd->pool);
4891 else
4892 poolDiscard(&dtd->pool);
4893 break;
4894 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004895 }
4896 }
4897 }
4898 return id;
4899}
4900
4901#define CONTEXT_SEP XML_T('\f')
4902
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004903static const XML_Char *
4904getContext(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004905{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004906 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004907 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004908 XML_Bool needSep = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004909
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004910 if (dtd->defaultPrefix.binding) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004911 int i;
4912 int len;
4913 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004914 return NULL;
4915 len = dtd->defaultPrefix.binding->uriLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004916 if (namespaceSeparator != XML_T('\0'))
4917 len--;
4918 for (i = 0; i < len; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004919 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
4920 return NULL;
4921 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004922 }
4923
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004924 hashTableIterInit(&iter, &(dtd->prefixes));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004925 for (;;) {
4926 int i;
4927 int len;
4928 const XML_Char *s;
4929 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
4930 if (!prefix)
4931 break;
4932 if (!prefix->binding)
4933 continue;
4934 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004935 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004936 for (s = prefix->name; *s; s++)
4937 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004938 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004939 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004940 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004941 len = prefix->binding->uriLen;
4942 if (namespaceSeparator != XML_T('\0'))
4943 len--;
4944 for (i = 0; i < len; i++)
4945 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004946 return NULL;
4947 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004948 }
4949
4950
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004951 hashTableIterInit(&iter, &(dtd->generalEntities));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004952 for (;;) {
4953 const XML_Char *s;
4954 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
4955 if (!e)
4956 break;
4957 if (!e->open)
4958 continue;
4959 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004960 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004961 for (s = e->name; *s; s++)
4962 if (!poolAppendChar(&tempPool, *s))
4963 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004964 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004965 }
4966
4967 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004968 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004969 return tempPool.start;
4970}
4971
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004972static XML_Bool
4973setContext(XML_Parser parser, const XML_Char *context)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004974{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004975 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004976 const XML_Char *s = context;
4977
4978 while (*context != XML_T('\0')) {
4979 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
4980 ENTITY *e;
4981 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004982 return XML_FALSE;
4983 e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004984 if (e)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004985 e->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004986 if (*s != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004987 s++;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004988 context = s;
4989 poolDiscard(&tempPool);
4990 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004991 else if (*s == XML_T('=')) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004992 PREFIX *prefix;
4993 if (poolLength(&tempPool) == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004994 prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004995 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004996 if (!poolAppendChar(&tempPool, XML_T('\0')))
4997 return XML_FALSE;
4998 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
4999 sizeof(PREFIX));
5000 if (!prefix)
5001 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005002 if (prefix->name == poolStart(&tempPool)) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005003 prefix->name = poolCopyString(&dtd->pool, prefix->name);
5004 if (!prefix->name)
5005 return XML_FALSE;
5006 }
5007 poolDiscard(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005008 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005009 for (context = s + 1;
5010 *context != CONTEXT_SEP && *context != XML_T('\0');
5011 context++)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005012 if (!poolAppendChar(&tempPool, *context))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005013 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005014 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005015 return XML_FALSE;
5016 if (addBinding(parser, prefix, 0, poolStart(&tempPool),
5017 &inheritedBindings) != XML_ERROR_NONE)
5018 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005019 poolDiscard(&tempPool);
5020 if (*context != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005021 ++context;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005022 s = context;
5023 }
5024 else {
5025 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005026 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005027 s++;
5028 }
5029 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005030 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005031}
5032
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005033static void FASTCALL
5034normalizePublicId(XML_Char *publicId)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005035{
5036 XML_Char *p = publicId;
5037 XML_Char *s;
5038 for (s = publicId; *s; s++) {
5039 switch (*s) {
5040 case 0x20:
5041 case 0xD:
5042 case 0xA:
5043 if (p != publicId && p[-1] != 0x20)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005044 *p++ = 0x20;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005045 break;
5046 default:
5047 *p++ = *s;
5048 }
5049 }
5050 if (p != publicId && p[-1] == 0x20)
5051 --p;
5052 *p = XML_T('\0');
5053}
5054
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005055static DTD *
5056dtdCreate(const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005057{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005058 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5059 if (p == NULL)
5060 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005061 poolInit(&(p->pool), ms);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005062#ifdef XML_DTD
5063 poolInit(&(p->entityValuePool), ms);
5064#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005065 hashTableInit(&(p->generalEntities), ms);
5066 hashTableInit(&(p->elementTypes), ms);
5067 hashTableInit(&(p->attributeIds), ms);
5068 hashTableInit(&(p->prefixes), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005069#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005070 p->paramEntityRead = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005071 hashTableInit(&(p->paramEntities), ms);
5072#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005073 p->defaultPrefix.name = NULL;
5074 p->defaultPrefix.binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005075
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005076 p->in_eldecl = XML_FALSE;
5077 p->scaffIndex = NULL;
5078 p->scaffold = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005079 p->scaffLevel = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005080 p->scaffSize = 0;
5081 p->scaffCount = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005082 p->contentStringLen = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005083
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005084 p->keepProcessing = XML_TRUE;
5085 p->hasParamEntityRefs = XML_FALSE;
5086 p->standalone = XML_FALSE;
5087 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005088}
5089
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005090static void
5091dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005092{
5093 HASH_TABLE_ITER iter;
5094 hashTableIterInit(&iter, &(p->elementTypes));
5095 for (;;) {
5096 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5097 if (!e)
5098 break;
5099 if (e->allocDefaultAtts != 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005100 ms->free_fcn(e->defaultAtts);
5101 }
5102 hashTableClear(&(p->generalEntities));
5103#ifdef XML_DTD
5104 p->paramEntityRead = XML_FALSE;
5105 hashTableClear(&(p->paramEntities));
5106#endif /* XML_DTD */
5107 hashTableClear(&(p->elementTypes));
5108 hashTableClear(&(p->attributeIds));
5109 hashTableClear(&(p->prefixes));
5110 poolClear(&(p->pool));
5111#ifdef XML_DTD
5112 poolClear(&(p->entityValuePool));
5113#endif /* XML_DTD */
5114 p->defaultPrefix.name = NULL;
5115 p->defaultPrefix.binding = NULL;
5116
5117 p->in_eldecl = XML_FALSE;
Fred Drake08317ae2003-10-21 15:38:55 +00005118
5119 ms->free_fcn(p->scaffIndex);
5120 p->scaffIndex = NULL;
5121 ms->free_fcn(p->scaffold);
5122 p->scaffold = NULL;
5123
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005124 p->scaffLevel = 0;
5125 p->scaffSize = 0;
5126 p->scaffCount = 0;
5127 p->contentStringLen = 0;
5128
5129 p->keepProcessing = XML_TRUE;
5130 p->hasParamEntityRefs = XML_FALSE;
5131 p->standalone = XML_FALSE;
5132}
5133
5134static void
5135dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5136{
5137 HASH_TABLE_ITER iter;
5138 hashTableIterInit(&iter, &(p->elementTypes));
5139 for (;;) {
5140 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5141 if (!e)
5142 break;
5143 if (e->allocDefaultAtts != 0)
5144 ms->free_fcn(e->defaultAtts);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005145 }
5146 hashTableDestroy(&(p->generalEntities));
5147#ifdef XML_DTD
5148 hashTableDestroy(&(p->paramEntities));
5149#endif /* XML_DTD */
5150 hashTableDestroy(&(p->elementTypes));
5151 hashTableDestroy(&(p->attributeIds));
5152 hashTableDestroy(&(p->prefixes));
5153 poolDestroy(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005154#ifdef XML_DTD
5155 poolDestroy(&(p->entityValuePool));
5156#endif /* XML_DTD */
5157 if (isDocEntity) {
Fred Drake08317ae2003-10-21 15:38:55 +00005158 ms->free_fcn(p->scaffIndex);
5159 ms->free_fcn(p->scaffold);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005160 }
5161 ms->free_fcn(p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005162}
5163
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005164/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5165 The new DTD has already been initialized.
5166*/
5167static int
5168dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005169{
5170 HASH_TABLE_ITER iter;
5171
5172 /* Copy the prefix table. */
5173
5174 hashTableIterInit(&iter, &(oldDtd->prefixes));
5175 for (;;) {
5176 const XML_Char *name;
5177 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5178 if (!oldP)
5179 break;
5180 name = poolCopyString(&(newDtd->pool), oldP->name);
5181 if (!name)
5182 return 0;
5183 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5184 return 0;
5185 }
5186
5187 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5188
5189 /* Copy the attribute id table. */
5190
5191 for (;;) {
5192 ATTRIBUTE_ID *newA;
5193 const XML_Char *name;
5194 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5195
5196 if (!oldA)
5197 break;
5198 /* Remember to allocate the scratch byte before the name. */
5199 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5200 return 0;
5201 name = poolCopyString(&(newDtd->pool), oldA->name);
5202 if (!name)
5203 return 0;
5204 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005205 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5206 sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005207 if (!newA)
5208 return 0;
5209 newA->maybeTokenized = oldA->maybeTokenized;
5210 if (oldA->prefix) {
5211 newA->xmlns = oldA->xmlns;
5212 if (oldA->prefix == &oldDtd->defaultPrefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005213 newA->prefix = &newDtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005214 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005215 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5216 oldA->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005217 }
5218 }
5219
5220 /* Copy the element type table. */
5221
5222 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5223
5224 for (;;) {
5225 int i;
5226 ELEMENT_TYPE *newE;
5227 const XML_Char *name;
5228 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5229 if (!oldE)
5230 break;
5231 name = poolCopyString(&(newDtd->pool), oldE->name);
5232 if (!name)
5233 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005234 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5235 sizeof(ELEMENT_TYPE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005236 if (!newE)
5237 return 0;
5238 if (oldE->nDefaultAtts) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005239 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5240 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5241 if (!newE->defaultAtts) {
5242 ms->free_fcn(newE);
5243 return 0;
5244 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005245 }
5246 if (oldE->idAtt)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005247 newE->idAtt = (ATTRIBUTE_ID *)
5248 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005249 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5250 if (oldE->prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005251 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5252 oldE->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005253 for (i = 0; i < newE->nDefaultAtts; i++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005254 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5255 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005256 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5257 if (oldE->defaultAtts[i].value) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005258 newE->defaultAtts[i].value
5259 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5260 if (!newE->defaultAtts[i].value)
5261 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005262 }
5263 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005264 newE->defaultAtts[i].value = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005265 }
5266 }
5267
5268 /* Copy the entity tables. */
5269 if (!copyEntityTable(&(newDtd->generalEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005270 &(newDtd->pool),
5271 &(oldDtd->generalEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005272 return 0;
5273
5274#ifdef XML_DTD
5275 if (!copyEntityTable(&(newDtd->paramEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005276 &(newDtd->pool),
5277 &(oldDtd->paramEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005278 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005279 newDtd->paramEntityRead = oldDtd->paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005280#endif /* XML_DTD */
5281
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005282 newDtd->keepProcessing = oldDtd->keepProcessing;
5283 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005284 newDtd->standalone = oldDtd->standalone;
5285
5286 /* Don't want deep copying for scaffolding */
5287 newDtd->in_eldecl = oldDtd->in_eldecl;
5288 newDtd->scaffold = oldDtd->scaffold;
5289 newDtd->contentStringLen = oldDtd->contentStringLen;
5290 newDtd->scaffSize = oldDtd->scaffSize;
5291 newDtd->scaffLevel = oldDtd->scaffLevel;
5292 newDtd->scaffIndex = oldDtd->scaffIndex;
5293
5294 return 1;
5295} /* End dtdCopy */
5296
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005297static int
5298copyEntityTable(HASH_TABLE *newTable,
5299 STRING_POOL *newPool,
5300 const HASH_TABLE *oldTable)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005301{
5302 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005303 const XML_Char *cachedOldBase = NULL;
5304 const XML_Char *cachedNewBase = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005305
5306 hashTableIterInit(&iter, oldTable);
5307
5308 for (;;) {
5309 ENTITY *newE;
5310 const XML_Char *name;
5311 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5312 if (!oldE)
5313 break;
5314 name = poolCopyString(newPool, oldE->name);
5315 if (!name)
5316 return 0;
5317 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5318 if (!newE)
5319 return 0;
5320 if (oldE->systemId) {
5321 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5322 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005323 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005324 newE->systemId = tem;
5325 if (oldE->base) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005326 if (oldE->base == cachedOldBase)
5327 newE->base = cachedNewBase;
5328 else {
5329 cachedOldBase = oldE->base;
5330 tem = poolCopyString(newPool, cachedOldBase);
5331 if (!tem)
5332 return 0;
5333 cachedNewBase = newE->base = tem;
5334 }
5335 }
5336 if (oldE->publicId) {
5337 tem = poolCopyString(newPool, oldE->publicId);
5338 if (!tem)
5339 return 0;
5340 newE->publicId = tem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005341 }
5342 }
5343 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005344 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5345 oldE->textLen);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005346 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005347 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005348 newE->textPtr = tem;
5349 newE->textLen = oldE->textLen;
5350 }
5351 if (oldE->notation) {
5352 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5353 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005354 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005355 newE->notation = tem;
5356 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005357 newE->is_param = oldE->is_param;
5358 newE->is_internal = oldE->is_internal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005359 }
5360 return 1;
5361}
5362
Fred Drake08317ae2003-10-21 15:38:55 +00005363#define INIT_POWER 6
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005364
Fred Drake08317ae2003-10-21 15:38:55 +00005365static XML_Bool FASTCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005366keyeq(KEY s1, KEY s2)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005367{
5368 for (; *s1 == *s2; s1++, s2++)
5369 if (*s1 == 0)
Fred Drake08317ae2003-10-21 15:38:55 +00005370 return XML_TRUE;
5371 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005372}
5373
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005374static unsigned long FASTCALL
5375hash(KEY s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005376{
5377 unsigned long h = 0;
5378 while (*s)
Fred Drake08317ae2003-10-21 15:38:55 +00005379 h = CHAR_HASH(h, *s++);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005380 return h;
5381}
5382
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005383static NAMED *
5384lookup(HASH_TABLE *table, KEY name, size_t createSize)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005385{
5386 size_t i;
5387 if (table->size == 0) {
5388 size_t tsize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005389 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005390 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005391 table->power = INIT_POWER;
5392 /* table->size is a power of 2 */
5393 table->size = (size_t)1 << INIT_POWER;
5394 tsize = table->size * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005395 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005396 if (!table->v)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005397 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005398 memset(table->v, 0, tsize);
Fred Drake08317ae2003-10-21 15:38:55 +00005399 i = hash(name) & ((unsigned long)table->size - 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005400 }
5401 else {
5402 unsigned long h = hash(name);
Fred Drake08317ae2003-10-21 15:38:55 +00005403 unsigned long mask = (unsigned long)table->size - 1;
5404 unsigned char step = 0;
5405 i = h & mask;
5406 while (table->v[i]) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005407 if (keyeq(name, table->v[i]->name))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005408 return table->v[i];
Fred Drake08317ae2003-10-21 15:38:55 +00005409 if (!step)
5410 step = PROBE_STEP(h, mask, table->power);
5411 i < step ? (i += table->size - step) : (i -= step);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005412 }
5413 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005414 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005415
5416 /* check for overflow (table is half full) */
5417 if (table->used >> (table->power - 1)) {
5418 unsigned char newPower = table->power + 1;
5419 size_t newSize = (size_t)1 << newPower;
5420 unsigned long newMask = (unsigned long)newSize - 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005421 size_t tsize = newSize * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005422 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005423 if (!newV)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005424 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005425 memset(newV, 0, tsize);
5426 for (i = 0; i < table->size; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005427 if (table->v[i]) {
Fred Drake08317ae2003-10-21 15:38:55 +00005428 unsigned long newHash = hash(table->v[i]->name);
5429 size_t j = newHash & newMask;
5430 step = 0;
5431 while (newV[j]) {
5432 if (!step)
5433 step = PROBE_STEP(newHash, newMask, newPower);
5434 j < step ? (j += newSize - step) : (j -= step);
5435 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005436 newV[j] = table->v[i];
5437 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005438 table->mem->free_fcn(table->v);
5439 table->v = newV;
Fred Drake08317ae2003-10-21 15:38:55 +00005440 table->power = newPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005441 table->size = newSize;
Fred Drake08317ae2003-10-21 15:38:55 +00005442 i = h & newMask;
5443 step = 0;
5444 while (table->v[i]) {
5445 if (!step)
5446 step = PROBE_STEP(h, newMask, newPower);
5447 i < step ? (i += newSize - step) : (i -= step);
5448 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005449 }
5450 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005451 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005452 if (!table->v[i])
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005453 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005454 memset(table->v[i], 0, createSize);
5455 table->v[i]->name = name;
5456 (table->used)++;
5457 return table->v[i];
5458}
5459
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005460static void FASTCALL
5461hashTableClear(HASH_TABLE *table)
5462{
5463 size_t i;
5464 for (i = 0; i < table->size; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00005465 table->mem->free_fcn(table->v[i]);
5466 table->v[i] = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005467 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005468 table->used = 0;
5469}
5470
5471static void FASTCALL
5472hashTableDestroy(HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005473{
5474 size_t i;
Fred Drake08317ae2003-10-21 15:38:55 +00005475 for (i = 0; i < table->size; i++)
5476 table->mem->free_fcn(table->v[i]);
5477 table->mem->free_fcn(table->v);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005478}
5479
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005480static void FASTCALL
5481hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005482{
Fred Drake08317ae2003-10-21 15:38:55 +00005483 p->power = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005484 p->size = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005485 p->used = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005486 p->v = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005487 p->mem = ms;
5488}
5489
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005490static void FASTCALL
5491hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005492{
5493 iter->p = table->v;
5494 iter->end = iter->p + table->size;
5495}
5496
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005497static NAMED * FASTCALL
5498hashTableIterNext(HASH_TABLE_ITER *iter)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005499{
5500 while (iter->p != iter->end) {
5501 NAMED *tem = *(iter->p)++;
5502 if (tem)
5503 return tem;
5504 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005505 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005506}
5507
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005508static void FASTCALL
5509poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005510{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005511 pool->blocks = NULL;
5512 pool->freeBlocks = NULL;
5513 pool->start = NULL;
5514 pool->ptr = NULL;
5515 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005516 pool->mem = ms;
5517}
5518
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005519static void FASTCALL
5520poolClear(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005521{
5522 if (!pool->freeBlocks)
5523 pool->freeBlocks = pool->blocks;
5524 else {
5525 BLOCK *p = pool->blocks;
5526 while (p) {
5527 BLOCK *tem = p->next;
5528 p->next = pool->freeBlocks;
5529 pool->freeBlocks = p;
5530 p = tem;
5531 }
5532 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005533 pool->blocks = NULL;
5534 pool->start = NULL;
5535 pool->ptr = NULL;
5536 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005537}
5538
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005539static void FASTCALL
5540poolDestroy(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005541{
5542 BLOCK *p = pool->blocks;
5543 while (p) {
5544 BLOCK *tem = p->next;
5545 pool->mem->free_fcn(p);
5546 p = tem;
5547 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005548 p = pool->freeBlocks;
5549 while (p) {
5550 BLOCK *tem = p->next;
5551 pool->mem->free_fcn(p);
5552 p = tem;
5553 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005554}
5555
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005556static XML_Char *
5557poolAppend(STRING_POOL *pool, const ENCODING *enc,
5558 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005559{
5560 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005561 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005562 for (;;) {
5563 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
5564 if (ptr == end)
5565 break;
5566 if (!poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005567 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005568 }
5569 return pool->start;
5570}
5571
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005572static const XML_Char * FASTCALL
5573poolCopyString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005574{
5575 do {
5576 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005577 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005578 } while (*s++);
5579 s = pool->start;
5580 poolFinish(pool);
5581 return s;
5582}
5583
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005584static const XML_Char *
5585poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005586{
5587 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005588 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005589 for (; n > 0; --n, s++) {
5590 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005591 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005592 }
5593 s = pool->start;
5594 poolFinish(pool);
5595 return s;
5596}
5597
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005598static const XML_Char * FASTCALL
5599poolAppendString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005600{
5601 while (*s) {
5602 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005603 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005604 s++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005605 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005606 return pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005607}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005608
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005609static XML_Char *
5610poolStoreString(STRING_POOL *pool, const ENCODING *enc,
5611 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005612{
5613 if (!poolAppend(pool, enc, ptr, end))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005614 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005615 if (pool->ptr == pool->end && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005616 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005617 *(pool->ptr)++ = 0;
5618 return pool->start;
5619}
5620
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005621static XML_Bool FASTCALL
5622poolGrow(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005623{
5624 if (pool->freeBlocks) {
5625 if (pool->start == 0) {
5626 pool->blocks = pool->freeBlocks;
5627 pool->freeBlocks = pool->freeBlocks->next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005628 pool->blocks->next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005629 pool->start = pool->blocks->s;
5630 pool->end = pool->start + pool->blocks->size;
5631 pool->ptr = pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005632 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005633 }
5634 if (pool->end - pool->start < pool->freeBlocks->size) {
5635 BLOCK *tem = pool->freeBlocks->next;
5636 pool->freeBlocks->next = pool->blocks;
5637 pool->blocks = pool->freeBlocks;
5638 pool->freeBlocks = tem;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005639 memcpy(pool->blocks->s, pool->start,
5640 (pool->end - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005641 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5642 pool->start = pool->blocks->s;
5643 pool->end = pool->start + pool->blocks->size;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005644 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005645 }
5646 }
5647 if (pool->blocks && pool->start == pool->blocks->s) {
5648 int blockSize = (pool->end - pool->start)*2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005649 pool->blocks = (BLOCK *)
5650 pool->mem->realloc_fcn(pool->blocks,
Fred Drake08317ae2003-10-21 15:38:55 +00005651 (offsetof(BLOCK, s)
5652 + blockSize * sizeof(XML_Char)));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005653 if (pool->blocks == NULL)
5654 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005655 pool->blocks->size = blockSize;
5656 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5657 pool->start = pool->blocks->s;
5658 pool->end = pool->start + blockSize;
5659 }
5660 else {
5661 BLOCK *tem;
5662 int blockSize = pool->end - pool->start;
5663 if (blockSize < INIT_BLOCK_SIZE)
5664 blockSize = INIT_BLOCK_SIZE;
5665 else
5666 blockSize *= 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005667 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
Fred Drake08317ae2003-10-21 15:38:55 +00005668 + blockSize * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005669 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005670 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005671 tem->size = blockSize;
5672 tem->next = pool->blocks;
5673 pool->blocks = tem;
5674 if (pool->ptr != pool->start)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005675 memcpy(tem->s, pool->start,
5676 (pool->ptr - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005677 pool->ptr = tem->s + (pool->ptr - pool->start);
5678 pool->start = tem->s;
5679 pool->end = tem->s + blockSize;
5680 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005681 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005682}
5683
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005684static int FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005685nextScaffoldPart(XML_Parser parser)
5686{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005687 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005688 CONTENT_SCAFFOLD * me;
5689 int next;
5690
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005691 if (!dtd->scaffIndex) {
5692 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
5693 if (!dtd->scaffIndex)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005694 return -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005695 dtd->scaffIndex[0] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005696 }
5697
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005698 if (dtd->scaffCount >= dtd->scaffSize) {
5699 CONTENT_SCAFFOLD *temp;
5700 if (dtd->scaffold) {
5701 temp = (CONTENT_SCAFFOLD *)
5702 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
5703 if (temp == NULL)
5704 return -1;
5705 dtd->scaffSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005706 }
5707 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005708 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
5709 * sizeof(CONTENT_SCAFFOLD));
5710 if (temp == NULL)
5711 return -1;
5712 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005713 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005714 dtd->scaffold = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005715 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005716 next = dtd->scaffCount++;
5717 me = &dtd->scaffold[next];
5718 if (dtd->scaffLevel) {
5719 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005720 if (parent->lastchild) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005721 dtd->scaffold[parent->lastchild].nextsib = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005722 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005723 if (!parent->childcnt)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005724 parent->firstchild = next;
5725 parent->lastchild = next;
5726 parent->childcnt++;
5727 }
5728 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
5729 return next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005730}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005731
5732static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005733build_node(XML_Parser parser,
5734 int src_node,
5735 XML_Content *dest,
5736 XML_Content **contpos,
5737 XML_Char **strpos)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005738{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005739 DTD * const dtd = _dtd; /* save one level of indirection */
5740 dest->type = dtd->scaffold[src_node].type;
5741 dest->quant = dtd->scaffold[src_node].quant;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005742 if (dest->type == XML_CTYPE_NAME) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005743 const XML_Char *src;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005744 dest->name = *strpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005745 src = dtd->scaffold[src_node].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005746 for (;;) {
5747 *(*strpos)++ = *src;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005748 if (!*src)
5749 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005750 src++;
5751 }
5752 dest->numchildren = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005753 dest->children = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005754 }
5755 else {
5756 unsigned int i;
5757 int cn;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005758 dest->numchildren = dtd->scaffold[src_node].childcnt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005759 dest->children = *contpos;
5760 *contpos += dest->numchildren;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005761 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
5762 i < dest->numchildren;
5763 i++, cn = dtd->scaffold[cn].nextsib) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005764 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
5765 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005766 dest->name = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005767 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005768}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005769
5770static XML_Content *
5771build_model (XML_Parser parser)
5772{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005773 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005774 XML_Content *ret;
5775 XML_Content *cpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005776 XML_Char * str;
5777 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
5778 + (dtd->contentStringLen * sizeof(XML_Char)));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005779
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005780 ret = (XML_Content *)MALLOC(allocsize);
5781 if (!ret)
5782 return NULL;
5783
5784 str = (XML_Char *) (&ret[dtd->scaffCount]);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005785 cpos = &ret[1];
5786
5787 build_node(parser, 0, ret, &cpos, &str);
5788 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005789}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005790
5791static ELEMENT_TYPE *
5792getElementType(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005793 const ENCODING *enc,
5794 const char *ptr,
5795 const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005796{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005797 DTD * const dtd = _dtd; /* save one level of indirection */
5798 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005799 ELEMENT_TYPE *ret;
5800
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005801 if (!name)
5802 return NULL;
5803 ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
5804 if (!ret)
5805 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005806 if (ret->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005807 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005808 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005809 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005810 if (!setElementTypePrefix(parser, ret))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005811 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005812 }
5813 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005814}