blob: b54d2bf1b1c3de87387966f2408946e915cbc433 [file] [log] [blame]
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003*/
4
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005#include <stddef.h>
6#include <string.h> /* memset(), memcpy() */
7
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00008#ifdef COMPILED_FROM_DSP
Martin v. Löwisfc03a942003-01-25 22:41:29 +00009
10#include "winconfig.h"
11#define XMLPARSEAPI(type) type __cdecl
12#include "expat.h"
13#undef XMLPARSEAPI
14
15#elif defined(MACOS_CLASSIC)
16
17#include "macconfig.h"
18#include "expat.h"
19
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000020#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +000021
22/* Unused - MvL
23#include <expat_config.h>
24*/
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000025
26#ifdef __declspec
Martin v. Löwisfc03a942003-01-25 22:41:29 +000027#define XMLPARSEAPI(type) type __cdecl
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000028#endif
29
30#include "expat.h"
31
32#ifdef __declspec
Martin v. Löwisfc03a942003-01-25 22:41:29 +000033#undef XMLPARSEAPI
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000034#endif
35#endif /* ndef COMPILED_FROM_DSP */
36
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000037#ifdef XML_UNICODE
38#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
39#define XmlConvert XmlUtf16Convert
40#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
41#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
42#define XmlEncode XmlUtf16Encode
43#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
44typedef unsigned short ICHAR;
45#else
46#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
47#define XmlConvert XmlUtf8Convert
48#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
49#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
50#define XmlEncode XmlUtf8Encode
51#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
52typedef char ICHAR;
53#endif
54
55
56#ifndef XML_NS
57
58#define XmlInitEncodingNS XmlInitEncoding
59#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
60#undef XmlGetInternalEncodingNS
61#define XmlGetInternalEncodingNS XmlGetInternalEncoding
62#define XmlParseXmlDeclNS XmlParseXmlDecl
63
64#endif
65
Martin v. Löwisfc03a942003-01-25 22:41:29 +000066#ifdef XML_UNICODE
67
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000068#ifdef XML_UNICODE_WCHAR_T
Martin v. Löwisfc03a942003-01-25 22:41:29 +000069#define XML_T(x) (const wchar_t)x
70#define XML_L(x) L ## x
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000071#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +000072#define XML_T(x) (const unsigned short)x
73#define XML_L(x) x
74#endif
75
76#else
77
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000078#define XML_T(x) x
Martin v. Löwisfc03a942003-01-25 22:41:29 +000079#define XML_L(x) x
80
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000081#endif
82
83/* Round up n to be a multiple of sz, where sz is a power of 2. */
84#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
85
Martin v. Löwisfc03a942003-01-25 22:41:29 +000086#include "internal.h"
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000087#include "xmltok.h"
88#include "xmlrole.h"
89
90typedef const XML_Char *KEY;
91
92typedef struct {
93 KEY name;
94} NAMED;
95
96typedef struct {
97 NAMED **v;
98 size_t size;
99 size_t used;
100 size_t usedLim;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000101 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000102} HASH_TABLE;
103
104typedef struct {
105 NAMED **p;
106 NAMED **end;
107} HASH_TABLE_ITER;
108
109#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
110#define INIT_DATA_BUF_SIZE 1024
111#define INIT_ATTS_SIZE 16
112#define INIT_BLOCK_SIZE 1024
113#define INIT_BUFFER_SIZE 1024
114
115#define EXPAND_SPARE 24
116
117typedef struct binding {
118 struct prefix *prefix;
119 struct binding *nextTagBinding;
120 struct binding *prevPrefixBinding;
121 const struct attribute_id *attId;
122 XML_Char *uri;
123 int uriLen;
124 int uriAlloc;
125} BINDING;
126
127typedef struct prefix {
128 const XML_Char *name;
129 BINDING *binding;
130} PREFIX;
131
132typedef struct {
133 const XML_Char *str;
134 const XML_Char *localPart;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000135 const XML_Char *prefix;
136 int strLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000137 int uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000138 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000139} TAG_NAME;
140
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000141/* TAG represents an open element.
142 The name of the element is stored in both the document and API
143 encodings. The memory buffer 'buf' is a separately-allocated
144 memory area which stores the name. During the XML_Parse()/
145 XMLParseBuffer() when the element is open, the memory for the 'raw'
146 version of the name (in the document encoding) is shared with the
147 document buffer. If the element is open across calls to
148 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
149 contain the 'raw' name as well.
150
151 A parser re-uses these structures, maintaining a list of allocated
152 TAG objects in a free list.
153*/
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000154typedef struct tag {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000155 struct tag *parent; /* parent of this element */
156 const char *rawName; /* tagName in the original encoding */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000157 int rawNameLength;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000158 TAG_NAME name; /* tagName in the API encoding */
159 char *buf; /* buffer for name components */
160 char *bufEnd; /* end of the buffer */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000161 BINDING *bindings;
162} TAG;
163
164typedef struct {
165 const XML_Char *name;
166 const XML_Char *textPtr;
167 int textLen;
168 const XML_Char *systemId;
169 const XML_Char *base;
170 const XML_Char *publicId;
171 const XML_Char *notation;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000172 XML_Bool open;
173 XML_Bool is_param;
174 XML_Bool is_internal; /* true if declared in internal subset outside PE */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000175} ENTITY;
176
177typedef struct {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000178 enum XML_Content_Type type;
179 enum XML_Content_Quant quant;
180 const XML_Char * name;
181 int firstchild;
182 int lastchild;
183 int childcnt;
184 int nextsib;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000185} CONTENT_SCAFFOLD;
186
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000187#define INIT_SCAFFOLD_ELEMENTS 32
188
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000189typedef struct block {
190 struct block *next;
191 int size;
192 XML_Char s[1];
193} BLOCK;
194
195typedef struct {
196 BLOCK *blocks;
197 BLOCK *freeBlocks;
198 const XML_Char *end;
199 XML_Char *ptr;
200 XML_Char *start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000201 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000202} STRING_POOL;
203
204/* The XML_Char before the name is used to determine whether
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000205 an attribute has been specified. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000206typedef struct attribute_id {
207 XML_Char *name;
208 PREFIX *prefix;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000209 XML_Bool maybeTokenized;
210 XML_Bool xmlns;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000211} ATTRIBUTE_ID;
212
213typedef struct {
214 const ATTRIBUTE_ID *id;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000215 XML_Bool isCdata;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000216 const XML_Char *value;
217} DEFAULT_ATTRIBUTE;
218
219typedef struct {
220 const XML_Char *name;
221 PREFIX *prefix;
222 const ATTRIBUTE_ID *idAtt;
223 int nDefaultAtts;
224 int allocDefaultAtts;
225 DEFAULT_ATTRIBUTE *defaultAtts;
226} ELEMENT_TYPE;
227
228typedef struct {
229 HASH_TABLE generalEntities;
230 HASH_TABLE elementTypes;
231 HASH_TABLE attributeIds;
232 HASH_TABLE prefixes;
233 STRING_POOL pool;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000234 STRING_POOL entityValuePool;
235 /* false once a parameter entity reference has been skipped */
236 XML_Bool keepProcessing;
237 /* true once an internal or external PE reference has been encountered;
238 this includes the reference to an external subset */
239 XML_Bool hasParamEntityRefs;
240 XML_Bool standalone;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000241#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000242 /* indicates if external PE has been read */
243 XML_Bool paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000244 HASH_TABLE paramEntities;
245#endif /* XML_DTD */
246 PREFIX defaultPrefix;
247 /* === scaffolding for building content model === */
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000248 XML_Bool in_eldecl;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000249 CONTENT_SCAFFOLD *scaffold;
250 unsigned contentStringLen;
251 unsigned scaffSize;
252 unsigned scaffCount;
253 int scaffLevel;
254 int *scaffIndex;
255} DTD;
256
257typedef struct open_internal_entity {
258 const char *internalEventPtr;
259 const char *internalEventEndPtr;
260 struct open_internal_entity *next;
261 ENTITY *entity;
262} OPEN_INTERNAL_ENTITY;
263
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000264typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
265 const char *start,
266 const char *end,
267 const char **endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000268
269static Processor prologProcessor;
270static Processor prologInitProcessor;
271static Processor contentProcessor;
272static Processor cdataSectionProcessor;
273#ifdef XML_DTD
274static Processor ignoreSectionProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000275static Processor externalParEntProcessor;
276static Processor externalParEntInitProcessor;
277static Processor entityValueProcessor;
278static Processor entityValueInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000279#endif /* XML_DTD */
280static Processor epilogProcessor;
281static Processor errorProcessor;
282static Processor externalEntityInitProcessor;
283static Processor externalEntityInitProcessor2;
284static Processor externalEntityInitProcessor3;
285static Processor externalEntityContentProcessor;
286
287static enum XML_Error
288handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
289static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000290processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
291 const char *, const char *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000292static enum XML_Error
293initializeEncoding(XML_Parser parser);
294static enum XML_Error
295doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000296 const char *end, int tok, const char *next, const char **nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000297static enum XML_Error
298processInternalParamEntity(XML_Parser parser, ENTITY *entity);
299static enum XML_Error
300doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000301 const char *start, const char *end, const char **endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000302static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000303doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
304 const char *end, const char **nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000305#ifdef XML_DTD
306static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000307doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
308 const char *end, const char **nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000309#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000310
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000311static enum XML_Error
312storeAtts(XML_Parser parser, const ENCODING *,
313 const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
314static enum XML_Error
315addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
316 const XML_Char *uri, BINDING **bindingsPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000317static int
318defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000319 XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue,
320 XML_Parser parser);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000321static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000322storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
323 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000324static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000325appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
326 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000327static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000328getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
329 const char *end);
330static int
331setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000332static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000333storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
334 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000335static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000336reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
337 const char *start, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000338static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000339reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
340 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000341static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000342reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
343 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000344
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000345static const XML_Char * getContext(XML_Parser parser);
346static XML_Bool
347setContext(XML_Parser parser, const XML_Char *context);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000348
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000349static void FASTCALL normalizePublicId(XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000350
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000351static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
352/* do not call if parentParser != NULL */
353static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
354static void
355dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
356static int
357dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
358static int
359copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000360
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000361static NAMED *
362lookup(HASH_TABLE *table, KEY name, size_t createSize);
363static void FASTCALL
364hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
365static void FASTCALL hashTableClear(HASH_TABLE *);
366static void FASTCALL hashTableDestroy(HASH_TABLE *);
367static void FASTCALL
368hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
369static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000370
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000371static void FASTCALL
372poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
373static void FASTCALL poolClear(STRING_POOL *);
374static void FASTCALL poolDestroy(STRING_POOL *);
375static XML_Char *
376poolAppend(STRING_POOL *pool, const ENCODING *enc,
377 const char *ptr, const char *end);
378static XML_Char *
379poolStoreString(STRING_POOL *pool, const ENCODING *enc,
380 const char *ptr, const char *end);
381static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
382static const XML_Char * FASTCALL
383poolCopyString(STRING_POOL *pool, const XML_Char *s);
384static const XML_Char *
385poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
386static const XML_Char * FASTCALL
387poolAppendString(STRING_POOL *pool, const XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000388
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000389static int FASTCALL nextScaffoldPart(XML_Parser parser);
390static XML_Content * build_model(XML_Parser parser);
391static ELEMENT_TYPE *
392getElementType(XML_Parser parser, const ENCODING *enc,
393 const char *ptr, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000394
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000395static XML_Parser
396parserCreate(const XML_Char *encodingName,
397 const XML_Memory_Handling_Suite *memsuite,
398 const XML_Char *nameSep,
399 DTD *dtd);
400static void
401parserInit(XML_Parser parser, const XML_Char *encodingName);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000402
403#define poolStart(pool) ((pool)->start)
404#define poolEnd(pool) ((pool)->ptr)
405#define poolLength(pool) ((pool)->ptr - (pool)->start)
406#define poolChop(pool) ((void)--(pool->ptr))
407#define poolLastChar(pool) (((pool)->ptr)[-1])
408#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
409#define poolFinish(pool) ((pool)->start = (pool)->ptr)
410#define poolAppendChar(pool, c) \
411 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
412 ? 0 \
413 : ((*((pool)->ptr)++ = c), 1))
414
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000415struct XML_ParserStruct {
416 /* The first member must be userData so that the XML_GetUserData
417 macro works. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000418 void *m_userData;
419 void *m_handlerArg;
420 char *m_buffer;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000421 const XML_Memory_Handling_Suite m_mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000422 /* first character to be parsed */
423 const char *m_bufferPtr;
424 /* past last character to be parsed */
425 char *m_bufferEnd;
426 /* allocated end of buffer */
427 const char *m_bufferLim;
428 long m_parseEndByteIndex;
429 const char *m_parseEndPtr;
430 XML_Char *m_dataBuf;
431 XML_Char *m_dataBufEnd;
432 XML_StartElementHandler m_startElementHandler;
433 XML_EndElementHandler m_endElementHandler;
434 XML_CharacterDataHandler m_characterDataHandler;
435 XML_ProcessingInstructionHandler m_processingInstructionHandler;
436 XML_CommentHandler m_commentHandler;
437 XML_StartCdataSectionHandler m_startCdataSectionHandler;
438 XML_EndCdataSectionHandler m_endCdataSectionHandler;
439 XML_DefaultHandler m_defaultHandler;
440 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
441 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
442 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
443 XML_NotationDeclHandler m_notationDeclHandler;
444 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
445 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
446 XML_NotStandaloneHandler m_notStandaloneHandler;
447 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000448 XML_Parser m_externalEntityRefHandlerArg;
449 XML_SkippedEntityHandler m_skippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000450 XML_UnknownEncodingHandler m_unknownEncodingHandler;
451 XML_ElementDeclHandler m_elementDeclHandler;
452 XML_AttlistDeclHandler m_attlistDeclHandler;
453 XML_EntityDeclHandler m_entityDeclHandler;
454 XML_XmlDeclHandler m_xmlDeclHandler;
455 const ENCODING *m_encoding;
456 INIT_ENCODING m_initEncoding;
457 const ENCODING *m_internalEncoding;
458 const XML_Char *m_protocolEncodingName;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000459 XML_Bool m_ns;
460 XML_Bool m_ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000461 void *m_unknownEncodingMem;
462 void *m_unknownEncodingData;
463 void *m_unknownEncodingHandlerData;
464 void (*m_unknownEncodingRelease)(void *);
465 PROLOG_STATE m_prologState;
466 Processor *m_processor;
467 enum XML_Error m_errorCode;
468 const char *m_eventPtr;
469 const char *m_eventEndPtr;
470 const char *m_positionPtr;
471 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000472 XML_Bool m_defaultExpandInternalEntities;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000473 int m_tagLevel;
474 ENTITY *m_declEntity;
475 const XML_Char *m_doctypeName;
476 const XML_Char *m_doctypeSysid;
477 const XML_Char *m_doctypePubid;
478 const XML_Char *m_declAttributeType;
479 const XML_Char *m_declNotationName;
480 const XML_Char *m_declNotationPublicId;
481 ELEMENT_TYPE *m_declElementType;
482 ATTRIBUTE_ID *m_declAttributeId;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000483 XML_Bool m_declAttributeIsCdata;
484 XML_Bool m_declAttributeIsId;
485 DTD *m_dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000486 const XML_Char *m_curBase;
487 TAG *m_tagStack;
488 TAG *m_freeTagList;
489 BINDING *m_inheritedBindings;
490 BINDING *m_freeBindingList;
491 int m_attsSize;
492 int m_nSpecifiedAtts;
493 int m_idAttIndex;
494 ATTRIBUTE *m_atts;
495 POSITION m_position;
496 STRING_POOL m_tempPool;
497 STRING_POOL m_temp2Pool;
498 char *m_groupConnector;
499 unsigned m_groupSize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000500 XML_Char m_namespaceSeparator;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000501 XML_Parser m_parentParser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000502#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000503 XML_Bool m_isParamEntity;
504 XML_Bool m_useForeignDTD;
505 enum XML_ParamEntityParsing m_paramEntityParsing;
506#endif
507};
508
509#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
510#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
511#define FREE(p) (parser->m_mem.free_fcn((p)))
512
513#define userData (parser->m_userData)
514#define handlerArg (parser->m_handlerArg)
515#define startElementHandler (parser->m_startElementHandler)
516#define endElementHandler (parser->m_endElementHandler)
517#define characterDataHandler (parser->m_characterDataHandler)
518#define processingInstructionHandler \
519 (parser->m_processingInstructionHandler)
520#define commentHandler (parser->m_commentHandler)
521#define startCdataSectionHandler \
522 (parser->m_startCdataSectionHandler)
523#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
524#define defaultHandler (parser->m_defaultHandler)
525#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
526#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
527#define unparsedEntityDeclHandler \
528 (parser->m_unparsedEntityDeclHandler)
529#define notationDeclHandler (parser->m_notationDeclHandler)
530#define startNamespaceDeclHandler \
531 (parser->m_startNamespaceDeclHandler)
532#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
533#define notStandaloneHandler (parser->m_notStandaloneHandler)
534#define externalEntityRefHandler \
535 (parser->m_externalEntityRefHandler)
536#define externalEntityRefHandlerArg \
537 (parser->m_externalEntityRefHandlerArg)
538#define internalEntityRefHandler \
539 (parser->m_internalEntityRefHandler)
540#define skippedEntityHandler (parser->m_skippedEntityHandler)
541#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
542#define elementDeclHandler (parser->m_elementDeclHandler)
543#define attlistDeclHandler (parser->m_attlistDeclHandler)
544#define entityDeclHandler (parser->m_entityDeclHandler)
545#define xmlDeclHandler (parser->m_xmlDeclHandler)
546#define encoding (parser->m_encoding)
547#define initEncoding (parser->m_initEncoding)
548#define internalEncoding (parser->m_internalEncoding)
549#define unknownEncodingMem (parser->m_unknownEncodingMem)
550#define unknownEncodingData (parser->m_unknownEncodingData)
551#define unknownEncodingHandlerData \
552 (parser->m_unknownEncodingHandlerData)
553#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
554#define protocolEncodingName (parser->m_protocolEncodingName)
555#define ns (parser->m_ns)
556#define ns_triplets (parser->m_ns_triplets)
557#define prologState (parser->m_prologState)
558#define processor (parser->m_processor)
559#define errorCode (parser->m_errorCode)
560#define eventPtr (parser->m_eventPtr)
561#define eventEndPtr (parser->m_eventEndPtr)
562#define positionPtr (parser->m_positionPtr)
563#define position (parser->m_position)
564#define openInternalEntities (parser->m_openInternalEntities)
565#define defaultExpandInternalEntities \
566 (parser->m_defaultExpandInternalEntities)
567#define tagLevel (parser->m_tagLevel)
568#define buffer (parser->m_buffer)
569#define bufferPtr (parser->m_bufferPtr)
570#define bufferEnd (parser->m_bufferEnd)
571#define parseEndByteIndex (parser->m_parseEndByteIndex)
572#define parseEndPtr (parser->m_parseEndPtr)
573#define bufferLim (parser->m_bufferLim)
574#define dataBuf (parser->m_dataBuf)
575#define dataBufEnd (parser->m_dataBufEnd)
576#define _dtd (parser->m_dtd)
577#define curBase (parser->m_curBase)
578#define declEntity (parser->m_declEntity)
579#define doctypeName (parser->m_doctypeName)
580#define doctypeSysid (parser->m_doctypeSysid)
581#define doctypePubid (parser->m_doctypePubid)
582#define declAttributeType (parser->m_declAttributeType)
583#define declNotationName (parser->m_declNotationName)
584#define declNotationPublicId (parser->m_declNotationPublicId)
585#define declElementType (parser->m_declElementType)
586#define declAttributeId (parser->m_declAttributeId)
587#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
588#define declAttributeIsId (parser->m_declAttributeIsId)
589#define freeTagList (parser->m_freeTagList)
590#define freeBindingList (parser->m_freeBindingList)
591#define inheritedBindings (parser->m_inheritedBindings)
592#define tagStack (parser->m_tagStack)
593#define atts (parser->m_atts)
594#define attsSize (parser->m_attsSize)
595#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
596#define idAttIndex (parser->m_idAttIndex)
597#define tempPool (parser->m_tempPool)
598#define temp2Pool (parser->m_temp2Pool)
599#define groupConnector (parser->m_groupConnector)
600#define groupSize (parser->m_groupSize)
601#define namespaceSeparator (parser->m_namespaceSeparator)
602#define parentParser (parser->m_parentParser)
603#ifdef XML_DTD
604#define isParamEntity (parser->m_isParamEntity)
605#define useForeignDTD (parser->m_useForeignDTD)
606#define paramEntityParsing (parser->m_paramEntityParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000607#endif /* XML_DTD */
608
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000609#define parsing \
610 (parentParser \
611 ? \
612 (isParamEntity \
613 ? \
614 (processor != externalParEntInitProcessor) \
615 : \
616 (processor != externalEntityInitProcessor)) \
617 : \
618 (processor != prologInitProcessor))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000619
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000620XML_Parser
621XML_ParserCreate(const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000622{
623 return XML_ParserCreate_MM(encodingName, NULL, NULL);
624}
625
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000626XML_Parser
627XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000628{
629 XML_Char tmp[2];
630 *tmp = nsSep;
631 return XML_ParserCreate_MM(encodingName, NULL, tmp);
632}
633
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000634static const XML_Char implicitContext[] = {
635 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
636 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
637 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
638 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
639};
640
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000641XML_Parser
642XML_ParserCreate_MM(const XML_Char *encodingName,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000643 const XML_Memory_Handling_Suite *memsuite,
644 const XML_Char *nameSep)
645{
646 XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
647 if (parser != NULL && ns) {
648 /* implicit context only set for root parser, since child
649 parsers (i.e. external entity parsers) will inherit it
650 */
651 if (!setContext(parser, implicitContext)) {
652 XML_ParserFree(parser);
653 return NULL;
654 }
655 }
656 return parser;
657}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000658
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000659static XML_Parser
660parserCreate(const XML_Char *encodingName,
661 const XML_Memory_Handling_Suite *memsuite,
662 const XML_Char *nameSep,
663 DTD *dtd)
664{
665 XML_Parser parser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000666
667 if (memsuite) {
668 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000669 parser = (XML_Parser)
670 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
671 if (parser != NULL) {
672 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
673 mtemp->malloc_fcn = memsuite->malloc_fcn;
674 mtemp->realloc_fcn = memsuite->realloc_fcn;
675 mtemp->free_fcn = memsuite->free_fcn;
676 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000677 }
678 else {
679 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000680 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
681 if (parser != NULL) {
682 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
683 mtemp->malloc_fcn = malloc;
684 mtemp->realloc_fcn = realloc;
685 mtemp->free_fcn = free;
686 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000687 }
688
689 if (!parser)
690 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000691
692 buffer = NULL;
693 bufferLim = NULL;
694
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000695 attsSize = INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000696 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
697 if (atts == NULL) {
698 FREE(parser);
699 return NULL;
700 }
701 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
702 if (dataBuf == NULL) {
703 FREE(atts);
704 FREE(parser);
705 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000706 }
707 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
708
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000709 if (dtd)
710 _dtd = dtd;
711 else {
712 _dtd = dtdCreate(&parser->m_mem);
713 if (_dtd == NULL) {
714 FREE(dataBuf);
715 FREE(atts);
716 FREE(parser);
717 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000718 }
719 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000720
721 freeBindingList = NULL;
722 freeTagList = NULL;
723
724 groupSize = 0;
725 groupConnector = NULL;
726
727 unknownEncodingHandler = NULL;
728 unknownEncodingHandlerData = NULL;
729
730 namespaceSeparator = '!';
731 ns = XML_FALSE;
732 ns_triplets = XML_FALSE;
733
734 poolInit(&tempPool, &(parser->m_mem));
735 poolInit(&temp2Pool, &(parser->m_mem));
736 parserInit(parser, encodingName);
737
738 if (encodingName && !protocolEncodingName) {
739 XML_ParserFree(parser);
740 return NULL;
741 }
742
743 if (nameSep) {
744 ns = XML_TRUE;
745 internalEncoding = XmlGetInternalEncodingNS();
746 namespaceSeparator = *nameSep;
747 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000748 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000749 internalEncoding = XmlGetInternalEncoding();
750 }
751
752 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000753}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000754
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000755static void
756parserInit(XML_Parser parser, const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000757{
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000758 processor = prologInitProcessor;
759 XmlPrologStateInit(&prologState);
760 protocolEncodingName = (encodingName != NULL
761 ? poolCopyString(&tempPool, encodingName)
762 : NULL);
763 curBase = NULL;
764 XmlInitEncoding(&initEncoding, &encoding, 0);
765 userData = NULL;
766 handlerArg = NULL;
767 startElementHandler = NULL;
768 endElementHandler = NULL;
769 characterDataHandler = NULL;
770 processingInstructionHandler = NULL;
771 commentHandler = NULL;
772 startCdataSectionHandler = NULL;
773 endCdataSectionHandler = NULL;
774 defaultHandler = NULL;
775 startDoctypeDeclHandler = NULL;
776 endDoctypeDeclHandler = NULL;
777 unparsedEntityDeclHandler = NULL;
778 notationDeclHandler = NULL;
779 startNamespaceDeclHandler = NULL;
780 endNamespaceDeclHandler = NULL;
781 notStandaloneHandler = NULL;
782 externalEntityRefHandler = NULL;
783 externalEntityRefHandlerArg = parser;
784 skippedEntityHandler = NULL;
785 elementDeclHandler = NULL;
786 attlistDeclHandler = NULL;
787 entityDeclHandler = NULL;
788 xmlDeclHandler = NULL;
789 bufferPtr = buffer;
790 bufferEnd = buffer;
791 parseEndByteIndex = 0;
792 parseEndPtr = NULL;
793 declElementType = NULL;
794 declAttributeId = NULL;
795 declEntity = NULL;
796 doctypeName = NULL;
797 doctypeSysid = NULL;
798 doctypePubid = NULL;
799 declAttributeType = NULL;
800 declNotationName = NULL;
801 declNotationPublicId = NULL;
802 declAttributeIsCdata = XML_FALSE;
803 declAttributeIsId = XML_FALSE;
804 memset(&position, 0, sizeof(POSITION));
805 errorCode = XML_ERROR_NONE;
806 eventPtr = NULL;
807 eventEndPtr = NULL;
808 positionPtr = NULL;
809 openInternalEntities = 0;
810 defaultExpandInternalEntities = XML_TRUE;
811 tagLevel = 0;
812 tagStack = NULL;
813 inheritedBindings = NULL;
814 nSpecifiedAtts = 0;
815 unknownEncodingMem = NULL;
816 unknownEncodingRelease = NULL;
817 unknownEncodingData = NULL;
818 parentParser = NULL;
819#ifdef XML_DTD
820 isParamEntity = XML_FALSE;
821 useForeignDTD = XML_FALSE;
822 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
823#endif
824}
825
826/* moves list of bindings to freeBindingList */
827static void FASTCALL
828moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
829{
830 while (bindings) {
831 BINDING *b = bindings;
832 bindings = bindings->nextTagBinding;
833 b->nextTagBinding = freeBindingList;
834 freeBindingList = b;
835 }
836}
837
838XML_Bool
839XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
840{
841 TAG *tStk;
842 if (parentParser)
843 return XML_FALSE;
844 /* move tagStack to freeTagList */
845 tStk = tagStack;
846 while (tStk) {
847 TAG *tag = tStk;
848 tStk = tStk->parent;
849 tag->parent = freeTagList;
850 moveToFreeBindingList(parser, tag->bindings);
851 tag->bindings = NULL;
852 freeTagList = tag;
853 }
854 moveToFreeBindingList(parser, inheritedBindings);
855 if (unknownEncodingMem)
856 FREE(unknownEncodingMem);
857 if (unknownEncodingRelease)
858 unknownEncodingRelease(unknownEncodingData);
859 poolClear(&tempPool);
860 poolClear(&temp2Pool);
861 parserInit(parser, encodingName);
862 dtdReset(_dtd, &parser->m_mem);
863 return setContext(parser, implicitContext);
864}
865
866enum XML_Status
867XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
868{
869 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
870 XXX There's no way for the caller to determine which of the
871 XXX possible error cases caused the XML_STATUS_ERROR return.
872 */
873 if (parsing)
874 return XML_STATUS_ERROR;
875 if (encodingName == NULL)
876 protocolEncodingName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000877 else {
878 protocolEncodingName = poolCopyString(&tempPool, encodingName);
879 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000880 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000881 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000882 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000883}
884
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000885XML_Parser
886XML_ExternalEntityParserCreate(XML_Parser oldParser,
887 const XML_Char *context,
888 const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000889{
890 XML_Parser parser = oldParser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000891 DTD *newDtd = NULL;
892 DTD *oldDtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000893 XML_StartElementHandler oldStartElementHandler = startElementHandler;
894 XML_EndElementHandler oldEndElementHandler = endElementHandler;
895 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000896 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
897 = processingInstructionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000898 XML_CommentHandler oldCommentHandler = commentHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000899 XML_StartCdataSectionHandler oldStartCdataSectionHandler
900 = startCdataSectionHandler;
901 XML_EndCdataSectionHandler oldEndCdataSectionHandler
902 = endCdataSectionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000903 XML_DefaultHandler oldDefaultHandler = defaultHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000904 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
905 = unparsedEntityDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000906 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000907 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
908 = startNamespaceDeclHandler;
909 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
910 = endNamespaceDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000911 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000912 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
913 = externalEntityRefHandler;
914 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
915 XML_UnknownEncodingHandler oldUnknownEncodingHandler
916 = unknownEncodingHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000917 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
918 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
919 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
920 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
921 ELEMENT_TYPE * oldDeclElementType = declElementType;
922
923 void *oldUserData = userData;
924 void *oldHandlerArg = handlerArg;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000925 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
926 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000927#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000928 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
929 int oldInEntityValue = prologState.inEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000930#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000931 XML_Bool oldns_triplets = ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000932
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000933#ifdef XML_DTD
934 if (!context)
935 newDtd = oldDtd;
936#endif /* XML_DTD */
937
938 /* Note that the magical uses of the pre-processor to make field
939 access look more like C++ require that `parser' be overwritten
940 here. This makes this function more painful to follow than it
941 would be otherwise.
942 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000943 if (ns) {
944 XML_Char tmp[2];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000945 *tmp = namespaceSeparator;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000946 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000947 }
948 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000949 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000950 }
951
952 if (!parser)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000953 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000954
955 startElementHandler = oldStartElementHandler;
956 endElementHandler = oldEndElementHandler;
957 characterDataHandler = oldCharacterDataHandler;
958 processingInstructionHandler = oldProcessingInstructionHandler;
959 commentHandler = oldCommentHandler;
960 startCdataSectionHandler = oldStartCdataSectionHandler;
961 endCdataSectionHandler = oldEndCdataSectionHandler;
962 defaultHandler = oldDefaultHandler;
963 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
964 notationDeclHandler = oldNotationDeclHandler;
965 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
966 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
967 notStandaloneHandler = oldNotStandaloneHandler;
968 externalEntityRefHandler = oldExternalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000969 skippedEntityHandler = oldSkippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000970 unknownEncodingHandler = oldUnknownEncodingHandler;
971 elementDeclHandler = oldElementDeclHandler;
972 attlistDeclHandler = oldAttlistDeclHandler;
973 entityDeclHandler = oldEntityDeclHandler;
974 xmlDeclHandler = oldXmlDeclHandler;
975 declElementType = oldDeclElementType;
976 userData = oldUserData;
977 if (oldUserData == oldHandlerArg)
978 handlerArg = userData;
979 else
980 handlerArg = parser;
981 if (oldExternalEntityRefHandlerArg != oldParser)
982 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
983 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
984 ns_triplets = oldns_triplets;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000985 parentParser = oldParser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000986#ifdef XML_DTD
987 paramEntityParsing = oldParamEntityParsing;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000988 prologState.inEntityValue = oldInEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000989 if (context) {
990#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000991 if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
992 || !setContext(parser, context)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000993 XML_ParserFree(parser);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000994 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000995 }
996 processor = externalEntityInitProcessor;
997#ifdef XML_DTD
998 }
999 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001000 /* The DTD instance referenced by _dtd is shared between the document's
1001 root parser and external PE parsers, therefore one does not need to
1002 call setContext. In addition, one also *must* not call setContext,
1003 because this would overwrite existing prefix->binding pointers in
1004 _dtd with ones that get destroyed with the external PE parser.
1005 This would leave those prefixes with dangling pointers.
1006 */
1007 isParamEntity = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001008 XmlPrologStateInitExternalEntity(&prologState);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001009 processor = externalParEntInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001010 }
1011#endif /* XML_DTD */
1012 return parser;
1013}
1014
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001015static void FASTCALL
1016destroyBindings(BINDING *bindings, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001017{
1018 for (;;) {
1019 BINDING *b = bindings;
1020 if (!b)
1021 break;
1022 bindings = b->nextTagBinding;
1023 FREE(b->uri);
1024 FREE(b);
1025 }
1026}
1027
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001028void
1029XML_ParserFree(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001030{
1031 for (;;) {
1032 TAG *p;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001033 if (tagStack == NULL) {
1034 if (freeTagList == NULL)
1035 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001036 tagStack = freeTagList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001037 freeTagList = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001038 }
1039 p = tagStack;
1040 tagStack = tagStack->parent;
1041 FREE(p->buf);
1042 destroyBindings(p->bindings, parser);
1043 FREE(p);
1044 }
1045 destroyBindings(freeBindingList, parser);
1046 destroyBindings(inheritedBindings, parser);
1047 poolDestroy(&tempPool);
1048 poolDestroy(&temp2Pool);
1049#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001050 /* external parameter entity parsers share the DTD structure
1051 parser->m_dtd with the root parser, so we must not destroy it
1052 */
1053 if (!isParamEntity && _dtd)
1054#else
1055 if (_dtd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001056#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001057 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001058 FREE((void *)atts);
1059 if (groupConnector)
1060 FREE(groupConnector);
1061 if (buffer)
1062 FREE(buffer);
1063 FREE(dataBuf);
1064 if (unknownEncodingMem)
1065 FREE(unknownEncodingMem);
1066 if (unknownEncodingRelease)
1067 unknownEncodingRelease(unknownEncodingData);
1068 FREE(parser);
1069}
1070
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001071void
1072XML_UseParserAsHandlerArg(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001073{
1074 handlerArg = parser;
1075}
1076
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001077enum XML_Error
1078XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1079{
1080#ifdef XML_DTD
1081 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1082 if (parsing)
1083 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1084 useForeignDTD = useDTD;
1085 return XML_ERROR_NONE;
1086#else
1087 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1088#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001089}
1090
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001091void
1092XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1093{
1094 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1095 if (parsing)
1096 return;
1097 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1098}
1099
1100void
1101XML_SetUserData(XML_Parser parser, void *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001102{
1103 if (handlerArg == userData)
1104 handlerArg = userData = p;
1105 else
1106 userData = p;
1107}
1108
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001109enum XML_Status
1110XML_SetBase(XML_Parser parser, const XML_Char *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001111{
1112 if (p) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001113 p = poolCopyString(&_dtd->pool, p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001114 if (!p)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001115 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001116 curBase = p;
1117 }
1118 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001119 curBase = NULL;
1120 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001121}
1122
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001123const XML_Char *
1124XML_GetBase(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001125{
1126 return curBase;
1127}
1128
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001129int
1130XML_GetSpecifiedAttributeCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001131{
1132 return nSpecifiedAtts;
1133}
1134
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001135int
1136XML_GetIdAttributeIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001137{
1138 return idAttIndex;
1139}
1140
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001141void
1142XML_SetElementHandler(XML_Parser parser,
1143 XML_StartElementHandler start,
1144 XML_EndElementHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001145{
1146 startElementHandler = start;
1147 endElementHandler = end;
1148}
1149
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001150void
1151XML_SetStartElementHandler(XML_Parser parser,
1152 XML_StartElementHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001153 startElementHandler = start;
1154}
1155
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001156void
1157XML_SetEndElementHandler(XML_Parser parser,
1158 XML_EndElementHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001159 endElementHandler = end;
1160}
1161
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001162void
1163XML_SetCharacterDataHandler(XML_Parser parser,
1164 XML_CharacterDataHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001165{
1166 characterDataHandler = handler;
1167}
1168
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001169void
1170XML_SetProcessingInstructionHandler(XML_Parser parser,
1171 XML_ProcessingInstructionHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001172{
1173 processingInstructionHandler = handler;
1174}
1175
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001176void
1177XML_SetCommentHandler(XML_Parser parser,
1178 XML_CommentHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001179{
1180 commentHandler = handler;
1181}
1182
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001183void
1184XML_SetCdataSectionHandler(XML_Parser parser,
1185 XML_StartCdataSectionHandler start,
1186 XML_EndCdataSectionHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001187{
1188 startCdataSectionHandler = start;
1189 endCdataSectionHandler = end;
1190}
1191
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001192void
1193XML_SetStartCdataSectionHandler(XML_Parser parser,
1194 XML_StartCdataSectionHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001195 startCdataSectionHandler = start;
1196}
1197
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001198void
1199XML_SetEndCdataSectionHandler(XML_Parser parser,
1200 XML_EndCdataSectionHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001201 endCdataSectionHandler = end;
1202}
1203
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001204void
1205XML_SetDefaultHandler(XML_Parser parser,
1206 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001207{
1208 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001209 defaultExpandInternalEntities = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001210}
1211
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001212void
1213XML_SetDefaultHandlerExpand(XML_Parser parser,
1214 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001215{
1216 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001217 defaultExpandInternalEntities = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001218}
1219
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001220void
1221XML_SetDoctypeDeclHandler(XML_Parser parser,
1222 XML_StartDoctypeDeclHandler start,
1223 XML_EndDoctypeDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001224{
1225 startDoctypeDeclHandler = start;
1226 endDoctypeDeclHandler = end;
1227}
1228
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001229void
1230XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1231 XML_StartDoctypeDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001232 startDoctypeDeclHandler = start;
1233}
1234
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001235void
1236XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1237 XML_EndDoctypeDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001238 endDoctypeDeclHandler = end;
1239}
1240
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001241void
1242XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1243 XML_UnparsedEntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001244{
1245 unparsedEntityDeclHandler = handler;
1246}
1247
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001248void
1249XML_SetNotationDeclHandler(XML_Parser parser,
1250 XML_NotationDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001251{
1252 notationDeclHandler = handler;
1253}
1254
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001255void
1256XML_SetNamespaceDeclHandler(XML_Parser parser,
1257 XML_StartNamespaceDeclHandler start,
1258 XML_EndNamespaceDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001259{
1260 startNamespaceDeclHandler = start;
1261 endNamespaceDeclHandler = end;
1262}
1263
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001264void
1265XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1266 XML_StartNamespaceDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001267 startNamespaceDeclHandler = start;
1268}
1269
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001270void
1271XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1272 XML_EndNamespaceDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001273 endNamespaceDeclHandler = end;
1274}
1275
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001276void
1277XML_SetNotStandaloneHandler(XML_Parser parser,
1278 XML_NotStandaloneHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001279{
1280 notStandaloneHandler = handler;
1281}
1282
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001283void
1284XML_SetExternalEntityRefHandler(XML_Parser parser,
1285 XML_ExternalEntityRefHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001286{
1287 externalEntityRefHandler = handler;
1288}
1289
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001290void
1291XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001292{
1293 if (arg)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001294 externalEntityRefHandlerArg = (XML_Parser)arg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001295 else
1296 externalEntityRefHandlerArg = parser;
1297}
1298
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001299void
1300XML_SetSkippedEntityHandler(XML_Parser parser,
1301 XML_SkippedEntityHandler handler)
1302{
1303 skippedEntityHandler = handler;
1304}
1305
1306void
1307XML_SetUnknownEncodingHandler(XML_Parser parser,
1308 XML_UnknownEncodingHandler handler,
1309 void *data)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001310{
1311 unknownEncodingHandler = handler;
1312 unknownEncodingHandlerData = data;
1313}
1314
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001315void
1316XML_SetElementDeclHandler(XML_Parser parser,
1317 XML_ElementDeclHandler eldecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001318{
1319 elementDeclHandler = eldecl;
1320}
1321
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001322void
1323XML_SetAttlistDeclHandler(XML_Parser parser,
1324 XML_AttlistDeclHandler attdecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001325{
1326 attlistDeclHandler = attdecl;
1327}
1328
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001329void
1330XML_SetEntityDeclHandler(XML_Parser parser,
1331 XML_EntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001332{
1333 entityDeclHandler = handler;
1334}
1335
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001336void
1337XML_SetXmlDeclHandler(XML_Parser parser,
1338 XML_XmlDeclHandler handler) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001339 xmlDeclHandler = handler;
1340}
1341
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001342int
1343XML_SetParamEntityParsing(XML_Parser parser,
1344 enum XML_ParamEntityParsing peParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001345{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001346 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1347 if (parsing)
1348 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001349#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001350 paramEntityParsing = peParsing;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001351 return 1;
1352#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001353 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001354#endif
1355}
1356
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001357enum XML_Status
1358XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001359{
1360 if (len == 0) {
1361 if (!isFinal)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001362 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001363 positionPtr = bufferPtr;
1364 errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
1365 if (errorCode == XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001366 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001367 eventEndPtr = eventPtr;
1368 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001369 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001370 }
1371#ifndef XML_CONTEXT_BYTES
1372 else if (bufferPtr == bufferEnd) {
1373 const char *end;
1374 int nLeftOver;
1375 parseEndByteIndex += len;
1376 positionPtr = s;
1377 if (isFinal) {
1378 errorCode = processor(parser, s, parseEndPtr = s + len, 0);
1379 if (errorCode == XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001380 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001381 eventEndPtr = eventPtr;
1382 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001383 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001384 }
1385 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1386 if (errorCode != XML_ERROR_NONE) {
1387 eventEndPtr = eventPtr;
1388 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001389 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001390 }
1391 XmlUpdatePosition(encoding, positionPtr, end, &position);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001392 positionPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001393 nLeftOver = s + len - end;
1394 if (nLeftOver) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001395 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1396 /* FIXME avoid integer overflow */
1397 char *temp;
1398 temp = (buffer == NULL
1399 ? (char *)MALLOC(len * 2)
1400 : (char *)REALLOC(buffer, len * 2));
1401 if (temp == NULL) {
1402 errorCode = XML_ERROR_NO_MEMORY;
1403 return XML_STATUS_ERROR;
1404 }
1405 buffer = temp;
1406 if (!buffer) {
1407 errorCode = XML_ERROR_NO_MEMORY;
1408 eventPtr = eventEndPtr = NULL;
1409 processor = errorProcessor;
1410 return XML_STATUS_ERROR;
1411 }
1412 bufferLim = buffer + len * 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001413 }
1414 memcpy(buffer, end, nLeftOver);
1415 bufferPtr = buffer;
1416 bufferEnd = buffer + nLeftOver;
1417 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001418 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001419 }
1420#endif /* not defined XML_CONTEXT_BYTES */
1421 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001422 void *buff = XML_GetBuffer(parser, len);
1423 if (buff == NULL)
1424 return XML_STATUS_ERROR;
1425 else {
1426 memcpy(buff, s, len);
1427 return XML_ParseBuffer(parser, len, isFinal);
1428 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001429 }
1430}
1431
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001432enum XML_Status
1433XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001434{
1435 const char *start = bufferPtr;
1436 positionPtr = start;
1437 bufferEnd += len;
1438 parseEndByteIndex += len;
1439 errorCode = processor(parser, start, parseEndPtr = bufferEnd,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001440 isFinal ? (const char **)NULL : &bufferPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001441 if (errorCode == XML_ERROR_NONE) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001442 if (!isFinal) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001443 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001444 positionPtr = bufferPtr;
1445 }
1446 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001447 }
1448 else {
1449 eventEndPtr = eventPtr;
1450 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001451 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001452 }
1453}
1454
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001455void *
1456XML_GetBuffer(XML_Parser parser, int len)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001457{
1458 if (len > bufferLim - bufferEnd) {
1459 /* FIXME avoid integer overflow */
1460 int neededSize = len + (bufferEnd - bufferPtr);
1461#ifdef XML_CONTEXT_BYTES
1462 int keep = bufferPtr - buffer;
1463
1464 if (keep > XML_CONTEXT_BYTES)
1465 keep = XML_CONTEXT_BYTES;
1466 neededSize += keep;
1467#endif /* defined XML_CONTEXT_BYTES */
1468 if (neededSize <= bufferLim - buffer) {
1469#ifdef XML_CONTEXT_BYTES
1470 if (keep < bufferPtr - buffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001471 int offset = (bufferPtr - buffer) - keep;
1472 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1473 bufferEnd -= offset;
1474 bufferPtr -= offset;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001475 }
1476#else
1477 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1478 bufferEnd = buffer + (bufferEnd - bufferPtr);
1479 bufferPtr = buffer;
1480#endif /* not defined XML_CONTEXT_BYTES */
1481 }
1482 else {
1483 char *newBuf;
1484 int bufferSize = bufferLim - bufferPtr;
1485 if (bufferSize == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001486 bufferSize = INIT_BUFFER_SIZE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001487 do {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001488 bufferSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001489 } while (bufferSize < neededSize);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001490 newBuf = (char *)MALLOC(bufferSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001491 if (newBuf == 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001492 errorCode = XML_ERROR_NO_MEMORY;
1493 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001494 }
1495 bufferLim = newBuf + bufferSize;
1496#ifdef XML_CONTEXT_BYTES
1497 if (bufferPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001498 int keep = bufferPtr - buffer;
1499 if (keep > XML_CONTEXT_BYTES)
1500 keep = XML_CONTEXT_BYTES;
1501 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1502 FREE(buffer);
1503 buffer = newBuf;
1504 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1505 bufferPtr = buffer + keep;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001506 }
1507 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001508 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1509 bufferPtr = buffer = newBuf;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001510 }
1511#else
1512 if (bufferPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001513 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1514 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001515 }
1516 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1517 bufferPtr = buffer = newBuf;
1518#endif /* not defined XML_CONTEXT_BYTES */
1519 }
1520 }
1521 return bufferEnd;
1522}
1523
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001524enum XML_Error
1525XML_GetErrorCode(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001526{
1527 return errorCode;
1528}
1529
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001530long
1531XML_GetCurrentByteIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001532{
1533 if (eventPtr)
1534 return parseEndByteIndex - (parseEndPtr - eventPtr);
1535 return -1;
1536}
1537
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001538int
1539XML_GetCurrentByteCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001540{
1541 if (eventEndPtr && eventPtr)
1542 return eventEndPtr - eventPtr;
1543 return 0;
1544}
1545
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001546const char *
1547XML_GetInputContext(XML_Parser parser, int *offset, int *size)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001548{
1549#ifdef XML_CONTEXT_BYTES
1550 if (eventPtr && buffer) {
1551 *offset = eventPtr - buffer;
1552 *size = bufferEnd - buffer;
1553 return buffer;
1554 }
1555#endif /* defined XML_CONTEXT_BYTES */
1556 return (char *) 0;
1557}
1558
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001559int
1560XML_GetCurrentLineNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001561{
1562 if (eventPtr) {
1563 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1564 positionPtr = eventPtr;
1565 }
1566 return position.lineNumber + 1;
1567}
1568
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001569int
1570XML_GetCurrentColumnNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001571{
1572 if (eventPtr) {
1573 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1574 positionPtr = eventPtr;
1575 }
1576 return position.columnNumber;
1577}
1578
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001579void
1580XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1581{
1582 FREE(model);
1583}
1584
1585void *
1586XML_MemMalloc(XML_Parser parser, size_t size)
1587{
1588 return MALLOC(size);
1589}
1590
1591void *
1592XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1593{
1594 return REALLOC(ptr, size);
1595}
1596
1597void
1598XML_MemFree(XML_Parser parser, void *ptr)
1599{
1600 FREE(ptr);
1601}
1602
1603void
1604XML_DefaultCurrent(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001605{
1606 if (defaultHandler) {
1607 if (openInternalEntities)
1608 reportDefault(parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001609 internalEncoding,
1610 openInternalEntities->internalEventPtr,
1611 openInternalEntities->internalEventEndPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001612 else
1613 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1614 }
1615}
1616
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001617const XML_LChar *
1618XML_ErrorString(enum XML_Error code)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001619{
1620 static const XML_LChar *message[] = {
1621 0,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001622 XML_L("out of memory"),
1623 XML_L("syntax error"),
1624 XML_L("no element found"),
1625 XML_L("not well-formed (invalid token)"),
1626 XML_L("unclosed token"),
1627 XML_L("partial character"),
1628 XML_L("mismatched tag"),
1629 XML_L("duplicate attribute"),
1630 XML_L("junk after document element"),
1631 XML_L("illegal parameter entity reference"),
1632 XML_L("undefined entity"),
1633 XML_L("recursive entity reference"),
1634 XML_L("asynchronous entity"),
1635 XML_L("reference to invalid character number"),
1636 XML_L("reference to binary entity"),
1637 XML_L("reference to external entity in attribute"),
1638 XML_L("xml declaration not at start of external entity"),
1639 XML_L("unknown encoding"),
1640 XML_L("encoding specified in XML declaration is incorrect"),
1641 XML_L("unclosed CDATA section"),
1642 XML_L("error in processing external entity reference"),
1643 XML_L("document is not standalone"),
1644 XML_L("unexpected parser state - please send a bug report"),
1645 XML_L("entity declared in parameter entity"),
1646 XML_L("requested feature requires XML_DTD support in Expat"),
1647 XML_L("cannot change setting once parsing has begun")
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001648 };
1649 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1650 return message[code];
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001651 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001652}
1653
1654const XML_LChar *
1655XML_ExpatVersion(void) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001656
1657 /* V1 is used to string-ize the version number. However, it would
1658 string-ize the actual version macro *names* unless we get them
1659 substituted before being passed to V1. CPP is defined to expand
1660 a macro, then rescan for more expansions. Thus, we use V2 to expand
1661 the version macros, then CPP will expand the resulting V1() macro
1662 with the correct numerals. */
1663 /* ### I'm assuming cpp is portable in this respect... */
1664
1665#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1666#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1667
1668 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1669
1670#undef V1
1671#undef V2
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001672}
1673
1674XML_Expat_Version
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001675XML_ExpatVersionInfo(void)
1676{
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001677 XML_Expat_Version version;
1678
1679 version.major = XML_MAJOR_VERSION;
1680 version.minor = XML_MINOR_VERSION;
1681 version.micro = XML_MICRO_VERSION;
1682
1683 return version;
1684}
1685
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001686const XML_Feature *
1687XML_GetFeatureList(void)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001688{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001689 static XML_Feature features[] = {
1690 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)")},
1691 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)")},
1692#ifdef XML_UNICODE
1693 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE")},
1694#endif
1695#ifdef XML_UNICODE_WCHAR_T
1696 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T")},
1697#endif
1698#ifdef XML_DTD
1699 {XML_FEATURE_DTD, XML_L("XML_DTD")},
1700#endif
1701#ifdef XML_CONTEXT_BYTES
1702 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
1703 XML_CONTEXT_BYTES},
1704#endif
1705#ifdef XML_MIN_SIZE
1706 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE")},
1707#endif
1708 {XML_FEATURE_END, NULL}
1709 };
1710
1711 features[0].value = sizeof(XML_Char);
1712 features[1].value = sizeof(XML_LChar);
1713 return features;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001714}
1715
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001716/* Initially tag->rawName always points into the parse buffer;
1717 for those TAG instances opened while the current parse buffer was
1718 processed, and not yet closed, we need to store tag->rawName in a more
1719 permanent location, since the parse buffer is about to be discarded.
1720*/
1721static XML_Bool
1722storeRawNames(XML_Parser parser)
1723{
1724 TAG *tag = tagStack;
1725 while (tag) {
1726 int bufSize;
1727 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
1728 char *rawNameBuf = tag->buf + nameLen;
1729 /* Stop if already stored. Since tagStack is a stack, we can stop
1730 at the first entry that has already been copied; everything
1731 below it in the stack is already been accounted for in a
1732 previous call to this function.
1733 */
1734 if (tag->rawName == rawNameBuf)
1735 break;
1736 /* For re-use purposes we need to ensure that the
1737 size of tag->buf is a multiple of sizeof(XML_Char).
1738 */
1739 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
1740 if (bufSize > tag->bufEnd - tag->buf) {
1741 char *temp = (char *)REALLOC(tag->buf, bufSize);
1742 if (temp == NULL)
1743 return XML_FALSE;
1744 /* if tag->name.str points to tag->buf (only when namespace
1745 processing is off) then we have to update it
1746 */
1747 if (tag->name.str == (XML_Char *)tag->buf)
1748 tag->name.str = (XML_Char *)temp;
1749 /* if tag->name.localPart is set (when namespace processing is on)
1750 then update it as well, since it will always point into tag->buf
1751 */
1752 if (tag->name.localPart)
1753 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
1754 (XML_Char *)tag->buf);
1755 tag->buf = temp;
1756 tag->bufEnd = temp + bufSize;
1757 rawNameBuf = temp + nameLen;
1758 }
1759 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
1760 tag->rawName = rawNameBuf;
1761 tag = tag->parent;
1762 }
1763 return XML_TRUE;
1764}
1765
1766static enum XML_Error PTRCALL
1767contentProcessor(XML_Parser parser,
1768 const char *start,
1769 const char *end,
1770 const char **endPtr)
1771{
1772 enum XML_Error result =
1773 doContent(parser, 0, encoding, start, end, endPtr);
1774 if (result != XML_ERROR_NONE)
1775 return result;
1776 if (!storeRawNames(parser))
1777 return XML_ERROR_NO_MEMORY;
1778 return result;
1779}
1780
1781static enum XML_Error PTRCALL
1782externalEntityInitProcessor(XML_Parser parser,
1783 const char *start,
1784 const char *end,
1785 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001786{
1787 enum XML_Error result = initializeEncoding(parser);
1788 if (result != XML_ERROR_NONE)
1789 return result;
1790 processor = externalEntityInitProcessor2;
1791 return externalEntityInitProcessor2(parser, start, end, endPtr);
1792}
1793
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001794static enum XML_Error PTRCALL
1795externalEntityInitProcessor2(XML_Parser parser,
1796 const char *start,
1797 const char *end,
1798 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001799{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001800 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001801 int tok = XmlContentTok(encoding, start, end, &next);
1802 switch (tok) {
1803 case XML_TOK_BOM:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001804 /* If we are at the end of the buffer, this would cause the next stage,
1805 i.e. externalEntityInitProcessor3, to pass control directly to
1806 doContent (by detecting XML_TOK_NONE) without processing any xml text
1807 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
1808 */
1809 if (next == end && endPtr) {
1810 *endPtr = next;
1811 return XML_ERROR_NONE;
1812 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001813 start = next;
1814 break;
1815 case XML_TOK_PARTIAL:
1816 if (endPtr) {
1817 *endPtr = start;
1818 return XML_ERROR_NONE;
1819 }
1820 eventPtr = start;
1821 return XML_ERROR_UNCLOSED_TOKEN;
1822 case XML_TOK_PARTIAL_CHAR:
1823 if (endPtr) {
1824 *endPtr = start;
1825 return XML_ERROR_NONE;
1826 }
1827 eventPtr = start;
1828 return XML_ERROR_PARTIAL_CHAR;
1829 }
1830 processor = externalEntityInitProcessor3;
1831 return externalEntityInitProcessor3(parser, start, end, endPtr);
1832}
1833
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001834static enum XML_Error PTRCALL
1835externalEntityInitProcessor3(XML_Parser parser,
1836 const char *start,
1837 const char *end,
1838 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001839{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001840 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001841 int tok = XmlContentTok(encoding, start, end, &next);
1842 switch (tok) {
1843 case XML_TOK_XML_DECL:
1844 {
1845 enum XML_Error result = processXmlDecl(parser, 1, start, next);
1846 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001847 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001848 start = next;
1849 }
1850 break;
1851 case XML_TOK_PARTIAL:
1852 if (endPtr) {
1853 *endPtr = start;
1854 return XML_ERROR_NONE;
1855 }
1856 eventPtr = start;
1857 return XML_ERROR_UNCLOSED_TOKEN;
1858 case XML_TOK_PARTIAL_CHAR:
1859 if (endPtr) {
1860 *endPtr = start;
1861 return XML_ERROR_NONE;
1862 }
1863 eventPtr = start;
1864 return XML_ERROR_PARTIAL_CHAR;
1865 }
1866 processor = externalEntityContentProcessor;
1867 tagLevel = 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001868 return externalEntityContentProcessor(parser, start, end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001869}
1870
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001871static enum XML_Error PTRCALL
1872externalEntityContentProcessor(XML_Parser parser,
1873 const char *start,
1874 const char *end,
1875 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001876{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001877 enum XML_Error result =
1878 doContent(parser, 1, encoding, start, end, endPtr);
1879 if (result != XML_ERROR_NONE)
1880 return result;
1881 if (!storeRawNames(parser))
1882 return XML_ERROR_NO_MEMORY;
1883 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001884}
1885
1886static enum XML_Error
1887doContent(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001888 int startTagLevel,
1889 const ENCODING *enc,
1890 const char *s,
1891 const char *end,
1892 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001893{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001894 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001895 const char **eventPP;
1896 const char **eventEndPP;
1897 if (enc == encoding) {
1898 eventPP = &eventPtr;
1899 eventEndPP = &eventEndPtr;
1900 }
1901 else {
1902 eventPP = &(openInternalEntities->internalEventPtr);
1903 eventEndPP = &(openInternalEntities->internalEventEndPtr);
1904 }
1905 *eventPP = s;
1906 for (;;) {
1907 const char *next = s; /* XmlContentTok doesn't always set the last arg */
1908 int tok = XmlContentTok(enc, s, end, &next);
1909 *eventEndPP = next;
1910 switch (tok) {
1911 case XML_TOK_TRAILING_CR:
1912 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001913 *nextPtr = s;
1914 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001915 }
1916 *eventEndPP = end;
1917 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001918 XML_Char c = 0xA;
1919 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001920 }
1921 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001922 reportDefault(parser, enc, s, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001923 if (startTagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001924 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001925 if (tagLevel != startTagLevel)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001926 return XML_ERROR_ASYNC_ENTITY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001927 return XML_ERROR_NONE;
1928 case XML_TOK_NONE:
1929 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001930 *nextPtr = s;
1931 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001932 }
1933 if (startTagLevel > 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001934 if (tagLevel != startTagLevel)
1935 return XML_ERROR_ASYNC_ENTITY;
1936 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001937 }
1938 return XML_ERROR_NO_ELEMENTS;
1939 case XML_TOK_INVALID:
1940 *eventPP = next;
1941 return XML_ERROR_INVALID_TOKEN;
1942 case XML_TOK_PARTIAL:
1943 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001944 *nextPtr = s;
1945 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001946 }
1947 return XML_ERROR_UNCLOSED_TOKEN;
1948 case XML_TOK_PARTIAL_CHAR:
1949 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001950 *nextPtr = s;
1951 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001952 }
1953 return XML_ERROR_PARTIAL_CHAR;
1954 case XML_TOK_ENTITY_REF:
1955 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001956 const XML_Char *name;
1957 ENTITY *entity;
1958 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
1959 s + enc->minBytesPerChar,
1960 next - enc->minBytesPerChar);
1961 if (ch) {
1962 if (characterDataHandler)
1963 characterDataHandler(handlerArg, &ch, 1);
1964 else if (defaultHandler)
1965 reportDefault(parser, enc, s, next);
1966 break;
1967 }
1968 name = poolStoreString(&dtd->pool, enc,
1969 s + enc->minBytesPerChar,
1970 next - enc->minBytesPerChar);
1971 if (!name)
1972 return XML_ERROR_NO_MEMORY;
1973 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
1974 poolDiscard(&dtd->pool);
1975 /* First, determine if a check for an existing declaration is needed;
1976 if yes, check that the entity exists, and that it is internal,
1977 otherwise call the skipped entity or default handler.
1978 */
1979 if (!dtd->hasParamEntityRefs || dtd->standalone) {
1980 if (!entity)
1981 return XML_ERROR_UNDEFINED_ENTITY;
1982 else if (!entity->is_internal)
1983 return XML_ERROR_ENTITY_DECLARED_IN_PE;
1984 }
1985 else if (!entity) {
1986 if (skippedEntityHandler)
1987 skippedEntityHandler(handlerArg, name, 0);
1988 else if (defaultHandler)
1989 reportDefault(parser, enc, s, next);
1990 break;
1991 }
1992 if (entity->open)
1993 return XML_ERROR_RECURSIVE_ENTITY_REF;
1994 if (entity->notation)
1995 return XML_ERROR_BINARY_ENTITY_REF;
1996 if (entity->textPtr) {
1997 enum XML_Error result;
1998 OPEN_INTERNAL_ENTITY openEntity;
1999 if (!defaultExpandInternalEntities) {
2000 if (skippedEntityHandler)
2001 skippedEntityHandler(handlerArg, entity->name, 0);
2002 else if (defaultHandler)
2003 reportDefault(parser, enc, s, next);
2004 break;
2005 }
2006 entity->open = XML_TRUE;
2007 openEntity.next = openInternalEntities;
2008 openInternalEntities = &openEntity;
2009 openEntity.entity = entity;
2010 openEntity.internalEventPtr = NULL;
2011 openEntity.internalEventEndPtr = NULL;
2012 result = doContent(parser,
2013 tagLevel,
2014 internalEncoding,
2015 (char *)entity->textPtr,
2016 (char *)(entity->textPtr + entity->textLen),
2017 0);
2018 entity->open = XML_FALSE;
2019 openInternalEntities = openEntity.next;
2020 if (result)
2021 return result;
2022 }
2023 else if (externalEntityRefHandler) {
2024 const XML_Char *context;
2025 entity->open = XML_TRUE;
2026 context = getContext(parser);
2027 entity->open = XML_FALSE;
2028 if (!context)
2029 return XML_ERROR_NO_MEMORY;
2030 if (!externalEntityRefHandler((XML_Parser)externalEntityRefHandlerArg,
2031 context,
2032 entity->base,
2033 entity->systemId,
2034 entity->publicId))
2035 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2036 poolDiscard(&tempPool);
2037 }
2038 else if (defaultHandler)
2039 reportDefault(parser, enc, s, next);
2040 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002041 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002042 case XML_TOK_START_TAG_NO_ATTS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002043 /* fall through */
2044 case XML_TOK_START_TAG_WITH_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002045 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002046 TAG *tag;
2047 enum XML_Error result;
2048 XML_Char *toPtr;
2049 if (freeTagList) {
2050 tag = freeTagList;
2051 freeTagList = freeTagList->parent;
2052 }
2053 else {
2054 tag = (TAG *)MALLOC(sizeof(TAG));
2055 if (!tag)
2056 return XML_ERROR_NO_MEMORY;
2057 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2058 if (!tag->buf) {
2059 FREE(tag);
2060 return XML_ERROR_NO_MEMORY;
2061 }
2062 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2063 }
2064 tag->bindings = NULL;
2065 tag->parent = tagStack;
2066 tagStack = tag;
2067 tag->name.localPart = NULL;
2068 tag->name.prefix = NULL;
2069 tag->rawName = s + enc->minBytesPerChar;
2070 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2071 ++tagLevel;
2072 {
2073 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2074 const char *fromPtr = tag->rawName;
2075 toPtr = (XML_Char *)tag->buf;
2076 for (;;) {
2077 int bufSize;
2078 int convLen;
2079 XmlConvert(enc,
2080 &fromPtr, rawNameEnd,
2081 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2082 convLen = toPtr - (XML_Char *)tag->buf;
2083 if (fromPtr == rawNameEnd) {
2084 tag->name.strLen = convLen;
2085 break;
2086 }
2087 bufSize = (tag->bufEnd - tag->buf) << 1;
2088 {
2089 char *temp = (char *)REALLOC(tag->buf, bufSize);
2090 if (temp == NULL)
2091 return XML_ERROR_NO_MEMORY;
2092 tag->buf = temp;
2093 tag->bufEnd = temp + bufSize;
2094 toPtr = (XML_Char *)temp + convLen;
2095 }
2096 }
2097 }
2098 tag->name.str = (XML_Char *)tag->buf;
2099 *toPtr = XML_T('\0');
2100 if (!startElementHandler && (tok == XML_TOK_START_TAG_NO_ATTS)) {
2101 if (defaultHandler)
2102 reportDefault(parser, enc, s, next);
2103 break;
2104 }
2105 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2106 if (result)
2107 return result;
2108 if (startElementHandler)
2109 startElementHandler(handlerArg, tag->name.str,
2110 (const XML_Char **)atts);
2111 else if (defaultHandler)
2112 reportDefault(parser, enc, s, next);
2113 poolClear(&tempPool);
2114 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002115 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002116 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2117 if (!startElementHandler && !endElementHandler) {
2118 if (defaultHandler)
2119 reportDefault(parser, enc, s, next);
2120 if (tagLevel == 0)
2121 return epilogProcessor(parser, next, end, nextPtr);
2122 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002123 }
2124 /* fall through */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002125 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2126 {
2127 const char *rawName = s + enc->minBytesPerChar;
2128 enum XML_Error result;
2129 BINDING *bindings = NULL;
2130 XML_Bool noElmHandlers = XML_TRUE;
2131 TAG_NAME name;
2132 name.str = poolStoreString(&tempPool, enc, rawName,
2133 rawName + XmlNameLength(enc, rawName));
2134 if (!name.str)
2135 return XML_ERROR_NO_MEMORY;
2136 poolFinish(&tempPool);
2137 if (startElementHandler ||
2138 (tok == XML_TOK_EMPTY_ELEMENT_WITH_ATTS)) {
2139 result = storeAtts(parser, enc, s, &name, &bindings);
2140 if (result)
2141 return result;
2142 poolFinish(&tempPool);
2143 }
2144 if (startElementHandler) {
2145 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2146 noElmHandlers = XML_FALSE;
2147 }
2148 if (endElementHandler) {
2149 if (startElementHandler)
2150 *eventPP = *eventEndPP;
2151 endElementHandler(handlerArg, name.str);
2152 noElmHandlers = XML_FALSE;
2153 }
2154 if (noElmHandlers && defaultHandler)
2155 reportDefault(parser, enc, s, next);
2156 poolClear(&tempPool);
2157 while (bindings) {
2158 BINDING *b = bindings;
2159 if (endNamespaceDeclHandler)
2160 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2161 bindings = bindings->nextTagBinding;
2162 b->nextTagBinding = freeBindingList;
2163 freeBindingList = b;
2164 b->prefix->binding = b->prevPrefixBinding;
2165 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002166 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002167 if (tagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002168 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002169 break;
2170 case XML_TOK_END_TAG:
2171 if (tagLevel == startTagLevel)
2172 return XML_ERROR_ASYNC_ENTITY;
2173 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002174 int len;
2175 const char *rawName;
2176 TAG *tag = tagStack;
2177 tagStack = tag->parent;
2178 tag->parent = freeTagList;
2179 freeTagList = tag;
2180 rawName = s + enc->minBytesPerChar*2;
2181 len = XmlNameLength(enc, rawName);
2182 if (len != tag->rawNameLength
2183 || memcmp(tag->rawName, rawName, len) != 0) {
2184 *eventPP = rawName;
2185 return XML_ERROR_TAG_MISMATCH;
2186 }
2187 --tagLevel;
2188 if (endElementHandler) {
2189 const XML_Char *localPart;
2190 const XML_Char *prefix;
2191 XML_Char *uri;
2192 localPart = tag->name.localPart;
2193 if (ns && localPart) {
2194 /* localPart and prefix may have been overwritten in
2195 tag->name.str, since this points to the binding->uri
2196 buffer which gets re-used; so we have to add them again
2197 */
2198 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2199 /* don't need to check for space - already done in storeAtts() */
2200 while (*localPart) *uri++ = *localPart++;
2201 prefix = (XML_Char *)tag->name.prefix;
2202 if (ns_triplets && prefix) {
2203 *uri++ = namespaceSeparator;
2204 while (*prefix) *uri++ = *prefix++;
2205 }
2206 *uri = XML_T('\0');
2207 }
2208 endElementHandler(handlerArg, tag->name.str);
2209 }
2210 else if (defaultHandler)
2211 reportDefault(parser, enc, s, next);
2212 while (tag->bindings) {
2213 BINDING *b = tag->bindings;
2214 if (endNamespaceDeclHandler)
2215 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2216 tag->bindings = tag->bindings->nextTagBinding;
2217 b->nextTagBinding = freeBindingList;
2218 freeBindingList = b;
2219 b->prefix->binding = b->prevPrefixBinding;
2220 }
2221 if (tagLevel == 0)
2222 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002223 }
2224 break;
2225 case XML_TOK_CHAR_REF:
2226 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002227 int n = XmlCharRefNumber(enc, s);
2228 if (n < 0)
2229 return XML_ERROR_BAD_CHAR_REF;
2230 if (characterDataHandler) {
2231 XML_Char buf[XML_ENCODE_MAX];
2232 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2233 }
2234 else if (defaultHandler)
2235 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002236 }
2237 break;
2238 case XML_TOK_XML_DECL:
2239 return XML_ERROR_MISPLACED_XML_PI;
2240 case XML_TOK_DATA_NEWLINE:
2241 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002242 XML_Char c = 0xA;
2243 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002244 }
2245 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002246 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002247 break;
2248 case XML_TOK_CDATA_SECT_OPEN:
2249 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002250 enum XML_Error result;
2251 if (startCdataSectionHandler)
2252 startCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002253#if 0
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002254 /* Suppose you doing a transformation on a document that involves
2255 changing only the character data. You set up a defaultHandler
2256 and a characterDataHandler. The defaultHandler simply copies
2257 characters through. The characterDataHandler does the
2258 transformation and writes the characters out escaping them as
2259 necessary. This case will fail to work if we leave out the
2260 following two lines (because & and < inside CDATA sections will
2261 be incorrectly escaped).
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002262
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002263 However, now we have a start/endCdataSectionHandler, so it seems
2264 easier to let the user deal with this.
2265 */
2266 else if (characterDataHandler)
2267 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002268#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002269 else if (defaultHandler)
2270 reportDefault(parser, enc, s, next);
2271 result = doCdataSection(parser, enc, &next, end, nextPtr);
2272 if (!next) {
2273 processor = cdataSectionProcessor;
2274 return result;
2275 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002276 }
2277 break;
2278 case XML_TOK_TRAILING_RSQB:
2279 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002280 *nextPtr = s;
2281 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002282 }
2283 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002284 if (MUST_CONVERT(enc, s)) {
2285 ICHAR *dataPtr = (ICHAR *)dataBuf;
2286 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2287 characterDataHandler(handlerArg, dataBuf,
2288 dataPtr - (ICHAR *)dataBuf);
2289 }
2290 else
2291 characterDataHandler(handlerArg,
2292 (XML_Char *)s,
2293 (XML_Char *)end - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002294 }
2295 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002296 reportDefault(parser, enc, s, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002297 if (startTagLevel == 0) {
2298 *eventPP = end;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002299 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002300 }
2301 if (tagLevel != startTagLevel) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002302 *eventPP = end;
2303 return XML_ERROR_ASYNC_ENTITY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002304 }
2305 return XML_ERROR_NONE;
2306 case XML_TOK_DATA_CHARS:
2307 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002308 if (MUST_CONVERT(enc, s)) {
2309 for (;;) {
2310 ICHAR *dataPtr = (ICHAR *)dataBuf;
2311 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2312 *eventEndPP = s;
2313 characterDataHandler(handlerArg, dataBuf,
2314 dataPtr - (ICHAR *)dataBuf);
2315 if (s == next)
2316 break;
2317 *eventPP = s;
2318 }
2319 }
2320 else
2321 characterDataHandler(handlerArg,
2322 (XML_Char *)s,
2323 (XML_Char *)next - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002324 }
2325 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002326 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002327 break;
2328 case XML_TOK_PI:
2329 if (!reportProcessingInstruction(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002330 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002331 break;
2332 case XML_TOK_COMMENT:
2333 if (!reportComment(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002334 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002335 break;
2336 default:
2337 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002338 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002339 break;
2340 }
2341 *eventPP = s = next;
2342 }
2343 /* not reached */
2344}
2345
2346/* If tagNamePtr is non-null, build a real list of attributes,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002347 otherwise just check the attributes for well-formedness.
2348*/
2349static enum XML_Error
2350storeAtts(XML_Parser parser, const ENCODING *enc,
2351 const char *attStr, TAG_NAME *tagNamePtr,
2352 BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002353{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002354 DTD * const dtd = _dtd; /* save one level of indirection */
2355 ELEMENT_TYPE *elementType = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002356 int nDefaultAtts = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002357 const XML_Char **appAtts; /* the attribute list for the application */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002358 int attIndex = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002359 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002360 int i;
2361 int n;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002362 XML_Char *uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002363 int nPrefixes = 0;
2364 BINDING *binding;
2365 const XML_Char *localPart;
2366
2367 /* lookup the element type name */
2368 if (tagNamePtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002369 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002370 if (!elementType) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002371 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2372 if (!name)
2373 return XML_ERROR_NO_MEMORY;
2374 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
2375 sizeof(ELEMENT_TYPE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002376 if (!elementType)
2377 return XML_ERROR_NO_MEMORY;
2378 if (ns && !setElementTypePrefix(parser, elementType))
2379 return XML_ERROR_NO_MEMORY;
2380 }
2381 nDefaultAtts = elementType->nDefaultAtts;
2382 }
2383 /* get the attributes from the tokenizer */
2384 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2385 if (n + nDefaultAtts > attsSize) {
2386 int oldAttsSize = attsSize;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002387 ATTRIBUTE *temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002388 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002389 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2390 if (temp == NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002391 return XML_ERROR_NO_MEMORY;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002392 atts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002393 if (n > oldAttsSize)
2394 XmlGetAttributes(enc, attStr, n, atts);
2395 }
2396 appAtts = (const XML_Char **)atts;
2397 for (i = 0; i < n; i++) {
2398 /* add the name and value to the attribute list */
2399 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002400 atts[i].name
2401 + XmlNameLength(enc, atts[i].name));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002402 if (!attId)
2403 return XML_ERROR_NO_MEMORY;
2404 /* detect duplicate attributes */
2405 if ((attId->name)[-1]) {
2406 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002407 eventPtr = atts[i].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002408 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2409 }
2410 (attId->name)[-1] = 1;
2411 appAtts[attIndex++] = attId->name;
2412 if (!atts[i].normalized) {
2413 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002414 XML_Bool isCdata = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002415
2416 /* figure out whether declared as other than CDATA */
2417 if (attId->maybeTokenized) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002418 int j;
2419 for (j = 0; j < nDefaultAtts; j++) {
2420 if (attId == elementType->defaultAtts[j].id) {
2421 isCdata = elementType->defaultAtts[j].isCdata;
2422 break;
2423 }
2424 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002425 }
2426
2427 /* normalize the attribute value */
2428 result = storeAttributeValue(parser, enc, isCdata,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002429 atts[i].valuePtr, atts[i].valueEnd,
2430 &tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002431 if (result)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002432 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002433 if (tagNamePtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002434 appAtts[attIndex] = poolStart(&tempPool);
2435 poolFinish(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002436 }
2437 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002438 poolDiscard(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002439 }
2440 else if (tagNamePtr) {
2441 /* the value did not need normalizing */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002442 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2443 atts[i].valueEnd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002444 if (appAtts[attIndex] == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002445 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002446 poolFinish(&tempPool);
2447 }
2448 /* handle prefixed attribute names */
2449 if (attId->prefix && tagNamePtr) {
2450 if (attId->xmlns) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002451 /* deal with namespace declarations here */
2452 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2453 appAtts[attIndex], bindingsPtr);
2454 if (result)
2455 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002456 --attIndex;
2457 }
2458 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002459 /* deal with other prefixed names later */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002460 attIndex++;
2461 nPrefixes++;
2462 (attId->name)[-1] = 2;
2463 }
2464 }
2465 else
2466 attIndex++;
2467 }
2468 if (tagNamePtr) {
2469 int j;
2470 nSpecifiedAtts = attIndex;
2471 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2472 for (i = 0; i < attIndex; i += 2)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002473 if (appAtts[i] == elementType->idAtt->name) {
2474 idAttIndex = i;
2475 break;
2476 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002477 }
2478 else
2479 idAttIndex = -1;
2480 /* do attribute defaulting */
2481 for (j = 0; j < nDefaultAtts; j++) {
2482 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
2483 if (!(da->id->name)[-1] && da->value) {
2484 if (da->id->prefix) {
2485 if (da->id->xmlns) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002486 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2487 da->value, bindingsPtr);
2488 if (result)
2489 return result;
2490 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002491 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002492 (da->id->name)[-1] = 2;
2493 nPrefixes++;
2494 appAtts[attIndex++] = da->id->name;
2495 appAtts[attIndex++] = da->value;
2496 }
2497 }
2498 else {
2499 (da->id->name)[-1] = 1;
2500 appAtts[attIndex++] = da->id->name;
2501 appAtts[attIndex++] = da->value;
2502 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002503 }
2504 }
2505 appAtts[attIndex] = 0;
2506 }
2507 i = 0;
2508 if (nPrefixes) {
2509 /* expand prefixed attribute names */
2510 for (; i < attIndex; i += 2) {
2511 if (appAtts[i][-1] == 2) {
2512 ATTRIBUTE_ID *id;
2513 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002514 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, appAtts[i], 0);
2515 if (id->prefix->binding) {
2516 int j;
2517 const BINDING *b = id->prefix->binding;
2518 const XML_Char *s = appAtts[i];
2519 for (j = 0; j < b->uriLen; j++) {
2520 if (!poolAppendChar(&tempPool, b->uri[j]))
2521 return XML_ERROR_NO_MEMORY;
2522 }
2523 while (*s++ != XML_T(':'))
2524 ;
2525 do {
2526 if (!poolAppendChar(&tempPool, *s))
2527 return XML_ERROR_NO_MEMORY;
2528 } while (*s++);
2529 if (ns_triplets) {
2530 tempPool.ptr[-1] = namespaceSeparator;
2531 s = b->prefix->name;
2532 do {
2533 if (!poolAppendChar(&tempPool, *s))
2534 return XML_ERROR_NO_MEMORY;
2535 } while (*s++);
2536 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002537
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002538 appAtts[i] = poolStart(&tempPool);
2539 poolFinish(&tempPool);
2540 }
2541 if (!--nPrefixes)
2542 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002543 }
2544 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002545 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002546 }
2547 }
2548 /* clear the flags that say whether attributes were specified */
2549 for (; i < attIndex; i += 2)
2550 ((XML_Char *)(appAtts[i]))[-1] = 0;
2551 if (!tagNamePtr)
2552 return XML_ERROR_NONE;
2553 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2554 binding->attId->name[-1] = 0;
2555 /* expand the element type name */
2556 if (elementType->prefix) {
2557 binding = elementType->prefix->binding;
2558 if (!binding)
2559 return XML_ERROR_NONE;
2560 localPart = tagNamePtr->str;
2561 while (*localPart++ != XML_T(':'))
2562 ;
2563 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002564 else if (dtd->defaultPrefix.binding) {
2565 binding = dtd->defaultPrefix.binding;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002566 localPart = tagNamePtr->str;
2567 }
2568 else
2569 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002570 prefixLen = 0;
2571 if (ns && ns_triplets && binding->prefix->name) {
2572 for (; binding->prefix->name[prefixLen++];)
2573 ;
2574 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002575 tagNamePtr->localPart = localPart;
2576 tagNamePtr->uriLen = binding->uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002577 tagNamePtr->prefix = binding->prefix->name;
2578 tagNamePtr->prefixLen = prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002579 for (i = 0; localPart[i++];)
2580 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002581 n = i + binding->uriLen + prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002582 if (n > binding->uriAlloc) {
2583 TAG *p;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002584 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002585 if (!uri)
2586 return XML_ERROR_NO_MEMORY;
2587 binding->uriAlloc = n + EXPAND_SPARE;
2588 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2589 for (p = tagStack; p; p = p->parent)
2590 if (p->name.str == binding->uri)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002591 p->name.str = uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002592 FREE(binding->uri);
2593 binding->uri = uri;
2594 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002595 uri = binding->uri + binding->uriLen;
2596 memcpy(uri, localPart, i * sizeof(XML_Char));
2597 if (prefixLen) {
2598 uri = uri + (i - 1);
2599 if (namespaceSeparator) { *(uri) = namespaceSeparator; }
2600 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2601 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002602 tagNamePtr->str = binding->uri;
2603 return XML_ERROR_NONE;
2604}
2605
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002606/* addBinding() overwrites the value of prefix->binding without checking.
2607 Therefore one must keep track of the old value outside of addBinding().
2608*/
2609static enum XML_Error
2610addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2611 const XML_Char *uri, BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002612{
2613 BINDING *b;
2614 int len;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002615
2616 /* empty string is only valid when there is no prefix per XML NS 1.0 */
2617 if (*uri == XML_T('\0') && prefix->name)
2618 return XML_ERROR_SYNTAX;
2619
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002620 for (len = 0; uri[len]; len++)
2621 ;
2622 if (namespaceSeparator)
2623 len++;
2624 if (freeBindingList) {
2625 b = freeBindingList;
2626 if (len > b->uriAlloc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002627 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
2628 sizeof(XML_Char) * (len + EXPAND_SPARE));
2629 if (temp == NULL)
2630 return XML_ERROR_NO_MEMORY;
2631 b->uri = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002632 b->uriAlloc = len + EXPAND_SPARE;
2633 }
2634 freeBindingList = b->nextTagBinding;
2635 }
2636 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002637 b = (BINDING *)MALLOC(sizeof(BINDING));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002638 if (!b)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002639 return XML_ERROR_NO_MEMORY;
2640 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002641 if (!b->uri) {
2642 FREE(b);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002643 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002644 }
2645 b->uriAlloc = len + EXPAND_SPARE;
2646 }
2647 b->uriLen = len;
2648 memcpy(b->uri, uri, len * sizeof(XML_Char));
2649 if (namespaceSeparator)
2650 b->uri[len - 1] = namespaceSeparator;
2651 b->prefix = prefix;
2652 b->attId = attId;
2653 b->prevPrefixBinding = prefix->binding;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002654 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
2655 prefix->binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002656 else
2657 prefix->binding = b;
2658 b->nextTagBinding = *bindingsPtr;
2659 *bindingsPtr = b;
2660 if (startNamespaceDeclHandler)
2661 startNamespaceDeclHandler(handlerArg, prefix->name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002662 prefix->binding ? uri : 0);
2663 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002664}
2665
2666/* The idea here is to avoid using stack for each CDATA section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002667 the whole file is parsed with one call.
2668*/
2669static enum XML_Error PTRCALL
2670cdataSectionProcessor(XML_Parser parser,
2671 const char *start,
2672 const char *end,
2673 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002674{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002675 enum XML_Error result = doCdataSection(parser, encoding, &start,
2676 end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002677 if (start) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002678 if (parentParser) { /* we are parsing an external entity */
2679 processor = externalEntityContentProcessor;
2680 return externalEntityContentProcessor(parser, start, end, endPtr);
2681 }
2682 else {
2683 processor = contentProcessor;
2684 return contentProcessor(parser, start, end, endPtr);
2685 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002686 }
2687 return result;
2688}
2689
2690/* startPtr gets set to non-null is the section is closed, and to null if
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002691 the section is not yet closed.
2692*/
2693static enum XML_Error
2694doCdataSection(XML_Parser parser,
2695 const ENCODING *enc,
2696 const char **startPtr,
2697 const char *end,
2698 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002699{
2700 const char *s = *startPtr;
2701 const char **eventPP;
2702 const char **eventEndPP;
2703 if (enc == encoding) {
2704 eventPP = &eventPtr;
2705 *eventPP = s;
2706 eventEndPP = &eventEndPtr;
2707 }
2708 else {
2709 eventPP = &(openInternalEntities->internalEventPtr);
2710 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2711 }
2712 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002713 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002714 for (;;) {
2715 const char *next;
2716 int tok = XmlCdataSectionTok(enc, s, end, &next);
2717 *eventEndPP = next;
2718 switch (tok) {
2719 case XML_TOK_CDATA_SECT_CLOSE:
2720 if (endCdataSectionHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002721 endCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002722#if 0
2723 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2724 else if (characterDataHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002725 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002726#endif
2727 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002728 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002729 *startPtr = next;
2730 return XML_ERROR_NONE;
2731 case XML_TOK_DATA_NEWLINE:
2732 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002733 XML_Char c = 0xA;
2734 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002735 }
2736 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002737 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002738 break;
2739 case XML_TOK_DATA_CHARS:
2740 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002741 if (MUST_CONVERT(enc, s)) {
2742 for (;;) {
2743 ICHAR *dataPtr = (ICHAR *)dataBuf;
2744 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2745 *eventEndPP = next;
2746 characterDataHandler(handlerArg, dataBuf,
2747 dataPtr - (ICHAR *)dataBuf);
2748 if (s == next)
2749 break;
2750 *eventPP = s;
2751 }
2752 }
2753 else
2754 characterDataHandler(handlerArg,
2755 (XML_Char *)s,
2756 (XML_Char *)next - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002757 }
2758 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002759 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002760 break;
2761 case XML_TOK_INVALID:
2762 *eventPP = next;
2763 return XML_ERROR_INVALID_TOKEN;
2764 case XML_TOK_PARTIAL_CHAR:
2765 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002766 *nextPtr = s;
2767 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002768 }
2769 return XML_ERROR_PARTIAL_CHAR;
2770 case XML_TOK_PARTIAL:
2771 case XML_TOK_NONE:
2772 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002773 *nextPtr = s;
2774 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002775 }
2776 return XML_ERROR_UNCLOSED_CDATA_SECTION;
2777 default:
2778 *eventPP = next;
2779 return XML_ERROR_UNEXPECTED_STATE;
2780 }
2781 *eventPP = s = next;
2782 }
2783 /* not reached */
2784}
2785
2786#ifdef XML_DTD
2787
2788/* The idea here is to avoid using stack for each IGNORE section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002789 the whole file is parsed with one call.
2790*/
2791static enum XML_Error PTRCALL
2792ignoreSectionProcessor(XML_Parser parser,
2793 const char *start,
2794 const char *end,
2795 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002796{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002797 enum XML_Error result = doIgnoreSection(parser, encoding, &start,
2798 end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002799 if (start) {
2800 processor = prologProcessor;
2801 return prologProcessor(parser, start, end, endPtr);
2802 }
2803 return result;
2804}
2805
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002806/* startPtr gets set to non-null is the section is closed, and to null
2807 if the section is not yet closed.
2808*/
2809static enum XML_Error
2810doIgnoreSection(XML_Parser parser,
2811 const ENCODING *enc,
2812 const char **startPtr,
2813 const char *end,
2814 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002815{
2816 const char *next;
2817 int tok;
2818 const char *s = *startPtr;
2819 const char **eventPP;
2820 const char **eventEndPP;
2821 if (enc == encoding) {
2822 eventPP = &eventPtr;
2823 *eventPP = s;
2824 eventEndPP = &eventEndPtr;
2825 }
2826 else {
2827 eventPP = &(openInternalEntities->internalEventPtr);
2828 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2829 }
2830 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002831 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002832 tok = XmlIgnoreSectionTok(enc, s, end, &next);
2833 *eventEndPP = next;
2834 switch (tok) {
2835 case XML_TOK_IGNORE_SECT:
2836 if (defaultHandler)
2837 reportDefault(parser, enc, s, next);
2838 *startPtr = next;
2839 return XML_ERROR_NONE;
2840 case XML_TOK_INVALID:
2841 *eventPP = next;
2842 return XML_ERROR_INVALID_TOKEN;
2843 case XML_TOK_PARTIAL_CHAR:
2844 if (nextPtr) {
2845 *nextPtr = s;
2846 return XML_ERROR_NONE;
2847 }
2848 return XML_ERROR_PARTIAL_CHAR;
2849 case XML_TOK_PARTIAL:
2850 case XML_TOK_NONE:
2851 if (nextPtr) {
2852 *nextPtr = s;
2853 return XML_ERROR_NONE;
2854 }
2855 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2856 default:
2857 *eventPP = next;
2858 return XML_ERROR_UNEXPECTED_STATE;
2859 }
2860 /* not reached */
2861}
2862
2863#endif /* XML_DTD */
2864
2865static enum XML_Error
2866initializeEncoding(XML_Parser parser)
2867{
2868 const char *s;
2869#ifdef XML_UNICODE
2870 char encodingBuf[128];
2871 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002872 s = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002873 else {
2874 int i;
2875 for (i = 0; protocolEncodingName[i]; i++) {
2876 if (i == sizeof(encodingBuf) - 1
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002877 || (protocolEncodingName[i] & ~0x7f) != 0) {
2878 encodingBuf[0] = '\0';
2879 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002880 }
2881 encodingBuf[i] = (char)protocolEncodingName[i];
2882 }
2883 encodingBuf[i] = '\0';
2884 s = encodingBuf;
2885 }
2886#else
2887 s = protocolEncodingName;
2888#endif
2889 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
2890 return XML_ERROR_NONE;
2891 return handleUnknownEncoding(parser, protocolEncodingName);
2892}
2893
2894static enum XML_Error
2895processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002896 const char *s, const char *next)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002897{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002898 const char *encodingName = NULL;
2899 const XML_Char *storedEncName = NULL;
2900 const ENCODING *newEncoding = NULL;
2901 const char *version = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002902 const char *versionend;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002903 const XML_Char *storedversion = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002904 int standalone = -1;
2905 if (!(ns
2906 ? XmlParseXmlDeclNS
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002907 : XmlParseXmlDecl)(isGeneralTextEntity,
2908 encoding,
2909 s,
2910 next,
2911 &eventPtr,
2912 &version,
2913 &versionend,
2914 &encodingName,
2915 &newEncoding,
2916 &standalone))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002917 return XML_ERROR_SYNTAX;
2918 if (!isGeneralTextEntity && standalone == 1) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002919 _dtd->standalone = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002920#ifdef XML_DTD
2921 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
2922 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
2923#endif /* XML_DTD */
2924 }
2925 if (xmlDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002926 if (encodingName != NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002927 storedEncName = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002928 encoding,
2929 encodingName,
2930 encodingName
2931 + XmlNameLength(encoding, encodingName));
2932 if (!storedEncName)
2933 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002934 poolFinish(&temp2Pool);
2935 }
2936 if (version) {
2937 storedversion = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002938 encoding,
2939 version,
2940 versionend - encoding->minBytesPerChar);
2941 if (!storedversion)
2942 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002943 }
2944 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
2945 }
2946 else if (defaultHandler)
2947 reportDefault(parser, encoding, s, next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002948 if (protocolEncodingName == NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002949 if (newEncoding) {
2950 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002951 eventPtr = encodingName;
2952 return XML_ERROR_INCORRECT_ENCODING;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002953 }
2954 encoding = newEncoding;
2955 }
2956 else if (encodingName) {
2957 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002958 if (!storedEncName) {
2959 storedEncName = poolStoreString(
2960 &temp2Pool, encoding, encodingName,
2961 encodingName + XmlNameLength(encoding, encodingName));
2962 if (!storedEncName)
2963 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002964 }
2965 result = handleUnknownEncoding(parser, storedEncName);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002966 poolClear(&temp2Pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002967 if (result == XML_ERROR_UNKNOWN_ENCODING)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002968 eventPtr = encodingName;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002969 return result;
2970 }
2971 }
2972
2973 if (storedEncName || storedversion)
2974 poolClear(&temp2Pool);
2975
2976 return XML_ERROR_NONE;
2977}
2978
2979static enum XML_Error
2980handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
2981{
2982 if (unknownEncodingHandler) {
2983 XML_Encoding info;
2984 int i;
2985 for (i = 0; i < 256; i++)
2986 info.map[i] = -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002987 info.convert = NULL;
2988 info.data = NULL;
2989 info.release = NULL;
2990 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
2991 &info)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002992 ENCODING *enc;
2993 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
2994 if (!unknownEncodingMem) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002995 if (info.release)
2996 info.release(info.data);
2997 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002998 }
2999 enc = (ns
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003000 ? XmlInitUnknownEncodingNS
3001 : XmlInitUnknownEncoding)(unknownEncodingMem,
3002 info.map,
3003 info.convert,
3004 info.data);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003005 if (enc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003006 unknownEncodingData = info.data;
3007 unknownEncodingRelease = info.release;
3008 encoding = enc;
3009 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003010 }
3011 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003012 if (info.release != NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003013 info.release(info.data);
3014 }
3015 return XML_ERROR_UNKNOWN_ENCODING;
3016}
3017
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003018static enum XML_Error PTRCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003019prologInitProcessor(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003020 const char *s,
3021 const char *end,
3022 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003023{
3024 enum XML_Error result = initializeEncoding(parser);
3025 if (result != XML_ERROR_NONE)
3026 return result;
3027 processor = prologProcessor;
3028 return prologProcessor(parser, s, end, nextPtr);
3029}
3030
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003031#ifdef XML_DTD
3032
3033static enum XML_Error PTRCALL
3034externalParEntInitProcessor(XML_Parser parser,
3035 const char *s,
3036 const char *end,
3037 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003038{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003039 enum XML_Error result = initializeEncoding(parser);
3040 if (result != XML_ERROR_NONE)
3041 return result;
3042
3043 /* we know now that XML_Parse(Buffer) has been called,
3044 so we consider the external parameter entity read */
3045 _dtd->paramEntityRead = XML_TRUE;
3046
3047 if (prologState.inEntityValue) {
3048 processor = entityValueInitProcessor;
3049 return entityValueInitProcessor(parser, s, end, nextPtr);
3050 }
3051 else {
3052 processor = externalParEntProcessor;
3053 return externalParEntProcessor(parser, s, end, nextPtr);
3054 }
3055}
3056
3057static enum XML_Error PTRCALL
3058entityValueInitProcessor(XML_Parser parser,
3059 const char *s,
3060 const char *end,
3061 const char **nextPtr)
3062{
3063 const char *start = s;
3064 const char *next = s;
3065 int tok;
3066
3067 for (;;) {
3068 tok = XmlPrologTok(encoding, start, end, &next);
3069 if (tok <= 0) {
3070 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3071 *nextPtr = s;
3072 return XML_ERROR_NONE;
3073 }
3074 switch (tok) {
3075 case XML_TOK_INVALID:
3076 return XML_ERROR_INVALID_TOKEN;
3077 case XML_TOK_PARTIAL:
3078 return XML_ERROR_UNCLOSED_TOKEN;
3079 case XML_TOK_PARTIAL_CHAR:
3080 return XML_ERROR_PARTIAL_CHAR;
3081 case XML_TOK_NONE: /* start == end */
3082 default:
3083 break;
3084 }
3085 return storeEntityValue(parser, encoding, s, end);
3086 }
3087 else if (tok == XML_TOK_XML_DECL) {
3088 enum XML_Error result = processXmlDecl(parser, 0, start, next);
3089 if (result != XML_ERROR_NONE)
3090 return result;
3091 if (nextPtr) *nextPtr = next;
3092 /* stop scanning for text declaration - we found one */
3093 processor = entityValueProcessor;
3094 return entityValueProcessor(parser, next, end, nextPtr);
3095 }
3096 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3097 return XML_TOK_NONE on the next call, which would then cause the
3098 function to exit with *nextPtr set to s - that is what we want for other
3099 tokens, but not for the BOM - we would rather like to skip it;
3100 then, when this routine is entered the next time, XmlPrologTok will
3101 return XML_TOK_INVALID, since the BOM is still in the buffer
3102 */
3103 else if (tok == XML_TOK_BOM && next == end && nextPtr) {
3104 *nextPtr = next;
3105 return XML_ERROR_NONE;
3106 }
3107 start = next;
3108 }
3109}
3110
3111static enum XML_Error PTRCALL
3112externalParEntProcessor(XML_Parser parser,
3113 const char *s,
3114 const char *end,
3115 const char **nextPtr)
3116{
3117 const char *start = s;
3118 const char *next = s;
3119 int tok;
3120
3121 tok = XmlPrologTok(encoding, start, end, &next);
3122 if (tok <= 0) {
3123 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3124 *nextPtr = s;
3125 return XML_ERROR_NONE;
3126 }
3127 switch (tok) {
3128 case XML_TOK_INVALID:
3129 return XML_ERROR_INVALID_TOKEN;
3130 case XML_TOK_PARTIAL:
3131 return XML_ERROR_UNCLOSED_TOKEN;
3132 case XML_TOK_PARTIAL_CHAR:
3133 return XML_ERROR_PARTIAL_CHAR;
3134 case XML_TOK_NONE: /* start == end */
3135 default:
3136 break;
3137 }
3138 }
3139 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3140 However, when parsing an external subset, doProlog will not accept a BOM
3141 as valid, and report a syntax error, so we have to skip the BOM
3142 */
3143 else if (tok == XML_TOK_BOM) {
3144 s = next;
3145 tok = XmlPrologTok(encoding, s, end, &next);
3146 }
3147
3148 processor = prologProcessor;
3149 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3150}
3151
3152static enum XML_Error PTRCALL
3153entityValueProcessor(XML_Parser parser,
3154 const char *s,
3155 const char *end,
3156 const char **nextPtr)
3157{
3158 const char *start = s;
3159 const char *next = s;
3160 const ENCODING *enc = encoding;
3161 int tok;
3162
3163 for (;;) {
3164 tok = XmlPrologTok(enc, start, end, &next);
3165 if (tok <= 0) {
3166 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3167 *nextPtr = s;
3168 return XML_ERROR_NONE;
3169 }
3170 switch (tok) {
3171 case XML_TOK_INVALID:
3172 return XML_ERROR_INVALID_TOKEN;
3173 case XML_TOK_PARTIAL:
3174 return XML_ERROR_UNCLOSED_TOKEN;
3175 case XML_TOK_PARTIAL_CHAR:
3176 return XML_ERROR_PARTIAL_CHAR;
3177 case XML_TOK_NONE: /* start == end */
3178 default:
3179 break;
3180 }
3181 return storeEntityValue(parser, enc, s, end);
3182 }
3183 start = next;
3184 }
3185}
3186
3187#endif /* XML_DTD */
3188
3189static enum XML_Error PTRCALL
3190prologProcessor(XML_Parser parser,
3191 const char *s,
3192 const char *end,
3193 const char **nextPtr)
3194{
3195 const char *next = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003196 int tok = XmlPrologTok(encoding, s, end, &next);
3197 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3198}
3199
3200static enum XML_Error
3201doProlog(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003202 const ENCODING *enc,
3203 const char *s,
3204 const char *end,
3205 int tok,
3206 const char *next,
3207 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003208{
3209#ifdef XML_DTD
3210 static const XML_Char externalSubsetName[] = { '#' , '\0' };
3211#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003212 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3213 static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3214 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3215 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3216 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3217 static const XML_Char atypeENTITIES[] =
3218 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3219 static const XML_Char atypeNMTOKEN[] = {
3220 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3221 static const XML_Char atypeNMTOKENS[] = {
3222 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3223 static const XML_Char notationPrefix[] = {
3224 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3225 static const XML_Char enumValueSep[] = { '|', '\0' };
3226 static const XML_Char enumValueStart[] = { '(', '\0' };
3227
3228 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003229
3230 const char **eventPP;
3231 const char **eventEndPP;
3232 enum XML_Content_Quant quant;
3233
3234 if (enc == encoding) {
3235 eventPP = &eventPtr;
3236 eventEndPP = &eventEndPtr;
3237 }
3238 else {
3239 eventPP = &(openInternalEntities->internalEventPtr);
3240 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3241 }
3242 for (;;) {
3243 int role;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003244 XML_Bool handleDefault = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003245 *eventPP = s;
3246 *eventEndPP = next;
3247 if (tok <= 0) {
3248 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003249 *nextPtr = s;
3250 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003251 }
3252 switch (tok) {
3253 case XML_TOK_INVALID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003254 *eventPP = next;
3255 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003256 case XML_TOK_PARTIAL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003257 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003258 case XML_TOK_PARTIAL_CHAR:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003259 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003260 case XML_TOK_NONE:
3261#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003262 if (enc != encoding)
3263 return XML_ERROR_NONE;
3264 if (isParamEntity) {
3265 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3266 == XML_ROLE_ERROR)
3267 return XML_ERROR_SYNTAX;
3268 return XML_ERROR_NONE;
3269 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003270#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003271 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003272 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003273 tok = -tok;
3274 next = end;
3275 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003276 }
3277 }
3278 role = XmlTokenRole(&prologState, tok, s, next, enc);
3279 switch (role) {
3280 case XML_ROLE_XML_DECL:
3281 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003282 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3283 if (result != XML_ERROR_NONE)
3284 return result;
3285 enc = encoding;
3286 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003287 }
3288 break;
3289 case XML_ROLE_DOCTYPE_NAME:
3290 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003291 doctypeName = poolStoreString(&tempPool, enc, s, next);
3292 if (!doctypeName)
3293 return XML_ERROR_NO_MEMORY;
3294 poolFinish(&tempPool);
3295 doctypePubid = NULL;
3296 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003297 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003298 doctypeSysid = NULL; /* always initialize to NULL */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003299 break;
3300 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3301 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003302 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3303 doctypePubid, 1);
3304 doctypeName = NULL;
3305 poolClear(&tempPool);
3306 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003307 }
3308 break;
3309#ifdef XML_DTD
3310 case XML_ROLE_TEXT_DECL:
3311 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003312 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3313 if (result != XML_ERROR_NONE)
3314 return result;
3315 enc = encoding;
3316 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003317 }
3318 break;
3319#endif /* XML_DTD */
3320 case XML_ROLE_DOCTYPE_PUBLIC_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003321#ifdef XML_DTD
3322 useForeignDTD = XML_FALSE;
3323#endif /* XML_DTD */
3324 dtd->hasParamEntityRefs = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003325 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003326 doctypePubid = poolStoreString(&tempPool, enc,
3327 s + enc->minBytesPerChar,
3328 next - enc->minBytesPerChar);
3329 if (!doctypePubid)
3330 return XML_ERROR_NO_MEMORY;
3331 poolFinish(&tempPool);
3332 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003333 }
3334#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003335 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3336 externalSubsetName,
3337 sizeof(ENTITY));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003338 if (!declEntity)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003339 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003340#endif /* XML_DTD */
3341 /* fall through */
3342 case XML_ROLE_ENTITY_PUBLIC_ID:
3343 if (!XmlIsPublicId(enc, s, next, eventPP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003344 return XML_ERROR_SYNTAX;
3345 if (dtd->keepProcessing && declEntity) {
3346 XML_Char *tem = poolStoreString(&dtd->pool,
3347 enc,
3348 s + enc->minBytesPerChar,
3349 next - enc->minBytesPerChar);
3350 if (!tem)
3351 return XML_ERROR_NO_MEMORY;
3352 normalizePublicId(tem);
3353 declEntity->publicId = tem;
3354 poolFinish(&dtd->pool);
3355 if (entityDeclHandler)
3356 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003357 }
3358 break;
3359 case XML_ROLE_DOCTYPE_CLOSE:
3360 if (doctypeName) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003361 startDoctypeDeclHandler(handlerArg, doctypeName,
3362 doctypeSysid, doctypePubid, 0);
3363 poolClear(&tempPool);
3364 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003365 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003366 /* doctypeSysid will be non-NULL in the case of a previous
3367 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3368 was not set, indicating an external subset
3369 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003370#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003371 if (doctypeSysid || useForeignDTD) {
3372 dtd->hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */
3373 if (paramEntityParsing && externalEntityRefHandler) {
3374 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3375 externalSubsetName,
3376 sizeof(ENTITY));
3377 if (!entity)
3378 return XML_ERROR_NO_MEMORY;
3379 if (useForeignDTD)
3380 entity->base = curBase;
3381 dtd->paramEntityRead = XML_FALSE;
3382 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3383 0,
3384 entity->base,
3385 entity->systemId,
3386 entity->publicId))
3387 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3388 if (dtd->paramEntityRead &&
3389 !dtd->standalone &&
3390 notStandaloneHandler &&
3391 !notStandaloneHandler(handlerArg))
3392 return XML_ERROR_NOT_STANDALONE;
3393 /* end of DTD - no need to update dtd->keepProcessing */
3394 }
3395 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003396 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003397#endif /* XML_DTD */
3398 if (endDoctypeDeclHandler) {
3399 endDoctypeDeclHandler(handlerArg);
3400 handleDefault = XML_FALSE;
3401 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003402 break;
3403 case XML_ROLE_INSTANCE_START:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003404#ifdef XML_DTD
3405 /* if there is no DOCTYPE declaration then now is the
3406 last chance to read the foreign DTD
3407 */
3408 if (useForeignDTD) {
3409 dtd->hasParamEntityRefs = XML_TRUE;
3410 if (paramEntityParsing && externalEntityRefHandler) {
3411 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3412 externalSubsetName,
3413 sizeof(ENTITY));
3414 if (!entity)
3415 return XML_ERROR_NO_MEMORY;
3416 entity->base = curBase;
3417 dtd->paramEntityRead = XML_FALSE;
3418 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3419 0,
3420 entity->base,
3421 entity->systemId,
3422 entity->publicId))
3423 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3424 if (dtd->paramEntityRead &&
3425 !dtd->standalone &&
3426 notStandaloneHandler &&
3427 !notStandaloneHandler(handlerArg))
3428 return XML_ERROR_NOT_STANDALONE;
3429 /* end of DTD - no need to update dtd->keepProcessing */
3430 }
3431 }
3432#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003433 processor = contentProcessor;
3434 return contentProcessor(parser, s, end, nextPtr);
3435 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3436 declElementType = getElementType(parser, enc, s, next);
3437 if (!declElementType)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003438 return XML_ERROR_NO_MEMORY;
3439 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003440 case XML_ROLE_ATTRIBUTE_NAME:
3441 declAttributeId = getAttributeId(parser, enc, s, next);
3442 if (!declAttributeId)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003443 return XML_ERROR_NO_MEMORY;
3444 declAttributeIsCdata = XML_FALSE;
3445 declAttributeType = NULL;
3446 declAttributeIsId = XML_FALSE;
3447 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003448 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003449 declAttributeIsCdata = XML_TRUE;
3450 declAttributeType = atypeCDATA;
3451 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003452 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003453 declAttributeIsId = XML_TRUE;
3454 declAttributeType = atypeID;
3455 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003456 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003457 declAttributeType = atypeIDREF;
3458 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003459 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003460 declAttributeType = atypeIDREFS;
3461 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003462 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003463 declAttributeType = atypeENTITY;
3464 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003465 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003466 declAttributeType = atypeENTITIES;
3467 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003468 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003469 declAttributeType = atypeNMTOKEN;
3470 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003471 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003472 declAttributeType = atypeNMTOKENS;
3473 checkAttListDeclHandler:
3474 if (dtd->keepProcessing && attlistDeclHandler)
3475 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003476 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003477 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3478 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003479 if (dtd->keepProcessing && attlistDeclHandler) {
3480 const XML_Char *prefix;
3481 if (declAttributeType) {
3482 prefix = enumValueSep;
3483 }
3484 else {
3485 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3486 ? notationPrefix
3487 : enumValueStart);
3488 }
3489 if (!poolAppendString(&tempPool, prefix))
3490 return XML_ERROR_NO_MEMORY;
3491 if (!poolAppend(&tempPool, enc, s, next))
3492 return XML_ERROR_NO_MEMORY;
3493 declAttributeType = tempPool.start;
3494 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003495 }
3496 break;
3497 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3498 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003499 if (dtd->keepProcessing) {
3500 if (!defineAttribute(declElementType, declAttributeId,
3501 declAttributeIsCdata, declAttributeIsId, 0,
3502 parser))
3503 return XML_ERROR_NO_MEMORY;
3504 if (attlistDeclHandler && declAttributeType) {
3505 if (*declAttributeType == XML_T('(')
3506 || (*declAttributeType == XML_T('N')
3507 && declAttributeType[1] == XML_T('O'))) {
3508 /* Enumerated or Notation type */
3509 if (!poolAppendChar(&tempPool, XML_T(')'))
3510 || !poolAppendChar(&tempPool, XML_T('\0')))
3511 return XML_ERROR_NO_MEMORY;
3512 declAttributeType = tempPool.start;
3513 poolFinish(&tempPool);
3514 }
3515 *eventEndPP = s;
3516 attlistDeclHandler(handlerArg, declElementType->name,
3517 declAttributeId->name, declAttributeType,
3518 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
3519 poolClear(&tempPool);
3520 handleDefault = XML_FALSE;
3521 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003522 }
3523 break;
3524 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3525 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003526 if (dtd->keepProcessing) {
3527 const XML_Char *attVal;
3528 enum XML_Error result
3529 = storeAttributeValue(parser, enc, declAttributeIsCdata,
3530 s + enc->minBytesPerChar,
3531 next - enc->minBytesPerChar,
3532 &dtd->pool);
3533 if (result)
3534 return result;
3535 attVal = poolStart(&dtd->pool);
3536 poolFinish(&dtd->pool);
3537 /* ID attributes aren't allowed to have a default */
3538 if (!defineAttribute(declElementType, declAttributeId,
3539 declAttributeIsCdata, XML_FALSE, attVal, parser))
3540 return XML_ERROR_NO_MEMORY;
3541 if (attlistDeclHandler && declAttributeType) {
3542 if (*declAttributeType == XML_T('(')
3543 || (*declAttributeType == XML_T('N')
3544 && declAttributeType[1] == XML_T('O'))) {
3545 /* Enumerated or Notation type */
3546 if (!poolAppendChar(&tempPool, XML_T(')'))
3547 || !poolAppendChar(&tempPool, XML_T('\0')))
3548 return XML_ERROR_NO_MEMORY;
3549 declAttributeType = tempPool.start;
3550 poolFinish(&tempPool);
3551 }
3552 *eventEndPP = s;
3553 attlistDeclHandler(handlerArg, declElementType->name,
3554 declAttributeId->name, declAttributeType,
3555 attVal,
3556 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
3557 poolClear(&tempPool);
3558 handleDefault = XML_FALSE;
3559 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003560 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003561 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003562 case XML_ROLE_ENTITY_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003563 if (dtd->keepProcessing) {
3564 enum XML_Error result = storeEntityValue(parser, enc,
3565 s + enc->minBytesPerChar,
3566 next - enc->minBytesPerChar);
3567 if (declEntity) {
3568 declEntity->textPtr = poolStart(&dtd->entityValuePool);
3569 declEntity->textLen = poolLength(&dtd->entityValuePool);
3570 poolFinish(&dtd->entityValuePool);
3571 if (entityDeclHandler) {
3572 *eventEndPP = s;
3573 entityDeclHandler(handlerArg,
3574 declEntity->name,
3575 declEntity->is_param,
3576 declEntity->textPtr,
3577 declEntity->textLen,
3578 curBase, 0, 0, 0);
3579 handleDefault = XML_FALSE;
3580 }
3581 }
3582 else
3583 poolDiscard(&dtd->entityValuePool);
3584 if (result != XML_ERROR_NONE)
3585 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003586 }
3587 break;
3588 case XML_ROLE_DOCTYPE_SYSTEM_ID:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003589#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003590 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003591#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003592 dtd->hasParamEntityRefs = XML_TRUE;
3593 if (startDoctypeDeclHandler) {
3594 doctypeSysid = poolStoreString(&tempPool, enc,
3595 s + enc->minBytesPerChar,
3596 next - enc->minBytesPerChar);
3597 if (doctypeSysid == NULL)
3598 return XML_ERROR_NO_MEMORY;
3599 poolFinish(&tempPool);
3600 handleDefault = XML_FALSE;
3601 }
3602#ifdef XML_DTD
3603 else
3604 /* use externalSubsetName to make doctypeSysid non-NULL
3605 for the case where no startDoctypeDeclHandler is set */
3606 doctypeSysid = externalSubsetName;
3607#endif /* XML_DTD */
3608 if (!dtd->standalone
3609#ifdef XML_DTD
3610 && !paramEntityParsing
3611#endif /* XML_DTD */
3612 && notStandaloneHandler
3613 && !notStandaloneHandler(handlerArg))
3614 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003615#ifndef XML_DTD
3616 break;
3617#else /* XML_DTD */
3618 if (!declEntity) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003619 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3620 externalSubsetName,
3621 sizeof(ENTITY));
3622 if (!declEntity)
3623 return XML_ERROR_NO_MEMORY;
3624 declEntity->publicId = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003625 }
3626 /* fall through */
3627#endif /* XML_DTD */
3628 case XML_ROLE_ENTITY_SYSTEM_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003629 if (dtd->keepProcessing && declEntity) {
3630 declEntity->systemId = poolStoreString(&dtd->pool, enc,
3631 s + enc->minBytesPerChar,
3632 next - enc->minBytesPerChar);
3633 if (!declEntity->systemId)
3634 return XML_ERROR_NO_MEMORY;
3635 declEntity->base = curBase;
3636 poolFinish(&dtd->pool);
3637 if (entityDeclHandler)
3638 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003639 }
3640 break;
3641 case XML_ROLE_ENTITY_COMPLETE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003642 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
3643 *eventEndPP = s;
3644 entityDeclHandler(handlerArg,
3645 declEntity->name,
3646 declEntity->is_param,
3647 0,0,
3648 declEntity->base,
3649 declEntity->systemId,
3650 declEntity->publicId,
3651 0);
3652 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003653 }
3654 break;
3655 case XML_ROLE_ENTITY_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003656 if (dtd->keepProcessing && declEntity) {
3657 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
3658 if (!declEntity->notation)
3659 return XML_ERROR_NO_MEMORY;
3660 poolFinish(&dtd->pool);
3661 if (unparsedEntityDeclHandler) {
3662 *eventEndPP = s;
3663 unparsedEntityDeclHandler(handlerArg,
3664 declEntity->name,
3665 declEntity->base,
3666 declEntity->systemId,
3667 declEntity->publicId,
3668 declEntity->notation);
3669 handleDefault = XML_FALSE;
3670 }
3671 else if (entityDeclHandler) {
3672 *eventEndPP = s;
3673 entityDeclHandler(handlerArg,
3674 declEntity->name,
3675 0,0,0,
3676 declEntity->base,
3677 declEntity->systemId,
3678 declEntity->publicId,
3679 declEntity->notation);
3680 handleDefault = XML_FALSE;
3681 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003682 }
3683 break;
3684 case XML_ROLE_GENERAL_ENTITY_NAME:
3685 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003686 if (XmlPredefinedEntityName(enc, s, next)) {
3687 declEntity = NULL;
3688 break;
3689 }
3690 if (dtd->keepProcessing) {
3691 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
3692 if (!name)
3693 return XML_ERROR_NO_MEMORY;
3694 declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
3695 sizeof(ENTITY));
3696 if (!declEntity)
3697 return XML_ERROR_NO_MEMORY;
3698 if (declEntity->name != name) {
3699 poolDiscard(&dtd->pool);
3700 declEntity = NULL;
3701 }
3702 else {
3703 poolFinish(&dtd->pool);
3704 declEntity->publicId = NULL;
3705 declEntity->is_param = XML_FALSE;
3706 /* if we have a parent parser or are reading an internal parameter
3707 entity, then the entity declaration is not considered "internal"
3708 */
3709 declEntity->is_internal = !(parentParser || openInternalEntities);
3710 if (entityDeclHandler)
3711 handleDefault = XML_FALSE;
3712 }
3713 }
3714 else {
3715 poolDiscard(&dtd->pool);
3716 declEntity = NULL;
3717 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003718 }
3719 break;
3720 case XML_ROLE_PARAM_ENTITY_NAME:
3721#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003722 if (dtd->keepProcessing) {
3723 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
3724 if (!name)
3725 return XML_ERROR_NO_MEMORY;
3726 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3727 name, sizeof(ENTITY));
3728 if (!declEntity)
3729 return XML_ERROR_NO_MEMORY;
3730 if (declEntity->name != name) {
3731 poolDiscard(&dtd->pool);
3732 declEntity = NULL;
3733 }
3734 else {
3735 poolFinish(&dtd->pool);
3736 declEntity->publicId = NULL;
3737 declEntity->is_param = XML_TRUE;
3738 /* if we have a parent parser or are reading an internal parameter
3739 entity, then the entity declaration is not considered "internal"
3740 */
3741 declEntity->is_internal = !(parentParser || openInternalEntities);
3742 if (entityDeclHandler)
3743 handleDefault = XML_FALSE;
3744 }
3745 }
3746 else {
3747 poolDiscard(&dtd->pool);
3748 declEntity = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003749 }
3750#else /* not XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003751 declEntity = NULL;
3752#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003753 break;
3754 case XML_ROLE_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003755 declNotationPublicId = NULL;
3756 declNotationName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003757 if (notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003758 declNotationName = poolStoreString(&tempPool, enc, s, next);
3759 if (!declNotationName)
3760 return XML_ERROR_NO_MEMORY;
3761 poolFinish(&tempPool);
3762 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003763 }
3764 break;
3765 case XML_ROLE_NOTATION_PUBLIC_ID:
3766 if (!XmlIsPublicId(enc, s, next, eventPP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003767 return XML_ERROR_SYNTAX;
3768 if (declNotationName) { /* means notationDeclHandler != NULL */
3769 XML_Char *tem = poolStoreString(&tempPool,
3770 enc,
3771 s + enc->minBytesPerChar,
3772 next - enc->minBytesPerChar);
3773 if (!tem)
3774 return XML_ERROR_NO_MEMORY;
3775 normalizePublicId(tem);
3776 declNotationPublicId = tem;
3777 poolFinish(&tempPool);
3778 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003779 }
3780 break;
3781 case XML_ROLE_NOTATION_SYSTEM_ID:
3782 if (declNotationName && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003783 const XML_Char *systemId
3784 = poolStoreString(&tempPool, enc,
3785 s + enc->minBytesPerChar,
3786 next - enc->minBytesPerChar);
3787 if (!systemId)
3788 return XML_ERROR_NO_MEMORY;
3789 *eventEndPP = s;
3790 notationDeclHandler(handlerArg,
3791 declNotationName,
3792 curBase,
3793 systemId,
3794 declNotationPublicId);
3795 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003796 }
3797 poolClear(&tempPool);
3798 break;
3799 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
3800 if (declNotationPublicId && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003801 *eventEndPP = s;
3802 notationDeclHandler(handlerArg,
3803 declNotationName,
3804 curBase,
3805 0,
3806 declNotationPublicId);
3807 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003808 }
3809 poolClear(&tempPool);
3810 break;
3811 case XML_ROLE_ERROR:
3812 switch (tok) {
3813 case XML_TOK_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003814 return XML_ERROR_PARAM_ENTITY_REF;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003815 case XML_TOK_XML_DECL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003816 return XML_ERROR_MISPLACED_XML_PI;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003817 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003818 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003819 }
3820#ifdef XML_DTD
3821 case XML_ROLE_IGNORE_SECT:
3822 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003823 enum XML_Error result;
3824 if (defaultHandler)
3825 reportDefault(parser, enc, s, next);
3826 handleDefault = XML_FALSE;
3827 result = doIgnoreSection(parser, enc, &next, end, nextPtr);
3828 if (!next) {
3829 processor = ignoreSectionProcessor;
3830 return result;
3831 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003832 }
3833 break;
3834#endif /* XML_DTD */
3835 case XML_ROLE_GROUP_OPEN:
3836 if (prologState.level >= groupSize) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003837 if (groupSize) {
3838 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
3839 if (temp == NULL)
3840 return XML_ERROR_NO_MEMORY;
3841 groupConnector = temp;
3842 if (dtd->scaffIndex) {
3843 int *temp = (int *)REALLOC(dtd->scaffIndex,
3844 groupSize * sizeof(int));
3845 if (temp == NULL)
3846 return XML_ERROR_NO_MEMORY;
3847 dtd->scaffIndex = temp;
3848 }
3849 }
3850 else {
3851 groupConnector = (char *)MALLOC(groupSize = 32);
3852 if (!groupConnector)
3853 return XML_ERROR_NO_MEMORY;
3854 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003855 }
3856 groupConnector[prologState.level] = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003857 if (dtd->in_eldecl) {
3858 int myindex = nextScaffoldPart(parser);
3859 if (myindex < 0)
3860 return XML_ERROR_NO_MEMORY;
3861 dtd->scaffIndex[dtd->scaffLevel] = myindex;
3862 dtd->scaffLevel++;
3863 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
3864 if (elementDeclHandler)
3865 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003866 }
3867 break;
3868 case XML_ROLE_GROUP_SEQUENCE:
3869 if (groupConnector[prologState.level] == '|')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003870 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003871 groupConnector[prologState.level] = ',';
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003872 if (dtd->in_eldecl && elementDeclHandler)
3873 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003874 break;
3875 case XML_ROLE_GROUP_CHOICE:
3876 if (groupConnector[prologState.level] == ',')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003877 return XML_ERROR_SYNTAX;
3878 if (dtd->in_eldecl
3879 && !groupConnector[prologState.level]
3880 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
3881 != XML_CTYPE_MIXED)
3882 ) {
3883 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
3884 = XML_CTYPE_CHOICE;
3885 if (elementDeclHandler)
3886 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003887 }
3888 groupConnector[prologState.level] = '|';
3889 break;
3890 case XML_ROLE_PARAM_ENTITY_REF:
3891#ifdef XML_DTD
3892 case XML_ROLE_INNER_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003893 /* PE references in internal subset are
3894 not allowed within declarations */
3895 if (prologState.documentEntity &&
3896 role == XML_ROLE_INNER_PARAM_ENTITY_REF)
3897 return XML_ERROR_PARAM_ENTITY_REF;
3898 dtd->hasParamEntityRefs = XML_TRUE;
3899 if (!paramEntityParsing)
3900 dtd->keepProcessing = dtd->standalone;
3901 else {
3902 const XML_Char *name;
3903 ENTITY *entity;
3904 name = poolStoreString(&dtd->pool, enc,
3905 s + enc->minBytesPerChar,
3906 next - enc->minBytesPerChar);
3907 if (!name)
3908 return XML_ERROR_NO_MEMORY;
3909 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
3910 poolDiscard(&dtd->pool);
3911 /* first, determine if a check for an existing declaration is needed;
3912 if yes, check that the entity exists, and that it is internal,
3913 otherwise call the skipped entity handler
3914 */
3915 if (prologState.documentEntity &&
3916 (dtd->standalone
3917 ? !openInternalEntities
3918 : !dtd->hasParamEntityRefs)) {
3919 if (!entity)
3920 return XML_ERROR_UNDEFINED_ENTITY;
3921 else if (!entity->is_internal)
3922 return XML_ERROR_ENTITY_DECLARED_IN_PE;
3923 }
3924 else if (!entity) {
3925 dtd->keepProcessing = dtd->standalone;
3926 /* cannot report skipped entities in declarations */
3927 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
3928 skippedEntityHandler(handlerArg, name, 1);
3929 handleDefault = XML_FALSE;
3930 }
3931 break;
3932 }
3933 if (entity->open)
3934 return XML_ERROR_RECURSIVE_ENTITY_REF;
3935 if (entity->textPtr) {
3936 enum XML_Error result;
3937 result = processInternalParamEntity(parser, entity);
3938 if (result != XML_ERROR_NONE)
3939 return result;
3940 handleDefault = XML_FALSE;
3941 break;
3942 }
3943 if (externalEntityRefHandler) {
3944 dtd->paramEntityRead = XML_FALSE;
3945 entity->open = XML_TRUE;
3946 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3947 0,
3948 entity->base,
3949 entity->systemId,
3950 entity->publicId)) {
3951 entity->open = XML_FALSE;
3952 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3953 }
3954 entity->open = XML_FALSE;
3955 handleDefault = XML_FALSE;
3956 if (!dtd->paramEntityRead) {
3957 dtd->keepProcessing = dtd->standalone;
3958 break;
3959 }
3960 }
3961 else {
3962 dtd->keepProcessing = dtd->standalone;
3963 break;
3964 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003965 }
3966#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003967 if (!dtd->standalone &&
3968 notStandaloneHandler &&
3969 !notStandaloneHandler(handlerArg))
3970 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003971 break;
3972
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003973 /* Element declaration stuff */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003974
3975 case XML_ROLE_ELEMENT_NAME:
3976 if (elementDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003977 declElementType = getElementType(parser, enc, s, next);
3978 if (!declElementType)
3979 return XML_ERROR_NO_MEMORY;
3980 dtd->scaffLevel = 0;
3981 dtd->scaffCount = 0;
3982 dtd->in_eldecl = XML_TRUE;
3983 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003984 }
3985 break;
3986
3987 case XML_ROLE_CONTENT_ANY:
3988 case XML_ROLE_CONTENT_EMPTY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003989 if (dtd->in_eldecl) {
3990 if (elementDeclHandler) {
3991 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
3992 if (!content)
3993 return XML_ERROR_NO_MEMORY;
3994 content->quant = XML_CQUANT_NONE;
3995 content->name = NULL;
3996 content->numchildren = 0;
3997 content->children = NULL;
3998 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
3999 XML_CTYPE_ANY :
4000 XML_CTYPE_EMPTY);
4001 *eventEndPP = s;
4002 elementDeclHandler(handlerArg, declElementType->name, content);
4003 handleDefault = XML_FALSE;
4004 }
4005 dtd->in_eldecl = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004006 }
4007 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004008
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004009 case XML_ROLE_CONTENT_PCDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004010 if (dtd->in_eldecl) {
4011 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4012 = XML_CTYPE_MIXED;
4013 if (elementDeclHandler)
4014 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004015 }
4016 break;
4017
4018 case XML_ROLE_CONTENT_ELEMENT:
4019 quant = XML_CQUANT_NONE;
4020 goto elementContent;
4021 case XML_ROLE_CONTENT_ELEMENT_OPT:
4022 quant = XML_CQUANT_OPT;
4023 goto elementContent;
4024 case XML_ROLE_CONTENT_ELEMENT_REP:
4025 quant = XML_CQUANT_REP;
4026 goto elementContent;
4027 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4028 quant = XML_CQUANT_PLUS;
4029 elementContent:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004030 if (dtd->in_eldecl) {
4031 ELEMENT_TYPE *el;
4032 const XML_Char *name;
4033 int nameLen;
4034 const char *nxt = (quant == XML_CQUANT_NONE
4035 ? next
4036 : next - enc->minBytesPerChar);
4037 int myindex = nextScaffoldPart(parser);
4038 if (myindex < 0)
4039 return XML_ERROR_NO_MEMORY;
4040 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4041 dtd->scaffold[myindex].quant = quant;
4042 el = getElementType(parser, enc, s, nxt);
4043 if (!el)
4044 return XML_ERROR_NO_MEMORY;
4045 name = el->name;
4046 dtd->scaffold[myindex].name = name;
4047 nameLen = 0;
4048 for (; name[nameLen++]; );
4049 dtd->contentStringLen += nameLen;
4050 if (elementDeclHandler)
4051 handleDefault = XML_FALSE;
4052 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004053 break;
4054
4055 case XML_ROLE_GROUP_CLOSE:
4056 quant = XML_CQUANT_NONE;
4057 goto closeGroup;
4058 case XML_ROLE_GROUP_CLOSE_OPT:
4059 quant = XML_CQUANT_OPT;
4060 goto closeGroup;
4061 case XML_ROLE_GROUP_CLOSE_REP:
4062 quant = XML_CQUANT_REP;
4063 goto closeGroup;
4064 case XML_ROLE_GROUP_CLOSE_PLUS:
4065 quant = XML_CQUANT_PLUS;
4066 closeGroup:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004067 if (dtd->in_eldecl) {
4068 if (elementDeclHandler)
4069 handleDefault = XML_FALSE;
4070 dtd->scaffLevel--;
4071 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4072 if (dtd->scaffLevel == 0) {
4073 if (!handleDefault) {
4074 XML_Content *model = build_model(parser);
4075 if (!model)
4076 return XML_ERROR_NO_MEMORY;
4077 *eventEndPP = s;
4078 elementDeclHandler(handlerArg, declElementType->name, model);
4079 }
4080 dtd->in_eldecl = XML_FALSE;
4081 dtd->contentStringLen = 0;
4082 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004083 }
4084 break;
4085 /* End element declaration stuff */
4086
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004087 case XML_ROLE_PI:
4088 if (!reportProcessingInstruction(parser, enc, s, next))
4089 return XML_ERROR_NO_MEMORY;
4090 handleDefault = XML_FALSE;
4091 break;
4092 case XML_ROLE_COMMENT:
4093 if (!reportComment(parser, enc, s, next))
4094 return XML_ERROR_NO_MEMORY;
4095 handleDefault = XML_FALSE;
4096 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004097 case XML_ROLE_NONE:
4098 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004099 case XML_TOK_BOM:
4100 handleDefault = XML_FALSE;
4101 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004102 }
4103 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004104 case XML_ROLE_DOCTYPE_NONE:
4105 if (startDoctypeDeclHandler)
4106 handleDefault = XML_FALSE;
4107 break;
4108 case XML_ROLE_ENTITY_NONE:
4109 if (dtd->keepProcessing && entityDeclHandler)
4110 handleDefault = XML_FALSE;
4111 break;
4112 case XML_ROLE_NOTATION_NONE:
4113 if (notationDeclHandler)
4114 handleDefault = XML_FALSE;
4115 break;
4116 case XML_ROLE_ATTLIST_NONE:
4117 if (dtd->keepProcessing && attlistDeclHandler)
4118 handleDefault = XML_FALSE;
4119 break;
4120 case XML_ROLE_ELEMENT_NONE:
4121 if (elementDeclHandler)
4122 handleDefault = XML_FALSE;
4123 break;
4124 } /* end of big switch */
4125
4126 if (handleDefault && defaultHandler)
4127 reportDefault(parser, enc, s, next);
4128
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004129 s = next;
4130 tok = XmlPrologTok(enc, s, end, &next);
4131 }
4132 /* not reached */
4133}
4134
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004135static enum XML_Error PTRCALL
4136epilogProcessor(XML_Parser parser,
4137 const char *s,
4138 const char *end,
4139 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004140{
4141 processor = epilogProcessor;
4142 eventPtr = s;
4143 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004144 const char *next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004145 int tok = XmlPrologTok(encoding, s, end, &next);
4146 eventEndPtr = next;
4147 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004148 /* report partial linebreak - it might be the last token */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004149 case -XML_TOK_PROLOG_S:
4150 if (defaultHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004151 eventEndPtr = next;
4152 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004153 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004154 if (nextPtr)
4155 *nextPtr = next;
4156 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004157 case XML_TOK_NONE:
4158 if (nextPtr)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004159 *nextPtr = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004160 return XML_ERROR_NONE;
4161 case XML_TOK_PROLOG_S:
4162 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004163 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004164 break;
4165 case XML_TOK_PI:
4166 if (!reportProcessingInstruction(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004167 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004168 break;
4169 case XML_TOK_COMMENT:
4170 if (!reportComment(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004171 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004172 break;
4173 case XML_TOK_INVALID:
4174 eventPtr = next;
4175 return XML_ERROR_INVALID_TOKEN;
4176 case XML_TOK_PARTIAL:
4177 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004178 *nextPtr = s;
4179 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004180 }
4181 return XML_ERROR_UNCLOSED_TOKEN;
4182 case XML_TOK_PARTIAL_CHAR:
4183 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004184 *nextPtr = s;
4185 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004186 }
4187 return XML_ERROR_PARTIAL_CHAR;
4188 default:
4189 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4190 }
4191 eventPtr = s = next;
4192 }
4193}
4194
4195#ifdef XML_DTD
4196
4197static enum XML_Error
4198processInternalParamEntity(XML_Parser parser, ENTITY *entity)
4199{
4200 const char *s, *end, *next;
4201 int tok;
4202 enum XML_Error result;
4203 OPEN_INTERNAL_ENTITY openEntity;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004204 entity->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004205 openEntity.next = openInternalEntities;
4206 openInternalEntities = &openEntity;
4207 openEntity.entity = entity;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004208 openEntity.internalEventPtr = NULL;
4209 openEntity.internalEventEndPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004210 s = (char *)entity->textPtr;
4211 end = (char *)(entity->textPtr + entity->textLen);
4212 tok = XmlPrologTok(internalEncoding, s, end, &next);
4213 result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004214 entity->open = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004215 openInternalEntities = openEntity.next;
4216 return result;
4217}
4218
4219#endif /* XML_DTD */
4220
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004221static enum XML_Error PTRCALL
4222errorProcessor(XML_Parser parser,
4223 const char *s,
4224 const char *end,
4225 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004226{
4227 return errorCode;
4228}
4229
4230static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004231storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4232 const char *ptr, const char *end,
4233 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004234{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004235 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4236 end, pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004237 if (result)
4238 return result;
4239 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4240 poolChop(pool);
4241 if (!poolAppendChar(pool, XML_T('\0')))
4242 return XML_ERROR_NO_MEMORY;
4243 return XML_ERROR_NONE;
4244}
4245
4246static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004247appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4248 const char *ptr, const char *end,
4249 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004250{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004251 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004252 for (;;) {
4253 const char *next;
4254 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4255 switch (tok) {
4256 case XML_TOK_NONE:
4257 return XML_ERROR_NONE;
4258 case XML_TOK_INVALID:
4259 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004260 eventPtr = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004261 return XML_ERROR_INVALID_TOKEN;
4262 case XML_TOK_PARTIAL:
4263 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004264 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004265 return XML_ERROR_INVALID_TOKEN;
4266 case XML_TOK_CHAR_REF:
4267 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004268 XML_Char buf[XML_ENCODE_MAX];
4269 int i;
4270 int n = XmlCharRefNumber(enc, ptr);
4271 if (n < 0) {
4272 if (enc == encoding)
4273 eventPtr = ptr;
4274 return XML_ERROR_BAD_CHAR_REF;
4275 }
4276 if (!isCdata
4277 && n == 0x20 /* space */
4278 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4279 break;
4280 n = XmlEncode(n, (ICHAR *)buf);
4281 if (!n) {
4282 if (enc == encoding)
4283 eventPtr = ptr;
4284 return XML_ERROR_BAD_CHAR_REF;
4285 }
4286 for (i = 0; i < n; i++) {
4287 if (!poolAppendChar(pool, buf[i]))
4288 return XML_ERROR_NO_MEMORY;
4289 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004290 }
4291 break;
4292 case XML_TOK_DATA_CHARS:
4293 if (!poolAppend(pool, enc, ptr, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004294 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004295 break;
4296 case XML_TOK_TRAILING_CR:
4297 next = ptr + enc->minBytesPerChar;
4298 /* fall through */
4299 case XML_TOK_ATTRIBUTE_VALUE_S:
4300 case XML_TOK_DATA_NEWLINE:
4301 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004302 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004303 if (!poolAppendChar(pool, 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004304 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004305 break;
4306 case XML_TOK_ENTITY_REF:
4307 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004308 const XML_Char *name;
4309 ENTITY *entity;
4310 char checkEntityDecl;
4311 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4312 ptr + enc->minBytesPerChar,
4313 next - enc->minBytesPerChar);
4314 if (ch) {
4315 if (!poolAppendChar(pool, ch))
4316 return XML_ERROR_NO_MEMORY;
4317 break;
4318 }
4319 name = poolStoreString(&temp2Pool, enc,
4320 ptr + enc->minBytesPerChar,
4321 next - enc->minBytesPerChar);
4322 if (!name)
4323 return XML_ERROR_NO_MEMORY;
4324 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
4325 poolDiscard(&temp2Pool);
4326 /* first, determine if a check for an existing declaration is needed;
4327 if yes, check that the entity exists, and that it is internal,
4328 otherwise call the default handler (if called from content)
4329 */
4330 if (pool == &dtd->pool) /* are we called from prolog? */
4331 checkEntityDecl =
4332#ifdef XML_DTD
4333 prologState.documentEntity &&
4334#endif /* XML_DTD */
4335 (dtd->standalone
4336 ? !openInternalEntities
4337 : !dtd->hasParamEntityRefs);
4338 else /* if (pool == &tempPool): we are called from content */
4339 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4340 if (checkEntityDecl) {
4341 if (!entity)
4342 return XML_ERROR_UNDEFINED_ENTITY;
4343 else if (!entity->is_internal)
4344 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4345 }
4346 else if (!entity) {
4347 /* cannot report skipped entity here - see comments on
4348 skippedEntityHandler
4349 if (skippedEntityHandler)
4350 skippedEntityHandler(handlerArg, name, 0);
4351 */
4352 if ((pool == &tempPool) && defaultHandler)
4353 reportDefault(parser, enc, ptr, next);
4354 break;
4355 }
4356 if (entity->open) {
4357 if (enc == encoding)
4358 eventPtr = ptr;
4359 return XML_ERROR_RECURSIVE_ENTITY_REF;
4360 }
4361 if (entity->notation) {
4362 if (enc == encoding)
4363 eventPtr = ptr;
4364 return XML_ERROR_BINARY_ENTITY_REF;
4365 }
4366 if (!entity->textPtr) {
4367 if (enc == encoding)
4368 eventPtr = ptr;
4369 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4370 }
4371 else {
4372 enum XML_Error result;
4373 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4374 entity->open = XML_TRUE;
4375 result = appendAttributeValue(parser, internalEncoding, isCdata,
4376 (char *)entity->textPtr,
4377 (char *)textEnd, pool);
4378 entity->open = XML_FALSE;
4379 if (result)
4380 return result;
4381 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004382 }
4383 break;
4384 default:
4385 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004386 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004387 return XML_ERROR_UNEXPECTED_STATE;
4388 }
4389 ptr = next;
4390 }
4391 /* not reached */
4392}
4393
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004394static enum XML_Error
4395storeEntityValue(XML_Parser parser,
4396 const ENCODING *enc,
4397 const char *entityTextPtr,
4398 const char *entityTextEnd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004399{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004400 DTD * const dtd = _dtd; /* save one level of indirection */
4401 STRING_POOL *pool = &(dtd->entityValuePool);
4402 enum XML_Error result = XML_ERROR_NONE;
4403#ifdef XML_DTD
4404 int oldInEntityValue = prologState.inEntityValue;
4405 prologState.inEntityValue = 1;
4406#endif /* XML_DTD */
4407 /* never return Null for the value argument in EntityDeclHandler,
4408 since this would indicate an external entity; therefore we
4409 have to make sure that entityValuePool.start is not null */
4410 if (!pool->blocks) {
4411 if (!poolGrow(pool))
4412 return XML_ERROR_NO_MEMORY;
4413 }
4414
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004415 for (;;) {
4416 const char *next;
4417 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4418 switch (tok) {
4419 case XML_TOK_PARAM_ENTITY_REF:
4420#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004421 if (isParamEntity || enc != encoding) {
4422 const XML_Char *name;
4423 ENTITY *entity;
4424 name = poolStoreString(&tempPool, enc,
4425 entityTextPtr + enc->minBytesPerChar,
4426 next - enc->minBytesPerChar);
4427 if (!name) {
4428 result = XML_ERROR_NO_MEMORY;
4429 goto endEntityValue;
4430 }
4431 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4432 poolDiscard(&tempPool);
4433 if (!entity) {
4434 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4435 /* cannot report skipped entity here - see comments on
4436 skippedEntityHandler
4437 if (skippedEntityHandler)
4438 skippedEntityHandler(handlerArg, name, 0);
4439 */
4440 dtd->keepProcessing = dtd->standalone;
4441 goto endEntityValue;
4442 }
4443 if (entity->open) {
4444 if (enc == encoding)
4445 eventPtr = entityTextPtr;
4446 result = XML_ERROR_RECURSIVE_ENTITY_REF;
4447 goto endEntityValue;
4448 }
4449 if (entity->systemId) {
4450 if (externalEntityRefHandler) {
4451 dtd->paramEntityRead = XML_FALSE;
4452 entity->open = XML_TRUE;
4453 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4454 0,
4455 entity->base,
4456 entity->systemId,
4457 entity->publicId)) {
4458 entity->open = XML_FALSE;
4459 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4460 goto endEntityValue;
4461 }
4462 entity->open = XML_FALSE;
4463 if (!dtd->paramEntityRead)
4464 dtd->keepProcessing = dtd->standalone;
4465 }
4466 else
4467 dtd->keepProcessing = dtd->standalone;
4468 }
4469 else {
4470 entity->open = XML_TRUE;
4471 result = storeEntityValue(parser,
4472 internalEncoding,
4473 (char *)entity->textPtr,
4474 (char *)(entity->textPtr
4475 + entity->textLen));
4476 entity->open = XML_FALSE;
4477 if (result)
4478 goto endEntityValue;
4479 }
4480 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004481 }
4482#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004483 /* in the internal subset, PE references are not legal
4484 within markup declarations, e.g entity values in this case */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004485 eventPtr = entityTextPtr;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004486 result = XML_ERROR_PARAM_ENTITY_REF;
4487 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004488 case XML_TOK_NONE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004489 result = XML_ERROR_NONE;
4490 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004491 case XML_TOK_ENTITY_REF:
4492 case XML_TOK_DATA_CHARS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004493 if (!poolAppend(pool, enc, entityTextPtr, next)) {
4494 result = XML_ERROR_NO_MEMORY;
4495 goto endEntityValue;
4496 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004497 break;
4498 case XML_TOK_TRAILING_CR:
4499 next = entityTextPtr + enc->minBytesPerChar;
4500 /* fall through */
4501 case XML_TOK_DATA_NEWLINE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004502 if (pool->end == pool->ptr && !poolGrow(pool)) {
4503 result = XML_ERROR_NO_MEMORY;
4504 goto endEntityValue;
4505 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004506 *(pool->ptr)++ = 0xA;
4507 break;
4508 case XML_TOK_CHAR_REF:
4509 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004510 XML_Char buf[XML_ENCODE_MAX];
4511 int i;
4512 int n = XmlCharRefNumber(enc, entityTextPtr);
4513 if (n < 0) {
4514 if (enc == encoding)
4515 eventPtr = entityTextPtr;
4516 result = XML_ERROR_BAD_CHAR_REF;
4517 goto endEntityValue;
4518 }
4519 n = XmlEncode(n, (ICHAR *)buf);
4520 if (!n) {
4521 if (enc == encoding)
4522 eventPtr = entityTextPtr;
4523 result = XML_ERROR_BAD_CHAR_REF;
4524 goto endEntityValue;
4525 }
4526 for (i = 0; i < n; i++) {
4527 if (pool->end == pool->ptr && !poolGrow(pool)) {
4528 result = XML_ERROR_NO_MEMORY;
4529 goto endEntityValue;
4530 }
4531 *(pool->ptr)++ = buf[i];
4532 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004533 }
4534 break;
4535 case XML_TOK_PARTIAL:
4536 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004537 eventPtr = entityTextPtr;
4538 result = XML_ERROR_INVALID_TOKEN;
4539 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004540 case XML_TOK_INVALID:
4541 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004542 eventPtr = next;
4543 result = XML_ERROR_INVALID_TOKEN;
4544 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004545 default:
4546 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004547 eventPtr = entityTextPtr;
4548 result = XML_ERROR_UNEXPECTED_STATE;
4549 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004550 }
4551 entityTextPtr = next;
4552 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004553endEntityValue:
4554#ifdef XML_DTD
4555 prologState.inEntityValue = oldInEntityValue;
4556#endif /* XML_DTD */
4557 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004558}
4559
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004560static void FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004561normalizeLines(XML_Char *s)
4562{
4563 XML_Char *p;
4564 for (;; s++) {
4565 if (*s == XML_T('\0'))
4566 return;
4567 if (*s == 0xD)
4568 break;
4569 }
4570 p = s;
4571 do {
4572 if (*s == 0xD) {
4573 *p++ = 0xA;
4574 if (*++s == 0xA)
4575 s++;
4576 }
4577 else
4578 *p++ = *s++;
4579 } while (*s);
4580 *p = XML_T('\0');
4581}
4582
4583static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004584reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
4585 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004586{
4587 const XML_Char *target;
4588 XML_Char *data;
4589 const char *tem;
4590 if (!processingInstructionHandler) {
4591 if (defaultHandler)
4592 reportDefault(parser, enc, start, end);
4593 return 1;
4594 }
4595 start += enc->minBytesPerChar * 2;
4596 tem = start + XmlNameLength(enc, start);
4597 target = poolStoreString(&tempPool, enc, start, tem);
4598 if (!target)
4599 return 0;
4600 poolFinish(&tempPool);
4601 data = poolStoreString(&tempPool, enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004602 XmlSkipS(enc, tem),
4603 end - enc->minBytesPerChar*2);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004604 if (!data)
4605 return 0;
4606 normalizeLines(data);
4607 processingInstructionHandler(handlerArg, target, data);
4608 poolClear(&tempPool);
4609 return 1;
4610}
4611
4612static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004613reportComment(XML_Parser parser, const ENCODING *enc,
4614 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004615{
4616 XML_Char *data;
4617 if (!commentHandler) {
4618 if (defaultHandler)
4619 reportDefault(parser, enc, start, end);
4620 return 1;
4621 }
4622 data = poolStoreString(&tempPool,
4623 enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004624 start + enc->minBytesPerChar * 4,
4625 end - enc->minBytesPerChar * 3);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004626 if (!data)
4627 return 0;
4628 normalizeLines(data);
4629 commentHandler(handlerArg, data);
4630 poolClear(&tempPool);
4631 return 1;
4632}
4633
4634static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004635reportDefault(XML_Parser parser, const ENCODING *enc,
4636 const char *s, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004637{
4638 if (MUST_CONVERT(enc, s)) {
4639 const char **eventPP;
4640 const char **eventEndPP;
4641 if (enc == encoding) {
4642 eventPP = &eventPtr;
4643 eventEndPP = &eventEndPtr;
4644 }
4645 else {
4646 eventPP = &(openInternalEntities->internalEventPtr);
4647 eventEndPP = &(openInternalEntities->internalEventEndPtr);
4648 }
4649 do {
4650 ICHAR *dataPtr = (ICHAR *)dataBuf;
4651 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
4652 *eventEndPP = s;
4653 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
4654 *eventPP = s;
4655 } while (s != end);
4656 }
4657 else
4658 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
4659}
4660
4661
4662static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004663defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
4664 XML_Bool isId, const XML_Char *value, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004665{
4666 DEFAULT_ATTRIBUTE *att;
4667 if (value || isId) {
4668 /* The handling of default attributes gets messed up if we have
4669 a default which duplicates a non-default. */
4670 int i;
4671 for (i = 0; i < type->nDefaultAtts; i++)
4672 if (attId == type->defaultAtts[i].id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004673 return 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004674 if (isId && !type->idAtt && !attId->xmlns)
4675 type->idAtt = attId;
4676 }
4677 if (type->nDefaultAtts == type->allocDefaultAtts) {
4678 if (type->allocDefaultAtts == 0) {
4679 type->allocDefaultAtts = 8;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004680 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
4681 * sizeof(DEFAULT_ATTRIBUTE));
4682 if (!type->defaultAtts)
4683 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004684 }
4685 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004686 DEFAULT_ATTRIBUTE *temp;
4687 int count = type->allocDefaultAtts * 2;
4688 temp = (DEFAULT_ATTRIBUTE *)
4689 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
4690 if (temp == NULL)
4691 return 0;
4692 type->allocDefaultAtts = count;
4693 type->defaultAtts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004694 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004695 }
4696 att = type->defaultAtts + type->nDefaultAtts;
4697 att->id = attId;
4698 att->value = value;
4699 att->isCdata = isCdata;
4700 if (!isCdata)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004701 attId->maybeTokenized = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004702 type->nDefaultAtts += 1;
4703 return 1;
4704}
4705
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004706static int
4707setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004708{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004709 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004710 const XML_Char *name;
4711 for (name = elementType->name; *name; name++) {
4712 if (*name == XML_T(':')) {
4713 PREFIX *prefix;
4714 const XML_Char *s;
4715 for (s = elementType->name; s != name; s++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004716 if (!poolAppendChar(&dtd->pool, *s))
4717 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004718 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004719 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4720 return 0;
4721 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4722 sizeof(PREFIX));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004723 if (!prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004724 return 0;
4725 if (prefix->name == poolStart(&dtd->pool))
4726 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004727 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004728 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004729 elementType->prefix = prefix;
4730
4731 }
4732 }
4733 return 1;
4734}
4735
4736static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004737getAttributeId(XML_Parser parser, const ENCODING *enc,
4738 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004739{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004740 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004741 ATTRIBUTE_ID *id;
4742 const XML_Char *name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004743 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4744 return NULL;
4745 name = poolStoreString(&dtd->pool, enc, start, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004746 if (!name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004747 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004748 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004749 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004750 if (!id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004751 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004752 if (id->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004753 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004754 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004755 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004756 if (!ns)
4757 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004758 else if (name[0] == XML_T('x')
4759 && name[1] == XML_T('m')
4760 && name[2] == XML_T('l')
4761 && name[3] == XML_T('n')
4762 && name[4] == XML_T('s')
4763 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
4764 if (name[5] == XML_T('\0'))
4765 id->prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004766 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004767 id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
4768 id->xmlns = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004769 }
4770 else {
4771 int i;
4772 for (i = 0; name[i]; i++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004773 if (name[i] == XML_T(':')) {
4774 int j;
4775 for (j = 0; j < i; j++) {
4776 if (!poolAppendChar(&dtd->pool, name[j]))
4777 return NULL;
4778 }
4779 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4780 return NULL;
4781 id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4782 sizeof(PREFIX));
4783 if (id->prefix->name == poolStart(&dtd->pool))
4784 poolFinish(&dtd->pool);
4785 else
4786 poolDiscard(&dtd->pool);
4787 break;
4788 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004789 }
4790 }
4791 }
4792 return id;
4793}
4794
4795#define CONTEXT_SEP XML_T('\f')
4796
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004797static const XML_Char *
4798getContext(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004799{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004800 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004801 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004802 XML_Bool needSep = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004803
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004804 if (dtd->defaultPrefix.binding) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004805 int i;
4806 int len;
4807 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004808 return NULL;
4809 len = dtd->defaultPrefix.binding->uriLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004810 if (namespaceSeparator != XML_T('\0'))
4811 len--;
4812 for (i = 0; i < len; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004813 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
4814 return NULL;
4815 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004816 }
4817
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004818 hashTableIterInit(&iter, &(dtd->prefixes));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004819 for (;;) {
4820 int i;
4821 int len;
4822 const XML_Char *s;
4823 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
4824 if (!prefix)
4825 break;
4826 if (!prefix->binding)
4827 continue;
4828 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004829 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004830 for (s = prefix->name; *s; s++)
4831 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004832 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004833 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004834 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004835 len = prefix->binding->uriLen;
4836 if (namespaceSeparator != XML_T('\0'))
4837 len--;
4838 for (i = 0; i < len; i++)
4839 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004840 return NULL;
4841 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004842 }
4843
4844
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004845 hashTableIterInit(&iter, &(dtd->generalEntities));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004846 for (;;) {
4847 const XML_Char *s;
4848 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
4849 if (!e)
4850 break;
4851 if (!e->open)
4852 continue;
4853 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004854 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004855 for (s = e->name; *s; s++)
4856 if (!poolAppendChar(&tempPool, *s))
4857 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004858 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004859 }
4860
4861 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004862 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004863 return tempPool.start;
4864}
4865
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004866static XML_Bool
4867setContext(XML_Parser parser, const XML_Char *context)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004868{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004869 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004870 const XML_Char *s = context;
4871
4872 while (*context != XML_T('\0')) {
4873 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
4874 ENTITY *e;
4875 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004876 return XML_FALSE;
4877 e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004878 if (e)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004879 e->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004880 if (*s != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004881 s++;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004882 context = s;
4883 poolDiscard(&tempPool);
4884 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004885 else if (*s == XML_T('=')) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004886 PREFIX *prefix;
4887 if (poolLength(&tempPool) == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004888 prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004889 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004890 if (!poolAppendChar(&tempPool, XML_T('\0')))
4891 return XML_FALSE;
4892 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
4893 sizeof(PREFIX));
4894 if (!prefix)
4895 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004896 if (prefix->name == poolStart(&tempPool)) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004897 prefix->name = poolCopyString(&dtd->pool, prefix->name);
4898 if (!prefix->name)
4899 return XML_FALSE;
4900 }
4901 poolDiscard(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004902 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004903 for (context = s + 1;
4904 *context != CONTEXT_SEP && *context != XML_T('\0');
4905 context++)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004906 if (!poolAppendChar(&tempPool, *context))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004907 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004908 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004909 return XML_FALSE;
4910 if (addBinding(parser, prefix, 0, poolStart(&tempPool),
4911 &inheritedBindings) != XML_ERROR_NONE)
4912 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004913 poolDiscard(&tempPool);
4914 if (*context != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004915 ++context;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004916 s = context;
4917 }
4918 else {
4919 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004920 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004921 s++;
4922 }
4923 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004924 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004925}
4926
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004927static void FASTCALL
4928normalizePublicId(XML_Char *publicId)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004929{
4930 XML_Char *p = publicId;
4931 XML_Char *s;
4932 for (s = publicId; *s; s++) {
4933 switch (*s) {
4934 case 0x20:
4935 case 0xD:
4936 case 0xA:
4937 if (p != publicId && p[-1] != 0x20)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004938 *p++ = 0x20;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004939 break;
4940 default:
4941 *p++ = *s;
4942 }
4943 }
4944 if (p != publicId && p[-1] == 0x20)
4945 --p;
4946 *p = XML_T('\0');
4947}
4948
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004949static DTD *
4950dtdCreate(const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004951{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004952 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
4953 if (p == NULL)
4954 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004955 poolInit(&(p->pool), ms);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004956#ifdef XML_DTD
4957 poolInit(&(p->entityValuePool), ms);
4958#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004959 hashTableInit(&(p->generalEntities), ms);
4960 hashTableInit(&(p->elementTypes), ms);
4961 hashTableInit(&(p->attributeIds), ms);
4962 hashTableInit(&(p->prefixes), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004963#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004964 p->paramEntityRead = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004965 hashTableInit(&(p->paramEntities), ms);
4966#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004967 p->defaultPrefix.name = NULL;
4968 p->defaultPrefix.binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004969
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004970 p->in_eldecl = XML_FALSE;
4971 p->scaffIndex = NULL;
4972 p->scaffold = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004973 p->scaffLevel = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004974 p->scaffSize = 0;
4975 p->scaffCount = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004976 p->contentStringLen = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004977
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004978 p->keepProcessing = XML_TRUE;
4979 p->hasParamEntityRefs = XML_FALSE;
4980 p->standalone = XML_FALSE;
4981 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004982}
4983
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004984static void
4985dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004986{
4987 HASH_TABLE_ITER iter;
4988 hashTableIterInit(&iter, &(p->elementTypes));
4989 for (;;) {
4990 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4991 if (!e)
4992 break;
4993 if (e->allocDefaultAtts != 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004994 ms->free_fcn(e->defaultAtts);
4995 }
4996 hashTableClear(&(p->generalEntities));
4997#ifdef XML_DTD
4998 p->paramEntityRead = XML_FALSE;
4999 hashTableClear(&(p->paramEntities));
5000#endif /* XML_DTD */
5001 hashTableClear(&(p->elementTypes));
5002 hashTableClear(&(p->attributeIds));
5003 hashTableClear(&(p->prefixes));
5004 poolClear(&(p->pool));
5005#ifdef XML_DTD
5006 poolClear(&(p->entityValuePool));
5007#endif /* XML_DTD */
5008 p->defaultPrefix.name = NULL;
5009 p->defaultPrefix.binding = NULL;
5010
5011 p->in_eldecl = XML_FALSE;
5012 if (p->scaffIndex) {
5013 ms->free_fcn(p->scaffIndex);
5014 p->scaffIndex = NULL;
5015 }
5016 if (p->scaffold) {
5017 ms->free_fcn(p->scaffold);
5018 p->scaffold = NULL;
5019 }
5020 p->scaffLevel = 0;
5021 p->scaffSize = 0;
5022 p->scaffCount = 0;
5023 p->contentStringLen = 0;
5024
5025 p->keepProcessing = XML_TRUE;
5026 p->hasParamEntityRefs = XML_FALSE;
5027 p->standalone = XML_FALSE;
5028}
5029
5030static void
5031dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5032{
5033 HASH_TABLE_ITER iter;
5034 hashTableIterInit(&iter, &(p->elementTypes));
5035 for (;;) {
5036 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5037 if (!e)
5038 break;
5039 if (e->allocDefaultAtts != 0)
5040 ms->free_fcn(e->defaultAtts);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005041 }
5042 hashTableDestroy(&(p->generalEntities));
5043#ifdef XML_DTD
5044 hashTableDestroy(&(p->paramEntities));
5045#endif /* XML_DTD */
5046 hashTableDestroy(&(p->elementTypes));
5047 hashTableDestroy(&(p->attributeIds));
5048 hashTableDestroy(&(p->prefixes));
5049 poolDestroy(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005050#ifdef XML_DTD
5051 poolDestroy(&(p->entityValuePool));
5052#endif /* XML_DTD */
5053 if (isDocEntity) {
5054 if (p->scaffIndex)
5055 ms->free_fcn(p->scaffIndex);
5056 if (p->scaffold)
5057 ms->free_fcn(p->scaffold);
5058 }
5059 ms->free_fcn(p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005060}
5061
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005062/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5063 The new DTD has already been initialized.
5064*/
5065static int
5066dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005067{
5068 HASH_TABLE_ITER iter;
5069
5070 /* Copy the prefix table. */
5071
5072 hashTableIterInit(&iter, &(oldDtd->prefixes));
5073 for (;;) {
5074 const XML_Char *name;
5075 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5076 if (!oldP)
5077 break;
5078 name = poolCopyString(&(newDtd->pool), oldP->name);
5079 if (!name)
5080 return 0;
5081 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5082 return 0;
5083 }
5084
5085 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5086
5087 /* Copy the attribute id table. */
5088
5089 for (;;) {
5090 ATTRIBUTE_ID *newA;
5091 const XML_Char *name;
5092 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5093
5094 if (!oldA)
5095 break;
5096 /* Remember to allocate the scratch byte before the name. */
5097 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5098 return 0;
5099 name = poolCopyString(&(newDtd->pool), oldA->name);
5100 if (!name)
5101 return 0;
5102 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005103 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5104 sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005105 if (!newA)
5106 return 0;
5107 newA->maybeTokenized = oldA->maybeTokenized;
5108 if (oldA->prefix) {
5109 newA->xmlns = oldA->xmlns;
5110 if (oldA->prefix == &oldDtd->defaultPrefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005111 newA->prefix = &newDtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005112 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005113 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5114 oldA->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005115 }
5116 }
5117
5118 /* Copy the element type table. */
5119
5120 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5121
5122 for (;;) {
5123 int i;
5124 ELEMENT_TYPE *newE;
5125 const XML_Char *name;
5126 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5127 if (!oldE)
5128 break;
5129 name = poolCopyString(&(newDtd->pool), oldE->name);
5130 if (!name)
5131 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005132 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5133 sizeof(ELEMENT_TYPE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005134 if (!newE)
5135 return 0;
5136 if (oldE->nDefaultAtts) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005137 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5138 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5139 if (!newE->defaultAtts) {
5140 ms->free_fcn(newE);
5141 return 0;
5142 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005143 }
5144 if (oldE->idAtt)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005145 newE->idAtt = (ATTRIBUTE_ID *)
5146 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005147 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5148 if (oldE->prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005149 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5150 oldE->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005151 for (i = 0; i < newE->nDefaultAtts; i++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005152 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5153 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005154 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5155 if (oldE->defaultAtts[i].value) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005156 newE->defaultAtts[i].value
5157 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5158 if (!newE->defaultAtts[i].value)
5159 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005160 }
5161 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005162 newE->defaultAtts[i].value = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005163 }
5164 }
5165
5166 /* Copy the entity tables. */
5167 if (!copyEntityTable(&(newDtd->generalEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005168 &(newDtd->pool),
5169 &(oldDtd->generalEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005170 return 0;
5171
5172#ifdef XML_DTD
5173 if (!copyEntityTable(&(newDtd->paramEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005174 &(newDtd->pool),
5175 &(oldDtd->paramEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005176 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005177 newDtd->paramEntityRead = oldDtd->paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005178#endif /* XML_DTD */
5179
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005180 newDtd->keepProcessing = oldDtd->keepProcessing;
5181 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005182 newDtd->standalone = oldDtd->standalone;
5183
5184 /* Don't want deep copying for scaffolding */
5185 newDtd->in_eldecl = oldDtd->in_eldecl;
5186 newDtd->scaffold = oldDtd->scaffold;
5187 newDtd->contentStringLen = oldDtd->contentStringLen;
5188 newDtd->scaffSize = oldDtd->scaffSize;
5189 newDtd->scaffLevel = oldDtd->scaffLevel;
5190 newDtd->scaffIndex = oldDtd->scaffIndex;
5191
5192 return 1;
5193} /* End dtdCopy */
5194
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005195static int
5196copyEntityTable(HASH_TABLE *newTable,
5197 STRING_POOL *newPool,
5198 const HASH_TABLE *oldTable)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005199{
5200 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005201 const XML_Char *cachedOldBase = NULL;
5202 const XML_Char *cachedNewBase = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005203
5204 hashTableIterInit(&iter, oldTable);
5205
5206 for (;;) {
5207 ENTITY *newE;
5208 const XML_Char *name;
5209 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5210 if (!oldE)
5211 break;
5212 name = poolCopyString(newPool, oldE->name);
5213 if (!name)
5214 return 0;
5215 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5216 if (!newE)
5217 return 0;
5218 if (oldE->systemId) {
5219 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5220 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005221 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005222 newE->systemId = tem;
5223 if (oldE->base) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005224 if (oldE->base == cachedOldBase)
5225 newE->base = cachedNewBase;
5226 else {
5227 cachedOldBase = oldE->base;
5228 tem = poolCopyString(newPool, cachedOldBase);
5229 if (!tem)
5230 return 0;
5231 cachedNewBase = newE->base = tem;
5232 }
5233 }
5234 if (oldE->publicId) {
5235 tem = poolCopyString(newPool, oldE->publicId);
5236 if (!tem)
5237 return 0;
5238 newE->publicId = tem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005239 }
5240 }
5241 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005242 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5243 oldE->textLen);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005244 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005245 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005246 newE->textPtr = tem;
5247 newE->textLen = oldE->textLen;
5248 }
5249 if (oldE->notation) {
5250 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5251 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005252 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005253 newE->notation = tem;
5254 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005255 newE->is_param = oldE->is_param;
5256 newE->is_internal = oldE->is_internal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005257 }
5258 return 1;
5259}
5260
5261#define INIT_SIZE 64
5262
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005263static int FASTCALL
5264keyeq(KEY s1, KEY s2)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005265{
5266 for (; *s1 == *s2; s1++, s2++)
5267 if (*s1 == 0)
5268 return 1;
5269 return 0;
5270}
5271
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005272static unsigned long FASTCALL
5273hash(KEY s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005274{
5275 unsigned long h = 0;
5276 while (*s)
5277 h = (h << 5) + h + (unsigned char)*s++;
5278 return h;
5279}
5280
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005281static NAMED *
5282lookup(HASH_TABLE *table, KEY name, size_t createSize)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005283{
5284 size_t i;
5285 if (table->size == 0) {
5286 size_t tsize;
5287
5288 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005289 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005290 tsize = INIT_SIZE * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005291 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005292 if (!table->v)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005293 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005294 memset(table->v, 0, tsize);
5295 table->size = INIT_SIZE;
5296 table->usedLim = INIT_SIZE / 2;
5297 i = hash(name) & (table->size - 1);
5298 }
5299 else {
5300 unsigned long h = hash(name);
5301 for (i = h & (table->size - 1);
5302 table->v[i];
5303 i == 0 ? i = table->size - 1 : --i) {
5304 if (keyeq(name, table->v[i]->name))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005305 return table->v[i];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005306 }
5307 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005308 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005309 if (table->used == table->usedLim) {
5310 /* check for overflow */
5311 size_t newSize = table->size * 2;
5312 size_t tsize = newSize * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005313 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005314 if (!newV)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005315 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005316 memset(newV, 0, tsize);
5317 for (i = 0; i < table->size; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005318 if (table->v[i]) {
5319 size_t j;
5320 for (j = hash(table->v[i]->name) & (newSize - 1);
5321 newV[j];
5322 j == 0 ? j = newSize - 1 : --j)
5323 ;
5324 newV[j] = table->v[i];
5325 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005326 table->mem->free_fcn(table->v);
5327 table->v = newV;
5328 table->size = newSize;
5329 table->usedLim = newSize/2;
5330 for (i = h & (table->size - 1);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005331 table->v[i];
5332 i == 0 ? i = table->size - 1 : --i)
5333 ;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005334 }
5335 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005336 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005337 if (!table->v[i])
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005338 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005339 memset(table->v[i], 0, createSize);
5340 table->v[i]->name = name;
5341 (table->used)++;
5342 return table->v[i];
5343}
5344
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005345static void FASTCALL
5346hashTableClear(HASH_TABLE *table)
5347{
5348 size_t i;
5349 for (i = 0; i < table->size; i++) {
5350 NAMED *p = table->v[i];
5351 if (p) {
5352 table->mem->free_fcn(p);
5353 table->v[i] = NULL;
5354 }
5355 }
5356 table->usedLim = table->size / 2;
5357 table->used = 0;
5358}
5359
5360static void FASTCALL
5361hashTableDestroy(HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005362{
5363 size_t i;
5364 for (i = 0; i < table->size; i++) {
5365 NAMED *p = table->v[i];
5366 if (p)
5367 table->mem->free_fcn(p);
5368 }
5369 if (table->v)
5370 table->mem->free_fcn(table->v);
5371}
5372
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005373static void FASTCALL
5374hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005375{
5376 p->size = 0;
5377 p->usedLim = 0;
5378 p->used = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005379 p->v = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005380 p->mem = ms;
5381}
5382
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005383static void FASTCALL
5384hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005385{
5386 iter->p = table->v;
5387 iter->end = iter->p + table->size;
5388}
5389
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005390static NAMED * FASTCALL
5391hashTableIterNext(HASH_TABLE_ITER *iter)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005392{
5393 while (iter->p != iter->end) {
5394 NAMED *tem = *(iter->p)++;
5395 if (tem)
5396 return tem;
5397 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005398 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005399}
5400
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005401static void FASTCALL
5402poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005403{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005404 pool->blocks = NULL;
5405 pool->freeBlocks = NULL;
5406 pool->start = NULL;
5407 pool->ptr = NULL;
5408 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005409 pool->mem = ms;
5410}
5411
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005412static void FASTCALL
5413poolClear(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005414{
5415 if (!pool->freeBlocks)
5416 pool->freeBlocks = pool->blocks;
5417 else {
5418 BLOCK *p = pool->blocks;
5419 while (p) {
5420 BLOCK *tem = p->next;
5421 p->next = pool->freeBlocks;
5422 pool->freeBlocks = p;
5423 p = tem;
5424 }
5425 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005426 pool->blocks = NULL;
5427 pool->start = NULL;
5428 pool->ptr = NULL;
5429 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005430}
5431
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005432static void FASTCALL
5433poolDestroy(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005434{
5435 BLOCK *p = pool->blocks;
5436 while (p) {
5437 BLOCK *tem = p->next;
5438 pool->mem->free_fcn(p);
5439 p = tem;
5440 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005441 p = pool->freeBlocks;
5442 while (p) {
5443 BLOCK *tem = p->next;
5444 pool->mem->free_fcn(p);
5445 p = tem;
5446 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005447}
5448
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005449static XML_Char *
5450poolAppend(STRING_POOL *pool, const ENCODING *enc,
5451 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005452{
5453 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005454 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005455 for (;;) {
5456 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
5457 if (ptr == end)
5458 break;
5459 if (!poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005460 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005461 }
5462 return pool->start;
5463}
5464
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005465static const XML_Char * FASTCALL
5466poolCopyString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005467{
5468 do {
5469 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005470 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005471 } while (*s++);
5472 s = pool->start;
5473 poolFinish(pool);
5474 return s;
5475}
5476
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005477static const XML_Char *
5478poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005479{
5480 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005481 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005482 for (; n > 0; --n, s++) {
5483 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005484 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005485 }
5486 s = pool->start;
5487 poolFinish(pool);
5488 return s;
5489}
5490
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005491static const XML_Char * FASTCALL
5492poolAppendString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005493{
5494 while (*s) {
5495 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005496 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005497 s++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005498 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005499 return pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005500}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005501
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005502static XML_Char *
5503poolStoreString(STRING_POOL *pool, const ENCODING *enc,
5504 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005505{
5506 if (!poolAppend(pool, enc, ptr, end))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005507 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005508 if (pool->ptr == pool->end && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005509 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005510 *(pool->ptr)++ = 0;
5511 return pool->start;
5512}
5513
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005514static XML_Bool FASTCALL
5515poolGrow(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005516{
5517 if (pool->freeBlocks) {
5518 if (pool->start == 0) {
5519 pool->blocks = pool->freeBlocks;
5520 pool->freeBlocks = pool->freeBlocks->next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005521 pool->blocks->next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005522 pool->start = pool->blocks->s;
5523 pool->end = pool->start + pool->blocks->size;
5524 pool->ptr = pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005525 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005526 }
5527 if (pool->end - pool->start < pool->freeBlocks->size) {
5528 BLOCK *tem = pool->freeBlocks->next;
5529 pool->freeBlocks->next = pool->blocks;
5530 pool->blocks = pool->freeBlocks;
5531 pool->freeBlocks = tem;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005532 memcpy(pool->blocks->s, pool->start,
5533 (pool->end - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005534 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5535 pool->start = pool->blocks->s;
5536 pool->end = pool->start + pool->blocks->size;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005537 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005538 }
5539 }
5540 if (pool->blocks && pool->start == pool->blocks->s) {
5541 int blockSize = (pool->end - pool->start)*2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005542 pool->blocks = (BLOCK *)
5543 pool->mem->realloc_fcn(pool->blocks,
5544 (offsetof(BLOCK, s)
5545 + blockSize * sizeof(XML_Char)));
5546 if (pool->blocks == NULL)
5547 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005548 pool->blocks->size = blockSize;
5549 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5550 pool->start = pool->blocks->s;
5551 pool->end = pool->start + blockSize;
5552 }
5553 else {
5554 BLOCK *tem;
5555 int blockSize = pool->end - pool->start;
5556 if (blockSize < INIT_BLOCK_SIZE)
5557 blockSize = INIT_BLOCK_SIZE;
5558 else
5559 blockSize *= 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005560 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
5561 + blockSize * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005562 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005563 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005564 tem->size = blockSize;
5565 tem->next = pool->blocks;
5566 pool->blocks = tem;
5567 if (pool->ptr != pool->start)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005568 memcpy(tem->s, pool->start,
5569 (pool->ptr - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005570 pool->ptr = tem->s + (pool->ptr - pool->start);
5571 pool->start = tem->s;
5572 pool->end = tem->s + blockSize;
5573 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005574 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005575}
5576
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005577static int FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005578nextScaffoldPart(XML_Parser parser)
5579{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005580 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005581 CONTENT_SCAFFOLD * me;
5582 int next;
5583
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005584 if (!dtd->scaffIndex) {
5585 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
5586 if (!dtd->scaffIndex)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005587 return -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005588 dtd->scaffIndex[0] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005589 }
5590
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005591 if (dtd->scaffCount >= dtd->scaffSize) {
5592 CONTENT_SCAFFOLD *temp;
5593 if (dtd->scaffold) {
5594 temp = (CONTENT_SCAFFOLD *)
5595 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
5596 if (temp == NULL)
5597 return -1;
5598 dtd->scaffSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005599 }
5600 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005601 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
5602 * sizeof(CONTENT_SCAFFOLD));
5603 if (temp == NULL)
5604 return -1;
5605 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005606 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005607 dtd->scaffold = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005608 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005609 next = dtd->scaffCount++;
5610 me = &dtd->scaffold[next];
5611 if (dtd->scaffLevel) {
5612 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005613 if (parent->lastchild) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005614 dtd->scaffold[parent->lastchild].nextsib = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005615 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005616 if (!parent->childcnt)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005617 parent->firstchild = next;
5618 parent->lastchild = next;
5619 parent->childcnt++;
5620 }
5621 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
5622 return next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005623}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005624
5625static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005626build_node(XML_Parser parser,
5627 int src_node,
5628 XML_Content *dest,
5629 XML_Content **contpos,
5630 XML_Char **strpos)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005631{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005632 DTD * const dtd = _dtd; /* save one level of indirection */
5633 dest->type = dtd->scaffold[src_node].type;
5634 dest->quant = dtd->scaffold[src_node].quant;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005635 if (dest->type == XML_CTYPE_NAME) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005636 const XML_Char *src;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005637 dest->name = *strpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005638 src = dtd->scaffold[src_node].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005639 for (;;) {
5640 *(*strpos)++ = *src;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005641 if (!*src)
5642 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005643 src++;
5644 }
5645 dest->numchildren = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005646 dest->children = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005647 }
5648 else {
5649 unsigned int i;
5650 int cn;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005651 dest->numchildren = dtd->scaffold[src_node].childcnt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005652 dest->children = *contpos;
5653 *contpos += dest->numchildren;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005654 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
5655 i < dest->numchildren;
5656 i++, cn = dtd->scaffold[cn].nextsib) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005657 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
5658 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005659 dest->name = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005660 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005661}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005662
5663static XML_Content *
5664build_model (XML_Parser parser)
5665{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005666 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005667 XML_Content *ret;
5668 XML_Content *cpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005669 XML_Char * str;
5670 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
5671 + (dtd->contentStringLen * sizeof(XML_Char)));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005672
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005673 ret = (XML_Content *)MALLOC(allocsize);
5674 if (!ret)
5675 return NULL;
5676
5677 str = (XML_Char *) (&ret[dtd->scaffCount]);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005678 cpos = &ret[1];
5679
5680 build_node(parser, 0, ret, &cpos, &str);
5681 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005682}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005683
5684static ELEMENT_TYPE *
5685getElementType(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005686 const ENCODING *enc,
5687 const char *ptr,
5688 const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005689{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005690 DTD * const dtd = _dtd; /* save one level of indirection */
5691 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005692 ELEMENT_TYPE *ret;
5693
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005694 if (!name)
5695 return NULL;
5696 ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
5697 if (!ret)
5698 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005699 if (ret->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005700 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005701 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005702 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005703 if (!setElementTypePrefix(parser, ret))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005704 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005705 }
5706 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005707}