blob: 3372bc962ee13f2d4d43635ceb07401c132d5d3e [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() */
Fred Drake31d485c2004-08-03 07:06:22 +00007#include <assert.h>
Martin v. Löwisfc03a942003-01-25 22:41:29 +00008
Fred Drake08317ae2003-10-21 15:38:55 +00009#define XML_BUILDING_EXPAT 1
10
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000011#ifdef COMPILED_FROM_DSP
Martin v. Löwisfc03a942003-01-25 22:41:29 +000012#include "winconfig.h"
Martin v. Löwisfc03a942003-01-25 22:41:29 +000013#elif defined(MACOS_CLASSIC)
Martin v. Löwisfc03a942003-01-25 22:41:29 +000014#include "macconfig.h"
Fred Drake31d485c2004-08-03 07:06:22 +000015#elif defined(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 /* ndef COMPILED_FROM_DSP */
18
Fred Drake08317ae2003-10-21 15:38:55 +000019#include "expat.h"
20
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000021#ifdef XML_UNICODE
22#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
23#define XmlConvert XmlUtf16Convert
24#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
25#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
26#define XmlEncode XmlUtf16Encode
27#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
28typedef unsigned short ICHAR;
29#else
30#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
31#define XmlConvert XmlUtf8Convert
32#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
33#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
34#define XmlEncode XmlUtf8Encode
35#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
36typedef char ICHAR;
37#endif
38
39
40#ifndef XML_NS
41
42#define XmlInitEncodingNS XmlInitEncoding
43#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
44#undef XmlGetInternalEncodingNS
45#define XmlGetInternalEncodingNS XmlGetInternalEncoding
46#define XmlParseXmlDeclNS XmlParseXmlDecl
47
48#endif
49
Martin v. Löwisfc03a942003-01-25 22:41:29 +000050#ifdef XML_UNICODE
51
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000052#ifdef XML_UNICODE_WCHAR_T
Martin v. Löwisfc03a942003-01-25 22:41:29 +000053#define XML_T(x) (const wchar_t)x
54#define XML_L(x) L ## x
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000055#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +000056#define XML_T(x) (const unsigned short)x
57#define XML_L(x) x
58#endif
59
60#else
61
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000062#define XML_T(x) x
Martin v. Löwisfc03a942003-01-25 22:41:29 +000063#define XML_L(x) x
64
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000065#endif
66
67/* Round up n to be a multiple of sz, where sz is a power of 2. */
68#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
69
Fred Drake08317ae2003-10-21 15:38:55 +000070/* Handle the case where memmove() doesn't exist. */
71#ifndef HAVE_MEMMOVE
72#ifdef HAVE_BCOPY
73#define memmove(d,s,l) bcopy((s),(d),(l))
74#else
75#error memmove does not exist on this platform, nor is a substitute available
76#endif /* HAVE_BCOPY */
77#endif /* HAVE_MEMMOVE */
78
Martin v. Löwisfc03a942003-01-25 22:41:29 +000079#include "internal.h"
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000080#include "xmltok.h"
81#include "xmlrole.h"
82
83typedef const XML_Char *KEY;
84
85typedef struct {
86 KEY name;
87} NAMED;
88
89typedef struct {
90 NAMED **v;
Fred Drake08317ae2003-10-21 15:38:55 +000091 unsigned char power;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000092 size_t size;
93 size_t used;
Martin v. Löwisfc03a942003-01-25 22:41:29 +000094 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000095} HASH_TABLE;
96
Fred Drake08317ae2003-10-21 15:38:55 +000097/* Basic character hash algorithm, taken from Python's string hash:
98 h = h * 1000003 ^ character, the constant being a prime number.
99
100*/
101#ifdef XML_UNICODE
102#define CHAR_HASH(h, c) \
103 (((h) * 0xF4243) ^ (unsigned short)(c))
104#else
105#define CHAR_HASH(h, c) \
106 (((h) * 0xF4243) ^ (unsigned char)(c))
107#endif
108
109/* For probing (after a collision) we need a step size relative prime
110 to the hash table size, which is a power of 2. We use double-hashing,
111 since we can calculate a second hash value cheaply by taking those bits
112 of the first hash value that were discarded (masked out) when the table
113 index was calculated: index = hash & mask, where mask = table->size - 1.
114 We limit the maximum step size to table->size / 4 (mask >> 2) and make
115 it odd, since odd numbers are always relative prime to a power of 2.
116*/
117#define SECOND_HASH(hash, mask, power) \
118 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
119#define PROBE_STEP(hash, mask, power) \
120 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
121
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000122typedef struct {
123 NAMED **p;
124 NAMED **end;
125} HASH_TABLE_ITER;
126
127#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
128#define INIT_DATA_BUF_SIZE 1024
129#define INIT_ATTS_SIZE 16
Fred Drake08317ae2003-10-21 15:38:55 +0000130#define INIT_ATTS_VERSION 0xFFFFFFFF
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000131#define INIT_BLOCK_SIZE 1024
132#define INIT_BUFFER_SIZE 1024
133
134#define EXPAND_SPARE 24
135
136typedef struct binding {
137 struct prefix *prefix;
138 struct binding *nextTagBinding;
139 struct binding *prevPrefixBinding;
140 const struct attribute_id *attId;
141 XML_Char *uri;
142 int uriLen;
143 int uriAlloc;
144} BINDING;
145
146typedef struct prefix {
147 const XML_Char *name;
148 BINDING *binding;
149} PREFIX;
150
151typedef struct {
152 const XML_Char *str;
153 const XML_Char *localPart;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000154 const XML_Char *prefix;
155 int strLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000156 int uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000157 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000158} TAG_NAME;
159
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000160/* TAG represents an open element.
161 The name of the element is stored in both the document and API
162 encodings. The memory buffer 'buf' is a separately-allocated
163 memory area which stores the name. During the XML_Parse()/
164 XMLParseBuffer() when the element is open, the memory for the 'raw'
165 version of the name (in the document encoding) is shared with the
166 document buffer. If the element is open across calls to
167 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
168 contain the 'raw' name as well.
169
170 A parser re-uses these structures, maintaining a list of allocated
171 TAG objects in a free list.
172*/
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000173typedef struct tag {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000174 struct tag *parent; /* parent of this element */
175 const char *rawName; /* tagName in the original encoding */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000176 int rawNameLength;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000177 TAG_NAME name; /* tagName in the API encoding */
178 char *buf; /* buffer for name components */
179 char *bufEnd; /* end of the buffer */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000180 BINDING *bindings;
181} TAG;
182
183typedef struct {
184 const XML_Char *name;
185 const XML_Char *textPtr;
Fred Drake31d485c2004-08-03 07:06:22 +0000186 int textLen; /* length in XML_Chars */
187 int processed; /* # of processed bytes - when suspended */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000188 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;
Fred Drake31d485c2004-08-03 07:06:22 +0000288 int startTagLevel;
289 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000290} OPEN_INTERNAL_ENTITY;
291
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000292typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
293 const char *start,
294 const char *end,
295 const char **endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000296
297static Processor prologProcessor;
298static Processor prologInitProcessor;
299static Processor contentProcessor;
300static Processor cdataSectionProcessor;
301#ifdef XML_DTD
302static Processor ignoreSectionProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000303static Processor externalParEntProcessor;
304static Processor externalParEntInitProcessor;
305static Processor entityValueProcessor;
306static Processor entityValueInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000307#endif /* XML_DTD */
308static Processor epilogProcessor;
309static Processor errorProcessor;
310static Processor externalEntityInitProcessor;
311static Processor externalEntityInitProcessor2;
312static Processor externalEntityInitProcessor3;
313static Processor externalEntityContentProcessor;
Fred Drake31d485c2004-08-03 07:06:22 +0000314static Processor internalEntityProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000315
316static enum XML_Error
317handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
318static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000319processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Fred Drake31d485c2004-08-03 07:06:22 +0000320 const char *s, const char *next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000321static enum XML_Error
322initializeEncoding(XML_Parser parser);
323static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +0000324doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
325 const char *end, int tok, const char *next, const char **nextPtr,
326 XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000327static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +0000328processInternalEntity(XML_Parser parser, ENTITY *entity,
329 XML_Bool betweenDecl);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000330static enum XML_Error
331doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
Fred Drake31d485c2004-08-03 07:06:22 +0000332 const char *start, const char *end, const char **endPtr,
333 XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000334static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000335doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000336 const char *end, const char **nextPtr, XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000337#ifdef XML_DTD
338static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000339doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000340 const char *end, const char **nextPtr, XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000341#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000342
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000343static enum XML_Error
Fred Drake4faea012003-01-28 06:42:40 +0000344storeAtts(XML_Parser parser, const ENCODING *, const char *s,
345 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000346static enum XML_Error
347addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
348 const XML_Char *uri, BINDING **bindingsPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000349static int
Fred Drake31d485c2004-08-03 07:06:22 +0000350defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
351 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000352static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000353storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
354 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000355static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000356appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
357 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000358static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000359getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
360 const char *end);
361static int
362setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000363static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000364storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
365 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000366static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000367reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
368 const char *start, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000369static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000370reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
371 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000372static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000373reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
374 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000375
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000376static const XML_Char * getContext(XML_Parser parser);
377static XML_Bool
378setContext(XML_Parser parser, const XML_Char *context);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000379
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000380static void FASTCALL normalizePublicId(XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000381
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000382static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
383/* do not call if parentParser != NULL */
384static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
385static void
386dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
387static int
388dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
389static int
390copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000391
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000392static NAMED *
393lookup(HASH_TABLE *table, KEY name, size_t createSize);
394static void FASTCALL
395hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
396static void FASTCALL hashTableClear(HASH_TABLE *);
397static void FASTCALL hashTableDestroy(HASH_TABLE *);
398static void FASTCALL
399hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
400static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000401
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000402static void FASTCALL
403poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
404static void FASTCALL poolClear(STRING_POOL *);
405static void FASTCALL poolDestroy(STRING_POOL *);
406static XML_Char *
407poolAppend(STRING_POOL *pool, const ENCODING *enc,
408 const char *ptr, const char *end);
409static XML_Char *
410poolStoreString(STRING_POOL *pool, const ENCODING *enc,
411 const char *ptr, const char *end);
412static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
413static const XML_Char * FASTCALL
414poolCopyString(STRING_POOL *pool, const XML_Char *s);
415static const XML_Char *
416poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
417static const XML_Char * FASTCALL
418poolAppendString(STRING_POOL *pool, const XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000419
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000420static int FASTCALL nextScaffoldPart(XML_Parser parser);
421static XML_Content * build_model(XML_Parser parser);
422static ELEMENT_TYPE *
423getElementType(XML_Parser parser, const ENCODING *enc,
424 const char *ptr, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000425
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000426static XML_Parser
427parserCreate(const XML_Char *encodingName,
428 const XML_Memory_Handling_Suite *memsuite,
429 const XML_Char *nameSep,
430 DTD *dtd);
431static void
432parserInit(XML_Parser parser, const XML_Char *encodingName);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000433
434#define poolStart(pool) ((pool)->start)
435#define poolEnd(pool) ((pool)->ptr)
436#define poolLength(pool) ((pool)->ptr - (pool)->start)
437#define poolChop(pool) ((void)--(pool->ptr))
438#define poolLastChar(pool) (((pool)->ptr)[-1])
439#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
440#define poolFinish(pool) ((pool)->start = (pool)->ptr)
441#define poolAppendChar(pool, c) \
442 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
443 ? 0 \
444 : ((*((pool)->ptr)++ = c), 1))
445
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000446struct XML_ParserStruct {
447 /* The first member must be userData so that the XML_GetUserData
448 macro works. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000449 void *m_userData;
450 void *m_handlerArg;
451 char *m_buffer;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000452 const XML_Memory_Handling_Suite m_mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000453 /* first character to be parsed */
454 const char *m_bufferPtr;
455 /* past last character to be parsed */
456 char *m_bufferEnd;
457 /* allocated end of buffer */
458 const char *m_bufferLim;
459 long m_parseEndByteIndex;
460 const char *m_parseEndPtr;
461 XML_Char *m_dataBuf;
462 XML_Char *m_dataBufEnd;
463 XML_StartElementHandler m_startElementHandler;
464 XML_EndElementHandler m_endElementHandler;
465 XML_CharacterDataHandler m_characterDataHandler;
466 XML_ProcessingInstructionHandler m_processingInstructionHandler;
467 XML_CommentHandler m_commentHandler;
468 XML_StartCdataSectionHandler m_startCdataSectionHandler;
469 XML_EndCdataSectionHandler m_endCdataSectionHandler;
470 XML_DefaultHandler m_defaultHandler;
471 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
472 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
473 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
474 XML_NotationDeclHandler m_notationDeclHandler;
475 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
476 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
477 XML_NotStandaloneHandler m_notStandaloneHandler;
478 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000479 XML_Parser m_externalEntityRefHandlerArg;
480 XML_SkippedEntityHandler m_skippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000481 XML_UnknownEncodingHandler m_unknownEncodingHandler;
482 XML_ElementDeclHandler m_elementDeclHandler;
483 XML_AttlistDeclHandler m_attlistDeclHandler;
484 XML_EntityDeclHandler m_entityDeclHandler;
485 XML_XmlDeclHandler m_xmlDeclHandler;
486 const ENCODING *m_encoding;
487 INIT_ENCODING m_initEncoding;
488 const ENCODING *m_internalEncoding;
489 const XML_Char *m_protocolEncodingName;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000490 XML_Bool m_ns;
491 XML_Bool m_ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000492 void *m_unknownEncodingMem;
493 void *m_unknownEncodingData;
494 void *m_unknownEncodingHandlerData;
Fred Drake31d485c2004-08-03 07:06:22 +0000495 void (XMLCALL *m_unknownEncodingRelease)(void *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000496 PROLOG_STATE m_prologState;
497 Processor *m_processor;
498 enum XML_Error m_errorCode;
499 const char *m_eventPtr;
500 const char *m_eventEndPtr;
501 const char *m_positionPtr;
502 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
Fred Drake31d485c2004-08-03 07:06:22 +0000503 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000504 XML_Bool m_defaultExpandInternalEntities;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000505 int m_tagLevel;
506 ENTITY *m_declEntity;
507 const XML_Char *m_doctypeName;
508 const XML_Char *m_doctypeSysid;
509 const XML_Char *m_doctypePubid;
510 const XML_Char *m_declAttributeType;
511 const XML_Char *m_declNotationName;
512 const XML_Char *m_declNotationPublicId;
513 ELEMENT_TYPE *m_declElementType;
514 ATTRIBUTE_ID *m_declAttributeId;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000515 XML_Bool m_declAttributeIsCdata;
516 XML_Bool m_declAttributeIsId;
517 DTD *m_dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000518 const XML_Char *m_curBase;
519 TAG *m_tagStack;
520 TAG *m_freeTagList;
521 BINDING *m_inheritedBindings;
522 BINDING *m_freeBindingList;
523 int m_attsSize;
524 int m_nSpecifiedAtts;
525 int m_idAttIndex;
526 ATTRIBUTE *m_atts;
Fred Drake08317ae2003-10-21 15:38:55 +0000527 NS_ATT *m_nsAtts;
528 unsigned long m_nsAttsVersion;
529 unsigned char m_nsAttsPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000530 POSITION m_position;
531 STRING_POOL m_tempPool;
532 STRING_POOL m_temp2Pool;
533 char *m_groupConnector;
Fred Drake08317ae2003-10-21 15:38:55 +0000534 unsigned int m_groupSize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000535 XML_Char m_namespaceSeparator;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000536 XML_Parser m_parentParser;
Fred Drake31d485c2004-08-03 07:06:22 +0000537 XML_ParsingStatus m_parsingStatus;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000538#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000539 XML_Bool m_isParamEntity;
540 XML_Bool m_useForeignDTD;
541 enum XML_ParamEntityParsing m_paramEntityParsing;
542#endif
543};
544
545#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
546#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
547#define FREE(p) (parser->m_mem.free_fcn((p)))
548
549#define userData (parser->m_userData)
550#define handlerArg (parser->m_handlerArg)
551#define startElementHandler (parser->m_startElementHandler)
552#define endElementHandler (parser->m_endElementHandler)
553#define characterDataHandler (parser->m_characterDataHandler)
554#define processingInstructionHandler \
555 (parser->m_processingInstructionHandler)
556#define commentHandler (parser->m_commentHandler)
557#define startCdataSectionHandler \
558 (parser->m_startCdataSectionHandler)
559#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
560#define defaultHandler (parser->m_defaultHandler)
561#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
562#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
563#define unparsedEntityDeclHandler \
564 (parser->m_unparsedEntityDeclHandler)
565#define notationDeclHandler (parser->m_notationDeclHandler)
566#define startNamespaceDeclHandler \
567 (parser->m_startNamespaceDeclHandler)
568#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
569#define notStandaloneHandler (parser->m_notStandaloneHandler)
570#define externalEntityRefHandler \
571 (parser->m_externalEntityRefHandler)
572#define externalEntityRefHandlerArg \
573 (parser->m_externalEntityRefHandlerArg)
574#define internalEntityRefHandler \
575 (parser->m_internalEntityRefHandler)
576#define skippedEntityHandler (parser->m_skippedEntityHandler)
577#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
578#define elementDeclHandler (parser->m_elementDeclHandler)
579#define attlistDeclHandler (parser->m_attlistDeclHandler)
580#define entityDeclHandler (parser->m_entityDeclHandler)
581#define xmlDeclHandler (parser->m_xmlDeclHandler)
582#define encoding (parser->m_encoding)
583#define initEncoding (parser->m_initEncoding)
584#define internalEncoding (parser->m_internalEncoding)
585#define unknownEncodingMem (parser->m_unknownEncodingMem)
586#define unknownEncodingData (parser->m_unknownEncodingData)
587#define unknownEncodingHandlerData \
588 (parser->m_unknownEncodingHandlerData)
589#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
590#define protocolEncodingName (parser->m_protocolEncodingName)
591#define ns (parser->m_ns)
592#define ns_triplets (parser->m_ns_triplets)
593#define prologState (parser->m_prologState)
594#define processor (parser->m_processor)
595#define errorCode (parser->m_errorCode)
596#define eventPtr (parser->m_eventPtr)
597#define eventEndPtr (parser->m_eventEndPtr)
598#define positionPtr (parser->m_positionPtr)
599#define position (parser->m_position)
600#define openInternalEntities (parser->m_openInternalEntities)
Fred Drake31d485c2004-08-03 07:06:22 +0000601#define freeInternalEntities (parser->m_freeInternalEntities)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000602#define defaultExpandInternalEntities \
603 (parser->m_defaultExpandInternalEntities)
604#define tagLevel (parser->m_tagLevel)
605#define buffer (parser->m_buffer)
606#define bufferPtr (parser->m_bufferPtr)
607#define bufferEnd (parser->m_bufferEnd)
608#define parseEndByteIndex (parser->m_parseEndByteIndex)
609#define parseEndPtr (parser->m_parseEndPtr)
610#define bufferLim (parser->m_bufferLim)
611#define dataBuf (parser->m_dataBuf)
612#define dataBufEnd (parser->m_dataBufEnd)
613#define _dtd (parser->m_dtd)
614#define curBase (parser->m_curBase)
615#define declEntity (parser->m_declEntity)
616#define doctypeName (parser->m_doctypeName)
617#define doctypeSysid (parser->m_doctypeSysid)
618#define doctypePubid (parser->m_doctypePubid)
619#define declAttributeType (parser->m_declAttributeType)
620#define declNotationName (parser->m_declNotationName)
621#define declNotationPublicId (parser->m_declNotationPublicId)
622#define declElementType (parser->m_declElementType)
623#define declAttributeId (parser->m_declAttributeId)
624#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
625#define declAttributeIsId (parser->m_declAttributeIsId)
626#define freeTagList (parser->m_freeTagList)
627#define freeBindingList (parser->m_freeBindingList)
628#define inheritedBindings (parser->m_inheritedBindings)
629#define tagStack (parser->m_tagStack)
630#define atts (parser->m_atts)
631#define attsSize (parser->m_attsSize)
632#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
633#define idAttIndex (parser->m_idAttIndex)
Fred Drake08317ae2003-10-21 15:38:55 +0000634#define nsAtts (parser->m_nsAtts)
635#define nsAttsVersion (parser->m_nsAttsVersion)
636#define nsAttsPower (parser->m_nsAttsPower)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000637#define tempPool (parser->m_tempPool)
638#define temp2Pool (parser->m_temp2Pool)
639#define groupConnector (parser->m_groupConnector)
640#define groupSize (parser->m_groupSize)
641#define namespaceSeparator (parser->m_namespaceSeparator)
642#define parentParser (parser->m_parentParser)
Fred Drake31d485c2004-08-03 07:06:22 +0000643#define parsing (parser->m_parsingStatus.parsing)
644#define finalBuffer (parser->m_parsingStatus.finalBuffer)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000645#ifdef XML_DTD
646#define isParamEntity (parser->m_isParamEntity)
647#define useForeignDTD (parser->m_useForeignDTD)
648#define paramEntityParsing (parser->m_paramEntityParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000649#endif /* XML_DTD */
650
Fred Drake08317ae2003-10-21 15:38:55 +0000651XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000652XML_ParserCreate(const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000653{
654 return XML_ParserCreate_MM(encodingName, NULL, NULL);
655}
656
Fred Drake08317ae2003-10-21 15:38:55 +0000657XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000658XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000659{
660 XML_Char tmp[2];
661 *tmp = nsSep;
662 return XML_ParserCreate_MM(encodingName, NULL, tmp);
663}
664
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000665static const XML_Char implicitContext[] = {
666 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
667 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
668 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
669 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
670};
671
Fred Drake08317ae2003-10-21 15:38:55 +0000672XML_Parser XMLCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000673XML_ParserCreate_MM(const XML_Char *encodingName,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000674 const XML_Memory_Handling_Suite *memsuite,
675 const XML_Char *nameSep)
676{
677 XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
678 if (parser != NULL && ns) {
679 /* implicit context only set for root parser, since child
680 parsers (i.e. external entity parsers) will inherit it
681 */
682 if (!setContext(parser, implicitContext)) {
683 XML_ParserFree(parser);
684 return NULL;
685 }
686 }
687 return parser;
688}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000689
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000690static XML_Parser
691parserCreate(const XML_Char *encodingName,
692 const XML_Memory_Handling_Suite *memsuite,
693 const XML_Char *nameSep,
694 DTD *dtd)
695{
696 XML_Parser parser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000697
698 if (memsuite) {
699 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000700 parser = (XML_Parser)
701 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
702 if (parser != NULL) {
703 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
704 mtemp->malloc_fcn = memsuite->malloc_fcn;
705 mtemp->realloc_fcn = memsuite->realloc_fcn;
706 mtemp->free_fcn = memsuite->free_fcn;
707 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000708 }
709 else {
710 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000711 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
712 if (parser != NULL) {
713 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
714 mtemp->malloc_fcn = malloc;
715 mtemp->realloc_fcn = realloc;
716 mtemp->free_fcn = free;
717 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000718 }
719
720 if (!parser)
721 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000722
723 buffer = NULL;
724 bufferLim = NULL;
725
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000726 attsSize = INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000727 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
728 if (atts == NULL) {
729 FREE(parser);
730 return NULL;
731 }
732 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
733 if (dataBuf == NULL) {
734 FREE(atts);
735 FREE(parser);
736 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000737 }
738 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
739
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000740 if (dtd)
741 _dtd = dtd;
742 else {
743 _dtd = dtdCreate(&parser->m_mem);
744 if (_dtd == NULL) {
745 FREE(dataBuf);
746 FREE(atts);
747 FREE(parser);
748 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000749 }
750 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000751
752 freeBindingList = NULL;
753 freeTagList = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000754 freeInternalEntities = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000755
756 groupSize = 0;
757 groupConnector = NULL;
758
759 unknownEncodingHandler = NULL;
760 unknownEncodingHandlerData = NULL;
761
762 namespaceSeparator = '!';
763 ns = XML_FALSE;
764 ns_triplets = XML_FALSE;
765
Fred Drake08317ae2003-10-21 15:38:55 +0000766 nsAtts = NULL;
767 nsAttsVersion = 0;
768 nsAttsPower = 0;
769
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000770 poolInit(&tempPool, &(parser->m_mem));
771 poolInit(&temp2Pool, &(parser->m_mem));
772 parserInit(parser, encodingName);
773
774 if (encodingName && !protocolEncodingName) {
775 XML_ParserFree(parser);
776 return NULL;
777 }
778
779 if (nameSep) {
780 ns = XML_TRUE;
781 internalEncoding = XmlGetInternalEncodingNS();
782 namespaceSeparator = *nameSep;
783 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000784 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000785 internalEncoding = XmlGetInternalEncoding();
786 }
787
788 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000789}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000790
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000791static void
792parserInit(XML_Parser parser, const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000793{
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000794 processor = prologInitProcessor;
795 XmlPrologStateInit(&prologState);
796 protocolEncodingName = (encodingName != NULL
797 ? poolCopyString(&tempPool, encodingName)
798 : NULL);
799 curBase = NULL;
800 XmlInitEncoding(&initEncoding, &encoding, 0);
801 userData = NULL;
802 handlerArg = NULL;
803 startElementHandler = NULL;
804 endElementHandler = NULL;
805 characterDataHandler = NULL;
806 processingInstructionHandler = NULL;
807 commentHandler = NULL;
808 startCdataSectionHandler = NULL;
809 endCdataSectionHandler = NULL;
810 defaultHandler = NULL;
811 startDoctypeDeclHandler = NULL;
812 endDoctypeDeclHandler = NULL;
813 unparsedEntityDeclHandler = NULL;
814 notationDeclHandler = NULL;
815 startNamespaceDeclHandler = NULL;
816 endNamespaceDeclHandler = NULL;
817 notStandaloneHandler = NULL;
818 externalEntityRefHandler = NULL;
819 externalEntityRefHandlerArg = parser;
820 skippedEntityHandler = NULL;
821 elementDeclHandler = NULL;
822 attlistDeclHandler = NULL;
823 entityDeclHandler = NULL;
824 xmlDeclHandler = NULL;
825 bufferPtr = buffer;
826 bufferEnd = buffer;
827 parseEndByteIndex = 0;
828 parseEndPtr = NULL;
829 declElementType = NULL;
830 declAttributeId = NULL;
831 declEntity = NULL;
832 doctypeName = NULL;
833 doctypeSysid = NULL;
834 doctypePubid = NULL;
835 declAttributeType = NULL;
836 declNotationName = NULL;
837 declNotationPublicId = NULL;
838 declAttributeIsCdata = XML_FALSE;
839 declAttributeIsId = XML_FALSE;
840 memset(&position, 0, sizeof(POSITION));
841 errorCode = XML_ERROR_NONE;
842 eventPtr = NULL;
843 eventEndPtr = NULL;
844 positionPtr = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000845 openInternalEntities = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000846 defaultExpandInternalEntities = XML_TRUE;
847 tagLevel = 0;
848 tagStack = NULL;
849 inheritedBindings = NULL;
850 nSpecifiedAtts = 0;
851 unknownEncodingMem = NULL;
852 unknownEncodingRelease = NULL;
853 unknownEncodingData = NULL;
854 parentParser = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000855 parsing = XML_INITIALIZED;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000856#ifdef XML_DTD
857 isParamEntity = XML_FALSE;
858 useForeignDTD = XML_FALSE;
859 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
860#endif
861}
862
863/* moves list of bindings to freeBindingList */
864static void FASTCALL
865moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
866{
867 while (bindings) {
868 BINDING *b = bindings;
869 bindings = bindings->nextTagBinding;
870 b->nextTagBinding = freeBindingList;
871 freeBindingList = b;
872 }
873}
874
Fred Drake08317ae2003-10-21 15:38:55 +0000875XML_Bool XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000876XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
877{
878 TAG *tStk;
Fred Drake31d485c2004-08-03 07:06:22 +0000879 OPEN_INTERNAL_ENTITY *openEntityList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000880 if (parentParser)
881 return XML_FALSE;
882 /* move tagStack to freeTagList */
883 tStk = tagStack;
884 while (tStk) {
885 TAG *tag = tStk;
886 tStk = tStk->parent;
887 tag->parent = freeTagList;
888 moveToFreeBindingList(parser, tag->bindings);
889 tag->bindings = NULL;
890 freeTagList = tag;
891 }
Fred Drake31d485c2004-08-03 07:06:22 +0000892 /* move openInternalEntities to freeInternalEntities */
893 openEntityList = openInternalEntities;
894 while (openEntityList) {
895 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
896 openEntityList = openEntity->next;
897 openEntity->next = freeInternalEntities;
898 freeInternalEntities = openEntity;
899 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000900 moveToFreeBindingList(parser, inheritedBindings);
Fred Drake08317ae2003-10-21 15:38:55 +0000901 FREE(unknownEncodingMem);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000902 if (unknownEncodingRelease)
903 unknownEncodingRelease(unknownEncodingData);
904 poolClear(&tempPool);
905 poolClear(&temp2Pool);
906 parserInit(parser, encodingName);
907 dtdReset(_dtd, &parser->m_mem);
908 return setContext(parser, implicitContext);
909}
910
Fred Drake08317ae2003-10-21 15:38:55 +0000911enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000912XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
913{
914 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
915 XXX There's no way for the caller to determine which of the
916 XXX possible error cases caused the XML_STATUS_ERROR return.
917 */
Fred Drake31d485c2004-08-03 07:06:22 +0000918 if (parsing == XML_PARSING || parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000919 return XML_STATUS_ERROR;
920 if (encodingName == NULL)
921 protocolEncodingName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000922 else {
923 protocolEncodingName = poolCopyString(&tempPool, encodingName);
924 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000925 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000926 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000927 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000928}
929
Fred Drake08317ae2003-10-21 15:38:55 +0000930XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000931XML_ExternalEntityParserCreate(XML_Parser oldParser,
932 const XML_Char *context,
933 const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000934{
935 XML_Parser parser = oldParser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000936 DTD *newDtd = NULL;
937 DTD *oldDtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000938 XML_StartElementHandler oldStartElementHandler = startElementHandler;
939 XML_EndElementHandler oldEndElementHandler = endElementHandler;
940 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000941 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
942 = processingInstructionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000943 XML_CommentHandler oldCommentHandler = commentHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000944 XML_StartCdataSectionHandler oldStartCdataSectionHandler
945 = startCdataSectionHandler;
946 XML_EndCdataSectionHandler oldEndCdataSectionHandler
947 = endCdataSectionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000948 XML_DefaultHandler oldDefaultHandler = defaultHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000949 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
950 = unparsedEntityDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000951 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000952 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
953 = startNamespaceDeclHandler;
954 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
955 = endNamespaceDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000956 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000957 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
958 = externalEntityRefHandler;
959 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
960 XML_UnknownEncodingHandler oldUnknownEncodingHandler
961 = unknownEncodingHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000962 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
963 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
964 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
965 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
966 ELEMENT_TYPE * oldDeclElementType = declElementType;
967
968 void *oldUserData = userData;
969 void *oldHandlerArg = handlerArg;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000970 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
971 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000972#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000973 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
974 int oldInEntityValue = prologState.inEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000975#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000976 XML_Bool oldns_triplets = ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000977
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000978#ifdef XML_DTD
979 if (!context)
980 newDtd = oldDtd;
981#endif /* XML_DTD */
982
983 /* Note that the magical uses of the pre-processor to make field
984 access look more like C++ require that `parser' be overwritten
985 here. This makes this function more painful to follow than it
986 would be otherwise.
987 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000988 if (ns) {
989 XML_Char tmp[2];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000990 *tmp = namespaceSeparator;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000991 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000992 }
993 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000994 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000995 }
996
997 if (!parser)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000998 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000999
1000 startElementHandler = oldStartElementHandler;
1001 endElementHandler = oldEndElementHandler;
1002 characterDataHandler = oldCharacterDataHandler;
1003 processingInstructionHandler = oldProcessingInstructionHandler;
1004 commentHandler = oldCommentHandler;
1005 startCdataSectionHandler = oldStartCdataSectionHandler;
1006 endCdataSectionHandler = oldEndCdataSectionHandler;
1007 defaultHandler = oldDefaultHandler;
1008 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1009 notationDeclHandler = oldNotationDeclHandler;
1010 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1011 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1012 notStandaloneHandler = oldNotStandaloneHandler;
1013 externalEntityRefHandler = oldExternalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001014 skippedEntityHandler = oldSkippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001015 unknownEncodingHandler = oldUnknownEncodingHandler;
1016 elementDeclHandler = oldElementDeclHandler;
1017 attlistDeclHandler = oldAttlistDeclHandler;
1018 entityDeclHandler = oldEntityDeclHandler;
1019 xmlDeclHandler = oldXmlDeclHandler;
1020 declElementType = oldDeclElementType;
1021 userData = oldUserData;
1022 if (oldUserData == oldHandlerArg)
1023 handlerArg = userData;
1024 else
1025 handlerArg = parser;
1026 if (oldExternalEntityRefHandlerArg != oldParser)
1027 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1028 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1029 ns_triplets = oldns_triplets;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001030 parentParser = oldParser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001031#ifdef XML_DTD
1032 paramEntityParsing = oldParamEntityParsing;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001033 prologState.inEntityValue = oldInEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001034 if (context) {
1035#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001036 if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
1037 || !setContext(parser, context)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001038 XML_ParserFree(parser);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001039 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001040 }
1041 processor = externalEntityInitProcessor;
1042#ifdef XML_DTD
1043 }
1044 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001045 /* The DTD instance referenced by _dtd is shared between the document's
1046 root parser and external PE parsers, therefore one does not need to
1047 call setContext. In addition, one also *must* not call setContext,
1048 because this would overwrite existing prefix->binding pointers in
1049 _dtd with ones that get destroyed with the external PE parser.
1050 This would leave those prefixes with dangling pointers.
1051 */
1052 isParamEntity = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001053 XmlPrologStateInitExternalEntity(&prologState);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001054 processor = externalParEntInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001055 }
1056#endif /* XML_DTD */
1057 return parser;
1058}
1059
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001060static void FASTCALL
1061destroyBindings(BINDING *bindings, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001062{
1063 for (;;) {
1064 BINDING *b = bindings;
1065 if (!b)
1066 break;
1067 bindings = b->nextTagBinding;
1068 FREE(b->uri);
1069 FREE(b);
1070 }
1071}
1072
Fred Drake08317ae2003-10-21 15:38:55 +00001073void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001074XML_ParserFree(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001075{
Fred Drake31d485c2004-08-03 07:06:22 +00001076 TAG *tagList;
1077 OPEN_INTERNAL_ENTITY *entityList;
1078 if (parser == NULL)
1079 return;
1080 /* free tagStack and freeTagList */
1081 tagList = tagStack;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001082 for (;;) {
1083 TAG *p;
Fred Drake31d485c2004-08-03 07:06:22 +00001084 if (tagList == NULL) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001085 if (freeTagList == NULL)
1086 break;
Fred Drake31d485c2004-08-03 07:06:22 +00001087 tagList = freeTagList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001088 freeTagList = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001089 }
Fred Drake31d485c2004-08-03 07:06:22 +00001090 p = tagList;
1091 tagList = tagList->parent;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001092 FREE(p->buf);
1093 destroyBindings(p->bindings, parser);
1094 FREE(p);
1095 }
Fred Drake31d485c2004-08-03 07:06:22 +00001096 /* free openInternalEntities and freeInternalEntities */
1097 entityList = openInternalEntities;
1098 for (;;) {
1099 OPEN_INTERNAL_ENTITY *openEntity;
1100 if (entityList == NULL) {
1101 if (freeInternalEntities == NULL)
1102 break;
1103 entityList = freeInternalEntities;
1104 freeInternalEntities = NULL;
1105 }
1106 openEntity = entityList;
1107 entityList = entityList->next;
1108 FREE(openEntity);
1109 }
1110
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001111 destroyBindings(freeBindingList, parser);
1112 destroyBindings(inheritedBindings, parser);
1113 poolDestroy(&tempPool);
1114 poolDestroy(&temp2Pool);
1115#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001116 /* external parameter entity parsers share the DTD structure
1117 parser->m_dtd with the root parser, so we must not destroy it
1118 */
1119 if (!isParamEntity && _dtd)
1120#else
1121 if (_dtd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001122#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001123 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001124 FREE((void *)atts);
Fred Drake08317ae2003-10-21 15:38:55 +00001125 FREE(groupConnector);
1126 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001127 FREE(dataBuf);
Fred Drake08317ae2003-10-21 15:38:55 +00001128 FREE(nsAtts);
1129 FREE(unknownEncodingMem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001130 if (unknownEncodingRelease)
1131 unknownEncodingRelease(unknownEncodingData);
1132 FREE(parser);
1133}
1134
Fred Drake08317ae2003-10-21 15:38:55 +00001135void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001136XML_UseParserAsHandlerArg(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001137{
1138 handlerArg = parser;
1139}
1140
Fred Drake08317ae2003-10-21 15:38:55 +00001141enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001142XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1143{
1144#ifdef XML_DTD
1145 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Fred Drake31d485c2004-08-03 07:06:22 +00001146 if (parsing == XML_PARSING || parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001147 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1148 useForeignDTD = useDTD;
1149 return XML_ERROR_NONE;
1150#else
1151 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1152#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001153}
1154
Fred Drake08317ae2003-10-21 15:38:55 +00001155void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001156XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1157{
1158 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Fred Drake31d485c2004-08-03 07:06:22 +00001159 if (parsing == XML_PARSING || parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001160 return;
1161 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1162}
1163
Fred Drake08317ae2003-10-21 15:38:55 +00001164void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001165XML_SetUserData(XML_Parser parser, void *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001166{
1167 if (handlerArg == userData)
1168 handlerArg = userData = p;
1169 else
1170 userData = p;
1171}
1172
Fred Drake08317ae2003-10-21 15:38:55 +00001173enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001174XML_SetBase(XML_Parser parser, const XML_Char *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001175{
1176 if (p) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001177 p = poolCopyString(&_dtd->pool, p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001178 if (!p)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001179 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001180 curBase = p;
1181 }
1182 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001183 curBase = NULL;
1184 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001185}
1186
Fred Drake08317ae2003-10-21 15:38:55 +00001187const XML_Char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001188XML_GetBase(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001189{
1190 return curBase;
1191}
1192
Fred Drake08317ae2003-10-21 15:38:55 +00001193int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001194XML_GetSpecifiedAttributeCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001195{
1196 return nSpecifiedAtts;
1197}
1198
Fred Drake08317ae2003-10-21 15:38:55 +00001199int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001200XML_GetIdAttributeIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001201{
1202 return idAttIndex;
1203}
1204
Fred Drake08317ae2003-10-21 15:38:55 +00001205void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001206XML_SetElementHandler(XML_Parser parser,
1207 XML_StartElementHandler start,
1208 XML_EndElementHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001209{
1210 startElementHandler = start;
1211 endElementHandler = end;
1212}
1213
Fred Drake08317ae2003-10-21 15:38:55 +00001214void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001215XML_SetStartElementHandler(XML_Parser parser,
1216 XML_StartElementHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001217 startElementHandler = start;
1218}
1219
Fred Drake08317ae2003-10-21 15:38:55 +00001220void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001221XML_SetEndElementHandler(XML_Parser parser,
1222 XML_EndElementHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001223 endElementHandler = end;
1224}
1225
Fred Drake08317ae2003-10-21 15:38:55 +00001226void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001227XML_SetCharacterDataHandler(XML_Parser parser,
1228 XML_CharacterDataHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001229{
1230 characterDataHandler = handler;
1231}
1232
Fred Drake08317ae2003-10-21 15:38:55 +00001233void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001234XML_SetProcessingInstructionHandler(XML_Parser parser,
1235 XML_ProcessingInstructionHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001236{
1237 processingInstructionHandler = handler;
1238}
1239
Fred Drake08317ae2003-10-21 15:38:55 +00001240void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001241XML_SetCommentHandler(XML_Parser parser,
1242 XML_CommentHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001243{
1244 commentHandler = handler;
1245}
1246
Fred Drake08317ae2003-10-21 15:38:55 +00001247void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001248XML_SetCdataSectionHandler(XML_Parser parser,
1249 XML_StartCdataSectionHandler start,
1250 XML_EndCdataSectionHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001251{
1252 startCdataSectionHandler = start;
1253 endCdataSectionHandler = end;
1254}
1255
Fred Drake08317ae2003-10-21 15:38:55 +00001256void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001257XML_SetStartCdataSectionHandler(XML_Parser parser,
1258 XML_StartCdataSectionHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001259 startCdataSectionHandler = start;
1260}
1261
Fred Drake08317ae2003-10-21 15:38:55 +00001262void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001263XML_SetEndCdataSectionHandler(XML_Parser parser,
1264 XML_EndCdataSectionHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001265 endCdataSectionHandler = end;
1266}
1267
Fred Drake08317ae2003-10-21 15:38:55 +00001268void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001269XML_SetDefaultHandler(XML_Parser parser,
1270 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001271{
1272 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001273 defaultExpandInternalEntities = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001274}
1275
Fred Drake08317ae2003-10-21 15:38:55 +00001276void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001277XML_SetDefaultHandlerExpand(XML_Parser parser,
1278 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001279{
1280 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001281 defaultExpandInternalEntities = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001282}
1283
Fred Drake08317ae2003-10-21 15:38:55 +00001284void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001285XML_SetDoctypeDeclHandler(XML_Parser parser,
1286 XML_StartDoctypeDeclHandler start,
1287 XML_EndDoctypeDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001288{
1289 startDoctypeDeclHandler = start;
1290 endDoctypeDeclHandler = end;
1291}
1292
Fred Drake08317ae2003-10-21 15:38:55 +00001293void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001294XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1295 XML_StartDoctypeDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001296 startDoctypeDeclHandler = start;
1297}
1298
Fred Drake08317ae2003-10-21 15:38:55 +00001299void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001300XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1301 XML_EndDoctypeDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001302 endDoctypeDeclHandler = end;
1303}
1304
Fred Drake08317ae2003-10-21 15:38:55 +00001305void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001306XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1307 XML_UnparsedEntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001308{
1309 unparsedEntityDeclHandler = handler;
1310}
1311
Fred Drake08317ae2003-10-21 15:38:55 +00001312void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001313XML_SetNotationDeclHandler(XML_Parser parser,
1314 XML_NotationDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001315{
1316 notationDeclHandler = handler;
1317}
1318
Fred Drake08317ae2003-10-21 15:38:55 +00001319void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001320XML_SetNamespaceDeclHandler(XML_Parser parser,
1321 XML_StartNamespaceDeclHandler start,
1322 XML_EndNamespaceDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001323{
1324 startNamespaceDeclHandler = start;
1325 endNamespaceDeclHandler = end;
1326}
1327
Fred Drake08317ae2003-10-21 15:38:55 +00001328void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001329XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1330 XML_StartNamespaceDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001331 startNamespaceDeclHandler = start;
1332}
1333
Fred Drake08317ae2003-10-21 15:38:55 +00001334void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001335XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1336 XML_EndNamespaceDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001337 endNamespaceDeclHandler = end;
1338}
1339
Fred Drake08317ae2003-10-21 15:38:55 +00001340void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001341XML_SetNotStandaloneHandler(XML_Parser parser,
1342 XML_NotStandaloneHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001343{
1344 notStandaloneHandler = handler;
1345}
1346
Fred Drake08317ae2003-10-21 15:38:55 +00001347void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001348XML_SetExternalEntityRefHandler(XML_Parser parser,
1349 XML_ExternalEntityRefHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001350{
1351 externalEntityRefHandler = handler;
1352}
1353
Fred Drake08317ae2003-10-21 15:38:55 +00001354void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001355XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001356{
1357 if (arg)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001358 externalEntityRefHandlerArg = (XML_Parser)arg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001359 else
1360 externalEntityRefHandlerArg = parser;
1361}
1362
Fred Drake08317ae2003-10-21 15:38:55 +00001363void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001364XML_SetSkippedEntityHandler(XML_Parser parser,
1365 XML_SkippedEntityHandler handler)
1366{
1367 skippedEntityHandler = handler;
1368}
1369
Fred Drake08317ae2003-10-21 15:38:55 +00001370void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001371XML_SetUnknownEncodingHandler(XML_Parser parser,
1372 XML_UnknownEncodingHandler handler,
1373 void *data)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001374{
1375 unknownEncodingHandler = handler;
1376 unknownEncodingHandlerData = data;
1377}
1378
Fred Drake08317ae2003-10-21 15:38:55 +00001379void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001380XML_SetElementDeclHandler(XML_Parser parser,
1381 XML_ElementDeclHandler eldecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001382{
1383 elementDeclHandler = eldecl;
1384}
1385
Fred Drake08317ae2003-10-21 15:38:55 +00001386void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001387XML_SetAttlistDeclHandler(XML_Parser parser,
1388 XML_AttlistDeclHandler attdecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001389{
1390 attlistDeclHandler = attdecl;
1391}
1392
Fred Drake08317ae2003-10-21 15:38:55 +00001393void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001394XML_SetEntityDeclHandler(XML_Parser parser,
1395 XML_EntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001396{
1397 entityDeclHandler = handler;
1398}
1399
Fred Drake08317ae2003-10-21 15:38:55 +00001400void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001401XML_SetXmlDeclHandler(XML_Parser parser,
1402 XML_XmlDeclHandler handler) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001403 xmlDeclHandler = handler;
1404}
1405
Fred Drake08317ae2003-10-21 15:38:55 +00001406int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001407XML_SetParamEntityParsing(XML_Parser parser,
1408 enum XML_ParamEntityParsing peParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001409{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001410 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Fred Drake31d485c2004-08-03 07:06:22 +00001411 if (parsing == XML_PARSING || parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001412 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001413#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001414 paramEntityParsing = peParsing;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001415 return 1;
1416#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001417 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001418#endif
1419}
1420
Fred Drake08317ae2003-10-21 15:38:55 +00001421enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001422XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001423{
Fred Drake31d485c2004-08-03 07:06:22 +00001424 switch (parsing) {
1425 case XML_SUSPENDED:
1426 errorCode = XML_ERROR_SUSPENDED;
1427 return XML_STATUS_ERROR;
1428 case XML_FINISHED:
1429 errorCode = XML_ERROR_FINISHED;
1430 return XML_STATUS_ERROR;
1431 default:
1432 parsing = XML_PARSING;
1433 }
1434
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001435 if (len == 0) {
Fred Drake31d485c2004-08-03 07:06:22 +00001436 finalBuffer = (XML_Bool)isFinal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001437 if (!isFinal)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001438 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001439 positionPtr = bufferPtr;
Fred Drake31d485c2004-08-03 07:06:22 +00001440 parseEndPtr = bufferEnd;
1441
1442 /* If data are left over from last buffer, and we now know that these
1443 data are the final chunk of input, then we have to check them again
1444 to detect errors based on this information.
1445 */
1446 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1447
1448 if (errorCode == XML_ERROR_NONE) {
1449 switch (parsing) {
1450 case XML_SUSPENDED:
1451 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1452 positionPtr = bufferPtr;
1453 return XML_STATUS_SUSPENDED;
1454 case XML_INITIALIZED:
1455 case XML_PARSING:
1456 parsing = XML_FINISHED;
1457 /* fall through */
1458 default:
1459 return XML_STATUS_OK;
1460 }
1461 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001462 eventEndPtr = eventPtr;
1463 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001464 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001465 }
1466#ifndef XML_CONTEXT_BYTES
1467 else if (bufferPtr == bufferEnd) {
1468 const char *end;
1469 int nLeftOver;
Fred Drake31d485c2004-08-03 07:06:22 +00001470 enum XML_Error result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001471 parseEndByteIndex += len;
1472 positionPtr = s;
Fred Drake31d485c2004-08-03 07:06:22 +00001473 finalBuffer = (XML_Bool)isFinal;
1474
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001475 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
Fred Drake31d485c2004-08-03 07:06:22 +00001476
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001477 if (errorCode != XML_ERROR_NONE) {
1478 eventEndPtr = eventPtr;
1479 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001480 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001481 }
Fred Drake31d485c2004-08-03 07:06:22 +00001482 else {
1483 switch (parsing) {
1484 case XML_SUSPENDED:
1485 result = XML_STATUS_SUSPENDED;
1486 break;
1487 case XML_INITIALIZED:
1488 case XML_PARSING:
1489 result = XML_STATUS_OK;
1490 if (isFinal) {
1491 parsing = XML_FINISHED;
1492 return result;
1493 }
1494 }
1495 }
1496
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001497 XmlUpdatePosition(encoding, positionPtr, end, &position);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001498 positionPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001499 nLeftOver = s + len - end;
1500 if (nLeftOver) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001501 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1502 /* FIXME avoid integer overflow */
1503 char *temp;
1504 temp = (buffer == NULL
1505 ? (char *)MALLOC(len * 2)
1506 : (char *)REALLOC(buffer, len * 2));
1507 if (temp == NULL) {
1508 errorCode = XML_ERROR_NO_MEMORY;
1509 return XML_STATUS_ERROR;
1510 }
1511 buffer = temp;
1512 if (!buffer) {
1513 errorCode = XML_ERROR_NO_MEMORY;
1514 eventPtr = eventEndPtr = NULL;
1515 processor = errorProcessor;
1516 return XML_STATUS_ERROR;
1517 }
1518 bufferLim = buffer + len * 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001519 }
1520 memcpy(buffer, end, nLeftOver);
1521 bufferPtr = buffer;
1522 bufferEnd = buffer + nLeftOver;
1523 }
Fred Drake31d485c2004-08-03 07:06:22 +00001524 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001525 }
1526#endif /* not defined XML_CONTEXT_BYTES */
1527 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001528 void *buff = XML_GetBuffer(parser, len);
1529 if (buff == NULL)
1530 return XML_STATUS_ERROR;
1531 else {
1532 memcpy(buff, s, len);
1533 return XML_ParseBuffer(parser, len, isFinal);
1534 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001535 }
1536}
1537
Fred Drake08317ae2003-10-21 15:38:55 +00001538enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001539XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001540{
Fred Drake31d485c2004-08-03 07:06:22 +00001541 const char *start;
Neal Norwitz52ca0dd2006-01-07 21:21:16 +00001542 enum XML_Status result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001543
1544 switch (parsing) {
1545 case XML_SUSPENDED:
1546 errorCode = XML_ERROR_SUSPENDED;
1547 return XML_STATUS_ERROR;
1548 case XML_FINISHED:
1549 errorCode = XML_ERROR_FINISHED;
1550 return XML_STATUS_ERROR;
1551 default:
1552 parsing = XML_PARSING;
1553 }
1554
1555 start = bufferPtr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001556 positionPtr = start;
1557 bufferEnd += len;
Fred Drake31d485c2004-08-03 07:06:22 +00001558 parseEndPtr = bufferEnd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001559 parseEndByteIndex += len;
Fred Drake31d485c2004-08-03 07:06:22 +00001560 finalBuffer = (XML_Bool)isFinal;
1561
1562 errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1563
1564 if (errorCode != XML_ERROR_NONE) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001565 eventEndPtr = eventPtr;
1566 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001567 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001568 }
Fred Drake31d485c2004-08-03 07:06:22 +00001569 else {
1570 switch (parsing) {
1571 case XML_SUSPENDED:
1572 result = XML_STATUS_SUSPENDED;
1573 break;
1574 case XML_INITIALIZED:
1575 case XML_PARSING:
1576 if (isFinal) {
1577 parsing = XML_FINISHED;
1578 return result;
1579 }
1580 default: ; /* should not happen */
1581 }
1582 }
1583
1584 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1585 positionPtr = bufferPtr;
1586 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001587}
1588
Fred Drake08317ae2003-10-21 15:38:55 +00001589void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001590XML_GetBuffer(XML_Parser parser, int len)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001591{
Fred Drake31d485c2004-08-03 07:06:22 +00001592 switch (parsing) {
1593 case XML_SUSPENDED:
1594 errorCode = XML_ERROR_SUSPENDED;
1595 return NULL;
1596 case XML_FINISHED:
1597 errorCode = XML_ERROR_FINISHED;
1598 return NULL;
1599 default: ;
1600 }
1601
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001602 if (len > bufferLim - bufferEnd) {
1603 /* FIXME avoid integer overflow */
1604 int neededSize = len + (bufferEnd - bufferPtr);
1605#ifdef XML_CONTEXT_BYTES
1606 int keep = bufferPtr - buffer;
1607
1608 if (keep > XML_CONTEXT_BYTES)
1609 keep = XML_CONTEXT_BYTES;
1610 neededSize += keep;
1611#endif /* defined XML_CONTEXT_BYTES */
1612 if (neededSize <= bufferLim - buffer) {
1613#ifdef XML_CONTEXT_BYTES
1614 if (keep < bufferPtr - buffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001615 int offset = (bufferPtr - buffer) - keep;
1616 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1617 bufferEnd -= offset;
1618 bufferPtr -= offset;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001619 }
1620#else
1621 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1622 bufferEnd = buffer + (bufferEnd - bufferPtr);
1623 bufferPtr = buffer;
1624#endif /* not defined XML_CONTEXT_BYTES */
1625 }
1626 else {
1627 char *newBuf;
1628 int bufferSize = bufferLim - bufferPtr;
1629 if (bufferSize == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001630 bufferSize = INIT_BUFFER_SIZE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001631 do {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001632 bufferSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001633 } while (bufferSize < neededSize);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001634 newBuf = (char *)MALLOC(bufferSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001635 if (newBuf == 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001636 errorCode = XML_ERROR_NO_MEMORY;
1637 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001638 }
1639 bufferLim = newBuf + bufferSize;
1640#ifdef XML_CONTEXT_BYTES
1641 if (bufferPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001642 int keep = bufferPtr - buffer;
1643 if (keep > XML_CONTEXT_BYTES)
1644 keep = XML_CONTEXT_BYTES;
1645 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1646 FREE(buffer);
1647 buffer = newBuf;
1648 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1649 bufferPtr = buffer + keep;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001650 }
1651 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001652 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1653 bufferPtr = buffer = newBuf;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001654 }
1655#else
1656 if (bufferPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001657 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1658 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001659 }
1660 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1661 bufferPtr = buffer = newBuf;
1662#endif /* not defined XML_CONTEXT_BYTES */
1663 }
1664 }
1665 return bufferEnd;
1666}
1667
Fred Drake31d485c2004-08-03 07:06:22 +00001668enum XML_Status XMLCALL
1669XML_StopParser(XML_Parser parser, XML_Bool resumable)
1670{
1671 switch (parsing) {
1672 case XML_SUSPENDED:
1673 if (resumable) {
1674 errorCode = XML_ERROR_SUSPENDED;
1675 return XML_STATUS_ERROR;
1676 }
1677 parsing = XML_FINISHED;
1678 break;
1679 case XML_FINISHED:
1680 errorCode = XML_ERROR_FINISHED;
1681 return XML_STATUS_ERROR;
1682 default:
1683 if (resumable) {
1684#ifdef XML_DTD
1685 if (isParamEntity) {
1686 errorCode = XML_ERROR_SUSPEND_PE;
1687 return XML_STATUS_ERROR;
1688 }
1689#endif
1690 parsing = XML_SUSPENDED;
1691 }
1692 else
1693 parsing = XML_FINISHED;
1694 }
1695 return XML_STATUS_OK;
1696}
1697
1698enum XML_Status XMLCALL
1699XML_ResumeParser(XML_Parser parser)
1700{
Neal Norwitz52ca0dd2006-01-07 21:21:16 +00001701 enum XML_Status result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001702
1703 if (parsing != XML_SUSPENDED) {
1704 errorCode = XML_ERROR_NOT_SUSPENDED;
1705 return XML_STATUS_ERROR;
1706 }
1707 parsing = XML_PARSING;
1708
1709 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1710
1711 if (errorCode != XML_ERROR_NONE) {
1712 eventEndPtr = eventPtr;
1713 processor = errorProcessor;
1714 return XML_STATUS_ERROR;
1715 }
1716 else {
1717 switch (parsing) {
1718 case XML_SUSPENDED:
1719 result = XML_STATUS_SUSPENDED;
1720 break;
1721 case XML_INITIALIZED:
1722 case XML_PARSING:
1723 if (finalBuffer) {
1724 parsing = XML_FINISHED;
1725 return result;
1726 }
1727 default: ;
1728 }
1729 }
1730
1731 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1732 positionPtr = bufferPtr;
1733 return result;
1734}
1735
1736void XMLCALL
1737XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1738{
1739 assert(status != NULL);
1740 *status = parser->m_parsingStatus;
1741}
1742
Fred Drake08317ae2003-10-21 15:38:55 +00001743enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001744XML_GetErrorCode(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001745{
1746 return errorCode;
1747}
1748
Fred Drake08317ae2003-10-21 15:38:55 +00001749long XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001750XML_GetCurrentByteIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001751{
1752 if (eventPtr)
1753 return parseEndByteIndex - (parseEndPtr - eventPtr);
1754 return -1;
1755}
1756
Fred Drake08317ae2003-10-21 15:38:55 +00001757int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001758XML_GetCurrentByteCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001759{
1760 if (eventEndPtr && eventPtr)
1761 return eventEndPtr - eventPtr;
1762 return 0;
1763}
1764
Fred Drake08317ae2003-10-21 15:38:55 +00001765const char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001766XML_GetInputContext(XML_Parser parser, int *offset, int *size)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001767{
1768#ifdef XML_CONTEXT_BYTES
1769 if (eventPtr && buffer) {
1770 *offset = eventPtr - buffer;
1771 *size = bufferEnd - buffer;
1772 return buffer;
1773 }
1774#endif /* defined XML_CONTEXT_BYTES */
1775 return (char *) 0;
1776}
1777
Fred Drake08317ae2003-10-21 15:38:55 +00001778int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001779XML_GetCurrentLineNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001780{
Fred Drake31d485c2004-08-03 07:06:22 +00001781 if (eventPtr && eventPtr >= positionPtr) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001782 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1783 positionPtr = eventPtr;
1784 }
1785 return position.lineNumber + 1;
1786}
1787
Fred Drake08317ae2003-10-21 15:38:55 +00001788int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001789XML_GetCurrentColumnNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001790{
Fred Drake31d485c2004-08-03 07:06:22 +00001791 if (eventPtr && eventPtr >= positionPtr) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001792 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1793 positionPtr = eventPtr;
1794 }
1795 return position.columnNumber;
1796}
1797
Fred Drake08317ae2003-10-21 15:38:55 +00001798void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001799XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1800{
1801 FREE(model);
1802}
1803
Fred Drake08317ae2003-10-21 15:38:55 +00001804void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001805XML_MemMalloc(XML_Parser parser, size_t size)
1806{
1807 return MALLOC(size);
1808}
1809
Fred Drake08317ae2003-10-21 15:38:55 +00001810void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001811XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1812{
1813 return REALLOC(ptr, size);
1814}
1815
Fred Drake08317ae2003-10-21 15:38:55 +00001816void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001817XML_MemFree(XML_Parser parser, void *ptr)
1818{
1819 FREE(ptr);
1820}
1821
Fred Drake08317ae2003-10-21 15:38:55 +00001822void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001823XML_DefaultCurrent(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001824{
1825 if (defaultHandler) {
1826 if (openInternalEntities)
1827 reportDefault(parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001828 internalEncoding,
1829 openInternalEntities->internalEventPtr,
1830 openInternalEntities->internalEventEndPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001831 else
1832 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1833 }
1834}
1835
Fred Drake08317ae2003-10-21 15:38:55 +00001836const XML_LChar * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001837XML_ErrorString(enum XML_Error code)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001838{
1839 static const XML_LChar *message[] = {
1840 0,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001841 XML_L("out of memory"),
1842 XML_L("syntax error"),
1843 XML_L("no element found"),
1844 XML_L("not well-formed (invalid token)"),
1845 XML_L("unclosed token"),
1846 XML_L("partial character"),
1847 XML_L("mismatched tag"),
1848 XML_L("duplicate attribute"),
1849 XML_L("junk after document element"),
1850 XML_L("illegal parameter entity reference"),
1851 XML_L("undefined entity"),
1852 XML_L("recursive entity reference"),
1853 XML_L("asynchronous entity"),
1854 XML_L("reference to invalid character number"),
1855 XML_L("reference to binary entity"),
1856 XML_L("reference to external entity in attribute"),
1857 XML_L("xml declaration not at start of external entity"),
1858 XML_L("unknown encoding"),
1859 XML_L("encoding specified in XML declaration is incorrect"),
1860 XML_L("unclosed CDATA section"),
1861 XML_L("error in processing external entity reference"),
1862 XML_L("document is not standalone"),
1863 XML_L("unexpected parser state - please send a bug report"),
1864 XML_L("entity declared in parameter entity"),
1865 XML_L("requested feature requires XML_DTD support in Expat"),
Fred Drake08317ae2003-10-21 15:38:55 +00001866 XML_L("cannot change setting once parsing has begun"),
Fred Drake31d485c2004-08-03 07:06:22 +00001867 XML_L("unbound prefix"),
1868 XML_L("must not undeclare prefix"),
1869 XML_L("incomplete markup in parameter entity"),
1870 XML_L("XML declaration not well-formed"),
1871 XML_L("text declaration not well-formed"),
1872 XML_L("illegal character(s) in public id"),
1873 XML_L("parser suspended"),
1874 XML_L("parser not suspended"),
1875 XML_L("parsing aborted"),
1876 XML_L("parsing finished"),
1877 XML_L("cannot suspend in external parameter entity")
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001878 };
1879 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1880 return message[code];
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001881 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001882}
1883
Fred Drake08317ae2003-10-21 15:38:55 +00001884const XML_LChar * XMLCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001885XML_ExpatVersion(void) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001886
1887 /* V1 is used to string-ize the version number. However, it would
1888 string-ize the actual version macro *names* unless we get them
1889 substituted before being passed to V1. CPP is defined to expand
1890 a macro, then rescan for more expansions. Thus, we use V2 to expand
1891 the version macros, then CPP will expand the resulting V1() macro
1892 with the correct numerals. */
1893 /* ### I'm assuming cpp is portable in this respect... */
1894
1895#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1896#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1897
1898 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1899
1900#undef V1
1901#undef V2
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001902}
1903
Fred Drake08317ae2003-10-21 15:38:55 +00001904XML_Expat_Version XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001905XML_ExpatVersionInfo(void)
1906{
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001907 XML_Expat_Version version;
1908
1909 version.major = XML_MAJOR_VERSION;
1910 version.minor = XML_MINOR_VERSION;
1911 version.micro = XML_MICRO_VERSION;
1912
1913 return version;
1914}
1915
Fred Drake08317ae2003-10-21 15:38:55 +00001916const XML_Feature * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001917XML_GetFeatureList(void)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001918{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001919 static XML_Feature features[] = {
Fred Drake08317ae2003-10-21 15:38:55 +00001920 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), 0},
1921 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001922#ifdef XML_UNICODE
Fred Drake08317ae2003-10-21 15:38:55 +00001923 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001924#endif
1925#ifdef XML_UNICODE_WCHAR_T
Fred Drake08317ae2003-10-21 15:38:55 +00001926 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001927#endif
1928#ifdef XML_DTD
Fred Drake08317ae2003-10-21 15:38:55 +00001929 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001930#endif
1931#ifdef XML_CONTEXT_BYTES
1932 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
1933 XML_CONTEXT_BYTES},
1934#endif
1935#ifdef XML_MIN_SIZE
Fred Drake08317ae2003-10-21 15:38:55 +00001936 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001937#endif
Fred Drake08317ae2003-10-21 15:38:55 +00001938 {XML_FEATURE_END, NULL, 0}
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001939 };
1940
1941 features[0].value = sizeof(XML_Char);
1942 features[1].value = sizeof(XML_LChar);
1943 return features;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001944}
1945
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001946/* Initially tag->rawName always points into the parse buffer;
1947 for those TAG instances opened while the current parse buffer was
1948 processed, and not yet closed, we need to store tag->rawName in a more
1949 permanent location, since the parse buffer is about to be discarded.
1950*/
1951static XML_Bool
1952storeRawNames(XML_Parser parser)
1953{
1954 TAG *tag = tagStack;
1955 while (tag) {
1956 int bufSize;
1957 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
1958 char *rawNameBuf = tag->buf + nameLen;
1959 /* Stop if already stored. Since tagStack is a stack, we can stop
1960 at the first entry that has already been copied; everything
1961 below it in the stack is already been accounted for in a
1962 previous call to this function.
1963 */
1964 if (tag->rawName == rawNameBuf)
1965 break;
1966 /* For re-use purposes we need to ensure that the
1967 size of tag->buf is a multiple of sizeof(XML_Char).
1968 */
1969 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
1970 if (bufSize > tag->bufEnd - tag->buf) {
1971 char *temp = (char *)REALLOC(tag->buf, bufSize);
1972 if (temp == NULL)
1973 return XML_FALSE;
1974 /* if tag->name.str points to tag->buf (only when namespace
1975 processing is off) then we have to update it
1976 */
1977 if (tag->name.str == (XML_Char *)tag->buf)
1978 tag->name.str = (XML_Char *)temp;
1979 /* if tag->name.localPart is set (when namespace processing is on)
1980 then update it as well, since it will always point into tag->buf
1981 */
1982 if (tag->name.localPart)
1983 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
1984 (XML_Char *)tag->buf);
1985 tag->buf = temp;
1986 tag->bufEnd = temp + bufSize;
1987 rawNameBuf = temp + nameLen;
1988 }
1989 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
1990 tag->rawName = rawNameBuf;
1991 tag = tag->parent;
1992 }
1993 return XML_TRUE;
1994}
1995
1996static enum XML_Error PTRCALL
1997contentProcessor(XML_Parser parser,
1998 const char *start,
1999 const char *end,
2000 const char **endPtr)
2001{
Fred Drake31d485c2004-08-03 07:06:22 +00002002 enum XML_Error result = doContent(parser, 0, encoding, start, end,
2003 endPtr, (XML_Bool)!finalBuffer);
2004 if (result == XML_ERROR_NONE) {
2005 if (!storeRawNames(parser))
2006 return XML_ERROR_NO_MEMORY;
2007 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002008 return result;
2009}
2010
2011static enum XML_Error PTRCALL
2012externalEntityInitProcessor(XML_Parser parser,
2013 const char *start,
2014 const char *end,
2015 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002016{
2017 enum XML_Error result = initializeEncoding(parser);
2018 if (result != XML_ERROR_NONE)
2019 return result;
2020 processor = externalEntityInitProcessor2;
2021 return externalEntityInitProcessor2(parser, start, end, endPtr);
2022}
2023
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002024static enum XML_Error PTRCALL
2025externalEntityInitProcessor2(XML_Parser parser,
2026 const char *start,
2027 const char *end,
2028 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002029{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002030 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002031 int tok = XmlContentTok(encoding, start, end, &next);
2032 switch (tok) {
2033 case XML_TOK_BOM:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002034 /* If we are at the end of the buffer, this would cause the next stage,
2035 i.e. externalEntityInitProcessor3, to pass control directly to
2036 doContent (by detecting XML_TOK_NONE) without processing any xml text
2037 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2038 */
Fred Drake31d485c2004-08-03 07:06:22 +00002039 if (next == end && !finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002040 *endPtr = next;
2041 return XML_ERROR_NONE;
2042 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002043 start = next;
2044 break;
2045 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00002046 if (!finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002047 *endPtr = start;
2048 return XML_ERROR_NONE;
2049 }
2050 eventPtr = start;
2051 return XML_ERROR_UNCLOSED_TOKEN;
2052 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00002053 if (!finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002054 *endPtr = start;
2055 return XML_ERROR_NONE;
2056 }
2057 eventPtr = start;
2058 return XML_ERROR_PARTIAL_CHAR;
2059 }
2060 processor = externalEntityInitProcessor3;
2061 return externalEntityInitProcessor3(parser, start, end, endPtr);
2062}
2063
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002064static enum XML_Error PTRCALL
2065externalEntityInitProcessor3(XML_Parser parser,
2066 const char *start,
2067 const char *end,
2068 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002069{
Fred Drake31d485c2004-08-03 07:06:22 +00002070 int tok;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002071 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Fred Drake31d485c2004-08-03 07:06:22 +00002072 eventPtr = start;
2073 tok = XmlContentTok(encoding, start, end, &next);
2074 eventEndPtr = next;
2075
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002076 switch (tok) {
2077 case XML_TOK_XML_DECL:
2078 {
Fred Drake31d485c2004-08-03 07:06:22 +00002079 enum XML_Error result;
2080 result = processXmlDecl(parser, 1, start, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002081 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002082 return result;
Fred Drake31d485c2004-08-03 07:06:22 +00002083 switch (parsing) {
2084 case XML_SUSPENDED:
2085 *endPtr = next;
2086 return XML_ERROR_NONE;
2087 case XML_FINISHED:
2088 return XML_ERROR_ABORTED;
2089 default:
2090 start = next;
2091 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002092 }
2093 break;
2094 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00002095 if (!finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002096 *endPtr = start;
2097 return XML_ERROR_NONE;
2098 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002099 return XML_ERROR_UNCLOSED_TOKEN;
2100 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00002101 if (!finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002102 *endPtr = start;
2103 return XML_ERROR_NONE;
2104 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002105 return XML_ERROR_PARTIAL_CHAR;
2106 }
2107 processor = externalEntityContentProcessor;
2108 tagLevel = 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002109 return externalEntityContentProcessor(parser, start, end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002110}
2111
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002112static enum XML_Error PTRCALL
2113externalEntityContentProcessor(XML_Parser parser,
2114 const char *start,
2115 const char *end,
2116 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002117{
Fred Drake31d485c2004-08-03 07:06:22 +00002118 enum XML_Error result = doContent(parser, 1, encoding, start, end,
2119 endPtr, (XML_Bool)!finalBuffer);
2120 if (result == XML_ERROR_NONE) {
2121 if (!storeRawNames(parser))
2122 return XML_ERROR_NO_MEMORY;
2123 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002124 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002125}
2126
2127static enum XML_Error
2128doContent(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002129 int startTagLevel,
2130 const ENCODING *enc,
2131 const char *s,
2132 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00002133 const char **nextPtr,
2134 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002135{
Fred Drake31d485c2004-08-03 07:06:22 +00002136 /* save one level of indirection */
2137 DTD * const dtd = _dtd;
2138
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002139 const char **eventPP;
2140 const char **eventEndPP;
2141 if (enc == encoding) {
2142 eventPP = &eventPtr;
2143 eventEndPP = &eventEndPtr;
2144 }
2145 else {
2146 eventPP = &(openInternalEntities->internalEventPtr);
2147 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2148 }
2149 *eventPP = s;
Fred Drake31d485c2004-08-03 07:06:22 +00002150
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002151 for (;;) {
2152 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2153 int tok = XmlContentTok(enc, s, end, &next);
2154 *eventEndPP = next;
2155 switch (tok) {
2156 case XML_TOK_TRAILING_CR:
Fred Drake31d485c2004-08-03 07:06:22 +00002157 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002158 *nextPtr = s;
2159 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002160 }
2161 *eventEndPP = end;
2162 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002163 XML_Char c = 0xA;
2164 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002165 }
2166 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002167 reportDefault(parser, enc, s, end);
Fred Drake31d485c2004-08-03 07:06:22 +00002168 /* We are at the end of the final buffer, should we check for
2169 XML_SUSPENDED, XML_FINISHED?
2170 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002171 if (startTagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002172 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002173 if (tagLevel != startTagLevel)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002174 return XML_ERROR_ASYNC_ENTITY;
Fred Drake31d485c2004-08-03 07:06:22 +00002175 *nextPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002176 return XML_ERROR_NONE;
2177 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00002178 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002179 *nextPtr = s;
2180 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002181 }
2182 if (startTagLevel > 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002183 if (tagLevel != startTagLevel)
2184 return XML_ERROR_ASYNC_ENTITY;
Fred Drake31d485c2004-08-03 07:06:22 +00002185 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002186 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002187 }
2188 return XML_ERROR_NO_ELEMENTS;
2189 case XML_TOK_INVALID:
2190 *eventPP = next;
2191 return XML_ERROR_INVALID_TOKEN;
2192 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00002193 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002194 *nextPtr = s;
2195 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002196 }
2197 return XML_ERROR_UNCLOSED_TOKEN;
2198 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00002199 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002200 *nextPtr = s;
2201 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002202 }
2203 return XML_ERROR_PARTIAL_CHAR;
2204 case XML_TOK_ENTITY_REF:
2205 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002206 const XML_Char *name;
2207 ENTITY *entity;
2208 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2209 s + enc->minBytesPerChar,
2210 next - enc->minBytesPerChar);
2211 if (ch) {
2212 if (characterDataHandler)
2213 characterDataHandler(handlerArg, &ch, 1);
2214 else if (defaultHandler)
2215 reportDefault(parser, enc, s, next);
2216 break;
2217 }
2218 name = poolStoreString(&dtd->pool, enc,
2219 s + enc->minBytesPerChar,
2220 next - enc->minBytesPerChar);
2221 if (!name)
2222 return XML_ERROR_NO_MEMORY;
2223 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
2224 poolDiscard(&dtd->pool);
2225 /* First, determine if a check for an existing declaration is needed;
2226 if yes, check that the entity exists, and that it is internal,
2227 otherwise call the skipped entity or default handler.
2228 */
2229 if (!dtd->hasParamEntityRefs || dtd->standalone) {
2230 if (!entity)
2231 return XML_ERROR_UNDEFINED_ENTITY;
2232 else if (!entity->is_internal)
2233 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2234 }
2235 else if (!entity) {
2236 if (skippedEntityHandler)
2237 skippedEntityHandler(handlerArg, name, 0);
2238 else if (defaultHandler)
2239 reportDefault(parser, enc, s, next);
2240 break;
2241 }
2242 if (entity->open)
2243 return XML_ERROR_RECURSIVE_ENTITY_REF;
2244 if (entity->notation)
2245 return XML_ERROR_BINARY_ENTITY_REF;
2246 if (entity->textPtr) {
2247 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002248 if (!defaultExpandInternalEntities) {
2249 if (skippedEntityHandler)
2250 skippedEntityHandler(handlerArg, entity->name, 0);
2251 else if (defaultHandler)
2252 reportDefault(parser, enc, s, next);
2253 break;
2254 }
Fred Drake31d485c2004-08-03 07:06:22 +00002255 result = processInternalEntity(parser, entity, XML_FALSE);
2256 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002257 return result;
2258 }
2259 else if (externalEntityRefHandler) {
2260 const XML_Char *context;
2261 entity->open = XML_TRUE;
2262 context = getContext(parser);
2263 entity->open = XML_FALSE;
2264 if (!context)
2265 return XML_ERROR_NO_MEMORY;
Fred Drake31d485c2004-08-03 07:06:22 +00002266 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002267 context,
2268 entity->base,
2269 entity->systemId,
2270 entity->publicId))
2271 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2272 poolDiscard(&tempPool);
2273 }
2274 else if (defaultHandler)
2275 reportDefault(parser, enc, s, next);
2276 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002277 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002278 case XML_TOK_START_TAG_NO_ATTS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002279 /* fall through */
2280 case XML_TOK_START_TAG_WITH_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002281 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002282 TAG *tag;
2283 enum XML_Error result;
2284 XML_Char *toPtr;
2285 if (freeTagList) {
2286 tag = freeTagList;
2287 freeTagList = freeTagList->parent;
2288 }
2289 else {
2290 tag = (TAG *)MALLOC(sizeof(TAG));
2291 if (!tag)
2292 return XML_ERROR_NO_MEMORY;
2293 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2294 if (!tag->buf) {
2295 FREE(tag);
2296 return XML_ERROR_NO_MEMORY;
2297 }
2298 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2299 }
2300 tag->bindings = NULL;
2301 tag->parent = tagStack;
2302 tagStack = tag;
2303 tag->name.localPart = NULL;
2304 tag->name.prefix = NULL;
2305 tag->rawName = s + enc->minBytesPerChar;
2306 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2307 ++tagLevel;
2308 {
2309 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2310 const char *fromPtr = tag->rawName;
2311 toPtr = (XML_Char *)tag->buf;
2312 for (;;) {
2313 int bufSize;
2314 int convLen;
2315 XmlConvert(enc,
2316 &fromPtr, rawNameEnd,
2317 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2318 convLen = toPtr - (XML_Char *)tag->buf;
2319 if (fromPtr == rawNameEnd) {
2320 tag->name.strLen = convLen;
2321 break;
2322 }
2323 bufSize = (tag->bufEnd - tag->buf) << 1;
2324 {
2325 char *temp = (char *)REALLOC(tag->buf, bufSize);
2326 if (temp == NULL)
2327 return XML_ERROR_NO_MEMORY;
2328 tag->buf = temp;
2329 tag->bufEnd = temp + bufSize;
2330 toPtr = (XML_Char *)temp + convLen;
2331 }
2332 }
2333 }
2334 tag->name.str = (XML_Char *)tag->buf;
2335 *toPtr = XML_T('\0');
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002336 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2337 if (result)
2338 return result;
2339 if (startElementHandler)
2340 startElementHandler(handlerArg, tag->name.str,
2341 (const XML_Char **)atts);
2342 else if (defaultHandler)
2343 reportDefault(parser, enc, s, next);
2344 poolClear(&tempPool);
2345 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002346 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002347 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002348 /* fall through */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002349 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2350 {
2351 const char *rawName = s + enc->minBytesPerChar;
2352 enum XML_Error result;
2353 BINDING *bindings = NULL;
2354 XML_Bool noElmHandlers = XML_TRUE;
2355 TAG_NAME name;
2356 name.str = poolStoreString(&tempPool, enc, rawName,
2357 rawName + XmlNameLength(enc, rawName));
2358 if (!name.str)
2359 return XML_ERROR_NO_MEMORY;
2360 poolFinish(&tempPool);
Fred Drake4faea012003-01-28 06:42:40 +00002361 result = storeAtts(parser, enc, s, &name, &bindings);
2362 if (result)
2363 return result;
2364 poolFinish(&tempPool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002365 if (startElementHandler) {
2366 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2367 noElmHandlers = XML_FALSE;
2368 }
2369 if (endElementHandler) {
2370 if (startElementHandler)
2371 *eventPP = *eventEndPP;
2372 endElementHandler(handlerArg, name.str);
2373 noElmHandlers = XML_FALSE;
2374 }
2375 if (noElmHandlers && defaultHandler)
2376 reportDefault(parser, enc, s, next);
2377 poolClear(&tempPool);
2378 while (bindings) {
2379 BINDING *b = bindings;
2380 if (endNamespaceDeclHandler)
2381 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2382 bindings = bindings->nextTagBinding;
2383 b->nextTagBinding = freeBindingList;
2384 freeBindingList = b;
2385 b->prefix->binding = b->prevPrefixBinding;
2386 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002387 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002388 if (tagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002389 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002390 break;
2391 case XML_TOK_END_TAG:
2392 if (tagLevel == startTagLevel)
2393 return XML_ERROR_ASYNC_ENTITY;
2394 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002395 int len;
2396 const char *rawName;
2397 TAG *tag = tagStack;
2398 tagStack = tag->parent;
2399 tag->parent = freeTagList;
2400 freeTagList = tag;
2401 rawName = s + enc->minBytesPerChar*2;
2402 len = XmlNameLength(enc, rawName);
2403 if (len != tag->rawNameLength
2404 || memcmp(tag->rawName, rawName, len) != 0) {
2405 *eventPP = rawName;
2406 return XML_ERROR_TAG_MISMATCH;
2407 }
2408 --tagLevel;
2409 if (endElementHandler) {
2410 const XML_Char *localPart;
2411 const XML_Char *prefix;
2412 XML_Char *uri;
2413 localPart = tag->name.localPart;
2414 if (ns && localPart) {
2415 /* localPart and prefix may have been overwritten in
2416 tag->name.str, since this points to the binding->uri
2417 buffer which gets re-used; so we have to add them again
2418 */
2419 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2420 /* don't need to check for space - already done in storeAtts() */
2421 while (*localPart) *uri++ = *localPart++;
2422 prefix = (XML_Char *)tag->name.prefix;
2423 if (ns_triplets && prefix) {
2424 *uri++ = namespaceSeparator;
2425 while (*prefix) *uri++ = *prefix++;
2426 }
2427 *uri = XML_T('\0');
2428 }
2429 endElementHandler(handlerArg, tag->name.str);
2430 }
2431 else if (defaultHandler)
2432 reportDefault(parser, enc, s, next);
2433 while (tag->bindings) {
2434 BINDING *b = tag->bindings;
2435 if (endNamespaceDeclHandler)
2436 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2437 tag->bindings = tag->bindings->nextTagBinding;
2438 b->nextTagBinding = freeBindingList;
2439 freeBindingList = b;
2440 b->prefix->binding = b->prevPrefixBinding;
2441 }
2442 if (tagLevel == 0)
2443 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002444 }
2445 break;
2446 case XML_TOK_CHAR_REF:
2447 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002448 int n = XmlCharRefNumber(enc, s);
2449 if (n < 0)
2450 return XML_ERROR_BAD_CHAR_REF;
2451 if (characterDataHandler) {
2452 XML_Char buf[XML_ENCODE_MAX];
2453 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2454 }
2455 else if (defaultHandler)
2456 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002457 }
2458 break;
2459 case XML_TOK_XML_DECL:
2460 return XML_ERROR_MISPLACED_XML_PI;
2461 case XML_TOK_DATA_NEWLINE:
2462 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002463 XML_Char c = 0xA;
2464 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002465 }
2466 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002467 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002468 break;
2469 case XML_TOK_CDATA_SECT_OPEN:
2470 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002471 enum XML_Error result;
2472 if (startCdataSectionHandler)
2473 startCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002474#if 0
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002475 /* Suppose you doing a transformation on a document that involves
2476 changing only the character data. You set up a defaultHandler
2477 and a characterDataHandler. The defaultHandler simply copies
2478 characters through. The characterDataHandler does the
2479 transformation and writes the characters out escaping them as
2480 necessary. This case will fail to work if we leave out the
2481 following two lines (because & and < inside CDATA sections will
2482 be incorrectly escaped).
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002483
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002484 However, now we have a start/endCdataSectionHandler, so it seems
2485 easier to let the user deal with this.
2486 */
2487 else if (characterDataHandler)
2488 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002489#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002490 else if (defaultHandler)
2491 reportDefault(parser, enc, s, next);
Fred Drake31d485c2004-08-03 07:06:22 +00002492 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2493 if (result != XML_ERROR_NONE)
2494 return result;
2495 else if (!next) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002496 processor = cdataSectionProcessor;
2497 return result;
2498 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002499 }
2500 break;
2501 case XML_TOK_TRAILING_RSQB:
Fred Drake31d485c2004-08-03 07:06:22 +00002502 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002503 *nextPtr = s;
2504 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002505 }
2506 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002507 if (MUST_CONVERT(enc, s)) {
2508 ICHAR *dataPtr = (ICHAR *)dataBuf;
2509 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2510 characterDataHandler(handlerArg, dataBuf,
2511 dataPtr - (ICHAR *)dataBuf);
2512 }
2513 else
2514 characterDataHandler(handlerArg,
2515 (XML_Char *)s,
2516 (XML_Char *)end - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002517 }
2518 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002519 reportDefault(parser, enc, s, end);
Fred Drake31d485c2004-08-03 07:06:22 +00002520 /* We are at the end of the final buffer, should we check for
2521 XML_SUSPENDED, XML_FINISHED?
2522 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002523 if (startTagLevel == 0) {
2524 *eventPP = end;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002525 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002526 }
2527 if (tagLevel != startTagLevel) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002528 *eventPP = end;
2529 return XML_ERROR_ASYNC_ENTITY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002530 }
Fred Drake31d485c2004-08-03 07:06:22 +00002531 *nextPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002532 return XML_ERROR_NONE;
2533 case XML_TOK_DATA_CHARS:
2534 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002535 if (MUST_CONVERT(enc, s)) {
2536 for (;;) {
2537 ICHAR *dataPtr = (ICHAR *)dataBuf;
2538 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2539 *eventEndPP = s;
2540 characterDataHandler(handlerArg, dataBuf,
2541 dataPtr - (ICHAR *)dataBuf);
2542 if (s == next)
2543 break;
2544 *eventPP = s;
2545 }
2546 }
2547 else
2548 characterDataHandler(handlerArg,
2549 (XML_Char *)s,
2550 (XML_Char *)next - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002551 }
2552 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002553 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002554 break;
2555 case XML_TOK_PI:
2556 if (!reportProcessingInstruction(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002557 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002558 break;
2559 case XML_TOK_COMMENT:
2560 if (!reportComment(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002561 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002562 break;
2563 default:
2564 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002565 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002566 break;
2567 }
2568 *eventPP = s = next;
Fred Drake31d485c2004-08-03 07:06:22 +00002569 switch (parsing) {
2570 case XML_SUSPENDED:
2571 *nextPtr = next;
2572 return XML_ERROR_NONE;
2573 case XML_FINISHED:
2574 return XML_ERROR_ABORTED;
2575 default: ;
2576 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002577 }
2578 /* not reached */
2579}
2580
Fred Drake4faea012003-01-28 06:42:40 +00002581/* Precondition: all arguments must be non-NULL;
2582 Purpose:
2583 - normalize attributes
2584 - check attributes for well-formedness
2585 - generate namespace aware attribute names (URI, prefix)
2586 - build list of attributes for startElementHandler
2587 - default attributes
2588 - process namespace declarations (check and report them)
2589 - generate namespace aware element name (URI, prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002590*/
2591static enum XML_Error
2592storeAtts(XML_Parser parser, const ENCODING *enc,
2593 const char *attStr, TAG_NAME *tagNamePtr,
2594 BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002595{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002596 DTD * const dtd = _dtd; /* save one level of indirection */
Fred Drake08317ae2003-10-21 15:38:55 +00002597 ELEMENT_TYPE *elementType;
2598 int nDefaultAtts;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002599 const XML_Char **appAtts; /* the attribute list for the application */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002600 int attIndex = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002601 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002602 int i;
2603 int n;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002604 XML_Char *uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002605 int nPrefixes = 0;
2606 BINDING *binding;
2607 const XML_Char *localPart;
2608
2609 /* lookup the element type name */
Fred Drake4faea012003-01-28 06:42:40 +00002610 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
2611 if (!elementType) {
2612 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2613 if (!name)
2614 return XML_ERROR_NO_MEMORY;
2615 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
2616 sizeof(ELEMENT_TYPE));
2617 if (!elementType)
2618 return XML_ERROR_NO_MEMORY;
2619 if (ns && !setElementTypePrefix(parser, elementType))
2620 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002621 }
Fred Drake4faea012003-01-28 06:42:40 +00002622 nDefaultAtts = elementType->nDefaultAtts;
2623
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002624 /* get the attributes from the tokenizer */
2625 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2626 if (n + nDefaultAtts > attsSize) {
2627 int oldAttsSize = attsSize;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002628 ATTRIBUTE *temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002629 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002630 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2631 if (temp == NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002632 return XML_ERROR_NO_MEMORY;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002633 atts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002634 if (n > oldAttsSize)
2635 XmlGetAttributes(enc, attStr, n, atts);
2636 }
Fred Drake4faea012003-01-28 06:42:40 +00002637
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002638 appAtts = (const XML_Char **)atts;
2639 for (i = 0; i < n; i++) {
2640 /* add the name and value to the attribute list */
2641 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002642 atts[i].name
2643 + XmlNameLength(enc, atts[i].name));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002644 if (!attId)
2645 return XML_ERROR_NO_MEMORY;
Fred Drake08317ae2003-10-21 15:38:55 +00002646 /* Detect duplicate attributes by their QNames. This does not work when
2647 namespace processing is turned on and different prefixes for the same
2648 namespace are used. For this case we have a check further down.
2649 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002650 if ((attId->name)[-1]) {
2651 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002652 eventPtr = atts[i].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002653 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2654 }
2655 (attId->name)[-1] = 1;
2656 appAtts[attIndex++] = attId->name;
2657 if (!atts[i].normalized) {
2658 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002659 XML_Bool isCdata = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002660
2661 /* figure out whether declared as other than CDATA */
2662 if (attId->maybeTokenized) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002663 int j;
2664 for (j = 0; j < nDefaultAtts; j++) {
2665 if (attId == elementType->defaultAtts[j].id) {
2666 isCdata = elementType->defaultAtts[j].isCdata;
2667 break;
2668 }
2669 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002670 }
2671
2672 /* normalize the attribute value */
2673 result = storeAttributeValue(parser, enc, isCdata,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002674 atts[i].valuePtr, atts[i].valueEnd,
2675 &tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002676 if (result)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002677 return result;
Fred Drake4faea012003-01-28 06:42:40 +00002678 appAtts[attIndex] = poolStart(&tempPool);
2679 poolFinish(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002680 }
Fred Drake4faea012003-01-28 06:42:40 +00002681 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002682 /* the value did not need normalizing */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002683 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2684 atts[i].valueEnd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002685 if (appAtts[attIndex] == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002686 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002687 poolFinish(&tempPool);
2688 }
2689 /* handle prefixed attribute names */
Fred Drake4faea012003-01-28 06:42:40 +00002690 if (attId->prefix) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002691 if (attId->xmlns) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002692 /* deal with namespace declarations here */
2693 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2694 appAtts[attIndex], bindingsPtr);
2695 if (result)
2696 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002697 --attIndex;
2698 }
2699 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002700 /* deal with other prefixed names later */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002701 attIndex++;
2702 nPrefixes++;
2703 (attId->name)[-1] = 2;
2704 }
2705 }
2706 else
2707 attIndex++;
2708 }
Fred Drake4faea012003-01-28 06:42:40 +00002709
2710 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2711 nSpecifiedAtts = attIndex;
2712 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2713 for (i = 0; i < attIndex; i += 2)
2714 if (appAtts[i] == elementType->idAtt->name) {
2715 idAttIndex = i;
2716 break;
2717 }
2718 }
2719 else
2720 idAttIndex = -1;
2721
2722 /* do attribute defaulting */
2723 for (i = 0; i < nDefaultAtts; i++) {
2724 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2725 if (!(da->id->name)[-1] && da->value) {
2726 if (da->id->prefix) {
2727 if (da->id->xmlns) {
2728 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2729 da->value, bindingsPtr);
2730 if (result)
2731 return result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002732 }
2733 else {
Fred Drake4faea012003-01-28 06:42:40 +00002734 (da->id->name)[-1] = 2;
2735 nPrefixes++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002736 appAtts[attIndex++] = da->id->name;
2737 appAtts[attIndex++] = da->value;
2738 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002739 }
Fred Drake4faea012003-01-28 06:42:40 +00002740 else {
2741 (da->id->name)[-1] = 1;
2742 appAtts[attIndex++] = da->id->name;
2743 appAtts[attIndex++] = da->value;
2744 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002745 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002746 }
Fred Drake4faea012003-01-28 06:42:40 +00002747 appAtts[attIndex] = 0;
2748
Fred Drake08317ae2003-10-21 15:38:55 +00002749 /* expand prefixed attribute names, check for duplicates,
2750 and clear flags that say whether attributes were specified */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002751 i = 0;
2752 if (nPrefixes) {
Fred Drake08317ae2003-10-21 15:38:55 +00002753 int j; /* hash table index */
2754 unsigned long version = nsAttsVersion;
2755 int nsAttsSize = (int)1 << nsAttsPower;
2756 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2757 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2758 NS_ATT *temp;
2759 /* hash table size must also be a power of 2 and >= 8 */
2760 while (nPrefixes >> nsAttsPower++);
2761 if (nsAttsPower < 3)
2762 nsAttsPower = 3;
2763 nsAttsSize = (int)1 << nsAttsPower;
2764 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2765 if (!temp)
2766 return XML_ERROR_NO_MEMORY;
2767 nsAtts = temp;
2768 version = 0; /* force re-initialization of nsAtts hash table */
2769 }
2770 /* using a version flag saves us from initializing nsAtts every time */
2771 if (!version) { /* initialize version flags when version wraps around */
2772 version = INIT_ATTS_VERSION;
2773 for (j = nsAttsSize; j != 0; )
2774 nsAtts[--j].version = version;
2775 }
2776 nsAttsVersion = --version;
2777
2778 /* expand prefixed names and check for duplicates */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002779 for (; i < attIndex; i += 2) {
Fred Drake08317ae2003-10-21 15:38:55 +00002780 const XML_Char *s = appAtts[i];
2781 if (s[-1] == 2) { /* prefixed */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002782 ATTRIBUTE_ID *id;
Fred Drake08317ae2003-10-21 15:38:55 +00002783 const BINDING *b;
2784 unsigned long uriHash = 0;
2785 ((XML_Char *)s)[-1] = 0; /* clear flag */
2786 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
2787 b = id->prefix->binding;
2788 if (!b)
2789 return XML_ERROR_UNBOUND_PREFIX;
2790
2791 /* as we expand the name we also calculate its hash value */
2792 for (j = 0; j < b->uriLen; j++) {
2793 const XML_Char c = b->uri[j];
2794 if (!poolAppendChar(&tempPool, c))
2795 return XML_ERROR_NO_MEMORY;
2796 uriHash = CHAR_HASH(uriHash, c);
2797 }
2798 while (*s++ != XML_T(':'))
2799 ;
2800 do { /* copies null terminator */
2801 const XML_Char c = *s;
2802 if (!poolAppendChar(&tempPool, *s))
2803 return XML_ERROR_NO_MEMORY;
2804 uriHash = CHAR_HASH(uriHash, c);
2805 } while (*s++);
2806
2807 { /* Check hash table for duplicate of expanded name (uriName).
2808 Derived from code in lookup(HASH_TABLE *table, ...).
2809 */
2810 unsigned char step = 0;
2811 unsigned long mask = nsAttsSize - 1;
2812 j = uriHash & mask; /* index into hash table */
2813 while (nsAtts[j].version == version) {
2814 /* for speed we compare stored hash values first */
2815 if (uriHash == nsAtts[j].hash) {
2816 const XML_Char *s1 = poolStart(&tempPool);
2817 const XML_Char *s2 = nsAtts[j].uriName;
2818 /* s1 is null terminated, but not s2 */
2819 for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2820 if (*s1 == 0)
2821 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2822 }
2823 if (!step)
2824 step = PROBE_STEP(uriHash, mask, nsAttsPower);
2825 j < step ? ( j += nsAttsSize - step) : (j -= step);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002826 }
Fred Drake08317ae2003-10-21 15:38:55 +00002827 }
2828
2829 if (ns_triplets) { /* append namespace separator and prefix */
2830 tempPool.ptr[-1] = namespaceSeparator;
2831 s = b->prefix->name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002832 do {
2833 if (!poolAppendChar(&tempPool, *s))
2834 return XML_ERROR_NO_MEMORY;
2835 } while (*s++);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002836 }
Fred Drake08317ae2003-10-21 15:38:55 +00002837
2838 /* store expanded name in attribute list */
2839 s = poolStart(&tempPool);
2840 poolFinish(&tempPool);
2841 appAtts[i] = s;
2842
2843 /* fill empty slot with new version, uriName and hash value */
2844 nsAtts[j].version = version;
2845 nsAtts[j].hash = uriHash;
2846 nsAtts[j].uriName = s;
2847
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002848 if (!--nPrefixes)
2849 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002850 }
Fred Drake08317ae2003-10-21 15:38:55 +00002851 else /* not prefixed */
2852 ((XML_Char *)s)[-1] = 0; /* clear flag */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002853 }
2854 }
Fred Drake08317ae2003-10-21 15:38:55 +00002855 /* clear flags for the remaining attributes */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002856 for (; i < attIndex; i += 2)
2857 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002858 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2859 binding->attId->name[-1] = 0;
Fred Drake4faea012003-01-28 06:42:40 +00002860
Fred Drake08317ae2003-10-21 15:38:55 +00002861 if (!ns)
2862 return XML_ERROR_NONE;
2863
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002864 /* expand the element type name */
2865 if (elementType->prefix) {
2866 binding = elementType->prefix->binding;
2867 if (!binding)
Fred Drake08317ae2003-10-21 15:38:55 +00002868 return XML_ERROR_UNBOUND_PREFIX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002869 localPart = tagNamePtr->str;
2870 while (*localPart++ != XML_T(':'))
2871 ;
2872 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002873 else if (dtd->defaultPrefix.binding) {
2874 binding = dtd->defaultPrefix.binding;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002875 localPart = tagNamePtr->str;
2876 }
2877 else
2878 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002879 prefixLen = 0;
Fred Drake08317ae2003-10-21 15:38:55 +00002880 if (ns_triplets && binding->prefix->name) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002881 for (; binding->prefix->name[prefixLen++];)
2882 ;
2883 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002884 tagNamePtr->localPart = localPart;
2885 tagNamePtr->uriLen = binding->uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002886 tagNamePtr->prefix = binding->prefix->name;
2887 tagNamePtr->prefixLen = prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002888 for (i = 0; localPart[i++];)
2889 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002890 n = i + binding->uriLen + prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002891 if (n > binding->uriAlloc) {
2892 TAG *p;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002893 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002894 if (!uri)
2895 return XML_ERROR_NO_MEMORY;
2896 binding->uriAlloc = n + EXPAND_SPARE;
2897 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2898 for (p = tagStack; p; p = p->parent)
2899 if (p->name.str == binding->uri)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002900 p->name.str = uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002901 FREE(binding->uri);
2902 binding->uri = uri;
2903 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002904 uri = binding->uri + binding->uriLen;
2905 memcpy(uri, localPart, i * sizeof(XML_Char));
2906 if (prefixLen) {
Fred Drake08317ae2003-10-21 15:38:55 +00002907 uri = uri + (i - 1);
2908 if (namespaceSeparator)
2909 *uri = namespaceSeparator;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002910 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2911 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002912 tagNamePtr->str = binding->uri;
2913 return XML_ERROR_NONE;
2914}
2915
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002916/* addBinding() overwrites the value of prefix->binding without checking.
2917 Therefore one must keep track of the old value outside of addBinding().
2918*/
2919static enum XML_Error
2920addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2921 const XML_Char *uri, BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002922{
2923 BINDING *b;
2924 int len;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002925
Fred Drake31d485c2004-08-03 07:06:22 +00002926 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002927 if (*uri == XML_T('\0') && prefix->name)
Fred Drake31d485c2004-08-03 07:06:22 +00002928 return XML_ERROR_UNDECLARING_PREFIX;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002929
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002930 for (len = 0; uri[len]; len++)
2931 ;
2932 if (namespaceSeparator)
2933 len++;
2934 if (freeBindingList) {
2935 b = freeBindingList;
2936 if (len > b->uriAlloc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002937 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
2938 sizeof(XML_Char) * (len + EXPAND_SPARE));
2939 if (temp == NULL)
2940 return XML_ERROR_NO_MEMORY;
2941 b->uri = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002942 b->uriAlloc = len + EXPAND_SPARE;
2943 }
2944 freeBindingList = b->nextTagBinding;
2945 }
2946 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002947 b = (BINDING *)MALLOC(sizeof(BINDING));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002948 if (!b)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002949 return XML_ERROR_NO_MEMORY;
2950 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002951 if (!b->uri) {
2952 FREE(b);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002953 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002954 }
2955 b->uriAlloc = len + EXPAND_SPARE;
2956 }
2957 b->uriLen = len;
2958 memcpy(b->uri, uri, len * sizeof(XML_Char));
2959 if (namespaceSeparator)
2960 b->uri[len - 1] = namespaceSeparator;
2961 b->prefix = prefix;
2962 b->attId = attId;
2963 b->prevPrefixBinding = prefix->binding;
Fred Drake08317ae2003-10-21 15:38:55 +00002964 /* NULL binding when default namespace undeclared */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002965 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
2966 prefix->binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002967 else
2968 prefix->binding = b;
2969 b->nextTagBinding = *bindingsPtr;
2970 *bindingsPtr = b;
Fred Drake31d485c2004-08-03 07:06:22 +00002971 /* if attId == NULL then we are not starting a namespace scope */
2972 if (attId && startNamespaceDeclHandler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002973 startNamespaceDeclHandler(handlerArg, prefix->name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002974 prefix->binding ? uri : 0);
2975 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002976}
2977
2978/* The idea here is to avoid using stack for each CDATA section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002979 the whole file is parsed with one call.
2980*/
2981static enum XML_Error PTRCALL
2982cdataSectionProcessor(XML_Parser parser,
2983 const char *start,
2984 const char *end,
2985 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002986{
Fred Drake31d485c2004-08-03 07:06:22 +00002987 enum XML_Error result = doCdataSection(parser, encoding, &start, end,
2988 endPtr, (XML_Bool)!finalBuffer);
2989 if (result != XML_ERROR_NONE)
2990 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002991 if (start) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002992 if (parentParser) { /* we are parsing an external entity */
2993 processor = externalEntityContentProcessor;
2994 return externalEntityContentProcessor(parser, start, end, endPtr);
2995 }
2996 else {
2997 processor = contentProcessor;
2998 return contentProcessor(parser, start, end, endPtr);
2999 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003000 }
3001 return result;
3002}
3003
Fred Drake31d485c2004-08-03 07:06:22 +00003004/* startPtr gets set to non-null if the section is closed, and to null if
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003005 the section is not yet closed.
3006*/
3007static enum XML_Error
3008doCdataSection(XML_Parser parser,
3009 const ENCODING *enc,
3010 const char **startPtr,
3011 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00003012 const char **nextPtr,
3013 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003014{
3015 const char *s = *startPtr;
3016 const char **eventPP;
3017 const char **eventEndPP;
3018 if (enc == encoding) {
3019 eventPP = &eventPtr;
3020 *eventPP = s;
3021 eventEndPP = &eventEndPtr;
3022 }
3023 else {
3024 eventPP = &(openInternalEntities->internalEventPtr);
3025 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3026 }
3027 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003028 *startPtr = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +00003029
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003030 for (;;) {
3031 const char *next;
3032 int tok = XmlCdataSectionTok(enc, s, end, &next);
3033 *eventEndPP = next;
3034 switch (tok) {
3035 case XML_TOK_CDATA_SECT_CLOSE:
3036 if (endCdataSectionHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003037 endCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003038#if 0
3039 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3040 else if (characterDataHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003041 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003042#endif
3043 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003044 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003045 *startPtr = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003046 *nextPtr = next;
3047 if (parsing == XML_FINISHED)
3048 return XML_ERROR_ABORTED;
3049 else
3050 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003051 case XML_TOK_DATA_NEWLINE:
3052 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003053 XML_Char c = 0xA;
3054 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003055 }
3056 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003057 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003058 break;
3059 case XML_TOK_DATA_CHARS:
3060 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003061 if (MUST_CONVERT(enc, s)) {
3062 for (;;) {
3063 ICHAR *dataPtr = (ICHAR *)dataBuf;
3064 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3065 *eventEndPP = next;
3066 characterDataHandler(handlerArg, dataBuf,
3067 dataPtr - (ICHAR *)dataBuf);
3068 if (s == next)
3069 break;
3070 *eventPP = s;
3071 }
3072 }
3073 else
3074 characterDataHandler(handlerArg,
3075 (XML_Char *)s,
3076 (XML_Char *)next - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003077 }
3078 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003079 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003080 break;
3081 case XML_TOK_INVALID:
3082 *eventPP = next;
3083 return XML_ERROR_INVALID_TOKEN;
3084 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003085 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003086 *nextPtr = s;
3087 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003088 }
3089 return XML_ERROR_PARTIAL_CHAR;
3090 case XML_TOK_PARTIAL:
3091 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00003092 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003093 *nextPtr = s;
3094 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003095 }
3096 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3097 default:
3098 *eventPP = next;
3099 return XML_ERROR_UNEXPECTED_STATE;
3100 }
Fred Drake31d485c2004-08-03 07:06:22 +00003101
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003102 *eventPP = s = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003103 switch (parsing) {
3104 case XML_SUSPENDED:
3105 *nextPtr = next;
3106 return XML_ERROR_NONE;
3107 case XML_FINISHED:
3108 return XML_ERROR_ABORTED;
3109 default: ;
3110 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003111 }
3112 /* not reached */
3113}
3114
3115#ifdef XML_DTD
3116
3117/* The idea here is to avoid using stack for each IGNORE section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003118 the whole file is parsed with one call.
3119*/
3120static enum XML_Error PTRCALL
3121ignoreSectionProcessor(XML_Parser parser,
3122 const char *start,
3123 const char *end,
3124 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003125{
Fred Drake31d485c2004-08-03 07:06:22 +00003126 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
3127 endPtr, (XML_Bool)!finalBuffer);
3128 if (result != XML_ERROR_NONE)
3129 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003130 if (start) {
3131 processor = prologProcessor;
3132 return prologProcessor(parser, start, end, endPtr);
3133 }
3134 return result;
3135}
3136
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003137/* startPtr gets set to non-null is the section is closed, and to null
3138 if the section is not yet closed.
3139*/
3140static enum XML_Error
3141doIgnoreSection(XML_Parser parser,
3142 const ENCODING *enc,
3143 const char **startPtr,
3144 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00003145 const char **nextPtr,
3146 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003147{
3148 const char *next;
3149 int tok;
3150 const char *s = *startPtr;
3151 const char **eventPP;
3152 const char **eventEndPP;
3153 if (enc == encoding) {
3154 eventPP = &eventPtr;
3155 *eventPP = s;
3156 eventEndPP = &eventEndPtr;
3157 }
3158 else {
3159 eventPP = &(openInternalEntities->internalEventPtr);
3160 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3161 }
3162 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003163 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003164 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3165 *eventEndPP = next;
3166 switch (tok) {
3167 case XML_TOK_IGNORE_SECT:
3168 if (defaultHandler)
3169 reportDefault(parser, enc, s, next);
3170 *startPtr = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003171 *nextPtr = next;
3172 if (parsing == XML_FINISHED)
3173 return XML_ERROR_ABORTED;
3174 else
3175 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003176 case XML_TOK_INVALID:
3177 *eventPP = next;
3178 return XML_ERROR_INVALID_TOKEN;
3179 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003180 if (haveMore) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003181 *nextPtr = s;
3182 return XML_ERROR_NONE;
3183 }
3184 return XML_ERROR_PARTIAL_CHAR;
3185 case XML_TOK_PARTIAL:
3186 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00003187 if (haveMore) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003188 *nextPtr = s;
3189 return XML_ERROR_NONE;
3190 }
3191 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3192 default:
3193 *eventPP = next;
3194 return XML_ERROR_UNEXPECTED_STATE;
3195 }
3196 /* not reached */
3197}
3198
3199#endif /* XML_DTD */
3200
3201static enum XML_Error
3202initializeEncoding(XML_Parser parser)
3203{
3204 const char *s;
3205#ifdef XML_UNICODE
3206 char encodingBuf[128];
3207 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003208 s = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003209 else {
3210 int i;
3211 for (i = 0; protocolEncodingName[i]; i++) {
3212 if (i == sizeof(encodingBuf) - 1
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003213 || (protocolEncodingName[i] & ~0x7f) != 0) {
3214 encodingBuf[0] = '\0';
3215 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003216 }
3217 encodingBuf[i] = (char)protocolEncodingName[i];
3218 }
3219 encodingBuf[i] = '\0';
3220 s = encodingBuf;
3221 }
3222#else
3223 s = protocolEncodingName;
3224#endif
3225 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3226 return XML_ERROR_NONE;
3227 return handleUnknownEncoding(parser, protocolEncodingName);
3228}
3229
3230static enum XML_Error
3231processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003232 const char *s, const char *next)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003233{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003234 const char *encodingName = NULL;
3235 const XML_Char *storedEncName = NULL;
3236 const ENCODING *newEncoding = NULL;
3237 const char *version = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003238 const char *versionend;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003239 const XML_Char *storedversion = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003240 int standalone = -1;
3241 if (!(ns
3242 ? XmlParseXmlDeclNS
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003243 : XmlParseXmlDecl)(isGeneralTextEntity,
3244 encoding,
3245 s,
3246 next,
3247 &eventPtr,
3248 &version,
3249 &versionend,
3250 &encodingName,
3251 &newEncoding,
Fred Drake31d485c2004-08-03 07:06:22 +00003252 &standalone)) {
3253 if (isGeneralTextEntity)
3254 return XML_ERROR_TEXT_DECL;
3255 else
3256 return XML_ERROR_XML_DECL;
3257 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003258 if (!isGeneralTextEntity && standalone == 1) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003259 _dtd->standalone = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003260#ifdef XML_DTD
3261 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3262 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3263#endif /* XML_DTD */
3264 }
3265 if (xmlDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003266 if (encodingName != NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003267 storedEncName = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003268 encoding,
3269 encodingName,
3270 encodingName
3271 + XmlNameLength(encoding, encodingName));
3272 if (!storedEncName)
3273 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003274 poolFinish(&temp2Pool);
3275 }
3276 if (version) {
3277 storedversion = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003278 encoding,
3279 version,
3280 versionend - encoding->minBytesPerChar);
3281 if (!storedversion)
3282 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003283 }
3284 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3285 }
3286 else if (defaultHandler)
3287 reportDefault(parser, encoding, s, next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003288 if (protocolEncodingName == NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003289 if (newEncoding) {
3290 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003291 eventPtr = encodingName;
3292 return XML_ERROR_INCORRECT_ENCODING;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003293 }
3294 encoding = newEncoding;
3295 }
3296 else if (encodingName) {
3297 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003298 if (!storedEncName) {
3299 storedEncName = poolStoreString(
3300 &temp2Pool, encoding, encodingName,
3301 encodingName + XmlNameLength(encoding, encodingName));
3302 if (!storedEncName)
3303 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003304 }
3305 result = handleUnknownEncoding(parser, storedEncName);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003306 poolClear(&temp2Pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003307 if (result == XML_ERROR_UNKNOWN_ENCODING)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003308 eventPtr = encodingName;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003309 return result;
3310 }
3311 }
3312
3313 if (storedEncName || storedversion)
3314 poolClear(&temp2Pool);
3315
3316 return XML_ERROR_NONE;
3317}
3318
3319static enum XML_Error
3320handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3321{
3322 if (unknownEncodingHandler) {
3323 XML_Encoding info;
3324 int i;
3325 for (i = 0; i < 256; i++)
3326 info.map[i] = -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003327 info.convert = NULL;
3328 info.data = NULL;
3329 info.release = NULL;
3330 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3331 &info)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003332 ENCODING *enc;
3333 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3334 if (!unknownEncodingMem) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003335 if (info.release)
3336 info.release(info.data);
3337 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003338 }
3339 enc = (ns
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003340 ? XmlInitUnknownEncodingNS
3341 : XmlInitUnknownEncoding)(unknownEncodingMem,
3342 info.map,
3343 info.convert,
3344 info.data);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003345 if (enc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003346 unknownEncodingData = info.data;
3347 unknownEncodingRelease = info.release;
3348 encoding = enc;
3349 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003350 }
3351 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003352 if (info.release != NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003353 info.release(info.data);
3354 }
3355 return XML_ERROR_UNKNOWN_ENCODING;
3356}
3357
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003358static enum XML_Error PTRCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003359prologInitProcessor(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003360 const char *s,
3361 const char *end,
3362 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003363{
3364 enum XML_Error result = initializeEncoding(parser);
3365 if (result != XML_ERROR_NONE)
3366 return result;
3367 processor = prologProcessor;
3368 return prologProcessor(parser, s, end, nextPtr);
3369}
3370
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003371#ifdef XML_DTD
3372
3373static enum XML_Error PTRCALL
3374externalParEntInitProcessor(XML_Parser parser,
3375 const char *s,
3376 const char *end,
3377 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003378{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003379 enum XML_Error result = initializeEncoding(parser);
3380 if (result != XML_ERROR_NONE)
3381 return result;
3382
3383 /* we know now that XML_Parse(Buffer) has been called,
3384 so we consider the external parameter entity read */
3385 _dtd->paramEntityRead = XML_TRUE;
3386
3387 if (prologState.inEntityValue) {
3388 processor = entityValueInitProcessor;
3389 return entityValueInitProcessor(parser, s, end, nextPtr);
3390 }
3391 else {
3392 processor = externalParEntProcessor;
3393 return externalParEntProcessor(parser, s, end, nextPtr);
3394 }
3395}
3396
3397static enum XML_Error PTRCALL
3398entityValueInitProcessor(XML_Parser parser,
3399 const char *s,
3400 const char *end,
3401 const char **nextPtr)
3402{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003403 int tok;
Fred Drake31d485c2004-08-03 07:06:22 +00003404 const char *start = s;
3405 const char *next = start;
3406 eventPtr = start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003407
Fred Drake31d485c2004-08-03 07:06:22 +00003408 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003409 tok = XmlPrologTok(encoding, start, end, &next);
Fred Drake31d485c2004-08-03 07:06:22 +00003410 eventEndPtr = next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003411 if (tok <= 0) {
Fred Drake31d485c2004-08-03 07:06:22 +00003412 if (!finalBuffer && tok != XML_TOK_INVALID) {
3413 *nextPtr = s;
3414 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003415 }
3416 switch (tok) {
3417 case XML_TOK_INVALID:
Fred Drake31d485c2004-08-03 07:06:22 +00003418 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003419 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00003420 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003421 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003422 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003423 case XML_TOK_NONE: /* start == end */
3424 default:
3425 break;
3426 }
Fred Drake31d485c2004-08-03 07:06:22 +00003427 /* found end of entity value - can store it now */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003428 return storeEntityValue(parser, encoding, s, end);
3429 }
3430 else if (tok == XML_TOK_XML_DECL) {
Fred Drake31d485c2004-08-03 07:06:22 +00003431 enum XML_Error result;
3432 result = processXmlDecl(parser, 0, start, next);
3433 if (result != XML_ERROR_NONE)
3434 return result;
3435 switch (parsing) {
3436 case XML_SUSPENDED:
3437 *nextPtr = next;
3438 return XML_ERROR_NONE;
3439 case XML_FINISHED:
3440 return XML_ERROR_ABORTED;
3441 default:
3442 *nextPtr = next;
3443 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003444 /* stop scanning for text declaration - we found one */
3445 processor = entityValueProcessor;
3446 return entityValueProcessor(parser, next, end, nextPtr);
3447 }
3448 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3449 return XML_TOK_NONE on the next call, which would then cause the
3450 function to exit with *nextPtr set to s - that is what we want for other
3451 tokens, but not for the BOM - we would rather like to skip it;
3452 then, when this routine is entered the next time, XmlPrologTok will
3453 return XML_TOK_INVALID, since the BOM is still in the buffer
3454 */
Fred Drake31d485c2004-08-03 07:06:22 +00003455 else if (tok == XML_TOK_BOM && next == end && !finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003456 *nextPtr = next;
3457 return XML_ERROR_NONE;
3458 }
3459 start = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003460 eventPtr = start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003461 }
3462}
3463
3464static enum XML_Error PTRCALL
3465externalParEntProcessor(XML_Parser parser,
3466 const char *s,
3467 const char *end,
3468 const char **nextPtr)
3469{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003470 const char *next = s;
3471 int tok;
3472
Fred Drake31d485c2004-08-03 07:06:22 +00003473 tok = XmlPrologTok(encoding, s, end, &next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003474 if (tok <= 0) {
Fred Drake31d485c2004-08-03 07:06:22 +00003475 if (!finalBuffer && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003476 *nextPtr = s;
3477 return XML_ERROR_NONE;
3478 }
3479 switch (tok) {
3480 case XML_TOK_INVALID:
3481 return XML_ERROR_INVALID_TOKEN;
3482 case XML_TOK_PARTIAL:
3483 return XML_ERROR_UNCLOSED_TOKEN;
3484 case XML_TOK_PARTIAL_CHAR:
3485 return XML_ERROR_PARTIAL_CHAR;
3486 case XML_TOK_NONE: /* start == end */
3487 default:
3488 break;
3489 }
3490 }
3491 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3492 However, when parsing an external subset, doProlog will not accept a BOM
3493 as valid, and report a syntax error, so we have to skip the BOM
3494 */
3495 else if (tok == XML_TOK_BOM) {
3496 s = next;
3497 tok = XmlPrologTok(encoding, s, end, &next);
3498 }
3499
3500 processor = prologProcessor;
Fred Drake31d485c2004-08-03 07:06:22 +00003501 return doProlog(parser, encoding, s, end, tok, next,
3502 nextPtr, (XML_Bool)!finalBuffer);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003503}
3504
3505static enum XML_Error PTRCALL
3506entityValueProcessor(XML_Parser parser,
3507 const char *s,
3508 const char *end,
3509 const char **nextPtr)
3510{
3511 const char *start = s;
3512 const char *next = s;
3513 const ENCODING *enc = encoding;
3514 int tok;
3515
3516 for (;;) {
3517 tok = XmlPrologTok(enc, start, end, &next);
3518 if (tok <= 0) {
Fred Drake31d485c2004-08-03 07:06:22 +00003519 if (!finalBuffer && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003520 *nextPtr = s;
3521 return XML_ERROR_NONE;
3522 }
3523 switch (tok) {
3524 case XML_TOK_INVALID:
Fred Drake31d485c2004-08-03 07:06:22 +00003525 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003526 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00003527 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003528 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003529 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003530 case XML_TOK_NONE: /* start == end */
3531 default:
3532 break;
3533 }
Fred Drake31d485c2004-08-03 07:06:22 +00003534 /* found end of entity value - can store it now */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003535 return storeEntityValue(parser, enc, s, end);
3536 }
3537 start = next;
3538 }
3539}
3540
3541#endif /* XML_DTD */
3542
3543static enum XML_Error PTRCALL
3544prologProcessor(XML_Parser parser,
3545 const char *s,
3546 const char *end,
3547 const char **nextPtr)
3548{
3549 const char *next = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003550 int tok = XmlPrologTok(encoding, s, end, &next);
Fred Drake31d485c2004-08-03 07:06:22 +00003551 return doProlog(parser, encoding, s, end, tok, next,
3552 nextPtr, (XML_Bool)!finalBuffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003553}
3554
3555static enum XML_Error
3556doProlog(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003557 const ENCODING *enc,
3558 const char *s,
3559 const char *end,
3560 int tok,
3561 const char *next,
Fred Drake31d485c2004-08-03 07:06:22 +00003562 const char **nextPtr,
3563 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003564{
3565#ifdef XML_DTD
3566 static const XML_Char externalSubsetName[] = { '#' , '\0' };
3567#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003568 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3569 static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3570 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3571 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3572 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3573 static const XML_Char atypeENTITIES[] =
3574 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3575 static const XML_Char atypeNMTOKEN[] = {
3576 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3577 static const XML_Char atypeNMTOKENS[] = {
3578 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3579 static const XML_Char notationPrefix[] = {
3580 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3581 static const XML_Char enumValueSep[] = { '|', '\0' };
3582 static const XML_Char enumValueStart[] = { '(', '\0' };
3583
Fred Drake31d485c2004-08-03 07:06:22 +00003584 /* save one level of indirection */
3585 DTD * const dtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003586
3587 const char **eventPP;
3588 const char **eventEndPP;
3589 enum XML_Content_Quant quant;
3590
3591 if (enc == encoding) {
3592 eventPP = &eventPtr;
3593 eventEndPP = &eventEndPtr;
3594 }
3595 else {
3596 eventPP = &(openInternalEntities->internalEventPtr);
3597 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3598 }
Fred Drake31d485c2004-08-03 07:06:22 +00003599
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003600 for (;;) {
3601 int role;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003602 XML_Bool handleDefault = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003603 *eventPP = s;
3604 *eventEndPP = next;
3605 if (tok <= 0) {
Fred Drake31d485c2004-08-03 07:06:22 +00003606 if (haveMore && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003607 *nextPtr = s;
3608 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003609 }
3610 switch (tok) {
3611 case XML_TOK_INVALID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003612 *eventPP = next;
3613 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003614 case XML_TOK_PARTIAL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003615 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003616 case XML_TOK_PARTIAL_CHAR:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003617 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003618 case XML_TOK_NONE:
3619#ifdef XML_DTD
Fred Drake31d485c2004-08-03 07:06:22 +00003620 /* for internal PE NOT referenced between declarations */
3621 if (enc != encoding && !openInternalEntities->betweenDecl) {
3622 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003623 return XML_ERROR_NONE;
Fred Drake31d485c2004-08-03 07:06:22 +00003624 }
3625 /* WFC: PE Between Declarations - must check that PE contains
3626 complete markup, not only for external PEs, but also for
3627 internal PEs if the reference occurs between declarations.
3628 */
3629 if (isParamEntity || enc != encoding) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003630 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3631 == XML_ROLE_ERROR)
Fred Drake31d485c2004-08-03 07:06:22 +00003632 return XML_ERROR_INCOMPLETE_PE;
3633 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003634 return XML_ERROR_NONE;
3635 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003636#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003637 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003638 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003639 tok = -tok;
3640 next = end;
3641 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003642 }
3643 }
3644 role = XmlTokenRole(&prologState, tok, s, next, enc);
3645 switch (role) {
3646 case XML_ROLE_XML_DECL:
3647 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003648 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3649 if (result != XML_ERROR_NONE)
3650 return result;
3651 enc = encoding;
3652 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003653 }
3654 break;
3655 case XML_ROLE_DOCTYPE_NAME:
3656 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003657 doctypeName = poolStoreString(&tempPool, enc, s, next);
3658 if (!doctypeName)
3659 return XML_ERROR_NO_MEMORY;
3660 poolFinish(&tempPool);
3661 doctypePubid = NULL;
3662 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003663 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003664 doctypeSysid = NULL; /* always initialize to NULL */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003665 break;
3666 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3667 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003668 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3669 doctypePubid, 1);
3670 doctypeName = NULL;
3671 poolClear(&tempPool);
3672 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003673 }
3674 break;
3675#ifdef XML_DTD
3676 case XML_ROLE_TEXT_DECL:
3677 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003678 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3679 if (result != XML_ERROR_NONE)
3680 return result;
3681 enc = encoding;
3682 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003683 }
3684 break;
3685#endif /* XML_DTD */
3686 case XML_ROLE_DOCTYPE_PUBLIC_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003687#ifdef XML_DTD
3688 useForeignDTD = XML_FALSE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003689 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3690 externalSubsetName,
3691 sizeof(ENTITY));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003692 if (!declEntity)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003693 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003694#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00003695 dtd->hasParamEntityRefs = XML_TRUE;
3696 if (startDoctypeDeclHandler) {
3697 if (!XmlIsPublicId(enc, s, next, eventPP))
3698 return XML_ERROR_PUBLICID;
3699 doctypePubid = poolStoreString(&tempPool, enc,
3700 s + enc->minBytesPerChar,
3701 next - enc->minBytesPerChar);
3702 if (!doctypePubid)
3703 return XML_ERROR_NO_MEMORY;
3704 normalizePublicId((XML_Char *)doctypePubid);
3705 poolFinish(&tempPool);
3706 handleDefault = XML_FALSE;
3707 goto alreadyChecked;
3708 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003709 /* fall through */
3710 case XML_ROLE_ENTITY_PUBLIC_ID:
3711 if (!XmlIsPublicId(enc, s, next, eventPP))
Fred Drake31d485c2004-08-03 07:06:22 +00003712 return XML_ERROR_PUBLICID;
3713 alreadyChecked:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003714 if (dtd->keepProcessing && declEntity) {
3715 XML_Char *tem = poolStoreString(&dtd->pool,
3716 enc,
3717 s + enc->minBytesPerChar,
3718 next - enc->minBytesPerChar);
3719 if (!tem)
3720 return XML_ERROR_NO_MEMORY;
3721 normalizePublicId(tem);
3722 declEntity->publicId = tem;
3723 poolFinish(&dtd->pool);
3724 if (entityDeclHandler)
3725 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003726 }
3727 break;
3728 case XML_ROLE_DOCTYPE_CLOSE:
3729 if (doctypeName) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003730 startDoctypeDeclHandler(handlerArg, doctypeName,
3731 doctypeSysid, doctypePubid, 0);
3732 poolClear(&tempPool);
3733 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003734 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003735 /* doctypeSysid will be non-NULL in the case of a previous
3736 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3737 was not set, indicating an external subset
3738 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003739#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003740 if (doctypeSysid || useForeignDTD) {
3741 dtd->hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */
3742 if (paramEntityParsing && externalEntityRefHandler) {
3743 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3744 externalSubsetName,
3745 sizeof(ENTITY));
3746 if (!entity)
3747 return XML_ERROR_NO_MEMORY;
3748 if (useForeignDTD)
3749 entity->base = curBase;
3750 dtd->paramEntityRead = XML_FALSE;
3751 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3752 0,
3753 entity->base,
3754 entity->systemId,
3755 entity->publicId))
3756 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3757 if (dtd->paramEntityRead &&
3758 !dtd->standalone &&
3759 notStandaloneHandler &&
3760 !notStandaloneHandler(handlerArg))
3761 return XML_ERROR_NOT_STANDALONE;
3762 /* end of DTD - no need to update dtd->keepProcessing */
3763 }
3764 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003765 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003766#endif /* XML_DTD */
3767 if (endDoctypeDeclHandler) {
3768 endDoctypeDeclHandler(handlerArg);
3769 handleDefault = XML_FALSE;
3770 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003771 break;
3772 case XML_ROLE_INSTANCE_START:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003773#ifdef XML_DTD
3774 /* if there is no DOCTYPE declaration then now is the
3775 last chance to read the foreign DTD
3776 */
3777 if (useForeignDTD) {
3778 dtd->hasParamEntityRefs = XML_TRUE;
3779 if (paramEntityParsing && externalEntityRefHandler) {
3780 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3781 externalSubsetName,
3782 sizeof(ENTITY));
3783 if (!entity)
3784 return XML_ERROR_NO_MEMORY;
3785 entity->base = curBase;
3786 dtd->paramEntityRead = XML_FALSE;
3787 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3788 0,
3789 entity->base,
3790 entity->systemId,
3791 entity->publicId))
3792 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3793 if (dtd->paramEntityRead &&
3794 !dtd->standalone &&
3795 notStandaloneHandler &&
3796 !notStandaloneHandler(handlerArg))
3797 return XML_ERROR_NOT_STANDALONE;
3798 /* end of DTD - no need to update dtd->keepProcessing */
3799 }
3800 }
3801#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003802 processor = contentProcessor;
3803 return contentProcessor(parser, s, end, nextPtr);
3804 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3805 declElementType = getElementType(parser, enc, s, next);
3806 if (!declElementType)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003807 return XML_ERROR_NO_MEMORY;
3808 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003809 case XML_ROLE_ATTRIBUTE_NAME:
3810 declAttributeId = getAttributeId(parser, enc, s, next);
3811 if (!declAttributeId)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003812 return XML_ERROR_NO_MEMORY;
3813 declAttributeIsCdata = XML_FALSE;
3814 declAttributeType = NULL;
3815 declAttributeIsId = XML_FALSE;
3816 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003817 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003818 declAttributeIsCdata = XML_TRUE;
3819 declAttributeType = atypeCDATA;
3820 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003821 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003822 declAttributeIsId = XML_TRUE;
3823 declAttributeType = atypeID;
3824 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003825 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003826 declAttributeType = atypeIDREF;
3827 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003828 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003829 declAttributeType = atypeIDREFS;
3830 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003831 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003832 declAttributeType = atypeENTITY;
3833 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003834 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003835 declAttributeType = atypeENTITIES;
3836 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003837 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003838 declAttributeType = atypeNMTOKEN;
3839 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003840 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003841 declAttributeType = atypeNMTOKENS;
3842 checkAttListDeclHandler:
3843 if (dtd->keepProcessing && attlistDeclHandler)
3844 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003845 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003846 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3847 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003848 if (dtd->keepProcessing && attlistDeclHandler) {
3849 const XML_Char *prefix;
3850 if (declAttributeType) {
3851 prefix = enumValueSep;
3852 }
3853 else {
3854 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3855 ? notationPrefix
3856 : enumValueStart);
3857 }
3858 if (!poolAppendString(&tempPool, prefix))
3859 return XML_ERROR_NO_MEMORY;
3860 if (!poolAppend(&tempPool, enc, s, next))
3861 return XML_ERROR_NO_MEMORY;
3862 declAttributeType = tempPool.start;
3863 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003864 }
3865 break;
3866 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3867 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003868 if (dtd->keepProcessing) {
3869 if (!defineAttribute(declElementType, declAttributeId,
Fred Drake08317ae2003-10-21 15:38:55 +00003870 declAttributeIsCdata, declAttributeIsId,
3871 0, parser))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003872 return XML_ERROR_NO_MEMORY;
3873 if (attlistDeclHandler && declAttributeType) {
3874 if (*declAttributeType == XML_T('(')
3875 || (*declAttributeType == XML_T('N')
3876 && declAttributeType[1] == XML_T('O'))) {
3877 /* Enumerated or Notation type */
3878 if (!poolAppendChar(&tempPool, XML_T(')'))
3879 || !poolAppendChar(&tempPool, XML_T('\0')))
3880 return XML_ERROR_NO_MEMORY;
3881 declAttributeType = tempPool.start;
3882 poolFinish(&tempPool);
3883 }
3884 *eventEndPP = s;
3885 attlistDeclHandler(handlerArg, declElementType->name,
3886 declAttributeId->name, declAttributeType,
3887 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
3888 poolClear(&tempPool);
3889 handleDefault = XML_FALSE;
3890 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003891 }
3892 break;
3893 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3894 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003895 if (dtd->keepProcessing) {
3896 const XML_Char *attVal;
Fred Drake08317ae2003-10-21 15:38:55 +00003897 enum XML_Error result =
3898 storeAttributeValue(parser, enc, declAttributeIsCdata,
3899 s + enc->minBytesPerChar,
3900 next - enc->minBytesPerChar,
3901 &dtd->pool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003902 if (result)
3903 return result;
3904 attVal = poolStart(&dtd->pool);
3905 poolFinish(&dtd->pool);
3906 /* ID attributes aren't allowed to have a default */
3907 if (!defineAttribute(declElementType, declAttributeId,
3908 declAttributeIsCdata, XML_FALSE, attVal, parser))
3909 return XML_ERROR_NO_MEMORY;
3910 if (attlistDeclHandler && declAttributeType) {
3911 if (*declAttributeType == XML_T('(')
3912 || (*declAttributeType == XML_T('N')
3913 && declAttributeType[1] == XML_T('O'))) {
3914 /* Enumerated or Notation type */
3915 if (!poolAppendChar(&tempPool, XML_T(')'))
3916 || !poolAppendChar(&tempPool, XML_T('\0')))
3917 return XML_ERROR_NO_MEMORY;
3918 declAttributeType = tempPool.start;
3919 poolFinish(&tempPool);
3920 }
3921 *eventEndPP = s;
3922 attlistDeclHandler(handlerArg, declElementType->name,
3923 declAttributeId->name, declAttributeType,
3924 attVal,
3925 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
3926 poolClear(&tempPool);
3927 handleDefault = XML_FALSE;
3928 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003929 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003930 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003931 case XML_ROLE_ENTITY_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003932 if (dtd->keepProcessing) {
3933 enum XML_Error result = storeEntityValue(parser, enc,
3934 s + enc->minBytesPerChar,
3935 next - enc->minBytesPerChar);
3936 if (declEntity) {
3937 declEntity->textPtr = poolStart(&dtd->entityValuePool);
3938 declEntity->textLen = poolLength(&dtd->entityValuePool);
3939 poolFinish(&dtd->entityValuePool);
3940 if (entityDeclHandler) {
3941 *eventEndPP = s;
3942 entityDeclHandler(handlerArg,
3943 declEntity->name,
3944 declEntity->is_param,
3945 declEntity->textPtr,
3946 declEntity->textLen,
3947 curBase, 0, 0, 0);
3948 handleDefault = XML_FALSE;
3949 }
3950 }
3951 else
3952 poolDiscard(&dtd->entityValuePool);
3953 if (result != XML_ERROR_NONE)
3954 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003955 }
3956 break;
3957 case XML_ROLE_DOCTYPE_SYSTEM_ID:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003958#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003959 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003960#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003961 dtd->hasParamEntityRefs = XML_TRUE;
3962 if (startDoctypeDeclHandler) {
3963 doctypeSysid = poolStoreString(&tempPool, enc,
3964 s + enc->minBytesPerChar,
3965 next - enc->minBytesPerChar);
3966 if (doctypeSysid == NULL)
3967 return XML_ERROR_NO_MEMORY;
3968 poolFinish(&tempPool);
3969 handleDefault = XML_FALSE;
3970 }
3971#ifdef XML_DTD
3972 else
3973 /* use externalSubsetName to make doctypeSysid non-NULL
3974 for the case where no startDoctypeDeclHandler is set */
3975 doctypeSysid = externalSubsetName;
3976#endif /* XML_DTD */
3977 if (!dtd->standalone
3978#ifdef XML_DTD
3979 && !paramEntityParsing
3980#endif /* XML_DTD */
3981 && notStandaloneHandler
3982 && !notStandaloneHandler(handlerArg))
3983 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003984#ifndef XML_DTD
3985 break;
3986#else /* XML_DTD */
3987 if (!declEntity) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003988 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3989 externalSubsetName,
3990 sizeof(ENTITY));
3991 if (!declEntity)
3992 return XML_ERROR_NO_MEMORY;
3993 declEntity->publicId = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003994 }
3995 /* fall through */
3996#endif /* XML_DTD */
3997 case XML_ROLE_ENTITY_SYSTEM_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003998 if (dtd->keepProcessing && declEntity) {
3999 declEntity->systemId = poolStoreString(&dtd->pool, enc,
4000 s + enc->minBytesPerChar,
4001 next - enc->minBytesPerChar);
4002 if (!declEntity->systemId)
4003 return XML_ERROR_NO_MEMORY;
4004 declEntity->base = curBase;
4005 poolFinish(&dtd->pool);
4006 if (entityDeclHandler)
4007 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004008 }
4009 break;
4010 case XML_ROLE_ENTITY_COMPLETE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004011 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4012 *eventEndPP = s;
4013 entityDeclHandler(handlerArg,
4014 declEntity->name,
4015 declEntity->is_param,
4016 0,0,
4017 declEntity->base,
4018 declEntity->systemId,
4019 declEntity->publicId,
4020 0);
4021 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004022 }
4023 break;
4024 case XML_ROLE_ENTITY_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004025 if (dtd->keepProcessing && declEntity) {
4026 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4027 if (!declEntity->notation)
4028 return XML_ERROR_NO_MEMORY;
4029 poolFinish(&dtd->pool);
4030 if (unparsedEntityDeclHandler) {
4031 *eventEndPP = s;
4032 unparsedEntityDeclHandler(handlerArg,
4033 declEntity->name,
4034 declEntity->base,
4035 declEntity->systemId,
4036 declEntity->publicId,
4037 declEntity->notation);
4038 handleDefault = XML_FALSE;
4039 }
4040 else if (entityDeclHandler) {
4041 *eventEndPP = s;
4042 entityDeclHandler(handlerArg,
4043 declEntity->name,
4044 0,0,0,
4045 declEntity->base,
4046 declEntity->systemId,
4047 declEntity->publicId,
4048 declEntity->notation);
4049 handleDefault = XML_FALSE;
4050 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004051 }
4052 break;
4053 case XML_ROLE_GENERAL_ENTITY_NAME:
4054 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004055 if (XmlPredefinedEntityName(enc, s, next)) {
4056 declEntity = NULL;
4057 break;
4058 }
4059 if (dtd->keepProcessing) {
4060 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4061 if (!name)
4062 return XML_ERROR_NO_MEMORY;
4063 declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
4064 sizeof(ENTITY));
4065 if (!declEntity)
4066 return XML_ERROR_NO_MEMORY;
4067 if (declEntity->name != name) {
4068 poolDiscard(&dtd->pool);
4069 declEntity = NULL;
4070 }
4071 else {
4072 poolFinish(&dtd->pool);
4073 declEntity->publicId = NULL;
4074 declEntity->is_param = XML_FALSE;
4075 /* if we have a parent parser or are reading an internal parameter
4076 entity, then the entity declaration is not considered "internal"
4077 */
4078 declEntity->is_internal = !(parentParser || openInternalEntities);
4079 if (entityDeclHandler)
4080 handleDefault = XML_FALSE;
4081 }
4082 }
4083 else {
4084 poolDiscard(&dtd->pool);
4085 declEntity = NULL;
4086 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004087 }
4088 break;
4089 case XML_ROLE_PARAM_ENTITY_NAME:
4090#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004091 if (dtd->keepProcessing) {
4092 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4093 if (!name)
4094 return XML_ERROR_NO_MEMORY;
4095 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
4096 name, sizeof(ENTITY));
4097 if (!declEntity)
4098 return XML_ERROR_NO_MEMORY;
4099 if (declEntity->name != name) {
4100 poolDiscard(&dtd->pool);
4101 declEntity = NULL;
4102 }
4103 else {
4104 poolFinish(&dtd->pool);
4105 declEntity->publicId = NULL;
4106 declEntity->is_param = XML_TRUE;
4107 /* if we have a parent parser or are reading an internal parameter
4108 entity, then the entity declaration is not considered "internal"
4109 */
4110 declEntity->is_internal = !(parentParser || openInternalEntities);
4111 if (entityDeclHandler)
4112 handleDefault = XML_FALSE;
4113 }
4114 }
4115 else {
4116 poolDiscard(&dtd->pool);
4117 declEntity = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004118 }
4119#else /* not XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004120 declEntity = NULL;
4121#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004122 break;
4123 case XML_ROLE_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004124 declNotationPublicId = NULL;
4125 declNotationName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004126 if (notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004127 declNotationName = poolStoreString(&tempPool, enc, s, next);
4128 if (!declNotationName)
4129 return XML_ERROR_NO_MEMORY;
4130 poolFinish(&tempPool);
4131 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004132 }
4133 break;
4134 case XML_ROLE_NOTATION_PUBLIC_ID:
4135 if (!XmlIsPublicId(enc, s, next, eventPP))
Fred Drake31d485c2004-08-03 07:06:22 +00004136 return XML_ERROR_PUBLICID;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004137 if (declNotationName) { /* means notationDeclHandler != NULL */
4138 XML_Char *tem = poolStoreString(&tempPool,
4139 enc,
4140 s + enc->minBytesPerChar,
4141 next - enc->minBytesPerChar);
4142 if (!tem)
4143 return XML_ERROR_NO_MEMORY;
4144 normalizePublicId(tem);
4145 declNotationPublicId = tem;
4146 poolFinish(&tempPool);
4147 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004148 }
4149 break;
4150 case XML_ROLE_NOTATION_SYSTEM_ID:
4151 if (declNotationName && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004152 const XML_Char *systemId
4153 = poolStoreString(&tempPool, enc,
4154 s + enc->minBytesPerChar,
4155 next - enc->minBytesPerChar);
4156 if (!systemId)
4157 return XML_ERROR_NO_MEMORY;
4158 *eventEndPP = s;
4159 notationDeclHandler(handlerArg,
4160 declNotationName,
4161 curBase,
4162 systemId,
4163 declNotationPublicId);
4164 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004165 }
4166 poolClear(&tempPool);
4167 break;
4168 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4169 if (declNotationPublicId && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004170 *eventEndPP = s;
4171 notationDeclHandler(handlerArg,
4172 declNotationName,
4173 curBase,
4174 0,
4175 declNotationPublicId);
4176 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004177 }
4178 poolClear(&tempPool);
4179 break;
4180 case XML_ROLE_ERROR:
4181 switch (tok) {
4182 case XML_TOK_PARAM_ENTITY_REF:
Fred Drake31d485c2004-08-03 07:06:22 +00004183 /* PE references in internal subset are
4184 not allowed within declarations. */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004185 return XML_ERROR_PARAM_ENTITY_REF;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004186 case XML_TOK_XML_DECL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004187 return XML_ERROR_MISPLACED_XML_PI;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004188 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004189 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004190 }
4191#ifdef XML_DTD
4192 case XML_ROLE_IGNORE_SECT:
4193 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004194 enum XML_Error result;
4195 if (defaultHandler)
4196 reportDefault(parser, enc, s, next);
4197 handleDefault = XML_FALSE;
Fred Drake31d485c2004-08-03 07:06:22 +00004198 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4199 if (result != XML_ERROR_NONE)
4200 return result;
4201 else if (!next) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004202 processor = ignoreSectionProcessor;
4203 return result;
4204 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004205 }
4206 break;
4207#endif /* XML_DTD */
4208 case XML_ROLE_GROUP_OPEN:
4209 if (prologState.level >= groupSize) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004210 if (groupSize) {
4211 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4212 if (temp == NULL)
4213 return XML_ERROR_NO_MEMORY;
4214 groupConnector = temp;
4215 if (dtd->scaffIndex) {
4216 int *temp = (int *)REALLOC(dtd->scaffIndex,
4217 groupSize * sizeof(int));
4218 if (temp == NULL)
4219 return XML_ERROR_NO_MEMORY;
4220 dtd->scaffIndex = temp;
4221 }
4222 }
4223 else {
4224 groupConnector = (char *)MALLOC(groupSize = 32);
4225 if (!groupConnector)
4226 return XML_ERROR_NO_MEMORY;
4227 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004228 }
4229 groupConnector[prologState.level] = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004230 if (dtd->in_eldecl) {
4231 int myindex = nextScaffoldPart(parser);
4232 if (myindex < 0)
4233 return XML_ERROR_NO_MEMORY;
4234 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4235 dtd->scaffLevel++;
4236 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4237 if (elementDeclHandler)
4238 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004239 }
4240 break;
4241 case XML_ROLE_GROUP_SEQUENCE:
4242 if (groupConnector[prologState.level] == '|')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004243 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004244 groupConnector[prologState.level] = ',';
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004245 if (dtd->in_eldecl && elementDeclHandler)
4246 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004247 break;
4248 case XML_ROLE_GROUP_CHOICE:
4249 if (groupConnector[prologState.level] == ',')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004250 return XML_ERROR_SYNTAX;
4251 if (dtd->in_eldecl
4252 && !groupConnector[prologState.level]
4253 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4254 != XML_CTYPE_MIXED)
4255 ) {
4256 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4257 = XML_CTYPE_CHOICE;
4258 if (elementDeclHandler)
4259 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004260 }
4261 groupConnector[prologState.level] = '|';
4262 break;
4263 case XML_ROLE_PARAM_ENTITY_REF:
4264#ifdef XML_DTD
4265 case XML_ROLE_INNER_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004266 dtd->hasParamEntityRefs = XML_TRUE;
4267 if (!paramEntityParsing)
4268 dtd->keepProcessing = dtd->standalone;
4269 else {
4270 const XML_Char *name;
4271 ENTITY *entity;
4272 name = poolStoreString(&dtd->pool, enc,
4273 s + enc->minBytesPerChar,
4274 next - enc->minBytesPerChar);
4275 if (!name)
4276 return XML_ERROR_NO_MEMORY;
4277 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4278 poolDiscard(&dtd->pool);
4279 /* first, determine if a check for an existing declaration is needed;
4280 if yes, check that the entity exists, and that it is internal,
4281 otherwise call the skipped entity handler
4282 */
4283 if (prologState.documentEntity &&
4284 (dtd->standalone
4285 ? !openInternalEntities
4286 : !dtd->hasParamEntityRefs)) {
4287 if (!entity)
4288 return XML_ERROR_UNDEFINED_ENTITY;
4289 else if (!entity->is_internal)
4290 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4291 }
4292 else if (!entity) {
4293 dtd->keepProcessing = dtd->standalone;
4294 /* cannot report skipped entities in declarations */
4295 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4296 skippedEntityHandler(handlerArg, name, 1);
4297 handleDefault = XML_FALSE;
4298 }
4299 break;
4300 }
4301 if (entity->open)
4302 return XML_ERROR_RECURSIVE_ENTITY_REF;
4303 if (entity->textPtr) {
4304 enum XML_Error result;
Fred Drake31d485c2004-08-03 07:06:22 +00004305 XML_Bool betweenDecl =
4306 (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4307 result = processInternalEntity(parser, entity, betweenDecl);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004308 if (result != XML_ERROR_NONE)
4309 return result;
4310 handleDefault = XML_FALSE;
4311 break;
4312 }
4313 if (externalEntityRefHandler) {
4314 dtd->paramEntityRead = XML_FALSE;
4315 entity->open = XML_TRUE;
4316 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4317 0,
4318 entity->base,
4319 entity->systemId,
4320 entity->publicId)) {
4321 entity->open = XML_FALSE;
4322 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4323 }
4324 entity->open = XML_FALSE;
4325 handleDefault = XML_FALSE;
4326 if (!dtd->paramEntityRead) {
4327 dtd->keepProcessing = dtd->standalone;
4328 break;
4329 }
4330 }
4331 else {
4332 dtd->keepProcessing = dtd->standalone;
4333 break;
4334 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004335 }
4336#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004337 if (!dtd->standalone &&
4338 notStandaloneHandler &&
4339 !notStandaloneHandler(handlerArg))
4340 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004341 break;
4342
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004343 /* Element declaration stuff */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004344
4345 case XML_ROLE_ELEMENT_NAME:
4346 if (elementDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004347 declElementType = getElementType(parser, enc, s, next);
4348 if (!declElementType)
4349 return XML_ERROR_NO_MEMORY;
4350 dtd->scaffLevel = 0;
4351 dtd->scaffCount = 0;
4352 dtd->in_eldecl = XML_TRUE;
4353 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004354 }
4355 break;
4356
4357 case XML_ROLE_CONTENT_ANY:
4358 case XML_ROLE_CONTENT_EMPTY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004359 if (dtd->in_eldecl) {
4360 if (elementDeclHandler) {
4361 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4362 if (!content)
4363 return XML_ERROR_NO_MEMORY;
4364 content->quant = XML_CQUANT_NONE;
4365 content->name = NULL;
4366 content->numchildren = 0;
4367 content->children = NULL;
4368 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4369 XML_CTYPE_ANY :
4370 XML_CTYPE_EMPTY);
4371 *eventEndPP = s;
4372 elementDeclHandler(handlerArg, declElementType->name, content);
4373 handleDefault = XML_FALSE;
4374 }
4375 dtd->in_eldecl = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004376 }
4377 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004378
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004379 case XML_ROLE_CONTENT_PCDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004380 if (dtd->in_eldecl) {
4381 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4382 = XML_CTYPE_MIXED;
4383 if (elementDeclHandler)
4384 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004385 }
4386 break;
4387
4388 case XML_ROLE_CONTENT_ELEMENT:
4389 quant = XML_CQUANT_NONE;
4390 goto elementContent;
4391 case XML_ROLE_CONTENT_ELEMENT_OPT:
4392 quant = XML_CQUANT_OPT;
4393 goto elementContent;
4394 case XML_ROLE_CONTENT_ELEMENT_REP:
4395 quant = XML_CQUANT_REP;
4396 goto elementContent;
4397 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4398 quant = XML_CQUANT_PLUS;
4399 elementContent:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004400 if (dtd->in_eldecl) {
4401 ELEMENT_TYPE *el;
4402 const XML_Char *name;
4403 int nameLen;
4404 const char *nxt = (quant == XML_CQUANT_NONE
4405 ? next
4406 : next - enc->minBytesPerChar);
4407 int myindex = nextScaffoldPart(parser);
4408 if (myindex < 0)
4409 return XML_ERROR_NO_MEMORY;
4410 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4411 dtd->scaffold[myindex].quant = quant;
4412 el = getElementType(parser, enc, s, nxt);
4413 if (!el)
4414 return XML_ERROR_NO_MEMORY;
4415 name = el->name;
4416 dtd->scaffold[myindex].name = name;
4417 nameLen = 0;
4418 for (; name[nameLen++]; );
4419 dtd->contentStringLen += nameLen;
4420 if (elementDeclHandler)
4421 handleDefault = XML_FALSE;
4422 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004423 break;
4424
4425 case XML_ROLE_GROUP_CLOSE:
4426 quant = XML_CQUANT_NONE;
4427 goto closeGroup;
4428 case XML_ROLE_GROUP_CLOSE_OPT:
4429 quant = XML_CQUANT_OPT;
4430 goto closeGroup;
4431 case XML_ROLE_GROUP_CLOSE_REP:
4432 quant = XML_CQUANT_REP;
4433 goto closeGroup;
4434 case XML_ROLE_GROUP_CLOSE_PLUS:
4435 quant = XML_CQUANT_PLUS;
4436 closeGroup:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004437 if (dtd->in_eldecl) {
4438 if (elementDeclHandler)
4439 handleDefault = XML_FALSE;
4440 dtd->scaffLevel--;
4441 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4442 if (dtd->scaffLevel == 0) {
4443 if (!handleDefault) {
4444 XML_Content *model = build_model(parser);
4445 if (!model)
4446 return XML_ERROR_NO_MEMORY;
4447 *eventEndPP = s;
4448 elementDeclHandler(handlerArg, declElementType->name, model);
4449 }
4450 dtd->in_eldecl = XML_FALSE;
4451 dtd->contentStringLen = 0;
4452 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004453 }
4454 break;
4455 /* End element declaration stuff */
4456
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004457 case XML_ROLE_PI:
4458 if (!reportProcessingInstruction(parser, enc, s, next))
4459 return XML_ERROR_NO_MEMORY;
4460 handleDefault = XML_FALSE;
4461 break;
4462 case XML_ROLE_COMMENT:
4463 if (!reportComment(parser, enc, s, next))
4464 return XML_ERROR_NO_MEMORY;
4465 handleDefault = XML_FALSE;
4466 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004467 case XML_ROLE_NONE:
4468 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004469 case XML_TOK_BOM:
4470 handleDefault = XML_FALSE;
4471 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004472 }
4473 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004474 case XML_ROLE_DOCTYPE_NONE:
4475 if (startDoctypeDeclHandler)
4476 handleDefault = XML_FALSE;
4477 break;
4478 case XML_ROLE_ENTITY_NONE:
4479 if (dtd->keepProcessing && entityDeclHandler)
4480 handleDefault = XML_FALSE;
4481 break;
4482 case XML_ROLE_NOTATION_NONE:
4483 if (notationDeclHandler)
4484 handleDefault = XML_FALSE;
4485 break;
4486 case XML_ROLE_ATTLIST_NONE:
4487 if (dtd->keepProcessing && attlistDeclHandler)
4488 handleDefault = XML_FALSE;
4489 break;
4490 case XML_ROLE_ELEMENT_NONE:
4491 if (elementDeclHandler)
4492 handleDefault = XML_FALSE;
4493 break;
4494 } /* end of big switch */
4495
4496 if (handleDefault && defaultHandler)
4497 reportDefault(parser, enc, s, next);
4498
Fred Drake31d485c2004-08-03 07:06:22 +00004499 switch (parsing) {
4500 case XML_SUSPENDED:
4501 *nextPtr = next;
4502 return XML_ERROR_NONE;
4503 case XML_FINISHED:
4504 return XML_ERROR_ABORTED;
4505 default:
4506 s = next;
4507 tok = XmlPrologTok(enc, s, end, &next);
4508 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004509 }
4510 /* not reached */
4511}
4512
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004513static enum XML_Error PTRCALL
4514epilogProcessor(XML_Parser parser,
4515 const char *s,
4516 const char *end,
4517 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004518{
4519 processor = epilogProcessor;
4520 eventPtr = s;
4521 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004522 const char *next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004523 int tok = XmlPrologTok(encoding, s, end, &next);
4524 eventEndPtr = next;
4525 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004526 /* report partial linebreak - it might be the last token */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004527 case -XML_TOK_PROLOG_S:
4528 if (defaultHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004529 reportDefault(parser, encoding, s, next);
Fred Drake31d485c2004-08-03 07:06:22 +00004530 if (parsing == XML_FINISHED)
4531 return XML_ERROR_ABORTED;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004532 }
Fred Drake31d485c2004-08-03 07:06:22 +00004533 *nextPtr = next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004534 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004535 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00004536 *nextPtr = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004537 return XML_ERROR_NONE;
4538 case XML_TOK_PROLOG_S:
4539 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004540 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004541 break;
4542 case XML_TOK_PI:
4543 if (!reportProcessingInstruction(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004544 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004545 break;
4546 case XML_TOK_COMMENT:
4547 if (!reportComment(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004548 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004549 break;
4550 case XML_TOK_INVALID:
4551 eventPtr = next;
4552 return XML_ERROR_INVALID_TOKEN;
4553 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00004554 if (!finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004555 *nextPtr = s;
4556 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004557 }
4558 return XML_ERROR_UNCLOSED_TOKEN;
4559 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00004560 if (!finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004561 *nextPtr = s;
4562 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004563 }
4564 return XML_ERROR_PARTIAL_CHAR;
4565 default:
4566 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4567 }
4568 eventPtr = s = next;
Fred Drake31d485c2004-08-03 07:06:22 +00004569 switch (parsing) {
4570 case XML_SUSPENDED:
4571 *nextPtr = next;
4572 return XML_ERROR_NONE;
4573 case XML_FINISHED:
4574 return XML_ERROR_ABORTED;
4575 default: ;
4576 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004577 }
4578}
4579
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004580static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +00004581processInternalEntity(XML_Parser parser, ENTITY *entity,
4582 XML_Bool betweenDecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004583{
Fred Drake31d485c2004-08-03 07:06:22 +00004584 const char *textStart, *textEnd;
4585 const char *next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004586 enum XML_Error result;
Fred Drake31d485c2004-08-03 07:06:22 +00004587 OPEN_INTERNAL_ENTITY *openEntity;
4588
4589 if (freeInternalEntities) {
4590 openEntity = freeInternalEntities;
4591 freeInternalEntities = openEntity->next;
4592 }
4593 else {
4594 openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4595 if (!openEntity)
4596 return XML_ERROR_NO_MEMORY;
4597 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004598 entity->open = XML_TRUE;
Fred Drake31d485c2004-08-03 07:06:22 +00004599 entity->processed = 0;
4600 openEntity->next = openInternalEntities;
4601 openInternalEntities = openEntity;
4602 openEntity->entity = entity;
4603 openEntity->startTagLevel = tagLevel;
4604 openEntity->betweenDecl = betweenDecl;
4605 openEntity->internalEventPtr = NULL;
4606 openEntity->internalEventEndPtr = NULL;
4607 textStart = (char *)entity->textPtr;
4608 textEnd = (char *)(entity->textPtr + entity->textLen);
4609
4610#ifdef XML_DTD
4611 if (entity->is_param) {
4612 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4613 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4614 next, &next, XML_FALSE);
4615 }
4616 else
4617#endif /* XML_DTD */
4618 result = doContent(parser, tagLevel, internalEncoding, textStart,
4619 textEnd, &next, XML_FALSE);
4620
4621 if (result == XML_ERROR_NONE) {
4622 if (textEnd != next && parsing == XML_SUSPENDED) {
4623 entity->processed = next - textStart;
4624 processor = internalEntityProcessor;
4625 }
4626 else {
4627 entity->open = XML_FALSE;
4628 openInternalEntities = openEntity->next;
4629 /* put openEntity back in list of free instances */
4630 openEntity->next = freeInternalEntities;
4631 freeInternalEntities = openEntity;
4632 }
4633 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004634 return result;
4635}
4636
Fred Drake31d485c2004-08-03 07:06:22 +00004637static enum XML_Error PTRCALL
4638internalEntityProcessor(XML_Parser parser,
4639 const char *s,
4640 const char *end,
4641 const char **nextPtr)
4642{
4643 ENTITY *entity;
4644 const char *textStart, *textEnd;
4645 const char *next;
4646 enum XML_Error result;
4647 OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4648 if (!openEntity)
4649 return XML_ERROR_UNEXPECTED_STATE;
4650
4651 entity = openEntity->entity;
4652 textStart = ((char *)entity->textPtr) + entity->processed;
4653 textEnd = (char *)(entity->textPtr + entity->textLen);
4654
4655#ifdef XML_DTD
4656 if (entity->is_param) {
4657 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4658 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4659 next, &next, XML_FALSE);
4660 }
4661 else
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004662#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00004663 result = doContent(parser, openEntity->startTagLevel, internalEncoding,
4664 textStart, textEnd, &next, XML_FALSE);
4665
4666 if (result != XML_ERROR_NONE)
4667 return result;
4668 else if (textEnd != next && parsing == XML_SUSPENDED) {
4669 entity->processed = next - (char *)entity->textPtr;
4670 return result;
4671 }
4672 else {
4673 entity->open = XML_FALSE;
4674 openInternalEntities = openEntity->next;
4675 /* put openEntity back in list of free instances */
4676 openEntity->next = freeInternalEntities;
4677 freeInternalEntities = openEntity;
4678 }
4679
4680#ifdef XML_DTD
4681 if (entity->is_param) {
4682 int tok;
4683 processor = prologProcessor;
4684 tok = XmlPrologTok(encoding, s, end, &next);
4685 return doProlog(parser, encoding, s, end, tok, next, nextPtr,
4686 (XML_Bool)!finalBuffer);
4687 }
4688 else
4689#endif /* XML_DTD */
4690 {
4691 processor = contentProcessor;
4692 /* see externalEntityContentProcessor vs contentProcessor */
4693 return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
4694 nextPtr, (XML_Bool)!finalBuffer);
4695 }
4696}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004697
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004698static enum XML_Error PTRCALL
4699errorProcessor(XML_Parser parser,
4700 const char *s,
4701 const char *end,
4702 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004703{
4704 return errorCode;
4705}
4706
4707static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004708storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4709 const char *ptr, const char *end,
4710 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004711{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004712 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4713 end, pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004714 if (result)
4715 return result;
4716 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4717 poolChop(pool);
4718 if (!poolAppendChar(pool, XML_T('\0')))
4719 return XML_ERROR_NO_MEMORY;
4720 return XML_ERROR_NONE;
4721}
4722
4723static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004724appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4725 const char *ptr, const char *end,
4726 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004727{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004728 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004729 for (;;) {
4730 const char *next;
4731 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4732 switch (tok) {
4733 case XML_TOK_NONE:
4734 return XML_ERROR_NONE;
4735 case XML_TOK_INVALID:
4736 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004737 eventPtr = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004738 return XML_ERROR_INVALID_TOKEN;
4739 case XML_TOK_PARTIAL:
4740 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004741 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004742 return XML_ERROR_INVALID_TOKEN;
4743 case XML_TOK_CHAR_REF:
4744 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004745 XML_Char buf[XML_ENCODE_MAX];
4746 int i;
4747 int n = XmlCharRefNumber(enc, ptr);
4748 if (n < 0) {
4749 if (enc == encoding)
4750 eventPtr = ptr;
4751 return XML_ERROR_BAD_CHAR_REF;
4752 }
4753 if (!isCdata
4754 && n == 0x20 /* space */
4755 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4756 break;
4757 n = XmlEncode(n, (ICHAR *)buf);
4758 if (!n) {
4759 if (enc == encoding)
4760 eventPtr = ptr;
4761 return XML_ERROR_BAD_CHAR_REF;
4762 }
4763 for (i = 0; i < n; i++) {
4764 if (!poolAppendChar(pool, buf[i]))
4765 return XML_ERROR_NO_MEMORY;
4766 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004767 }
4768 break;
4769 case XML_TOK_DATA_CHARS:
4770 if (!poolAppend(pool, enc, ptr, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004771 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004772 break;
4773 case XML_TOK_TRAILING_CR:
4774 next = ptr + enc->minBytesPerChar;
4775 /* fall through */
4776 case XML_TOK_ATTRIBUTE_VALUE_S:
4777 case XML_TOK_DATA_NEWLINE:
4778 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004779 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004780 if (!poolAppendChar(pool, 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004781 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004782 break;
4783 case XML_TOK_ENTITY_REF:
4784 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004785 const XML_Char *name;
4786 ENTITY *entity;
4787 char checkEntityDecl;
4788 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4789 ptr + enc->minBytesPerChar,
4790 next - enc->minBytesPerChar);
4791 if (ch) {
4792 if (!poolAppendChar(pool, ch))
4793 return XML_ERROR_NO_MEMORY;
4794 break;
4795 }
4796 name = poolStoreString(&temp2Pool, enc,
4797 ptr + enc->minBytesPerChar,
4798 next - enc->minBytesPerChar);
4799 if (!name)
4800 return XML_ERROR_NO_MEMORY;
4801 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
4802 poolDiscard(&temp2Pool);
4803 /* first, determine if a check for an existing declaration is needed;
4804 if yes, check that the entity exists, and that it is internal,
4805 otherwise call the default handler (if called from content)
4806 */
4807 if (pool == &dtd->pool) /* are we called from prolog? */
4808 checkEntityDecl =
4809#ifdef XML_DTD
4810 prologState.documentEntity &&
4811#endif /* XML_DTD */
4812 (dtd->standalone
4813 ? !openInternalEntities
4814 : !dtd->hasParamEntityRefs);
4815 else /* if (pool == &tempPool): we are called from content */
4816 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4817 if (checkEntityDecl) {
4818 if (!entity)
4819 return XML_ERROR_UNDEFINED_ENTITY;
4820 else if (!entity->is_internal)
4821 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4822 }
4823 else if (!entity) {
4824 /* cannot report skipped entity here - see comments on
4825 skippedEntityHandler
4826 if (skippedEntityHandler)
4827 skippedEntityHandler(handlerArg, name, 0);
4828 */
4829 if ((pool == &tempPool) && defaultHandler)
4830 reportDefault(parser, enc, ptr, next);
4831 break;
4832 }
4833 if (entity->open) {
4834 if (enc == encoding)
4835 eventPtr = ptr;
4836 return XML_ERROR_RECURSIVE_ENTITY_REF;
4837 }
4838 if (entity->notation) {
4839 if (enc == encoding)
4840 eventPtr = ptr;
4841 return XML_ERROR_BINARY_ENTITY_REF;
4842 }
4843 if (!entity->textPtr) {
4844 if (enc == encoding)
4845 eventPtr = ptr;
4846 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4847 }
4848 else {
4849 enum XML_Error result;
4850 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4851 entity->open = XML_TRUE;
4852 result = appendAttributeValue(parser, internalEncoding, isCdata,
4853 (char *)entity->textPtr,
4854 (char *)textEnd, pool);
4855 entity->open = XML_FALSE;
4856 if (result)
4857 return result;
4858 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004859 }
4860 break;
4861 default:
4862 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004863 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004864 return XML_ERROR_UNEXPECTED_STATE;
4865 }
4866 ptr = next;
4867 }
4868 /* not reached */
4869}
4870
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004871static enum XML_Error
4872storeEntityValue(XML_Parser parser,
4873 const ENCODING *enc,
4874 const char *entityTextPtr,
4875 const char *entityTextEnd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004876{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004877 DTD * const dtd = _dtd; /* save one level of indirection */
4878 STRING_POOL *pool = &(dtd->entityValuePool);
4879 enum XML_Error result = XML_ERROR_NONE;
4880#ifdef XML_DTD
4881 int oldInEntityValue = prologState.inEntityValue;
4882 prologState.inEntityValue = 1;
4883#endif /* XML_DTD */
4884 /* never return Null for the value argument in EntityDeclHandler,
4885 since this would indicate an external entity; therefore we
4886 have to make sure that entityValuePool.start is not null */
4887 if (!pool->blocks) {
4888 if (!poolGrow(pool))
4889 return XML_ERROR_NO_MEMORY;
4890 }
4891
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004892 for (;;) {
4893 const char *next;
4894 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4895 switch (tok) {
4896 case XML_TOK_PARAM_ENTITY_REF:
4897#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004898 if (isParamEntity || enc != encoding) {
4899 const XML_Char *name;
4900 ENTITY *entity;
4901 name = poolStoreString(&tempPool, enc,
4902 entityTextPtr + enc->minBytesPerChar,
4903 next - enc->minBytesPerChar);
4904 if (!name) {
4905 result = XML_ERROR_NO_MEMORY;
4906 goto endEntityValue;
4907 }
4908 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4909 poolDiscard(&tempPool);
4910 if (!entity) {
4911 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4912 /* cannot report skipped entity here - see comments on
4913 skippedEntityHandler
4914 if (skippedEntityHandler)
4915 skippedEntityHandler(handlerArg, name, 0);
4916 */
4917 dtd->keepProcessing = dtd->standalone;
4918 goto endEntityValue;
4919 }
4920 if (entity->open) {
4921 if (enc == encoding)
4922 eventPtr = entityTextPtr;
4923 result = XML_ERROR_RECURSIVE_ENTITY_REF;
4924 goto endEntityValue;
4925 }
4926 if (entity->systemId) {
4927 if (externalEntityRefHandler) {
4928 dtd->paramEntityRead = XML_FALSE;
4929 entity->open = XML_TRUE;
4930 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4931 0,
4932 entity->base,
4933 entity->systemId,
4934 entity->publicId)) {
4935 entity->open = XML_FALSE;
4936 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4937 goto endEntityValue;
4938 }
4939 entity->open = XML_FALSE;
4940 if (!dtd->paramEntityRead)
4941 dtd->keepProcessing = dtd->standalone;
4942 }
4943 else
4944 dtd->keepProcessing = dtd->standalone;
4945 }
4946 else {
4947 entity->open = XML_TRUE;
4948 result = storeEntityValue(parser,
4949 internalEncoding,
4950 (char *)entity->textPtr,
4951 (char *)(entity->textPtr
4952 + entity->textLen));
4953 entity->open = XML_FALSE;
4954 if (result)
4955 goto endEntityValue;
4956 }
4957 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004958 }
4959#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00004960 /* In the internal subset, PE references are not legal
4961 within markup declarations, e.g entity values in this case. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004962 eventPtr = entityTextPtr;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004963 result = XML_ERROR_PARAM_ENTITY_REF;
4964 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004965 case XML_TOK_NONE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004966 result = XML_ERROR_NONE;
4967 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004968 case XML_TOK_ENTITY_REF:
4969 case XML_TOK_DATA_CHARS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004970 if (!poolAppend(pool, enc, entityTextPtr, next)) {
4971 result = XML_ERROR_NO_MEMORY;
4972 goto endEntityValue;
4973 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004974 break;
4975 case XML_TOK_TRAILING_CR:
4976 next = entityTextPtr + enc->minBytesPerChar;
4977 /* fall through */
4978 case XML_TOK_DATA_NEWLINE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004979 if (pool->end == pool->ptr && !poolGrow(pool)) {
4980 result = XML_ERROR_NO_MEMORY;
4981 goto endEntityValue;
4982 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004983 *(pool->ptr)++ = 0xA;
4984 break;
4985 case XML_TOK_CHAR_REF:
4986 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004987 XML_Char buf[XML_ENCODE_MAX];
4988 int i;
4989 int n = XmlCharRefNumber(enc, entityTextPtr);
4990 if (n < 0) {
4991 if (enc == encoding)
4992 eventPtr = entityTextPtr;
4993 result = XML_ERROR_BAD_CHAR_REF;
4994 goto endEntityValue;
4995 }
4996 n = XmlEncode(n, (ICHAR *)buf);
4997 if (!n) {
4998 if (enc == encoding)
4999 eventPtr = entityTextPtr;
5000 result = XML_ERROR_BAD_CHAR_REF;
5001 goto endEntityValue;
5002 }
5003 for (i = 0; i < n; i++) {
5004 if (pool->end == pool->ptr && !poolGrow(pool)) {
5005 result = XML_ERROR_NO_MEMORY;
5006 goto endEntityValue;
5007 }
5008 *(pool->ptr)++ = buf[i];
5009 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005010 }
5011 break;
5012 case XML_TOK_PARTIAL:
5013 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005014 eventPtr = entityTextPtr;
5015 result = XML_ERROR_INVALID_TOKEN;
5016 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005017 case XML_TOK_INVALID:
5018 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005019 eventPtr = next;
5020 result = XML_ERROR_INVALID_TOKEN;
5021 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005022 default:
5023 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005024 eventPtr = entityTextPtr;
5025 result = XML_ERROR_UNEXPECTED_STATE;
5026 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005027 }
5028 entityTextPtr = next;
5029 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005030endEntityValue:
5031#ifdef XML_DTD
5032 prologState.inEntityValue = oldInEntityValue;
5033#endif /* XML_DTD */
5034 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005035}
5036
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005037static void FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005038normalizeLines(XML_Char *s)
5039{
5040 XML_Char *p;
5041 for (;; s++) {
5042 if (*s == XML_T('\0'))
5043 return;
5044 if (*s == 0xD)
5045 break;
5046 }
5047 p = s;
5048 do {
5049 if (*s == 0xD) {
5050 *p++ = 0xA;
5051 if (*++s == 0xA)
5052 s++;
5053 }
5054 else
5055 *p++ = *s++;
5056 } while (*s);
5057 *p = XML_T('\0');
5058}
5059
5060static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005061reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5062 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005063{
5064 const XML_Char *target;
5065 XML_Char *data;
5066 const char *tem;
5067 if (!processingInstructionHandler) {
5068 if (defaultHandler)
5069 reportDefault(parser, enc, start, end);
5070 return 1;
5071 }
5072 start += enc->minBytesPerChar * 2;
5073 tem = start + XmlNameLength(enc, start);
5074 target = poolStoreString(&tempPool, enc, start, tem);
5075 if (!target)
5076 return 0;
5077 poolFinish(&tempPool);
5078 data = poolStoreString(&tempPool, enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005079 XmlSkipS(enc, tem),
5080 end - enc->minBytesPerChar*2);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005081 if (!data)
5082 return 0;
5083 normalizeLines(data);
5084 processingInstructionHandler(handlerArg, target, data);
5085 poolClear(&tempPool);
5086 return 1;
5087}
5088
5089static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005090reportComment(XML_Parser parser, const ENCODING *enc,
5091 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005092{
5093 XML_Char *data;
5094 if (!commentHandler) {
5095 if (defaultHandler)
5096 reportDefault(parser, enc, start, end);
5097 return 1;
5098 }
5099 data = poolStoreString(&tempPool,
5100 enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005101 start + enc->minBytesPerChar * 4,
5102 end - enc->minBytesPerChar * 3);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005103 if (!data)
5104 return 0;
5105 normalizeLines(data);
5106 commentHandler(handlerArg, data);
5107 poolClear(&tempPool);
5108 return 1;
5109}
5110
5111static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005112reportDefault(XML_Parser parser, const ENCODING *enc,
5113 const char *s, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005114{
5115 if (MUST_CONVERT(enc, s)) {
5116 const char **eventPP;
5117 const char **eventEndPP;
5118 if (enc == encoding) {
5119 eventPP = &eventPtr;
5120 eventEndPP = &eventEndPtr;
5121 }
5122 else {
5123 eventPP = &(openInternalEntities->internalEventPtr);
5124 eventEndPP = &(openInternalEntities->internalEventEndPtr);
5125 }
5126 do {
5127 ICHAR *dataPtr = (ICHAR *)dataBuf;
5128 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5129 *eventEndPP = s;
5130 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
5131 *eventPP = s;
5132 } while (s != end);
5133 }
5134 else
5135 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
5136}
5137
5138
5139static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005140defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5141 XML_Bool isId, const XML_Char *value, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005142{
5143 DEFAULT_ATTRIBUTE *att;
5144 if (value || isId) {
5145 /* The handling of default attributes gets messed up if we have
5146 a default which duplicates a non-default. */
5147 int i;
5148 for (i = 0; i < type->nDefaultAtts; i++)
5149 if (attId == type->defaultAtts[i].id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005150 return 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005151 if (isId && !type->idAtt && !attId->xmlns)
5152 type->idAtt = attId;
5153 }
5154 if (type->nDefaultAtts == type->allocDefaultAtts) {
5155 if (type->allocDefaultAtts == 0) {
5156 type->allocDefaultAtts = 8;
Fred Drake08317ae2003-10-21 15:38:55 +00005157 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005158 * sizeof(DEFAULT_ATTRIBUTE));
5159 if (!type->defaultAtts)
5160 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005161 }
5162 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005163 DEFAULT_ATTRIBUTE *temp;
5164 int count = type->allocDefaultAtts * 2;
5165 temp = (DEFAULT_ATTRIBUTE *)
5166 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5167 if (temp == NULL)
5168 return 0;
5169 type->allocDefaultAtts = count;
5170 type->defaultAtts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005171 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005172 }
5173 att = type->defaultAtts + type->nDefaultAtts;
5174 att->id = attId;
5175 att->value = value;
5176 att->isCdata = isCdata;
5177 if (!isCdata)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005178 attId->maybeTokenized = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005179 type->nDefaultAtts += 1;
5180 return 1;
5181}
5182
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005183static int
5184setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005185{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005186 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005187 const XML_Char *name;
5188 for (name = elementType->name; *name; name++) {
5189 if (*name == XML_T(':')) {
5190 PREFIX *prefix;
5191 const XML_Char *s;
5192 for (s = elementType->name; s != name; s++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005193 if (!poolAppendChar(&dtd->pool, *s))
5194 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005195 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005196 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5197 return 0;
5198 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
5199 sizeof(PREFIX));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005200 if (!prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005201 return 0;
5202 if (prefix->name == poolStart(&dtd->pool))
5203 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005204 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005205 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005206 elementType->prefix = prefix;
5207
5208 }
5209 }
5210 return 1;
5211}
5212
5213static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005214getAttributeId(XML_Parser parser, const ENCODING *enc,
5215 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005216{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005217 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005218 ATTRIBUTE_ID *id;
5219 const XML_Char *name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005220 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5221 return NULL;
5222 name = poolStoreString(&dtd->pool, enc, start, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005223 if (!name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005224 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005225 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005226 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005227 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005228 if (!id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005229 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005230 if (id->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005231 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005232 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005233 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005234 if (!ns)
5235 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005236 else if (name[0] == XML_T('x')
5237 && name[1] == XML_T('m')
5238 && name[2] == XML_T('l')
5239 && name[3] == XML_T('n')
5240 && name[4] == XML_T('s')
5241 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
5242 if (name[5] == XML_T('\0'))
5243 id->prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005244 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005245 id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
5246 id->xmlns = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005247 }
5248 else {
5249 int i;
5250 for (i = 0; name[i]; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00005251 /* attributes without prefix are *not* in the default namespace */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005252 if (name[i] == XML_T(':')) {
5253 int j;
5254 for (j = 0; j < i; j++) {
5255 if (!poolAppendChar(&dtd->pool, name[j]))
5256 return NULL;
5257 }
5258 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5259 return NULL;
5260 id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
5261 sizeof(PREFIX));
5262 if (id->prefix->name == poolStart(&dtd->pool))
5263 poolFinish(&dtd->pool);
5264 else
5265 poolDiscard(&dtd->pool);
5266 break;
5267 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005268 }
5269 }
5270 }
5271 return id;
5272}
5273
5274#define CONTEXT_SEP XML_T('\f')
5275
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005276static const XML_Char *
5277getContext(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005278{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005279 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005280 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005281 XML_Bool needSep = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005282
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005283 if (dtd->defaultPrefix.binding) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005284 int i;
5285 int len;
5286 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005287 return NULL;
5288 len = dtd->defaultPrefix.binding->uriLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005289 if (namespaceSeparator != XML_T('\0'))
5290 len--;
5291 for (i = 0; i < len; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005292 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5293 return NULL;
5294 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005295 }
5296
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005297 hashTableIterInit(&iter, &(dtd->prefixes));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005298 for (;;) {
5299 int i;
5300 int len;
5301 const XML_Char *s;
5302 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5303 if (!prefix)
5304 break;
5305 if (!prefix->binding)
5306 continue;
5307 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005308 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005309 for (s = prefix->name; *s; s++)
5310 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005311 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005312 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005313 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005314 len = prefix->binding->uriLen;
5315 if (namespaceSeparator != XML_T('\0'))
5316 len--;
5317 for (i = 0; i < len; i++)
5318 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005319 return NULL;
5320 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005321 }
5322
5323
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005324 hashTableIterInit(&iter, &(dtd->generalEntities));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005325 for (;;) {
5326 const XML_Char *s;
5327 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5328 if (!e)
5329 break;
5330 if (!e->open)
5331 continue;
5332 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005333 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005334 for (s = e->name; *s; s++)
5335 if (!poolAppendChar(&tempPool, *s))
5336 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005337 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005338 }
5339
5340 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005341 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005342 return tempPool.start;
5343}
5344
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005345static XML_Bool
5346setContext(XML_Parser parser, const XML_Char *context)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005347{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005348 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005349 const XML_Char *s = context;
5350
5351 while (*context != XML_T('\0')) {
5352 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5353 ENTITY *e;
5354 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005355 return XML_FALSE;
5356 e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005357 if (e)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005358 e->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005359 if (*s != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005360 s++;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005361 context = s;
5362 poolDiscard(&tempPool);
5363 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005364 else if (*s == XML_T('=')) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005365 PREFIX *prefix;
5366 if (poolLength(&tempPool) == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005367 prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005368 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005369 if (!poolAppendChar(&tempPool, XML_T('\0')))
5370 return XML_FALSE;
5371 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
5372 sizeof(PREFIX));
5373 if (!prefix)
5374 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005375 if (prefix->name == poolStart(&tempPool)) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005376 prefix->name = poolCopyString(&dtd->pool, prefix->name);
5377 if (!prefix->name)
5378 return XML_FALSE;
5379 }
5380 poolDiscard(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005381 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005382 for (context = s + 1;
5383 *context != CONTEXT_SEP && *context != XML_T('\0');
5384 context++)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005385 if (!poolAppendChar(&tempPool, *context))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005386 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005387 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005388 return XML_FALSE;
Fred Drake31d485c2004-08-03 07:06:22 +00005389 if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005390 &inheritedBindings) != XML_ERROR_NONE)
5391 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005392 poolDiscard(&tempPool);
5393 if (*context != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005394 ++context;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005395 s = context;
5396 }
5397 else {
5398 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005399 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005400 s++;
5401 }
5402 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005403 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005404}
5405
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005406static void FASTCALL
5407normalizePublicId(XML_Char *publicId)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005408{
5409 XML_Char *p = publicId;
5410 XML_Char *s;
5411 for (s = publicId; *s; s++) {
5412 switch (*s) {
5413 case 0x20:
5414 case 0xD:
5415 case 0xA:
5416 if (p != publicId && p[-1] != 0x20)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005417 *p++ = 0x20;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005418 break;
5419 default:
5420 *p++ = *s;
5421 }
5422 }
5423 if (p != publicId && p[-1] == 0x20)
5424 --p;
5425 *p = XML_T('\0');
5426}
5427
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005428static DTD *
5429dtdCreate(const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005430{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005431 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5432 if (p == NULL)
5433 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005434 poolInit(&(p->pool), ms);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005435 poolInit(&(p->entityValuePool), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005436 hashTableInit(&(p->generalEntities), ms);
5437 hashTableInit(&(p->elementTypes), ms);
5438 hashTableInit(&(p->attributeIds), ms);
5439 hashTableInit(&(p->prefixes), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005440#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005441 p->paramEntityRead = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005442 hashTableInit(&(p->paramEntities), ms);
5443#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005444 p->defaultPrefix.name = NULL;
5445 p->defaultPrefix.binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005446
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005447 p->in_eldecl = XML_FALSE;
5448 p->scaffIndex = NULL;
5449 p->scaffold = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005450 p->scaffLevel = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005451 p->scaffSize = 0;
5452 p->scaffCount = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005453 p->contentStringLen = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005454
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005455 p->keepProcessing = XML_TRUE;
5456 p->hasParamEntityRefs = XML_FALSE;
5457 p->standalone = XML_FALSE;
5458 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005459}
5460
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005461static void
5462dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005463{
5464 HASH_TABLE_ITER iter;
5465 hashTableIterInit(&iter, &(p->elementTypes));
5466 for (;;) {
5467 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5468 if (!e)
5469 break;
5470 if (e->allocDefaultAtts != 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005471 ms->free_fcn(e->defaultAtts);
5472 }
5473 hashTableClear(&(p->generalEntities));
5474#ifdef XML_DTD
5475 p->paramEntityRead = XML_FALSE;
5476 hashTableClear(&(p->paramEntities));
5477#endif /* XML_DTD */
5478 hashTableClear(&(p->elementTypes));
5479 hashTableClear(&(p->attributeIds));
5480 hashTableClear(&(p->prefixes));
5481 poolClear(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005482 poolClear(&(p->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005483 p->defaultPrefix.name = NULL;
5484 p->defaultPrefix.binding = NULL;
5485
5486 p->in_eldecl = XML_FALSE;
Fred Drake08317ae2003-10-21 15:38:55 +00005487
5488 ms->free_fcn(p->scaffIndex);
5489 p->scaffIndex = NULL;
5490 ms->free_fcn(p->scaffold);
5491 p->scaffold = NULL;
5492
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005493 p->scaffLevel = 0;
5494 p->scaffSize = 0;
5495 p->scaffCount = 0;
5496 p->contentStringLen = 0;
5497
5498 p->keepProcessing = XML_TRUE;
5499 p->hasParamEntityRefs = XML_FALSE;
5500 p->standalone = XML_FALSE;
5501}
5502
5503static void
5504dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5505{
5506 HASH_TABLE_ITER iter;
5507 hashTableIterInit(&iter, &(p->elementTypes));
5508 for (;;) {
5509 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5510 if (!e)
5511 break;
5512 if (e->allocDefaultAtts != 0)
5513 ms->free_fcn(e->defaultAtts);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005514 }
5515 hashTableDestroy(&(p->generalEntities));
5516#ifdef XML_DTD
5517 hashTableDestroy(&(p->paramEntities));
5518#endif /* XML_DTD */
5519 hashTableDestroy(&(p->elementTypes));
5520 hashTableDestroy(&(p->attributeIds));
5521 hashTableDestroy(&(p->prefixes));
5522 poolDestroy(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005523 poolDestroy(&(p->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005524 if (isDocEntity) {
Fred Drake08317ae2003-10-21 15:38:55 +00005525 ms->free_fcn(p->scaffIndex);
5526 ms->free_fcn(p->scaffold);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005527 }
5528 ms->free_fcn(p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005529}
5530
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005531/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5532 The new DTD has already been initialized.
5533*/
5534static int
5535dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005536{
5537 HASH_TABLE_ITER iter;
5538
5539 /* Copy the prefix table. */
5540
5541 hashTableIterInit(&iter, &(oldDtd->prefixes));
5542 for (;;) {
5543 const XML_Char *name;
5544 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5545 if (!oldP)
5546 break;
5547 name = poolCopyString(&(newDtd->pool), oldP->name);
5548 if (!name)
5549 return 0;
5550 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5551 return 0;
5552 }
5553
5554 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5555
5556 /* Copy the attribute id table. */
5557
5558 for (;;) {
5559 ATTRIBUTE_ID *newA;
5560 const XML_Char *name;
5561 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5562
5563 if (!oldA)
5564 break;
5565 /* Remember to allocate the scratch byte before the name. */
5566 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5567 return 0;
5568 name = poolCopyString(&(newDtd->pool), oldA->name);
5569 if (!name)
5570 return 0;
5571 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005572 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5573 sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005574 if (!newA)
5575 return 0;
5576 newA->maybeTokenized = oldA->maybeTokenized;
5577 if (oldA->prefix) {
5578 newA->xmlns = oldA->xmlns;
5579 if (oldA->prefix == &oldDtd->defaultPrefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005580 newA->prefix = &newDtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005581 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005582 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5583 oldA->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005584 }
5585 }
5586
5587 /* Copy the element type table. */
5588
5589 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5590
5591 for (;;) {
5592 int i;
5593 ELEMENT_TYPE *newE;
5594 const XML_Char *name;
5595 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5596 if (!oldE)
5597 break;
5598 name = poolCopyString(&(newDtd->pool), oldE->name);
5599 if (!name)
5600 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005601 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5602 sizeof(ELEMENT_TYPE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005603 if (!newE)
5604 return 0;
5605 if (oldE->nDefaultAtts) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005606 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5607 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5608 if (!newE->defaultAtts) {
5609 ms->free_fcn(newE);
5610 return 0;
5611 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005612 }
5613 if (oldE->idAtt)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005614 newE->idAtt = (ATTRIBUTE_ID *)
5615 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005616 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5617 if (oldE->prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005618 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5619 oldE->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005620 for (i = 0; i < newE->nDefaultAtts; i++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005621 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5622 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005623 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5624 if (oldE->defaultAtts[i].value) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005625 newE->defaultAtts[i].value
5626 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5627 if (!newE->defaultAtts[i].value)
5628 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005629 }
5630 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005631 newE->defaultAtts[i].value = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005632 }
5633 }
5634
5635 /* Copy the entity tables. */
5636 if (!copyEntityTable(&(newDtd->generalEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005637 &(newDtd->pool),
5638 &(oldDtd->generalEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005639 return 0;
5640
5641#ifdef XML_DTD
5642 if (!copyEntityTable(&(newDtd->paramEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005643 &(newDtd->pool),
5644 &(oldDtd->paramEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005645 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005646 newDtd->paramEntityRead = oldDtd->paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005647#endif /* XML_DTD */
5648
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005649 newDtd->keepProcessing = oldDtd->keepProcessing;
5650 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005651 newDtd->standalone = oldDtd->standalone;
5652
5653 /* Don't want deep copying for scaffolding */
5654 newDtd->in_eldecl = oldDtd->in_eldecl;
5655 newDtd->scaffold = oldDtd->scaffold;
5656 newDtd->contentStringLen = oldDtd->contentStringLen;
5657 newDtd->scaffSize = oldDtd->scaffSize;
5658 newDtd->scaffLevel = oldDtd->scaffLevel;
5659 newDtd->scaffIndex = oldDtd->scaffIndex;
5660
5661 return 1;
5662} /* End dtdCopy */
5663
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005664static int
5665copyEntityTable(HASH_TABLE *newTable,
5666 STRING_POOL *newPool,
5667 const HASH_TABLE *oldTable)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005668{
5669 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005670 const XML_Char *cachedOldBase = NULL;
5671 const XML_Char *cachedNewBase = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005672
5673 hashTableIterInit(&iter, oldTable);
5674
5675 for (;;) {
5676 ENTITY *newE;
5677 const XML_Char *name;
5678 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5679 if (!oldE)
5680 break;
5681 name = poolCopyString(newPool, oldE->name);
5682 if (!name)
5683 return 0;
5684 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5685 if (!newE)
5686 return 0;
5687 if (oldE->systemId) {
5688 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5689 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005690 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005691 newE->systemId = tem;
5692 if (oldE->base) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005693 if (oldE->base == cachedOldBase)
5694 newE->base = cachedNewBase;
5695 else {
5696 cachedOldBase = oldE->base;
5697 tem = poolCopyString(newPool, cachedOldBase);
5698 if (!tem)
5699 return 0;
5700 cachedNewBase = newE->base = tem;
5701 }
5702 }
5703 if (oldE->publicId) {
5704 tem = poolCopyString(newPool, oldE->publicId);
5705 if (!tem)
5706 return 0;
5707 newE->publicId = tem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005708 }
5709 }
5710 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005711 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5712 oldE->textLen);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005713 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005714 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005715 newE->textPtr = tem;
5716 newE->textLen = oldE->textLen;
5717 }
5718 if (oldE->notation) {
5719 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5720 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005721 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005722 newE->notation = tem;
5723 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005724 newE->is_param = oldE->is_param;
5725 newE->is_internal = oldE->is_internal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005726 }
5727 return 1;
5728}
5729
Fred Drake08317ae2003-10-21 15:38:55 +00005730#define INIT_POWER 6
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005731
Fred Drake08317ae2003-10-21 15:38:55 +00005732static XML_Bool FASTCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005733keyeq(KEY s1, KEY s2)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005734{
5735 for (; *s1 == *s2; s1++, s2++)
5736 if (*s1 == 0)
Fred Drake08317ae2003-10-21 15:38:55 +00005737 return XML_TRUE;
5738 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005739}
5740
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005741static unsigned long FASTCALL
5742hash(KEY s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005743{
5744 unsigned long h = 0;
5745 while (*s)
Fred Drake08317ae2003-10-21 15:38:55 +00005746 h = CHAR_HASH(h, *s++);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005747 return h;
5748}
5749
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005750static NAMED *
5751lookup(HASH_TABLE *table, KEY name, size_t createSize)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005752{
5753 size_t i;
5754 if (table->size == 0) {
5755 size_t tsize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005756 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005757 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005758 table->power = INIT_POWER;
5759 /* table->size is a power of 2 */
5760 table->size = (size_t)1 << INIT_POWER;
5761 tsize = table->size * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005762 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Fred Drake31d485c2004-08-03 07:06:22 +00005763 if (!table->v) {
5764 table->size = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005765 return NULL;
Fred Drake31d485c2004-08-03 07:06:22 +00005766 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005767 memset(table->v, 0, tsize);
Fred Drake08317ae2003-10-21 15:38:55 +00005768 i = hash(name) & ((unsigned long)table->size - 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005769 }
5770 else {
5771 unsigned long h = hash(name);
Fred Drake08317ae2003-10-21 15:38:55 +00005772 unsigned long mask = (unsigned long)table->size - 1;
5773 unsigned char step = 0;
5774 i = h & mask;
5775 while (table->v[i]) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005776 if (keyeq(name, table->v[i]->name))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005777 return table->v[i];
Fred Drake08317ae2003-10-21 15:38:55 +00005778 if (!step)
5779 step = PROBE_STEP(h, mask, table->power);
5780 i < step ? (i += table->size - step) : (i -= step);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005781 }
5782 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005783 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005784
5785 /* check for overflow (table is half full) */
5786 if (table->used >> (table->power - 1)) {
5787 unsigned char newPower = table->power + 1;
5788 size_t newSize = (size_t)1 << newPower;
5789 unsigned long newMask = (unsigned long)newSize - 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005790 size_t tsize = newSize * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005791 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005792 if (!newV)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005793 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005794 memset(newV, 0, tsize);
5795 for (i = 0; i < table->size; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005796 if (table->v[i]) {
Fred Drake08317ae2003-10-21 15:38:55 +00005797 unsigned long newHash = hash(table->v[i]->name);
5798 size_t j = newHash & newMask;
5799 step = 0;
5800 while (newV[j]) {
5801 if (!step)
5802 step = PROBE_STEP(newHash, newMask, newPower);
5803 j < step ? (j += newSize - step) : (j -= step);
5804 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005805 newV[j] = table->v[i];
5806 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005807 table->mem->free_fcn(table->v);
5808 table->v = newV;
Fred Drake08317ae2003-10-21 15:38:55 +00005809 table->power = newPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005810 table->size = newSize;
Fred Drake08317ae2003-10-21 15:38:55 +00005811 i = h & newMask;
5812 step = 0;
5813 while (table->v[i]) {
5814 if (!step)
5815 step = PROBE_STEP(h, newMask, newPower);
5816 i < step ? (i += newSize - step) : (i -= step);
5817 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005818 }
5819 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005820 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005821 if (!table->v[i])
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005822 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005823 memset(table->v[i], 0, createSize);
5824 table->v[i]->name = name;
5825 (table->used)++;
5826 return table->v[i];
5827}
5828
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005829static void FASTCALL
5830hashTableClear(HASH_TABLE *table)
5831{
5832 size_t i;
5833 for (i = 0; i < table->size; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00005834 table->mem->free_fcn(table->v[i]);
5835 table->v[i] = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005836 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005837 table->used = 0;
5838}
5839
5840static void FASTCALL
5841hashTableDestroy(HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005842{
5843 size_t i;
Fred Drake08317ae2003-10-21 15:38:55 +00005844 for (i = 0; i < table->size; i++)
5845 table->mem->free_fcn(table->v[i]);
5846 table->mem->free_fcn(table->v);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005847}
5848
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005849static void FASTCALL
5850hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005851{
Fred Drake08317ae2003-10-21 15:38:55 +00005852 p->power = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005853 p->size = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005854 p->used = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005855 p->v = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005856 p->mem = ms;
5857}
5858
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005859static void FASTCALL
5860hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005861{
5862 iter->p = table->v;
5863 iter->end = iter->p + table->size;
5864}
5865
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005866static NAMED * FASTCALL
5867hashTableIterNext(HASH_TABLE_ITER *iter)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005868{
5869 while (iter->p != iter->end) {
5870 NAMED *tem = *(iter->p)++;
5871 if (tem)
5872 return tem;
5873 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005874 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005875}
5876
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005877static void FASTCALL
5878poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005879{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005880 pool->blocks = NULL;
5881 pool->freeBlocks = NULL;
5882 pool->start = NULL;
5883 pool->ptr = NULL;
5884 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005885 pool->mem = ms;
5886}
5887
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005888static void FASTCALL
5889poolClear(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005890{
5891 if (!pool->freeBlocks)
5892 pool->freeBlocks = pool->blocks;
5893 else {
5894 BLOCK *p = pool->blocks;
5895 while (p) {
5896 BLOCK *tem = p->next;
5897 p->next = pool->freeBlocks;
5898 pool->freeBlocks = p;
5899 p = tem;
5900 }
5901 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005902 pool->blocks = NULL;
5903 pool->start = NULL;
5904 pool->ptr = NULL;
5905 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005906}
5907
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005908static void FASTCALL
5909poolDestroy(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005910{
5911 BLOCK *p = pool->blocks;
5912 while (p) {
5913 BLOCK *tem = p->next;
5914 pool->mem->free_fcn(p);
5915 p = tem;
5916 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005917 p = pool->freeBlocks;
5918 while (p) {
5919 BLOCK *tem = p->next;
5920 pool->mem->free_fcn(p);
5921 p = tem;
5922 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005923}
5924
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005925static XML_Char *
5926poolAppend(STRING_POOL *pool, const ENCODING *enc,
5927 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005928{
5929 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005930 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005931 for (;;) {
5932 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
5933 if (ptr == end)
5934 break;
5935 if (!poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005936 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005937 }
5938 return pool->start;
5939}
5940
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005941static const XML_Char * FASTCALL
5942poolCopyString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005943{
5944 do {
5945 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005946 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005947 } while (*s++);
5948 s = pool->start;
5949 poolFinish(pool);
5950 return s;
5951}
5952
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005953static const XML_Char *
5954poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005955{
5956 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005957 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005958 for (; n > 0; --n, s++) {
5959 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005960 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005961 }
5962 s = pool->start;
5963 poolFinish(pool);
5964 return s;
5965}
5966
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005967static const XML_Char * FASTCALL
5968poolAppendString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005969{
5970 while (*s) {
5971 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005972 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005973 s++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005974 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005975 return pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005976}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005977
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005978static XML_Char *
5979poolStoreString(STRING_POOL *pool, const ENCODING *enc,
5980 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005981{
5982 if (!poolAppend(pool, enc, ptr, end))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005983 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005984 if (pool->ptr == pool->end && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005985 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005986 *(pool->ptr)++ = 0;
5987 return pool->start;
5988}
5989
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005990static XML_Bool FASTCALL
5991poolGrow(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005992{
5993 if (pool->freeBlocks) {
5994 if (pool->start == 0) {
5995 pool->blocks = pool->freeBlocks;
5996 pool->freeBlocks = pool->freeBlocks->next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005997 pool->blocks->next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005998 pool->start = pool->blocks->s;
5999 pool->end = pool->start + pool->blocks->size;
6000 pool->ptr = pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006001 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006002 }
6003 if (pool->end - pool->start < pool->freeBlocks->size) {
6004 BLOCK *tem = pool->freeBlocks->next;
6005 pool->freeBlocks->next = pool->blocks;
6006 pool->blocks = pool->freeBlocks;
6007 pool->freeBlocks = tem;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006008 memcpy(pool->blocks->s, pool->start,
6009 (pool->end - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006010 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6011 pool->start = pool->blocks->s;
6012 pool->end = pool->start + pool->blocks->size;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006013 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006014 }
6015 }
6016 if (pool->blocks && pool->start == pool->blocks->s) {
6017 int blockSize = (pool->end - pool->start)*2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006018 pool->blocks = (BLOCK *)
6019 pool->mem->realloc_fcn(pool->blocks,
Fred Drake08317ae2003-10-21 15:38:55 +00006020 (offsetof(BLOCK, s)
6021 + blockSize * sizeof(XML_Char)));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006022 if (pool->blocks == NULL)
6023 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006024 pool->blocks->size = blockSize;
6025 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6026 pool->start = pool->blocks->s;
6027 pool->end = pool->start + blockSize;
6028 }
6029 else {
6030 BLOCK *tem;
6031 int blockSize = pool->end - pool->start;
6032 if (blockSize < INIT_BLOCK_SIZE)
6033 blockSize = INIT_BLOCK_SIZE;
6034 else
6035 blockSize *= 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006036 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
Fred Drake08317ae2003-10-21 15:38:55 +00006037 + blockSize * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006038 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006039 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006040 tem->size = blockSize;
6041 tem->next = pool->blocks;
6042 pool->blocks = tem;
6043 if (pool->ptr != pool->start)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006044 memcpy(tem->s, pool->start,
6045 (pool->ptr - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006046 pool->ptr = tem->s + (pool->ptr - pool->start);
6047 pool->start = tem->s;
6048 pool->end = tem->s + blockSize;
6049 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006050 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006051}
6052
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006053static int FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006054nextScaffoldPart(XML_Parser parser)
6055{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006056 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006057 CONTENT_SCAFFOLD * me;
6058 int next;
6059
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006060 if (!dtd->scaffIndex) {
6061 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6062 if (!dtd->scaffIndex)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006063 return -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006064 dtd->scaffIndex[0] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006065 }
6066
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006067 if (dtd->scaffCount >= dtd->scaffSize) {
6068 CONTENT_SCAFFOLD *temp;
6069 if (dtd->scaffold) {
6070 temp = (CONTENT_SCAFFOLD *)
6071 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6072 if (temp == NULL)
6073 return -1;
6074 dtd->scaffSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006075 }
6076 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006077 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6078 * sizeof(CONTENT_SCAFFOLD));
6079 if (temp == NULL)
6080 return -1;
6081 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006082 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006083 dtd->scaffold = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006084 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006085 next = dtd->scaffCount++;
6086 me = &dtd->scaffold[next];
6087 if (dtd->scaffLevel) {
6088 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006089 if (parent->lastchild) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006090 dtd->scaffold[parent->lastchild].nextsib = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006091 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006092 if (!parent->childcnt)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006093 parent->firstchild = next;
6094 parent->lastchild = next;
6095 parent->childcnt++;
6096 }
6097 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6098 return next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006099}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006100
6101static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006102build_node(XML_Parser parser,
6103 int src_node,
6104 XML_Content *dest,
6105 XML_Content **contpos,
6106 XML_Char **strpos)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006107{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006108 DTD * const dtd = _dtd; /* save one level of indirection */
6109 dest->type = dtd->scaffold[src_node].type;
6110 dest->quant = dtd->scaffold[src_node].quant;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006111 if (dest->type == XML_CTYPE_NAME) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006112 const XML_Char *src;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006113 dest->name = *strpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006114 src = dtd->scaffold[src_node].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006115 for (;;) {
6116 *(*strpos)++ = *src;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006117 if (!*src)
6118 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006119 src++;
6120 }
6121 dest->numchildren = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006122 dest->children = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006123 }
6124 else {
6125 unsigned int i;
6126 int cn;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006127 dest->numchildren = dtd->scaffold[src_node].childcnt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006128 dest->children = *contpos;
6129 *contpos += dest->numchildren;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006130 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6131 i < dest->numchildren;
6132 i++, cn = dtd->scaffold[cn].nextsib) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006133 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6134 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006135 dest->name = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006136 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006137}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006138
6139static XML_Content *
6140build_model (XML_Parser parser)
6141{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006142 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006143 XML_Content *ret;
6144 XML_Content *cpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006145 XML_Char * str;
6146 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6147 + (dtd->contentStringLen * sizeof(XML_Char)));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006148
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006149 ret = (XML_Content *)MALLOC(allocsize);
6150 if (!ret)
6151 return NULL;
6152
6153 str = (XML_Char *) (&ret[dtd->scaffCount]);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006154 cpos = &ret[1];
6155
6156 build_node(parser, 0, ret, &cpos, &str);
6157 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006158}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006159
6160static ELEMENT_TYPE *
6161getElementType(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006162 const ENCODING *enc,
6163 const char *ptr,
6164 const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006165{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006166 DTD * const dtd = _dtd; /* save one level of indirection */
6167 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006168 ELEMENT_TYPE *ret;
6169
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006170 if (!name)
6171 return NULL;
6172 ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
6173 if (!ret)
6174 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006175 if (ret->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006176 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006177 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006178 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006179 if (!setElementTypePrefix(parser, ret))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006180 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006181 }
6182 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006183}