blob: eae9374ff5a22917bbdf1b8ce9d741faa6603bc6 [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
Fred Drake4faea012003-01-28 06:42:40 +0000312storeAtts(XML_Parser parser, const ENCODING *, const char *s,
313 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000314static 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');
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002100 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2101 if (result)
2102 return result;
2103 if (startElementHandler)
2104 startElementHandler(handlerArg, tag->name.str,
2105 (const XML_Char **)atts);
2106 else if (defaultHandler)
2107 reportDefault(parser, enc, s, next);
2108 poolClear(&tempPool);
2109 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002110 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002111 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002112 /* fall through */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002113 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2114 {
2115 const char *rawName = s + enc->minBytesPerChar;
2116 enum XML_Error result;
2117 BINDING *bindings = NULL;
2118 XML_Bool noElmHandlers = XML_TRUE;
2119 TAG_NAME name;
2120 name.str = poolStoreString(&tempPool, enc, rawName,
2121 rawName + XmlNameLength(enc, rawName));
2122 if (!name.str)
2123 return XML_ERROR_NO_MEMORY;
2124 poolFinish(&tempPool);
Fred Drake4faea012003-01-28 06:42:40 +00002125 result = storeAtts(parser, enc, s, &name, &bindings);
2126 if (result)
2127 return result;
2128 poolFinish(&tempPool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002129 if (startElementHandler) {
2130 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2131 noElmHandlers = XML_FALSE;
2132 }
2133 if (endElementHandler) {
2134 if (startElementHandler)
2135 *eventPP = *eventEndPP;
2136 endElementHandler(handlerArg, name.str);
2137 noElmHandlers = XML_FALSE;
2138 }
2139 if (noElmHandlers && defaultHandler)
2140 reportDefault(parser, enc, s, next);
2141 poolClear(&tempPool);
2142 while (bindings) {
2143 BINDING *b = bindings;
2144 if (endNamespaceDeclHandler)
2145 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2146 bindings = bindings->nextTagBinding;
2147 b->nextTagBinding = freeBindingList;
2148 freeBindingList = b;
2149 b->prefix->binding = b->prevPrefixBinding;
2150 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002151 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002152 if (tagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002153 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002154 break;
2155 case XML_TOK_END_TAG:
2156 if (tagLevel == startTagLevel)
2157 return XML_ERROR_ASYNC_ENTITY;
2158 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002159 int len;
2160 const char *rawName;
2161 TAG *tag = tagStack;
2162 tagStack = tag->parent;
2163 tag->parent = freeTagList;
2164 freeTagList = tag;
2165 rawName = s + enc->minBytesPerChar*2;
2166 len = XmlNameLength(enc, rawName);
2167 if (len != tag->rawNameLength
2168 || memcmp(tag->rawName, rawName, len) != 0) {
2169 *eventPP = rawName;
2170 return XML_ERROR_TAG_MISMATCH;
2171 }
2172 --tagLevel;
2173 if (endElementHandler) {
2174 const XML_Char *localPart;
2175 const XML_Char *prefix;
2176 XML_Char *uri;
2177 localPart = tag->name.localPart;
2178 if (ns && localPart) {
2179 /* localPart and prefix may have been overwritten in
2180 tag->name.str, since this points to the binding->uri
2181 buffer which gets re-used; so we have to add them again
2182 */
2183 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2184 /* don't need to check for space - already done in storeAtts() */
2185 while (*localPart) *uri++ = *localPart++;
2186 prefix = (XML_Char *)tag->name.prefix;
2187 if (ns_triplets && prefix) {
2188 *uri++ = namespaceSeparator;
2189 while (*prefix) *uri++ = *prefix++;
2190 }
2191 *uri = XML_T('\0');
2192 }
2193 endElementHandler(handlerArg, tag->name.str);
2194 }
2195 else if (defaultHandler)
2196 reportDefault(parser, enc, s, next);
2197 while (tag->bindings) {
2198 BINDING *b = tag->bindings;
2199 if (endNamespaceDeclHandler)
2200 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2201 tag->bindings = tag->bindings->nextTagBinding;
2202 b->nextTagBinding = freeBindingList;
2203 freeBindingList = b;
2204 b->prefix->binding = b->prevPrefixBinding;
2205 }
2206 if (tagLevel == 0)
2207 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002208 }
2209 break;
2210 case XML_TOK_CHAR_REF:
2211 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002212 int n = XmlCharRefNumber(enc, s);
2213 if (n < 0)
2214 return XML_ERROR_BAD_CHAR_REF;
2215 if (characterDataHandler) {
2216 XML_Char buf[XML_ENCODE_MAX];
2217 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2218 }
2219 else if (defaultHandler)
2220 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002221 }
2222 break;
2223 case XML_TOK_XML_DECL:
2224 return XML_ERROR_MISPLACED_XML_PI;
2225 case XML_TOK_DATA_NEWLINE:
2226 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002227 XML_Char c = 0xA;
2228 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002229 }
2230 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002231 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002232 break;
2233 case XML_TOK_CDATA_SECT_OPEN:
2234 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002235 enum XML_Error result;
2236 if (startCdataSectionHandler)
2237 startCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002238#if 0
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002239 /* Suppose you doing a transformation on a document that involves
2240 changing only the character data. You set up a defaultHandler
2241 and a characterDataHandler. The defaultHandler simply copies
2242 characters through. The characterDataHandler does the
2243 transformation and writes the characters out escaping them as
2244 necessary. This case will fail to work if we leave out the
2245 following two lines (because & and < inside CDATA sections will
2246 be incorrectly escaped).
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002247
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002248 However, now we have a start/endCdataSectionHandler, so it seems
2249 easier to let the user deal with this.
2250 */
2251 else if (characterDataHandler)
2252 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002253#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002254 else if (defaultHandler)
2255 reportDefault(parser, enc, s, next);
2256 result = doCdataSection(parser, enc, &next, end, nextPtr);
2257 if (!next) {
2258 processor = cdataSectionProcessor;
2259 return result;
2260 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002261 }
2262 break;
2263 case XML_TOK_TRAILING_RSQB:
2264 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002265 *nextPtr = s;
2266 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002267 }
2268 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002269 if (MUST_CONVERT(enc, s)) {
2270 ICHAR *dataPtr = (ICHAR *)dataBuf;
2271 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2272 characterDataHandler(handlerArg, dataBuf,
2273 dataPtr - (ICHAR *)dataBuf);
2274 }
2275 else
2276 characterDataHandler(handlerArg,
2277 (XML_Char *)s,
2278 (XML_Char *)end - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002279 }
2280 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002281 reportDefault(parser, enc, s, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002282 if (startTagLevel == 0) {
2283 *eventPP = end;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002284 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002285 }
2286 if (tagLevel != startTagLevel) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002287 *eventPP = end;
2288 return XML_ERROR_ASYNC_ENTITY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002289 }
2290 return XML_ERROR_NONE;
2291 case XML_TOK_DATA_CHARS:
2292 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002293 if (MUST_CONVERT(enc, s)) {
2294 for (;;) {
2295 ICHAR *dataPtr = (ICHAR *)dataBuf;
2296 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2297 *eventEndPP = s;
2298 characterDataHandler(handlerArg, dataBuf,
2299 dataPtr - (ICHAR *)dataBuf);
2300 if (s == next)
2301 break;
2302 *eventPP = s;
2303 }
2304 }
2305 else
2306 characterDataHandler(handlerArg,
2307 (XML_Char *)s,
2308 (XML_Char *)next - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002309 }
2310 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002311 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002312 break;
2313 case XML_TOK_PI:
2314 if (!reportProcessingInstruction(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002315 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002316 break;
2317 case XML_TOK_COMMENT:
2318 if (!reportComment(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002319 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002320 break;
2321 default:
2322 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002323 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002324 break;
2325 }
2326 *eventPP = s = next;
2327 }
2328 /* not reached */
2329}
2330
Fred Drake4faea012003-01-28 06:42:40 +00002331/* Precondition: all arguments must be non-NULL;
2332 Purpose:
2333 - normalize attributes
2334 - check attributes for well-formedness
2335 - generate namespace aware attribute names (URI, prefix)
2336 - build list of attributes for startElementHandler
2337 - default attributes
2338 - process namespace declarations (check and report them)
2339 - generate namespace aware element name (URI, prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002340*/
2341static enum XML_Error
2342storeAtts(XML_Parser parser, const ENCODING *enc,
2343 const char *attStr, TAG_NAME *tagNamePtr,
2344 BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002345{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002346 DTD * const dtd = _dtd; /* save one level of indirection */
2347 ELEMENT_TYPE *elementType = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002348 int nDefaultAtts = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002349 const XML_Char **appAtts; /* the attribute list for the application */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002350 int attIndex = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002351 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002352 int i;
2353 int n;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002354 XML_Char *uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002355 int nPrefixes = 0;
2356 BINDING *binding;
2357 const XML_Char *localPart;
2358
2359 /* lookup the element type name */
Fred Drake4faea012003-01-28 06:42:40 +00002360 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
2361 if (!elementType) {
2362 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2363 if (!name)
2364 return XML_ERROR_NO_MEMORY;
2365 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
2366 sizeof(ELEMENT_TYPE));
2367 if (!elementType)
2368 return XML_ERROR_NO_MEMORY;
2369 if (ns && !setElementTypePrefix(parser, elementType))
2370 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002371 }
Fred Drake4faea012003-01-28 06:42:40 +00002372 nDefaultAtts = elementType->nDefaultAtts;
2373
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002374 /* get the attributes from the tokenizer */
2375 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2376 if (n + nDefaultAtts > attsSize) {
2377 int oldAttsSize = attsSize;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002378 ATTRIBUTE *temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002379 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002380 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2381 if (temp == NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002382 return XML_ERROR_NO_MEMORY;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002383 atts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002384 if (n > oldAttsSize)
2385 XmlGetAttributes(enc, attStr, n, atts);
2386 }
Fred Drake4faea012003-01-28 06:42:40 +00002387
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002388 appAtts = (const XML_Char **)atts;
2389 for (i = 0; i < n; i++) {
2390 /* add the name and value to the attribute list */
2391 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002392 atts[i].name
2393 + XmlNameLength(enc, atts[i].name));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002394 if (!attId)
2395 return XML_ERROR_NO_MEMORY;
2396 /* detect duplicate attributes */
2397 if ((attId->name)[-1]) {
2398 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002399 eventPtr = atts[i].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002400 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2401 }
2402 (attId->name)[-1] = 1;
2403 appAtts[attIndex++] = attId->name;
2404 if (!atts[i].normalized) {
2405 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002406 XML_Bool isCdata = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002407
2408 /* figure out whether declared as other than CDATA */
2409 if (attId->maybeTokenized) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002410 int j;
2411 for (j = 0; j < nDefaultAtts; j++) {
2412 if (attId == elementType->defaultAtts[j].id) {
2413 isCdata = elementType->defaultAtts[j].isCdata;
2414 break;
2415 }
2416 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002417 }
2418
2419 /* normalize the attribute value */
2420 result = storeAttributeValue(parser, enc, isCdata,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002421 atts[i].valuePtr, atts[i].valueEnd,
2422 &tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002423 if (result)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002424 return result;
Fred Drake4faea012003-01-28 06:42:40 +00002425 appAtts[attIndex] = poolStart(&tempPool);
2426 poolFinish(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002427 }
Fred Drake4faea012003-01-28 06:42:40 +00002428 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002429 /* the value did not need normalizing */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002430 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2431 atts[i].valueEnd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002432 if (appAtts[attIndex] == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002433 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002434 poolFinish(&tempPool);
2435 }
2436 /* handle prefixed attribute names */
Fred Drake4faea012003-01-28 06:42:40 +00002437 if (attId->prefix) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002438 if (attId->xmlns) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002439 /* deal with namespace declarations here */
2440 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2441 appAtts[attIndex], bindingsPtr);
2442 if (result)
2443 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002444 --attIndex;
2445 }
2446 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002447 /* deal with other prefixed names later */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002448 attIndex++;
2449 nPrefixes++;
2450 (attId->name)[-1] = 2;
2451 }
2452 }
2453 else
2454 attIndex++;
2455 }
Fred Drake4faea012003-01-28 06:42:40 +00002456
2457 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2458 nSpecifiedAtts = attIndex;
2459 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2460 for (i = 0; i < attIndex; i += 2)
2461 if (appAtts[i] == elementType->idAtt->name) {
2462 idAttIndex = i;
2463 break;
2464 }
2465 }
2466 else
2467 idAttIndex = -1;
2468
2469 /* do attribute defaulting */
2470 for (i = 0; i < nDefaultAtts; i++) {
2471 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2472 if (!(da->id->name)[-1] && da->value) {
2473 if (da->id->prefix) {
2474 if (da->id->xmlns) {
2475 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2476 da->value, bindingsPtr);
2477 if (result)
2478 return result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002479 }
2480 else {
Fred Drake4faea012003-01-28 06:42:40 +00002481 (da->id->name)[-1] = 2;
2482 nPrefixes++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002483 appAtts[attIndex++] = da->id->name;
2484 appAtts[attIndex++] = da->value;
2485 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002486 }
Fred Drake4faea012003-01-28 06:42:40 +00002487 else {
2488 (da->id->name)[-1] = 1;
2489 appAtts[attIndex++] = da->id->name;
2490 appAtts[attIndex++] = da->value;
2491 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002492 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002493 }
Fred Drake4faea012003-01-28 06:42:40 +00002494 appAtts[attIndex] = 0;
2495
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002496 i = 0;
2497 if (nPrefixes) {
2498 /* expand prefixed attribute names */
2499 for (; i < attIndex; i += 2) {
2500 if (appAtts[i][-1] == 2) {
2501 ATTRIBUTE_ID *id;
2502 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002503 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, appAtts[i], 0);
2504 if (id->prefix->binding) {
2505 int j;
2506 const BINDING *b = id->prefix->binding;
2507 const XML_Char *s = appAtts[i];
2508 for (j = 0; j < b->uriLen; j++) {
2509 if (!poolAppendChar(&tempPool, b->uri[j]))
2510 return XML_ERROR_NO_MEMORY;
2511 }
2512 while (*s++ != XML_T(':'))
2513 ;
2514 do {
2515 if (!poolAppendChar(&tempPool, *s))
2516 return XML_ERROR_NO_MEMORY;
2517 } while (*s++);
2518 if (ns_triplets) {
2519 tempPool.ptr[-1] = namespaceSeparator;
2520 s = b->prefix->name;
2521 do {
2522 if (!poolAppendChar(&tempPool, *s))
2523 return XML_ERROR_NO_MEMORY;
2524 } while (*s++);
2525 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002526
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002527 appAtts[i] = poolStart(&tempPool);
2528 poolFinish(&tempPool);
2529 }
2530 if (!--nPrefixes)
2531 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002532 }
2533 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002534 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002535 }
2536 }
2537 /* clear the flags that say whether attributes were specified */
2538 for (; i < attIndex; i += 2)
2539 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002540 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2541 binding->attId->name[-1] = 0;
Fred Drake4faea012003-01-28 06:42:40 +00002542
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002543 /* expand the element type name */
2544 if (elementType->prefix) {
2545 binding = elementType->prefix->binding;
2546 if (!binding)
2547 return XML_ERROR_NONE;
2548 localPart = tagNamePtr->str;
2549 while (*localPart++ != XML_T(':'))
2550 ;
2551 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002552 else if (dtd->defaultPrefix.binding) {
2553 binding = dtd->defaultPrefix.binding;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002554 localPart = tagNamePtr->str;
2555 }
2556 else
2557 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002558 prefixLen = 0;
2559 if (ns && ns_triplets && binding->prefix->name) {
2560 for (; binding->prefix->name[prefixLen++];)
2561 ;
2562 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002563 tagNamePtr->localPart = localPart;
2564 tagNamePtr->uriLen = binding->uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002565 tagNamePtr->prefix = binding->prefix->name;
2566 tagNamePtr->prefixLen = prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002567 for (i = 0; localPart[i++];)
2568 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002569 n = i + binding->uriLen + prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002570 if (n > binding->uriAlloc) {
2571 TAG *p;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002572 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002573 if (!uri)
2574 return XML_ERROR_NO_MEMORY;
2575 binding->uriAlloc = n + EXPAND_SPARE;
2576 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2577 for (p = tagStack; p; p = p->parent)
2578 if (p->name.str == binding->uri)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002579 p->name.str = uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002580 FREE(binding->uri);
2581 binding->uri = uri;
2582 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002583 uri = binding->uri + binding->uriLen;
2584 memcpy(uri, localPart, i * sizeof(XML_Char));
2585 if (prefixLen) {
2586 uri = uri + (i - 1);
2587 if (namespaceSeparator) { *(uri) = namespaceSeparator; }
2588 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2589 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002590 tagNamePtr->str = binding->uri;
2591 return XML_ERROR_NONE;
2592}
2593
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002594/* addBinding() overwrites the value of prefix->binding without checking.
2595 Therefore one must keep track of the old value outside of addBinding().
2596*/
2597static enum XML_Error
2598addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2599 const XML_Char *uri, BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002600{
2601 BINDING *b;
2602 int len;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002603
2604 /* empty string is only valid when there is no prefix per XML NS 1.0 */
2605 if (*uri == XML_T('\0') && prefix->name)
2606 return XML_ERROR_SYNTAX;
2607
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002608 for (len = 0; uri[len]; len++)
2609 ;
2610 if (namespaceSeparator)
2611 len++;
2612 if (freeBindingList) {
2613 b = freeBindingList;
2614 if (len > b->uriAlloc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002615 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
2616 sizeof(XML_Char) * (len + EXPAND_SPARE));
2617 if (temp == NULL)
2618 return XML_ERROR_NO_MEMORY;
2619 b->uri = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002620 b->uriAlloc = len + EXPAND_SPARE;
2621 }
2622 freeBindingList = b->nextTagBinding;
2623 }
2624 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002625 b = (BINDING *)MALLOC(sizeof(BINDING));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002626 if (!b)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002627 return XML_ERROR_NO_MEMORY;
2628 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002629 if (!b->uri) {
2630 FREE(b);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002631 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002632 }
2633 b->uriAlloc = len + EXPAND_SPARE;
2634 }
2635 b->uriLen = len;
2636 memcpy(b->uri, uri, len * sizeof(XML_Char));
2637 if (namespaceSeparator)
2638 b->uri[len - 1] = namespaceSeparator;
2639 b->prefix = prefix;
2640 b->attId = attId;
2641 b->prevPrefixBinding = prefix->binding;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002642 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
2643 prefix->binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002644 else
2645 prefix->binding = b;
2646 b->nextTagBinding = *bindingsPtr;
2647 *bindingsPtr = b;
2648 if (startNamespaceDeclHandler)
2649 startNamespaceDeclHandler(handlerArg, prefix->name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002650 prefix->binding ? uri : 0);
2651 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002652}
2653
2654/* The idea here is to avoid using stack for each CDATA section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002655 the whole file is parsed with one call.
2656*/
2657static enum XML_Error PTRCALL
2658cdataSectionProcessor(XML_Parser parser,
2659 const char *start,
2660 const char *end,
2661 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002662{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002663 enum XML_Error result = doCdataSection(parser, encoding, &start,
2664 end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002665 if (start) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002666 if (parentParser) { /* we are parsing an external entity */
2667 processor = externalEntityContentProcessor;
2668 return externalEntityContentProcessor(parser, start, end, endPtr);
2669 }
2670 else {
2671 processor = contentProcessor;
2672 return contentProcessor(parser, start, end, endPtr);
2673 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002674 }
2675 return result;
2676}
2677
2678/* startPtr gets set to non-null is the section is closed, and to null if
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002679 the section is not yet closed.
2680*/
2681static enum XML_Error
2682doCdataSection(XML_Parser parser,
2683 const ENCODING *enc,
2684 const char **startPtr,
2685 const char *end,
2686 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002687{
2688 const char *s = *startPtr;
2689 const char **eventPP;
2690 const char **eventEndPP;
2691 if (enc == encoding) {
2692 eventPP = &eventPtr;
2693 *eventPP = s;
2694 eventEndPP = &eventEndPtr;
2695 }
2696 else {
2697 eventPP = &(openInternalEntities->internalEventPtr);
2698 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2699 }
2700 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002701 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002702 for (;;) {
2703 const char *next;
2704 int tok = XmlCdataSectionTok(enc, s, end, &next);
2705 *eventEndPP = next;
2706 switch (tok) {
2707 case XML_TOK_CDATA_SECT_CLOSE:
2708 if (endCdataSectionHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002709 endCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002710#if 0
2711 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2712 else if (characterDataHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002713 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002714#endif
2715 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002716 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002717 *startPtr = next;
2718 return XML_ERROR_NONE;
2719 case XML_TOK_DATA_NEWLINE:
2720 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002721 XML_Char c = 0xA;
2722 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002723 }
2724 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002725 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002726 break;
2727 case XML_TOK_DATA_CHARS:
2728 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002729 if (MUST_CONVERT(enc, s)) {
2730 for (;;) {
2731 ICHAR *dataPtr = (ICHAR *)dataBuf;
2732 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2733 *eventEndPP = next;
2734 characterDataHandler(handlerArg, dataBuf,
2735 dataPtr - (ICHAR *)dataBuf);
2736 if (s == next)
2737 break;
2738 *eventPP = s;
2739 }
2740 }
2741 else
2742 characterDataHandler(handlerArg,
2743 (XML_Char *)s,
2744 (XML_Char *)next - (XML_Char *)s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002745 }
2746 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002747 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002748 break;
2749 case XML_TOK_INVALID:
2750 *eventPP = next;
2751 return XML_ERROR_INVALID_TOKEN;
2752 case XML_TOK_PARTIAL_CHAR:
2753 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002754 *nextPtr = s;
2755 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002756 }
2757 return XML_ERROR_PARTIAL_CHAR;
2758 case XML_TOK_PARTIAL:
2759 case XML_TOK_NONE:
2760 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002761 *nextPtr = s;
2762 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002763 }
2764 return XML_ERROR_UNCLOSED_CDATA_SECTION;
2765 default:
2766 *eventPP = next;
2767 return XML_ERROR_UNEXPECTED_STATE;
2768 }
2769 *eventPP = s = next;
2770 }
2771 /* not reached */
2772}
2773
2774#ifdef XML_DTD
2775
2776/* The idea here is to avoid using stack for each IGNORE section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002777 the whole file is parsed with one call.
2778*/
2779static enum XML_Error PTRCALL
2780ignoreSectionProcessor(XML_Parser parser,
2781 const char *start,
2782 const char *end,
2783 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002784{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002785 enum XML_Error result = doIgnoreSection(parser, encoding, &start,
2786 end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002787 if (start) {
2788 processor = prologProcessor;
2789 return prologProcessor(parser, start, end, endPtr);
2790 }
2791 return result;
2792}
2793
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002794/* startPtr gets set to non-null is the section is closed, and to null
2795 if the section is not yet closed.
2796*/
2797static enum XML_Error
2798doIgnoreSection(XML_Parser parser,
2799 const ENCODING *enc,
2800 const char **startPtr,
2801 const char *end,
2802 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002803{
2804 const char *next;
2805 int tok;
2806 const char *s = *startPtr;
2807 const char **eventPP;
2808 const char **eventEndPP;
2809 if (enc == encoding) {
2810 eventPP = &eventPtr;
2811 *eventPP = s;
2812 eventEndPP = &eventEndPtr;
2813 }
2814 else {
2815 eventPP = &(openInternalEntities->internalEventPtr);
2816 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2817 }
2818 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002819 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002820 tok = XmlIgnoreSectionTok(enc, s, end, &next);
2821 *eventEndPP = next;
2822 switch (tok) {
2823 case XML_TOK_IGNORE_SECT:
2824 if (defaultHandler)
2825 reportDefault(parser, enc, s, next);
2826 *startPtr = next;
2827 return XML_ERROR_NONE;
2828 case XML_TOK_INVALID:
2829 *eventPP = next;
2830 return XML_ERROR_INVALID_TOKEN;
2831 case XML_TOK_PARTIAL_CHAR:
2832 if (nextPtr) {
2833 *nextPtr = s;
2834 return XML_ERROR_NONE;
2835 }
2836 return XML_ERROR_PARTIAL_CHAR;
2837 case XML_TOK_PARTIAL:
2838 case XML_TOK_NONE:
2839 if (nextPtr) {
2840 *nextPtr = s;
2841 return XML_ERROR_NONE;
2842 }
2843 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2844 default:
2845 *eventPP = next;
2846 return XML_ERROR_UNEXPECTED_STATE;
2847 }
2848 /* not reached */
2849}
2850
2851#endif /* XML_DTD */
2852
2853static enum XML_Error
2854initializeEncoding(XML_Parser parser)
2855{
2856 const char *s;
2857#ifdef XML_UNICODE
2858 char encodingBuf[128];
2859 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002860 s = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002861 else {
2862 int i;
2863 for (i = 0; protocolEncodingName[i]; i++) {
2864 if (i == sizeof(encodingBuf) - 1
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002865 || (protocolEncodingName[i] & ~0x7f) != 0) {
2866 encodingBuf[0] = '\0';
2867 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002868 }
2869 encodingBuf[i] = (char)protocolEncodingName[i];
2870 }
2871 encodingBuf[i] = '\0';
2872 s = encodingBuf;
2873 }
2874#else
2875 s = protocolEncodingName;
2876#endif
2877 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
2878 return XML_ERROR_NONE;
2879 return handleUnknownEncoding(parser, protocolEncodingName);
2880}
2881
2882static enum XML_Error
2883processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002884 const char *s, const char *next)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002885{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002886 const char *encodingName = NULL;
2887 const XML_Char *storedEncName = NULL;
2888 const ENCODING *newEncoding = NULL;
2889 const char *version = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002890 const char *versionend;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002891 const XML_Char *storedversion = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002892 int standalone = -1;
2893 if (!(ns
2894 ? XmlParseXmlDeclNS
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002895 : XmlParseXmlDecl)(isGeneralTextEntity,
2896 encoding,
2897 s,
2898 next,
2899 &eventPtr,
2900 &version,
2901 &versionend,
2902 &encodingName,
2903 &newEncoding,
2904 &standalone))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002905 return XML_ERROR_SYNTAX;
2906 if (!isGeneralTextEntity && standalone == 1) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002907 _dtd->standalone = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002908#ifdef XML_DTD
2909 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
2910 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
2911#endif /* XML_DTD */
2912 }
2913 if (xmlDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002914 if (encodingName != NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002915 storedEncName = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002916 encoding,
2917 encodingName,
2918 encodingName
2919 + XmlNameLength(encoding, encodingName));
2920 if (!storedEncName)
2921 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002922 poolFinish(&temp2Pool);
2923 }
2924 if (version) {
2925 storedversion = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002926 encoding,
2927 version,
2928 versionend - encoding->minBytesPerChar);
2929 if (!storedversion)
2930 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002931 }
2932 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
2933 }
2934 else if (defaultHandler)
2935 reportDefault(parser, encoding, s, next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002936 if (protocolEncodingName == NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002937 if (newEncoding) {
2938 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002939 eventPtr = encodingName;
2940 return XML_ERROR_INCORRECT_ENCODING;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002941 }
2942 encoding = newEncoding;
2943 }
2944 else if (encodingName) {
2945 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002946 if (!storedEncName) {
2947 storedEncName = poolStoreString(
2948 &temp2Pool, encoding, encodingName,
2949 encodingName + XmlNameLength(encoding, encodingName));
2950 if (!storedEncName)
2951 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002952 }
2953 result = handleUnknownEncoding(parser, storedEncName);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002954 poolClear(&temp2Pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002955 if (result == XML_ERROR_UNKNOWN_ENCODING)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002956 eventPtr = encodingName;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002957 return result;
2958 }
2959 }
2960
2961 if (storedEncName || storedversion)
2962 poolClear(&temp2Pool);
2963
2964 return XML_ERROR_NONE;
2965}
2966
2967static enum XML_Error
2968handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
2969{
2970 if (unknownEncodingHandler) {
2971 XML_Encoding info;
2972 int i;
2973 for (i = 0; i < 256; i++)
2974 info.map[i] = -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002975 info.convert = NULL;
2976 info.data = NULL;
2977 info.release = NULL;
2978 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
2979 &info)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002980 ENCODING *enc;
2981 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
2982 if (!unknownEncodingMem) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002983 if (info.release)
2984 info.release(info.data);
2985 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002986 }
2987 enc = (ns
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002988 ? XmlInitUnknownEncodingNS
2989 : XmlInitUnknownEncoding)(unknownEncodingMem,
2990 info.map,
2991 info.convert,
2992 info.data);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002993 if (enc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002994 unknownEncodingData = info.data;
2995 unknownEncodingRelease = info.release;
2996 encoding = enc;
2997 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002998 }
2999 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003000 if (info.release != NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003001 info.release(info.data);
3002 }
3003 return XML_ERROR_UNKNOWN_ENCODING;
3004}
3005
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003006static enum XML_Error PTRCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003007prologInitProcessor(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003008 const char *s,
3009 const char *end,
3010 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003011{
3012 enum XML_Error result = initializeEncoding(parser);
3013 if (result != XML_ERROR_NONE)
3014 return result;
3015 processor = prologProcessor;
3016 return prologProcessor(parser, s, end, nextPtr);
3017}
3018
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003019#ifdef XML_DTD
3020
3021static enum XML_Error PTRCALL
3022externalParEntInitProcessor(XML_Parser parser,
3023 const char *s,
3024 const char *end,
3025 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003026{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003027 enum XML_Error result = initializeEncoding(parser);
3028 if (result != XML_ERROR_NONE)
3029 return result;
3030
3031 /* we know now that XML_Parse(Buffer) has been called,
3032 so we consider the external parameter entity read */
3033 _dtd->paramEntityRead = XML_TRUE;
3034
3035 if (prologState.inEntityValue) {
3036 processor = entityValueInitProcessor;
3037 return entityValueInitProcessor(parser, s, end, nextPtr);
3038 }
3039 else {
3040 processor = externalParEntProcessor;
3041 return externalParEntProcessor(parser, s, end, nextPtr);
3042 }
3043}
3044
3045static enum XML_Error PTRCALL
3046entityValueInitProcessor(XML_Parser parser,
3047 const char *s,
3048 const char *end,
3049 const char **nextPtr)
3050{
3051 const char *start = s;
3052 const char *next = s;
3053 int tok;
3054
3055 for (;;) {
3056 tok = XmlPrologTok(encoding, start, end, &next);
3057 if (tok <= 0) {
3058 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3059 *nextPtr = s;
3060 return XML_ERROR_NONE;
3061 }
3062 switch (tok) {
3063 case XML_TOK_INVALID:
3064 return XML_ERROR_INVALID_TOKEN;
3065 case XML_TOK_PARTIAL:
3066 return XML_ERROR_UNCLOSED_TOKEN;
3067 case XML_TOK_PARTIAL_CHAR:
3068 return XML_ERROR_PARTIAL_CHAR;
3069 case XML_TOK_NONE: /* start == end */
3070 default:
3071 break;
3072 }
3073 return storeEntityValue(parser, encoding, s, end);
3074 }
3075 else if (tok == XML_TOK_XML_DECL) {
3076 enum XML_Error result = processXmlDecl(parser, 0, start, next);
3077 if (result != XML_ERROR_NONE)
3078 return result;
3079 if (nextPtr) *nextPtr = next;
3080 /* stop scanning for text declaration - we found one */
3081 processor = entityValueProcessor;
3082 return entityValueProcessor(parser, next, end, nextPtr);
3083 }
3084 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3085 return XML_TOK_NONE on the next call, which would then cause the
3086 function to exit with *nextPtr set to s - that is what we want for other
3087 tokens, but not for the BOM - we would rather like to skip it;
3088 then, when this routine is entered the next time, XmlPrologTok will
3089 return XML_TOK_INVALID, since the BOM is still in the buffer
3090 */
3091 else if (tok == XML_TOK_BOM && next == end && nextPtr) {
3092 *nextPtr = next;
3093 return XML_ERROR_NONE;
3094 }
3095 start = next;
3096 }
3097}
3098
3099static enum XML_Error PTRCALL
3100externalParEntProcessor(XML_Parser parser,
3101 const char *s,
3102 const char *end,
3103 const char **nextPtr)
3104{
3105 const char *start = s;
3106 const char *next = s;
3107 int tok;
3108
3109 tok = XmlPrologTok(encoding, start, end, &next);
3110 if (tok <= 0) {
3111 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3112 *nextPtr = s;
3113 return XML_ERROR_NONE;
3114 }
3115 switch (tok) {
3116 case XML_TOK_INVALID:
3117 return XML_ERROR_INVALID_TOKEN;
3118 case XML_TOK_PARTIAL:
3119 return XML_ERROR_UNCLOSED_TOKEN;
3120 case XML_TOK_PARTIAL_CHAR:
3121 return XML_ERROR_PARTIAL_CHAR;
3122 case XML_TOK_NONE: /* start == end */
3123 default:
3124 break;
3125 }
3126 }
3127 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3128 However, when parsing an external subset, doProlog will not accept a BOM
3129 as valid, and report a syntax error, so we have to skip the BOM
3130 */
3131 else if (tok == XML_TOK_BOM) {
3132 s = next;
3133 tok = XmlPrologTok(encoding, s, end, &next);
3134 }
3135
3136 processor = prologProcessor;
3137 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3138}
3139
3140static enum XML_Error PTRCALL
3141entityValueProcessor(XML_Parser parser,
3142 const char *s,
3143 const char *end,
3144 const char **nextPtr)
3145{
3146 const char *start = s;
3147 const char *next = s;
3148 const ENCODING *enc = encoding;
3149 int tok;
3150
3151 for (;;) {
3152 tok = XmlPrologTok(enc, start, end, &next);
3153 if (tok <= 0) {
3154 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3155 *nextPtr = s;
3156 return XML_ERROR_NONE;
3157 }
3158 switch (tok) {
3159 case XML_TOK_INVALID:
3160 return XML_ERROR_INVALID_TOKEN;
3161 case XML_TOK_PARTIAL:
3162 return XML_ERROR_UNCLOSED_TOKEN;
3163 case XML_TOK_PARTIAL_CHAR:
3164 return XML_ERROR_PARTIAL_CHAR;
3165 case XML_TOK_NONE: /* start == end */
3166 default:
3167 break;
3168 }
3169 return storeEntityValue(parser, enc, s, end);
3170 }
3171 start = next;
3172 }
3173}
3174
3175#endif /* XML_DTD */
3176
3177static enum XML_Error PTRCALL
3178prologProcessor(XML_Parser parser,
3179 const char *s,
3180 const char *end,
3181 const char **nextPtr)
3182{
3183 const char *next = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003184 int tok = XmlPrologTok(encoding, s, end, &next);
3185 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3186}
3187
3188static enum XML_Error
3189doProlog(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003190 const ENCODING *enc,
3191 const char *s,
3192 const char *end,
3193 int tok,
3194 const char *next,
3195 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003196{
3197#ifdef XML_DTD
3198 static const XML_Char externalSubsetName[] = { '#' , '\0' };
3199#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003200 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3201 static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3202 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3203 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3204 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3205 static const XML_Char atypeENTITIES[] =
3206 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3207 static const XML_Char atypeNMTOKEN[] = {
3208 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3209 static const XML_Char atypeNMTOKENS[] = {
3210 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3211 static const XML_Char notationPrefix[] = {
3212 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3213 static const XML_Char enumValueSep[] = { '|', '\0' };
3214 static const XML_Char enumValueStart[] = { '(', '\0' };
3215
3216 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003217
3218 const char **eventPP;
3219 const char **eventEndPP;
3220 enum XML_Content_Quant quant;
3221
3222 if (enc == encoding) {
3223 eventPP = &eventPtr;
3224 eventEndPP = &eventEndPtr;
3225 }
3226 else {
3227 eventPP = &(openInternalEntities->internalEventPtr);
3228 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3229 }
3230 for (;;) {
3231 int role;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003232 XML_Bool handleDefault = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003233 *eventPP = s;
3234 *eventEndPP = next;
3235 if (tok <= 0) {
3236 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003237 *nextPtr = s;
3238 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003239 }
3240 switch (tok) {
3241 case XML_TOK_INVALID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003242 *eventPP = next;
3243 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003244 case XML_TOK_PARTIAL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003245 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003246 case XML_TOK_PARTIAL_CHAR:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003247 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003248 case XML_TOK_NONE:
3249#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003250 if (enc != encoding)
3251 return XML_ERROR_NONE;
3252 if (isParamEntity) {
3253 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3254 == XML_ROLE_ERROR)
3255 return XML_ERROR_SYNTAX;
3256 return XML_ERROR_NONE;
3257 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003258#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003259 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003260 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003261 tok = -tok;
3262 next = end;
3263 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003264 }
3265 }
3266 role = XmlTokenRole(&prologState, tok, s, next, enc);
3267 switch (role) {
3268 case XML_ROLE_XML_DECL:
3269 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003270 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3271 if (result != XML_ERROR_NONE)
3272 return result;
3273 enc = encoding;
3274 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003275 }
3276 break;
3277 case XML_ROLE_DOCTYPE_NAME:
3278 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003279 doctypeName = poolStoreString(&tempPool, enc, s, next);
3280 if (!doctypeName)
3281 return XML_ERROR_NO_MEMORY;
3282 poolFinish(&tempPool);
3283 doctypePubid = NULL;
3284 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003285 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003286 doctypeSysid = NULL; /* always initialize to NULL */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003287 break;
3288 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3289 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003290 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3291 doctypePubid, 1);
3292 doctypeName = NULL;
3293 poolClear(&tempPool);
3294 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003295 }
3296 break;
3297#ifdef XML_DTD
3298 case XML_ROLE_TEXT_DECL:
3299 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003300 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3301 if (result != XML_ERROR_NONE)
3302 return result;
3303 enc = encoding;
3304 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003305 }
3306 break;
3307#endif /* XML_DTD */
3308 case XML_ROLE_DOCTYPE_PUBLIC_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003309#ifdef XML_DTD
3310 useForeignDTD = XML_FALSE;
3311#endif /* XML_DTD */
3312 dtd->hasParamEntityRefs = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003313 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003314 doctypePubid = poolStoreString(&tempPool, enc,
3315 s + enc->minBytesPerChar,
3316 next - enc->minBytesPerChar);
3317 if (!doctypePubid)
3318 return XML_ERROR_NO_MEMORY;
3319 poolFinish(&tempPool);
3320 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003321 }
3322#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003323 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3324 externalSubsetName,
3325 sizeof(ENTITY));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003326 if (!declEntity)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003327 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003328#endif /* XML_DTD */
3329 /* fall through */
3330 case XML_ROLE_ENTITY_PUBLIC_ID:
3331 if (!XmlIsPublicId(enc, s, next, eventPP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003332 return XML_ERROR_SYNTAX;
3333 if (dtd->keepProcessing && declEntity) {
3334 XML_Char *tem = poolStoreString(&dtd->pool,
3335 enc,
3336 s + enc->minBytesPerChar,
3337 next - enc->minBytesPerChar);
3338 if (!tem)
3339 return XML_ERROR_NO_MEMORY;
3340 normalizePublicId(tem);
3341 declEntity->publicId = tem;
3342 poolFinish(&dtd->pool);
3343 if (entityDeclHandler)
3344 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003345 }
3346 break;
3347 case XML_ROLE_DOCTYPE_CLOSE:
3348 if (doctypeName) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003349 startDoctypeDeclHandler(handlerArg, doctypeName,
3350 doctypeSysid, doctypePubid, 0);
3351 poolClear(&tempPool);
3352 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003353 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003354 /* doctypeSysid will be non-NULL in the case of a previous
3355 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3356 was not set, indicating an external subset
3357 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003358#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003359 if (doctypeSysid || useForeignDTD) {
3360 dtd->hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */
3361 if (paramEntityParsing && externalEntityRefHandler) {
3362 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3363 externalSubsetName,
3364 sizeof(ENTITY));
3365 if (!entity)
3366 return XML_ERROR_NO_MEMORY;
3367 if (useForeignDTD)
3368 entity->base = curBase;
3369 dtd->paramEntityRead = XML_FALSE;
3370 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3371 0,
3372 entity->base,
3373 entity->systemId,
3374 entity->publicId))
3375 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3376 if (dtd->paramEntityRead &&
3377 !dtd->standalone &&
3378 notStandaloneHandler &&
3379 !notStandaloneHandler(handlerArg))
3380 return XML_ERROR_NOT_STANDALONE;
3381 /* end of DTD - no need to update dtd->keepProcessing */
3382 }
3383 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003384 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003385#endif /* XML_DTD */
3386 if (endDoctypeDeclHandler) {
3387 endDoctypeDeclHandler(handlerArg);
3388 handleDefault = XML_FALSE;
3389 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003390 break;
3391 case XML_ROLE_INSTANCE_START:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003392#ifdef XML_DTD
3393 /* if there is no DOCTYPE declaration then now is the
3394 last chance to read the foreign DTD
3395 */
3396 if (useForeignDTD) {
3397 dtd->hasParamEntityRefs = XML_TRUE;
3398 if (paramEntityParsing && externalEntityRefHandler) {
3399 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3400 externalSubsetName,
3401 sizeof(ENTITY));
3402 if (!entity)
3403 return XML_ERROR_NO_MEMORY;
3404 entity->base = curBase;
3405 dtd->paramEntityRead = XML_FALSE;
3406 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3407 0,
3408 entity->base,
3409 entity->systemId,
3410 entity->publicId))
3411 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3412 if (dtd->paramEntityRead &&
3413 !dtd->standalone &&
3414 notStandaloneHandler &&
3415 !notStandaloneHandler(handlerArg))
3416 return XML_ERROR_NOT_STANDALONE;
3417 /* end of DTD - no need to update dtd->keepProcessing */
3418 }
3419 }
3420#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003421 processor = contentProcessor;
3422 return contentProcessor(parser, s, end, nextPtr);
3423 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3424 declElementType = getElementType(parser, enc, s, next);
3425 if (!declElementType)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003426 return XML_ERROR_NO_MEMORY;
3427 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003428 case XML_ROLE_ATTRIBUTE_NAME:
3429 declAttributeId = getAttributeId(parser, enc, s, next);
3430 if (!declAttributeId)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003431 return XML_ERROR_NO_MEMORY;
3432 declAttributeIsCdata = XML_FALSE;
3433 declAttributeType = NULL;
3434 declAttributeIsId = XML_FALSE;
3435 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003436 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003437 declAttributeIsCdata = XML_TRUE;
3438 declAttributeType = atypeCDATA;
3439 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003440 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003441 declAttributeIsId = XML_TRUE;
3442 declAttributeType = atypeID;
3443 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003444 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003445 declAttributeType = atypeIDREF;
3446 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003447 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003448 declAttributeType = atypeIDREFS;
3449 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003450 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003451 declAttributeType = atypeENTITY;
3452 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003453 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003454 declAttributeType = atypeENTITIES;
3455 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003456 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003457 declAttributeType = atypeNMTOKEN;
3458 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003459 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003460 declAttributeType = atypeNMTOKENS;
3461 checkAttListDeclHandler:
3462 if (dtd->keepProcessing && attlistDeclHandler)
3463 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003464 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003465 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3466 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003467 if (dtd->keepProcessing && attlistDeclHandler) {
3468 const XML_Char *prefix;
3469 if (declAttributeType) {
3470 prefix = enumValueSep;
3471 }
3472 else {
3473 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3474 ? notationPrefix
3475 : enumValueStart);
3476 }
3477 if (!poolAppendString(&tempPool, prefix))
3478 return XML_ERROR_NO_MEMORY;
3479 if (!poolAppend(&tempPool, enc, s, next))
3480 return XML_ERROR_NO_MEMORY;
3481 declAttributeType = tempPool.start;
3482 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003483 }
3484 break;
3485 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3486 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003487 if (dtd->keepProcessing) {
3488 if (!defineAttribute(declElementType, declAttributeId,
3489 declAttributeIsCdata, declAttributeIsId, 0,
3490 parser))
3491 return XML_ERROR_NO_MEMORY;
3492 if (attlistDeclHandler && declAttributeType) {
3493 if (*declAttributeType == XML_T('(')
3494 || (*declAttributeType == XML_T('N')
3495 && declAttributeType[1] == XML_T('O'))) {
3496 /* Enumerated or Notation type */
3497 if (!poolAppendChar(&tempPool, XML_T(')'))
3498 || !poolAppendChar(&tempPool, XML_T('\0')))
3499 return XML_ERROR_NO_MEMORY;
3500 declAttributeType = tempPool.start;
3501 poolFinish(&tempPool);
3502 }
3503 *eventEndPP = s;
3504 attlistDeclHandler(handlerArg, declElementType->name,
3505 declAttributeId->name, declAttributeType,
3506 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
3507 poolClear(&tempPool);
3508 handleDefault = XML_FALSE;
3509 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003510 }
3511 break;
3512 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3513 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003514 if (dtd->keepProcessing) {
3515 const XML_Char *attVal;
3516 enum XML_Error result
3517 = storeAttributeValue(parser, enc, declAttributeIsCdata,
3518 s + enc->minBytesPerChar,
3519 next - enc->minBytesPerChar,
3520 &dtd->pool);
3521 if (result)
3522 return result;
3523 attVal = poolStart(&dtd->pool);
3524 poolFinish(&dtd->pool);
3525 /* ID attributes aren't allowed to have a default */
3526 if (!defineAttribute(declElementType, declAttributeId,
3527 declAttributeIsCdata, XML_FALSE, attVal, parser))
3528 return XML_ERROR_NO_MEMORY;
3529 if (attlistDeclHandler && declAttributeType) {
3530 if (*declAttributeType == XML_T('(')
3531 || (*declAttributeType == XML_T('N')
3532 && declAttributeType[1] == XML_T('O'))) {
3533 /* Enumerated or Notation type */
3534 if (!poolAppendChar(&tempPool, XML_T(')'))
3535 || !poolAppendChar(&tempPool, XML_T('\0')))
3536 return XML_ERROR_NO_MEMORY;
3537 declAttributeType = tempPool.start;
3538 poolFinish(&tempPool);
3539 }
3540 *eventEndPP = s;
3541 attlistDeclHandler(handlerArg, declElementType->name,
3542 declAttributeId->name, declAttributeType,
3543 attVal,
3544 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
3545 poolClear(&tempPool);
3546 handleDefault = XML_FALSE;
3547 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003548 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003549 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003550 case XML_ROLE_ENTITY_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003551 if (dtd->keepProcessing) {
3552 enum XML_Error result = storeEntityValue(parser, enc,
3553 s + enc->minBytesPerChar,
3554 next - enc->minBytesPerChar);
3555 if (declEntity) {
3556 declEntity->textPtr = poolStart(&dtd->entityValuePool);
3557 declEntity->textLen = poolLength(&dtd->entityValuePool);
3558 poolFinish(&dtd->entityValuePool);
3559 if (entityDeclHandler) {
3560 *eventEndPP = s;
3561 entityDeclHandler(handlerArg,
3562 declEntity->name,
3563 declEntity->is_param,
3564 declEntity->textPtr,
3565 declEntity->textLen,
3566 curBase, 0, 0, 0);
3567 handleDefault = XML_FALSE;
3568 }
3569 }
3570 else
3571 poolDiscard(&dtd->entityValuePool);
3572 if (result != XML_ERROR_NONE)
3573 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003574 }
3575 break;
3576 case XML_ROLE_DOCTYPE_SYSTEM_ID:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003577#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003578 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003579#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003580 dtd->hasParamEntityRefs = XML_TRUE;
3581 if (startDoctypeDeclHandler) {
3582 doctypeSysid = poolStoreString(&tempPool, enc,
3583 s + enc->minBytesPerChar,
3584 next - enc->minBytesPerChar);
3585 if (doctypeSysid == NULL)
3586 return XML_ERROR_NO_MEMORY;
3587 poolFinish(&tempPool);
3588 handleDefault = XML_FALSE;
3589 }
3590#ifdef XML_DTD
3591 else
3592 /* use externalSubsetName to make doctypeSysid non-NULL
3593 for the case where no startDoctypeDeclHandler is set */
3594 doctypeSysid = externalSubsetName;
3595#endif /* XML_DTD */
3596 if (!dtd->standalone
3597#ifdef XML_DTD
3598 && !paramEntityParsing
3599#endif /* XML_DTD */
3600 && notStandaloneHandler
3601 && !notStandaloneHandler(handlerArg))
3602 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003603#ifndef XML_DTD
3604 break;
3605#else /* XML_DTD */
3606 if (!declEntity) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003607 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3608 externalSubsetName,
3609 sizeof(ENTITY));
3610 if (!declEntity)
3611 return XML_ERROR_NO_MEMORY;
3612 declEntity->publicId = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003613 }
3614 /* fall through */
3615#endif /* XML_DTD */
3616 case XML_ROLE_ENTITY_SYSTEM_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003617 if (dtd->keepProcessing && declEntity) {
3618 declEntity->systemId = poolStoreString(&dtd->pool, enc,
3619 s + enc->minBytesPerChar,
3620 next - enc->minBytesPerChar);
3621 if (!declEntity->systemId)
3622 return XML_ERROR_NO_MEMORY;
3623 declEntity->base = curBase;
3624 poolFinish(&dtd->pool);
3625 if (entityDeclHandler)
3626 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003627 }
3628 break;
3629 case XML_ROLE_ENTITY_COMPLETE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003630 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
3631 *eventEndPP = s;
3632 entityDeclHandler(handlerArg,
3633 declEntity->name,
3634 declEntity->is_param,
3635 0,0,
3636 declEntity->base,
3637 declEntity->systemId,
3638 declEntity->publicId,
3639 0);
3640 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003641 }
3642 break;
3643 case XML_ROLE_ENTITY_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003644 if (dtd->keepProcessing && declEntity) {
3645 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
3646 if (!declEntity->notation)
3647 return XML_ERROR_NO_MEMORY;
3648 poolFinish(&dtd->pool);
3649 if (unparsedEntityDeclHandler) {
3650 *eventEndPP = s;
3651 unparsedEntityDeclHandler(handlerArg,
3652 declEntity->name,
3653 declEntity->base,
3654 declEntity->systemId,
3655 declEntity->publicId,
3656 declEntity->notation);
3657 handleDefault = XML_FALSE;
3658 }
3659 else if (entityDeclHandler) {
3660 *eventEndPP = s;
3661 entityDeclHandler(handlerArg,
3662 declEntity->name,
3663 0,0,0,
3664 declEntity->base,
3665 declEntity->systemId,
3666 declEntity->publicId,
3667 declEntity->notation);
3668 handleDefault = XML_FALSE;
3669 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003670 }
3671 break;
3672 case XML_ROLE_GENERAL_ENTITY_NAME:
3673 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003674 if (XmlPredefinedEntityName(enc, s, next)) {
3675 declEntity = NULL;
3676 break;
3677 }
3678 if (dtd->keepProcessing) {
3679 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
3680 if (!name)
3681 return XML_ERROR_NO_MEMORY;
3682 declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
3683 sizeof(ENTITY));
3684 if (!declEntity)
3685 return XML_ERROR_NO_MEMORY;
3686 if (declEntity->name != name) {
3687 poolDiscard(&dtd->pool);
3688 declEntity = NULL;
3689 }
3690 else {
3691 poolFinish(&dtd->pool);
3692 declEntity->publicId = NULL;
3693 declEntity->is_param = XML_FALSE;
3694 /* if we have a parent parser or are reading an internal parameter
3695 entity, then the entity declaration is not considered "internal"
3696 */
3697 declEntity->is_internal = !(parentParser || openInternalEntities);
3698 if (entityDeclHandler)
3699 handleDefault = XML_FALSE;
3700 }
3701 }
3702 else {
3703 poolDiscard(&dtd->pool);
3704 declEntity = NULL;
3705 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003706 }
3707 break;
3708 case XML_ROLE_PARAM_ENTITY_NAME:
3709#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003710 if (dtd->keepProcessing) {
3711 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
3712 if (!name)
3713 return XML_ERROR_NO_MEMORY;
3714 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3715 name, sizeof(ENTITY));
3716 if (!declEntity)
3717 return XML_ERROR_NO_MEMORY;
3718 if (declEntity->name != name) {
3719 poolDiscard(&dtd->pool);
3720 declEntity = NULL;
3721 }
3722 else {
3723 poolFinish(&dtd->pool);
3724 declEntity->publicId = NULL;
3725 declEntity->is_param = XML_TRUE;
3726 /* if we have a parent parser or are reading an internal parameter
3727 entity, then the entity declaration is not considered "internal"
3728 */
3729 declEntity->is_internal = !(parentParser || openInternalEntities);
3730 if (entityDeclHandler)
3731 handleDefault = XML_FALSE;
3732 }
3733 }
3734 else {
3735 poolDiscard(&dtd->pool);
3736 declEntity = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003737 }
3738#else /* not XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003739 declEntity = NULL;
3740#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003741 break;
3742 case XML_ROLE_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003743 declNotationPublicId = NULL;
3744 declNotationName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003745 if (notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003746 declNotationName = poolStoreString(&tempPool, enc, s, next);
3747 if (!declNotationName)
3748 return XML_ERROR_NO_MEMORY;
3749 poolFinish(&tempPool);
3750 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003751 }
3752 break;
3753 case XML_ROLE_NOTATION_PUBLIC_ID:
3754 if (!XmlIsPublicId(enc, s, next, eventPP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003755 return XML_ERROR_SYNTAX;
3756 if (declNotationName) { /* means notationDeclHandler != NULL */
3757 XML_Char *tem = poolStoreString(&tempPool,
3758 enc,
3759 s + enc->minBytesPerChar,
3760 next - enc->minBytesPerChar);
3761 if (!tem)
3762 return XML_ERROR_NO_MEMORY;
3763 normalizePublicId(tem);
3764 declNotationPublicId = tem;
3765 poolFinish(&tempPool);
3766 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003767 }
3768 break;
3769 case XML_ROLE_NOTATION_SYSTEM_ID:
3770 if (declNotationName && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003771 const XML_Char *systemId
3772 = poolStoreString(&tempPool, enc,
3773 s + enc->minBytesPerChar,
3774 next - enc->minBytesPerChar);
3775 if (!systemId)
3776 return XML_ERROR_NO_MEMORY;
3777 *eventEndPP = s;
3778 notationDeclHandler(handlerArg,
3779 declNotationName,
3780 curBase,
3781 systemId,
3782 declNotationPublicId);
3783 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003784 }
3785 poolClear(&tempPool);
3786 break;
3787 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
3788 if (declNotationPublicId && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003789 *eventEndPP = s;
3790 notationDeclHandler(handlerArg,
3791 declNotationName,
3792 curBase,
3793 0,
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_ERROR:
3800 switch (tok) {
3801 case XML_TOK_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003802 return XML_ERROR_PARAM_ENTITY_REF;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003803 case XML_TOK_XML_DECL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003804 return XML_ERROR_MISPLACED_XML_PI;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003805 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003806 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003807 }
3808#ifdef XML_DTD
3809 case XML_ROLE_IGNORE_SECT:
3810 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003811 enum XML_Error result;
3812 if (defaultHandler)
3813 reportDefault(parser, enc, s, next);
3814 handleDefault = XML_FALSE;
3815 result = doIgnoreSection(parser, enc, &next, end, nextPtr);
3816 if (!next) {
3817 processor = ignoreSectionProcessor;
3818 return result;
3819 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003820 }
3821 break;
3822#endif /* XML_DTD */
3823 case XML_ROLE_GROUP_OPEN:
3824 if (prologState.level >= groupSize) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003825 if (groupSize) {
3826 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
3827 if (temp == NULL)
3828 return XML_ERROR_NO_MEMORY;
3829 groupConnector = temp;
3830 if (dtd->scaffIndex) {
3831 int *temp = (int *)REALLOC(dtd->scaffIndex,
3832 groupSize * sizeof(int));
3833 if (temp == NULL)
3834 return XML_ERROR_NO_MEMORY;
3835 dtd->scaffIndex = temp;
3836 }
3837 }
3838 else {
3839 groupConnector = (char *)MALLOC(groupSize = 32);
3840 if (!groupConnector)
3841 return XML_ERROR_NO_MEMORY;
3842 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003843 }
3844 groupConnector[prologState.level] = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003845 if (dtd->in_eldecl) {
3846 int myindex = nextScaffoldPart(parser);
3847 if (myindex < 0)
3848 return XML_ERROR_NO_MEMORY;
3849 dtd->scaffIndex[dtd->scaffLevel] = myindex;
3850 dtd->scaffLevel++;
3851 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
3852 if (elementDeclHandler)
3853 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003854 }
3855 break;
3856 case XML_ROLE_GROUP_SEQUENCE:
3857 if (groupConnector[prologState.level] == '|')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003858 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003859 groupConnector[prologState.level] = ',';
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003860 if (dtd->in_eldecl && elementDeclHandler)
3861 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003862 break;
3863 case XML_ROLE_GROUP_CHOICE:
3864 if (groupConnector[prologState.level] == ',')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003865 return XML_ERROR_SYNTAX;
3866 if (dtd->in_eldecl
3867 && !groupConnector[prologState.level]
3868 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
3869 != XML_CTYPE_MIXED)
3870 ) {
3871 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
3872 = XML_CTYPE_CHOICE;
3873 if (elementDeclHandler)
3874 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003875 }
3876 groupConnector[prologState.level] = '|';
3877 break;
3878 case XML_ROLE_PARAM_ENTITY_REF:
3879#ifdef XML_DTD
3880 case XML_ROLE_INNER_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003881 /* PE references in internal subset are
3882 not allowed within declarations */
3883 if (prologState.documentEntity &&
3884 role == XML_ROLE_INNER_PARAM_ENTITY_REF)
3885 return XML_ERROR_PARAM_ENTITY_REF;
3886 dtd->hasParamEntityRefs = XML_TRUE;
3887 if (!paramEntityParsing)
3888 dtd->keepProcessing = dtd->standalone;
3889 else {
3890 const XML_Char *name;
3891 ENTITY *entity;
3892 name = poolStoreString(&dtd->pool, enc,
3893 s + enc->minBytesPerChar,
3894 next - enc->minBytesPerChar);
3895 if (!name)
3896 return XML_ERROR_NO_MEMORY;
3897 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
3898 poolDiscard(&dtd->pool);
3899 /* first, determine if a check for an existing declaration is needed;
3900 if yes, check that the entity exists, and that it is internal,
3901 otherwise call the skipped entity handler
3902 */
3903 if (prologState.documentEntity &&
3904 (dtd->standalone
3905 ? !openInternalEntities
3906 : !dtd->hasParamEntityRefs)) {
3907 if (!entity)
3908 return XML_ERROR_UNDEFINED_ENTITY;
3909 else if (!entity->is_internal)
3910 return XML_ERROR_ENTITY_DECLARED_IN_PE;
3911 }
3912 else if (!entity) {
3913 dtd->keepProcessing = dtd->standalone;
3914 /* cannot report skipped entities in declarations */
3915 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
3916 skippedEntityHandler(handlerArg, name, 1);
3917 handleDefault = XML_FALSE;
3918 }
3919 break;
3920 }
3921 if (entity->open)
3922 return XML_ERROR_RECURSIVE_ENTITY_REF;
3923 if (entity->textPtr) {
3924 enum XML_Error result;
3925 result = processInternalParamEntity(parser, entity);
3926 if (result != XML_ERROR_NONE)
3927 return result;
3928 handleDefault = XML_FALSE;
3929 break;
3930 }
3931 if (externalEntityRefHandler) {
3932 dtd->paramEntityRead = XML_FALSE;
3933 entity->open = XML_TRUE;
3934 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3935 0,
3936 entity->base,
3937 entity->systemId,
3938 entity->publicId)) {
3939 entity->open = XML_FALSE;
3940 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3941 }
3942 entity->open = XML_FALSE;
3943 handleDefault = XML_FALSE;
3944 if (!dtd->paramEntityRead) {
3945 dtd->keepProcessing = dtd->standalone;
3946 break;
3947 }
3948 }
3949 else {
3950 dtd->keepProcessing = dtd->standalone;
3951 break;
3952 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003953 }
3954#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003955 if (!dtd->standalone &&
3956 notStandaloneHandler &&
3957 !notStandaloneHandler(handlerArg))
3958 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003959 break;
3960
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003961 /* Element declaration stuff */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003962
3963 case XML_ROLE_ELEMENT_NAME:
3964 if (elementDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003965 declElementType = getElementType(parser, enc, s, next);
3966 if (!declElementType)
3967 return XML_ERROR_NO_MEMORY;
3968 dtd->scaffLevel = 0;
3969 dtd->scaffCount = 0;
3970 dtd->in_eldecl = XML_TRUE;
3971 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003972 }
3973 break;
3974
3975 case XML_ROLE_CONTENT_ANY:
3976 case XML_ROLE_CONTENT_EMPTY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003977 if (dtd->in_eldecl) {
3978 if (elementDeclHandler) {
3979 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
3980 if (!content)
3981 return XML_ERROR_NO_MEMORY;
3982 content->quant = XML_CQUANT_NONE;
3983 content->name = NULL;
3984 content->numchildren = 0;
3985 content->children = NULL;
3986 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
3987 XML_CTYPE_ANY :
3988 XML_CTYPE_EMPTY);
3989 *eventEndPP = s;
3990 elementDeclHandler(handlerArg, declElementType->name, content);
3991 handleDefault = XML_FALSE;
3992 }
3993 dtd->in_eldecl = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003994 }
3995 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003996
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003997 case XML_ROLE_CONTENT_PCDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003998 if (dtd->in_eldecl) {
3999 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4000 = XML_CTYPE_MIXED;
4001 if (elementDeclHandler)
4002 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004003 }
4004 break;
4005
4006 case XML_ROLE_CONTENT_ELEMENT:
4007 quant = XML_CQUANT_NONE;
4008 goto elementContent;
4009 case XML_ROLE_CONTENT_ELEMENT_OPT:
4010 quant = XML_CQUANT_OPT;
4011 goto elementContent;
4012 case XML_ROLE_CONTENT_ELEMENT_REP:
4013 quant = XML_CQUANT_REP;
4014 goto elementContent;
4015 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4016 quant = XML_CQUANT_PLUS;
4017 elementContent:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004018 if (dtd->in_eldecl) {
4019 ELEMENT_TYPE *el;
4020 const XML_Char *name;
4021 int nameLen;
4022 const char *nxt = (quant == XML_CQUANT_NONE
4023 ? next
4024 : next - enc->minBytesPerChar);
4025 int myindex = nextScaffoldPart(parser);
4026 if (myindex < 0)
4027 return XML_ERROR_NO_MEMORY;
4028 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4029 dtd->scaffold[myindex].quant = quant;
4030 el = getElementType(parser, enc, s, nxt);
4031 if (!el)
4032 return XML_ERROR_NO_MEMORY;
4033 name = el->name;
4034 dtd->scaffold[myindex].name = name;
4035 nameLen = 0;
4036 for (; name[nameLen++]; );
4037 dtd->contentStringLen += nameLen;
4038 if (elementDeclHandler)
4039 handleDefault = XML_FALSE;
4040 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004041 break;
4042
4043 case XML_ROLE_GROUP_CLOSE:
4044 quant = XML_CQUANT_NONE;
4045 goto closeGroup;
4046 case XML_ROLE_GROUP_CLOSE_OPT:
4047 quant = XML_CQUANT_OPT;
4048 goto closeGroup;
4049 case XML_ROLE_GROUP_CLOSE_REP:
4050 quant = XML_CQUANT_REP;
4051 goto closeGroup;
4052 case XML_ROLE_GROUP_CLOSE_PLUS:
4053 quant = XML_CQUANT_PLUS;
4054 closeGroup:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004055 if (dtd->in_eldecl) {
4056 if (elementDeclHandler)
4057 handleDefault = XML_FALSE;
4058 dtd->scaffLevel--;
4059 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4060 if (dtd->scaffLevel == 0) {
4061 if (!handleDefault) {
4062 XML_Content *model = build_model(parser);
4063 if (!model)
4064 return XML_ERROR_NO_MEMORY;
4065 *eventEndPP = s;
4066 elementDeclHandler(handlerArg, declElementType->name, model);
4067 }
4068 dtd->in_eldecl = XML_FALSE;
4069 dtd->contentStringLen = 0;
4070 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004071 }
4072 break;
4073 /* End element declaration stuff */
4074
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004075 case XML_ROLE_PI:
4076 if (!reportProcessingInstruction(parser, enc, s, next))
4077 return XML_ERROR_NO_MEMORY;
4078 handleDefault = XML_FALSE;
4079 break;
4080 case XML_ROLE_COMMENT:
4081 if (!reportComment(parser, enc, s, next))
4082 return XML_ERROR_NO_MEMORY;
4083 handleDefault = XML_FALSE;
4084 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004085 case XML_ROLE_NONE:
4086 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004087 case XML_TOK_BOM:
4088 handleDefault = XML_FALSE;
4089 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004090 }
4091 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004092 case XML_ROLE_DOCTYPE_NONE:
4093 if (startDoctypeDeclHandler)
4094 handleDefault = XML_FALSE;
4095 break;
4096 case XML_ROLE_ENTITY_NONE:
4097 if (dtd->keepProcessing && entityDeclHandler)
4098 handleDefault = XML_FALSE;
4099 break;
4100 case XML_ROLE_NOTATION_NONE:
4101 if (notationDeclHandler)
4102 handleDefault = XML_FALSE;
4103 break;
4104 case XML_ROLE_ATTLIST_NONE:
4105 if (dtd->keepProcessing && attlistDeclHandler)
4106 handleDefault = XML_FALSE;
4107 break;
4108 case XML_ROLE_ELEMENT_NONE:
4109 if (elementDeclHandler)
4110 handleDefault = XML_FALSE;
4111 break;
4112 } /* end of big switch */
4113
4114 if (handleDefault && defaultHandler)
4115 reportDefault(parser, enc, s, next);
4116
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004117 s = next;
4118 tok = XmlPrologTok(enc, s, end, &next);
4119 }
4120 /* not reached */
4121}
4122
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004123static enum XML_Error PTRCALL
4124epilogProcessor(XML_Parser parser,
4125 const char *s,
4126 const char *end,
4127 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004128{
4129 processor = epilogProcessor;
4130 eventPtr = s;
4131 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004132 const char *next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004133 int tok = XmlPrologTok(encoding, s, end, &next);
4134 eventEndPtr = next;
4135 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004136 /* report partial linebreak - it might be the last token */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004137 case -XML_TOK_PROLOG_S:
4138 if (defaultHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004139 eventEndPtr = next;
4140 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004141 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004142 if (nextPtr)
4143 *nextPtr = next;
4144 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004145 case XML_TOK_NONE:
4146 if (nextPtr)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004147 *nextPtr = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004148 return XML_ERROR_NONE;
4149 case XML_TOK_PROLOG_S:
4150 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004151 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004152 break;
4153 case XML_TOK_PI:
4154 if (!reportProcessingInstruction(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004155 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004156 break;
4157 case XML_TOK_COMMENT:
4158 if (!reportComment(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004159 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004160 break;
4161 case XML_TOK_INVALID:
4162 eventPtr = next;
4163 return XML_ERROR_INVALID_TOKEN;
4164 case XML_TOK_PARTIAL:
4165 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004166 *nextPtr = s;
4167 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004168 }
4169 return XML_ERROR_UNCLOSED_TOKEN;
4170 case XML_TOK_PARTIAL_CHAR:
4171 if (nextPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004172 *nextPtr = s;
4173 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004174 }
4175 return XML_ERROR_PARTIAL_CHAR;
4176 default:
4177 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4178 }
4179 eventPtr = s = next;
4180 }
4181}
4182
4183#ifdef XML_DTD
4184
4185static enum XML_Error
4186processInternalParamEntity(XML_Parser parser, ENTITY *entity)
4187{
4188 const char *s, *end, *next;
4189 int tok;
4190 enum XML_Error result;
4191 OPEN_INTERNAL_ENTITY openEntity;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004192 entity->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004193 openEntity.next = openInternalEntities;
4194 openInternalEntities = &openEntity;
4195 openEntity.entity = entity;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004196 openEntity.internalEventPtr = NULL;
4197 openEntity.internalEventEndPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004198 s = (char *)entity->textPtr;
4199 end = (char *)(entity->textPtr + entity->textLen);
4200 tok = XmlPrologTok(internalEncoding, s, end, &next);
4201 result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004202 entity->open = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004203 openInternalEntities = openEntity.next;
4204 return result;
4205}
4206
4207#endif /* XML_DTD */
4208
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004209static enum XML_Error PTRCALL
4210errorProcessor(XML_Parser parser,
4211 const char *s,
4212 const char *end,
4213 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004214{
4215 return errorCode;
4216}
4217
4218static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004219storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4220 const char *ptr, const char *end,
4221 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004222{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004223 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4224 end, pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004225 if (result)
4226 return result;
4227 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4228 poolChop(pool);
4229 if (!poolAppendChar(pool, XML_T('\0')))
4230 return XML_ERROR_NO_MEMORY;
4231 return XML_ERROR_NONE;
4232}
4233
4234static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004235appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4236 const char *ptr, const char *end,
4237 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004238{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004239 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004240 for (;;) {
4241 const char *next;
4242 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4243 switch (tok) {
4244 case XML_TOK_NONE:
4245 return XML_ERROR_NONE;
4246 case XML_TOK_INVALID:
4247 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004248 eventPtr = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004249 return XML_ERROR_INVALID_TOKEN;
4250 case XML_TOK_PARTIAL:
4251 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004252 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004253 return XML_ERROR_INVALID_TOKEN;
4254 case XML_TOK_CHAR_REF:
4255 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004256 XML_Char buf[XML_ENCODE_MAX];
4257 int i;
4258 int n = XmlCharRefNumber(enc, ptr);
4259 if (n < 0) {
4260 if (enc == encoding)
4261 eventPtr = ptr;
4262 return XML_ERROR_BAD_CHAR_REF;
4263 }
4264 if (!isCdata
4265 && n == 0x20 /* space */
4266 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4267 break;
4268 n = XmlEncode(n, (ICHAR *)buf);
4269 if (!n) {
4270 if (enc == encoding)
4271 eventPtr = ptr;
4272 return XML_ERROR_BAD_CHAR_REF;
4273 }
4274 for (i = 0; i < n; i++) {
4275 if (!poolAppendChar(pool, buf[i]))
4276 return XML_ERROR_NO_MEMORY;
4277 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004278 }
4279 break;
4280 case XML_TOK_DATA_CHARS:
4281 if (!poolAppend(pool, enc, ptr, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004282 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004283 break;
4284 case XML_TOK_TRAILING_CR:
4285 next = ptr + enc->minBytesPerChar;
4286 /* fall through */
4287 case XML_TOK_ATTRIBUTE_VALUE_S:
4288 case XML_TOK_DATA_NEWLINE:
4289 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004290 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004291 if (!poolAppendChar(pool, 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004292 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004293 break;
4294 case XML_TOK_ENTITY_REF:
4295 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004296 const XML_Char *name;
4297 ENTITY *entity;
4298 char checkEntityDecl;
4299 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4300 ptr + enc->minBytesPerChar,
4301 next - enc->minBytesPerChar);
4302 if (ch) {
4303 if (!poolAppendChar(pool, ch))
4304 return XML_ERROR_NO_MEMORY;
4305 break;
4306 }
4307 name = poolStoreString(&temp2Pool, enc,
4308 ptr + enc->minBytesPerChar,
4309 next - enc->minBytesPerChar);
4310 if (!name)
4311 return XML_ERROR_NO_MEMORY;
4312 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
4313 poolDiscard(&temp2Pool);
4314 /* first, determine if a check for an existing declaration is needed;
4315 if yes, check that the entity exists, and that it is internal,
4316 otherwise call the default handler (if called from content)
4317 */
4318 if (pool == &dtd->pool) /* are we called from prolog? */
4319 checkEntityDecl =
4320#ifdef XML_DTD
4321 prologState.documentEntity &&
4322#endif /* XML_DTD */
4323 (dtd->standalone
4324 ? !openInternalEntities
4325 : !dtd->hasParamEntityRefs);
4326 else /* if (pool == &tempPool): we are called from content */
4327 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4328 if (checkEntityDecl) {
4329 if (!entity)
4330 return XML_ERROR_UNDEFINED_ENTITY;
4331 else if (!entity->is_internal)
4332 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4333 }
4334 else if (!entity) {
4335 /* cannot report skipped entity here - see comments on
4336 skippedEntityHandler
4337 if (skippedEntityHandler)
4338 skippedEntityHandler(handlerArg, name, 0);
4339 */
4340 if ((pool == &tempPool) && defaultHandler)
4341 reportDefault(parser, enc, ptr, next);
4342 break;
4343 }
4344 if (entity->open) {
4345 if (enc == encoding)
4346 eventPtr = ptr;
4347 return XML_ERROR_RECURSIVE_ENTITY_REF;
4348 }
4349 if (entity->notation) {
4350 if (enc == encoding)
4351 eventPtr = ptr;
4352 return XML_ERROR_BINARY_ENTITY_REF;
4353 }
4354 if (!entity->textPtr) {
4355 if (enc == encoding)
4356 eventPtr = ptr;
4357 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4358 }
4359 else {
4360 enum XML_Error result;
4361 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4362 entity->open = XML_TRUE;
4363 result = appendAttributeValue(parser, internalEncoding, isCdata,
4364 (char *)entity->textPtr,
4365 (char *)textEnd, pool);
4366 entity->open = XML_FALSE;
4367 if (result)
4368 return result;
4369 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004370 }
4371 break;
4372 default:
4373 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004374 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004375 return XML_ERROR_UNEXPECTED_STATE;
4376 }
4377 ptr = next;
4378 }
4379 /* not reached */
4380}
4381
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004382static enum XML_Error
4383storeEntityValue(XML_Parser parser,
4384 const ENCODING *enc,
4385 const char *entityTextPtr,
4386 const char *entityTextEnd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004387{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004388 DTD * const dtd = _dtd; /* save one level of indirection */
4389 STRING_POOL *pool = &(dtd->entityValuePool);
4390 enum XML_Error result = XML_ERROR_NONE;
4391#ifdef XML_DTD
4392 int oldInEntityValue = prologState.inEntityValue;
4393 prologState.inEntityValue = 1;
4394#endif /* XML_DTD */
4395 /* never return Null for the value argument in EntityDeclHandler,
4396 since this would indicate an external entity; therefore we
4397 have to make sure that entityValuePool.start is not null */
4398 if (!pool->blocks) {
4399 if (!poolGrow(pool))
4400 return XML_ERROR_NO_MEMORY;
4401 }
4402
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004403 for (;;) {
4404 const char *next;
4405 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4406 switch (tok) {
4407 case XML_TOK_PARAM_ENTITY_REF:
4408#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004409 if (isParamEntity || enc != encoding) {
4410 const XML_Char *name;
4411 ENTITY *entity;
4412 name = poolStoreString(&tempPool, enc,
4413 entityTextPtr + enc->minBytesPerChar,
4414 next - enc->minBytesPerChar);
4415 if (!name) {
4416 result = XML_ERROR_NO_MEMORY;
4417 goto endEntityValue;
4418 }
4419 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4420 poolDiscard(&tempPool);
4421 if (!entity) {
4422 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4423 /* cannot report skipped entity here - see comments on
4424 skippedEntityHandler
4425 if (skippedEntityHandler)
4426 skippedEntityHandler(handlerArg, name, 0);
4427 */
4428 dtd->keepProcessing = dtd->standalone;
4429 goto endEntityValue;
4430 }
4431 if (entity->open) {
4432 if (enc == encoding)
4433 eventPtr = entityTextPtr;
4434 result = XML_ERROR_RECURSIVE_ENTITY_REF;
4435 goto endEntityValue;
4436 }
4437 if (entity->systemId) {
4438 if (externalEntityRefHandler) {
4439 dtd->paramEntityRead = XML_FALSE;
4440 entity->open = XML_TRUE;
4441 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4442 0,
4443 entity->base,
4444 entity->systemId,
4445 entity->publicId)) {
4446 entity->open = XML_FALSE;
4447 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4448 goto endEntityValue;
4449 }
4450 entity->open = XML_FALSE;
4451 if (!dtd->paramEntityRead)
4452 dtd->keepProcessing = dtd->standalone;
4453 }
4454 else
4455 dtd->keepProcessing = dtd->standalone;
4456 }
4457 else {
4458 entity->open = XML_TRUE;
4459 result = storeEntityValue(parser,
4460 internalEncoding,
4461 (char *)entity->textPtr,
4462 (char *)(entity->textPtr
4463 + entity->textLen));
4464 entity->open = XML_FALSE;
4465 if (result)
4466 goto endEntityValue;
4467 }
4468 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004469 }
4470#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004471 /* in the internal subset, PE references are not legal
4472 within markup declarations, e.g entity values in this case */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004473 eventPtr = entityTextPtr;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004474 result = XML_ERROR_PARAM_ENTITY_REF;
4475 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004476 case XML_TOK_NONE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004477 result = XML_ERROR_NONE;
4478 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004479 case XML_TOK_ENTITY_REF:
4480 case XML_TOK_DATA_CHARS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004481 if (!poolAppend(pool, enc, entityTextPtr, next)) {
4482 result = XML_ERROR_NO_MEMORY;
4483 goto endEntityValue;
4484 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004485 break;
4486 case XML_TOK_TRAILING_CR:
4487 next = entityTextPtr + enc->minBytesPerChar;
4488 /* fall through */
4489 case XML_TOK_DATA_NEWLINE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004490 if (pool->end == pool->ptr && !poolGrow(pool)) {
4491 result = XML_ERROR_NO_MEMORY;
4492 goto endEntityValue;
4493 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004494 *(pool->ptr)++ = 0xA;
4495 break;
4496 case XML_TOK_CHAR_REF:
4497 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004498 XML_Char buf[XML_ENCODE_MAX];
4499 int i;
4500 int n = XmlCharRefNumber(enc, entityTextPtr);
4501 if (n < 0) {
4502 if (enc == encoding)
4503 eventPtr = entityTextPtr;
4504 result = XML_ERROR_BAD_CHAR_REF;
4505 goto endEntityValue;
4506 }
4507 n = XmlEncode(n, (ICHAR *)buf);
4508 if (!n) {
4509 if (enc == encoding)
4510 eventPtr = entityTextPtr;
4511 result = XML_ERROR_BAD_CHAR_REF;
4512 goto endEntityValue;
4513 }
4514 for (i = 0; i < n; i++) {
4515 if (pool->end == pool->ptr && !poolGrow(pool)) {
4516 result = XML_ERROR_NO_MEMORY;
4517 goto endEntityValue;
4518 }
4519 *(pool->ptr)++ = buf[i];
4520 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004521 }
4522 break;
4523 case XML_TOK_PARTIAL:
4524 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004525 eventPtr = entityTextPtr;
4526 result = XML_ERROR_INVALID_TOKEN;
4527 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004528 case XML_TOK_INVALID:
4529 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004530 eventPtr = next;
4531 result = XML_ERROR_INVALID_TOKEN;
4532 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004533 default:
4534 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004535 eventPtr = entityTextPtr;
4536 result = XML_ERROR_UNEXPECTED_STATE;
4537 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004538 }
4539 entityTextPtr = next;
4540 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004541endEntityValue:
4542#ifdef XML_DTD
4543 prologState.inEntityValue = oldInEntityValue;
4544#endif /* XML_DTD */
4545 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004546}
4547
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004548static void FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004549normalizeLines(XML_Char *s)
4550{
4551 XML_Char *p;
4552 for (;; s++) {
4553 if (*s == XML_T('\0'))
4554 return;
4555 if (*s == 0xD)
4556 break;
4557 }
4558 p = s;
4559 do {
4560 if (*s == 0xD) {
4561 *p++ = 0xA;
4562 if (*++s == 0xA)
4563 s++;
4564 }
4565 else
4566 *p++ = *s++;
4567 } while (*s);
4568 *p = XML_T('\0');
4569}
4570
4571static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004572reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
4573 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004574{
4575 const XML_Char *target;
4576 XML_Char *data;
4577 const char *tem;
4578 if (!processingInstructionHandler) {
4579 if (defaultHandler)
4580 reportDefault(parser, enc, start, end);
4581 return 1;
4582 }
4583 start += enc->minBytesPerChar * 2;
4584 tem = start + XmlNameLength(enc, start);
4585 target = poolStoreString(&tempPool, enc, start, tem);
4586 if (!target)
4587 return 0;
4588 poolFinish(&tempPool);
4589 data = poolStoreString(&tempPool, enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004590 XmlSkipS(enc, tem),
4591 end - enc->minBytesPerChar*2);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004592 if (!data)
4593 return 0;
4594 normalizeLines(data);
4595 processingInstructionHandler(handlerArg, target, data);
4596 poolClear(&tempPool);
4597 return 1;
4598}
4599
4600static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004601reportComment(XML_Parser parser, const ENCODING *enc,
4602 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004603{
4604 XML_Char *data;
4605 if (!commentHandler) {
4606 if (defaultHandler)
4607 reportDefault(parser, enc, start, end);
4608 return 1;
4609 }
4610 data = poolStoreString(&tempPool,
4611 enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004612 start + enc->minBytesPerChar * 4,
4613 end - enc->minBytesPerChar * 3);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004614 if (!data)
4615 return 0;
4616 normalizeLines(data);
4617 commentHandler(handlerArg, data);
4618 poolClear(&tempPool);
4619 return 1;
4620}
4621
4622static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004623reportDefault(XML_Parser parser, const ENCODING *enc,
4624 const char *s, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004625{
4626 if (MUST_CONVERT(enc, s)) {
4627 const char **eventPP;
4628 const char **eventEndPP;
4629 if (enc == encoding) {
4630 eventPP = &eventPtr;
4631 eventEndPP = &eventEndPtr;
4632 }
4633 else {
4634 eventPP = &(openInternalEntities->internalEventPtr);
4635 eventEndPP = &(openInternalEntities->internalEventEndPtr);
4636 }
4637 do {
4638 ICHAR *dataPtr = (ICHAR *)dataBuf;
4639 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
4640 *eventEndPP = s;
4641 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
4642 *eventPP = s;
4643 } while (s != end);
4644 }
4645 else
4646 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
4647}
4648
4649
4650static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004651defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
4652 XML_Bool isId, const XML_Char *value, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004653{
4654 DEFAULT_ATTRIBUTE *att;
4655 if (value || isId) {
4656 /* The handling of default attributes gets messed up if we have
4657 a default which duplicates a non-default. */
4658 int i;
4659 for (i = 0; i < type->nDefaultAtts; i++)
4660 if (attId == type->defaultAtts[i].id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004661 return 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004662 if (isId && !type->idAtt && !attId->xmlns)
4663 type->idAtt = attId;
4664 }
4665 if (type->nDefaultAtts == type->allocDefaultAtts) {
4666 if (type->allocDefaultAtts == 0) {
4667 type->allocDefaultAtts = 8;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004668 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
4669 * sizeof(DEFAULT_ATTRIBUTE));
4670 if (!type->defaultAtts)
4671 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004672 }
4673 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004674 DEFAULT_ATTRIBUTE *temp;
4675 int count = type->allocDefaultAtts * 2;
4676 temp = (DEFAULT_ATTRIBUTE *)
4677 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
4678 if (temp == NULL)
4679 return 0;
4680 type->allocDefaultAtts = count;
4681 type->defaultAtts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004682 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004683 }
4684 att = type->defaultAtts + type->nDefaultAtts;
4685 att->id = attId;
4686 att->value = value;
4687 att->isCdata = isCdata;
4688 if (!isCdata)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004689 attId->maybeTokenized = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004690 type->nDefaultAtts += 1;
4691 return 1;
4692}
4693
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004694static int
4695setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004696{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004697 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004698 const XML_Char *name;
4699 for (name = elementType->name; *name; name++) {
4700 if (*name == XML_T(':')) {
4701 PREFIX *prefix;
4702 const XML_Char *s;
4703 for (s = elementType->name; s != name; s++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004704 if (!poolAppendChar(&dtd->pool, *s))
4705 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004706 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004707 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4708 return 0;
4709 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4710 sizeof(PREFIX));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004711 if (!prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004712 return 0;
4713 if (prefix->name == poolStart(&dtd->pool))
4714 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004715 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004716 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004717 elementType->prefix = prefix;
4718
4719 }
4720 }
4721 return 1;
4722}
4723
4724static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004725getAttributeId(XML_Parser parser, const ENCODING *enc,
4726 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004727{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004728 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004729 ATTRIBUTE_ID *id;
4730 const XML_Char *name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004731 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4732 return NULL;
4733 name = poolStoreString(&dtd->pool, enc, start, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004734 if (!name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004735 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004736 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004737 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004738 if (!id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004739 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004740 if (id->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004741 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004742 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004743 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004744 if (!ns)
4745 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004746 else if (name[0] == XML_T('x')
4747 && name[1] == XML_T('m')
4748 && name[2] == XML_T('l')
4749 && name[3] == XML_T('n')
4750 && name[4] == XML_T('s')
4751 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
4752 if (name[5] == XML_T('\0'))
4753 id->prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004754 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004755 id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
4756 id->xmlns = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004757 }
4758 else {
4759 int i;
4760 for (i = 0; name[i]; i++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004761 if (name[i] == XML_T(':')) {
4762 int j;
4763 for (j = 0; j < i; j++) {
4764 if (!poolAppendChar(&dtd->pool, name[j]))
4765 return NULL;
4766 }
4767 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
4768 return NULL;
4769 id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
4770 sizeof(PREFIX));
4771 if (id->prefix->name == poolStart(&dtd->pool))
4772 poolFinish(&dtd->pool);
4773 else
4774 poolDiscard(&dtd->pool);
4775 break;
4776 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004777 }
4778 }
4779 }
4780 return id;
4781}
4782
4783#define CONTEXT_SEP XML_T('\f')
4784
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004785static const XML_Char *
4786getContext(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004787{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004788 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004789 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004790 XML_Bool needSep = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004791
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004792 if (dtd->defaultPrefix.binding) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004793 int i;
4794 int len;
4795 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004796 return NULL;
4797 len = dtd->defaultPrefix.binding->uriLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004798 if (namespaceSeparator != XML_T('\0'))
4799 len--;
4800 for (i = 0; i < len; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004801 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
4802 return NULL;
4803 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004804 }
4805
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004806 hashTableIterInit(&iter, &(dtd->prefixes));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004807 for (;;) {
4808 int i;
4809 int len;
4810 const XML_Char *s;
4811 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
4812 if (!prefix)
4813 break;
4814 if (!prefix->binding)
4815 continue;
4816 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004817 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004818 for (s = prefix->name; *s; s++)
4819 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004820 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004821 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004822 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004823 len = prefix->binding->uriLen;
4824 if (namespaceSeparator != XML_T('\0'))
4825 len--;
4826 for (i = 0; i < len; i++)
4827 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004828 return NULL;
4829 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004830 }
4831
4832
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004833 hashTableIterInit(&iter, &(dtd->generalEntities));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004834 for (;;) {
4835 const XML_Char *s;
4836 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
4837 if (!e)
4838 break;
4839 if (!e->open)
4840 continue;
4841 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004842 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004843 for (s = e->name; *s; s++)
4844 if (!poolAppendChar(&tempPool, *s))
4845 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004846 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004847 }
4848
4849 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004850 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004851 return tempPool.start;
4852}
4853
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004854static XML_Bool
4855setContext(XML_Parser parser, const XML_Char *context)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004856{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004857 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004858 const XML_Char *s = context;
4859
4860 while (*context != XML_T('\0')) {
4861 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
4862 ENTITY *e;
4863 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004864 return XML_FALSE;
4865 e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004866 if (e)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004867 e->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004868 if (*s != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004869 s++;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004870 context = s;
4871 poolDiscard(&tempPool);
4872 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004873 else if (*s == XML_T('=')) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004874 PREFIX *prefix;
4875 if (poolLength(&tempPool) == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004876 prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004877 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004878 if (!poolAppendChar(&tempPool, XML_T('\0')))
4879 return XML_FALSE;
4880 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
4881 sizeof(PREFIX));
4882 if (!prefix)
4883 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004884 if (prefix->name == poolStart(&tempPool)) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004885 prefix->name = poolCopyString(&dtd->pool, prefix->name);
4886 if (!prefix->name)
4887 return XML_FALSE;
4888 }
4889 poolDiscard(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004890 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004891 for (context = s + 1;
4892 *context != CONTEXT_SEP && *context != XML_T('\0');
4893 context++)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004894 if (!poolAppendChar(&tempPool, *context))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004895 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004896 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004897 return XML_FALSE;
4898 if (addBinding(parser, prefix, 0, poolStart(&tempPool),
4899 &inheritedBindings) != XML_ERROR_NONE)
4900 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004901 poolDiscard(&tempPool);
4902 if (*context != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004903 ++context;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004904 s = context;
4905 }
4906 else {
4907 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004908 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004909 s++;
4910 }
4911 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004912 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004913}
4914
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004915static void FASTCALL
4916normalizePublicId(XML_Char *publicId)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004917{
4918 XML_Char *p = publicId;
4919 XML_Char *s;
4920 for (s = publicId; *s; s++) {
4921 switch (*s) {
4922 case 0x20:
4923 case 0xD:
4924 case 0xA:
4925 if (p != publicId && p[-1] != 0x20)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004926 *p++ = 0x20;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004927 break;
4928 default:
4929 *p++ = *s;
4930 }
4931 }
4932 if (p != publicId && p[-1] == 0x20)
4933 --p;
4934 *p = XML_T('\0');
4935}
4936
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004937static DTD *
4938dtdCreate(const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004939{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004940 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
4941 if (p == NULL)
4942 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004943 poolInit(&(p->pool), ms);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004944#ifdef XML_DTD
4945 poolInit(&(p->entityValuePool), ms);
4946#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004947 hashTableInit(&(p->generalEntities), ms);
4948 hashTableInit(&(p->elementTypes), ms);
4949 hashTableInit(&(p->attributeIds), ms);
4950 hashTableInit(&(p->prefixes), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004951#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004952 p->paramEntityRead = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004953 hashTableInit(&(p->paramEntities), ms);
4954#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004955 p->defaultPrefix.name = NULL;
4956 p->defaultPrefix.binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004957
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004958 p->in_eldecl = XML_FALSE;
4959 p->scaffIndex = NULL;
4960 p->scaffold = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004961 p->scaffLevel = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004962 p->scaffSize = 0;
4963 p->scaffCount = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004964 p->contentStringLen = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004965
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004966 p->keepProcessing = XML_TRUE;
4967 p->hasParamEntityRefs = XML_FALSE;
4968 p->standalone = XML_FALSE;
4969 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004970}
4971
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004972static void
4973dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004974{
4975 HASH_TABLE_ITER iter;
4976 hashTableIterInit(&iter, &(p->elementTypes));
4977 for (;;) {
4978 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4979 if (!e)
4980 break;
4981 if (e->allocDefaultAtts != 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004982 ms->free_fcn(e->defaultAtts);
4983 }
4984 hashTableClear(&(p->generalEntities));
4985#ifdef XML_DTD
4986 p->paramEntityRead = XML_FALSE;
4987 hashTableClear(&(p->paramEntities));
4988#endif /* XML_DTD */
4989 hashTableClear(&(p->elementTypes));
4990 hashTableClear(&(p->attributeIds));
4991 hashTableClear(&(p->prefixes));
4992 poolClear(&(p->pool));
4993#ifdef XML_DTD
4994 poolClear(&(p->entityValuePool));
4995#endif /* XML_DTD */
4996 p->defaultPrefix.name = NULL;
4997 p->defaultPrefix.binding = NULL;
4998
4999 p->in_eldecl = XML_FALSE;
5000 if (p->scaffIndex) {
5001 ms->free_fcn(p->scaffIndex);
5002 p->scaffIndex = NULL;
5003 }
5004 if (p->scaffold) {
5005 ms->free_fcn(p->scaffold);
5006 p->scaffold = NULL;
5007 }
5008 p->scaffLevel = 0;
5009 p->scaffSize = 0;
5010 p->scaffCount = 0;
5011 p->contentStringLen = 0;
5012
5013 p->keepProcessing = XML_TRUE;
5014 p->hasParamEntityRefs = XML_FALSE;
5015 p->standalone = XML_FALSE;
5016}
5017
5018static void
5019dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5020{
5021 HASH_TABLE_ITER iter;
5022 hashTableIterInit(&iter, &(p->elementTypes));
5023 for (;;) {
5024 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5025 if (!e)
5026 break;
5027 if (e->allocDefaultAtts != 0)
5028 ms->free_fcn(e->defaultAtts);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005029 }
5030 hashTableDestroy(&(p->generalEntities));
5031#ifdef XML_DTD
5032 hashTableDestroy(&(p->paramEntities));
5033#endif /* XML_DTD */
5034 hashTableDestroy(&(p->elementTypes));
5035 hashTableDestroy(&(p->attributeIds));
5036 hashTableDestroy(&(p->prefixes));
5037 poolDestroy(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005038#ifdef XML_DTD
5039 poolDestroy(&(p->entityValuePool));
5040#endif /* XML_DTD */
5041 if (isDocEntity) {
5042 if (p->scaffIndex)
5043 ms->free_fcn(p->scaffIndex);
5044 if (p->scaffold)
5045 ms->free_fcn(p->scaffold);
5046 }
5047 ms->free_fcn(p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005048}
5049
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005050/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5051 The new DTD has already been initialized.
5052*/
5053static int
5054dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005055{
5056 HASH_TABLE_ITER iter;
5057
5058 /* Copy the prefix table. */
5059
5060 hashTableIterInit(&iter, &(oldDtd->prefixes));
5061 for (;;) {
5062 const XML_Char *name;
5063 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5064 if (!oldP)
5065 break;
5066 name = poolCopyString(&(newDtd->pool), oldP->name);
5067 if (!name)
5068 return 0;
5069 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5070 return 0;
5071 }
5072
5073 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5074
5075 /* Copy the attribute id table. */
5076
5077 for (;;) {
5078 ATTRIBUTE_ID *newA;
5079 const XML_Char *name;
5080 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5081
5082 if (!oldA)
5083 break;
5084 /* Remember to allocate the scratch byte before the name. */
5085 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5086 return 0;
5087 name = poolCopyString(&(newDtd->pool), oldA->name);
5088 if (!name)
5089 return 0;
5090 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005091 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5092 sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005093 if (!newA)
5094 return 0;
5095 newA->maybeTokenized = oldA->maybeTokenized;
5096 if (oldA->prefix) {
5097 newA->xmlns = oldA->xmlns;
5098 if (oldA->prefix == &oldDtd->defaultPrefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005099 newA->prefix = &newDtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005100 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005101 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5102 oldA->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005103 }
5104 }
5105
5106 /* Copy the element type table. */
5107
5108 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5109
5110 for (;;) {
5111 int i;
5112 ELEMENT_TYPE *newE;
5113 const XML_Char *name;
5114 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5115 if (!oldE)
5116 break;
5117 name = poolCopyString(&(newDtd->pool), oldE->name);
5118 if (!name)
5119 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005120 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5121 sizeof(ELEMENT_TYPE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005122 if (!newE)
5123 return 0;
5124 if (oldE->nDefaultAtts) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005125 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5126 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5127 if (!newE->defaultAtts) {
5128 ms->free_fcn(newE);
5129 return 0;
5130 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005131 }
5132 if (oldE->idAtt)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005133 newE->idAtt = (ATTRIBUTE_ID *)
5134 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005135 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5136 if (oldE->prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005137 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5138 oldE->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005139 for (i = 0; i < newE->nDefaultAtts; i++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005140 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5141 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005142 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5143 if (oldE->defaultAtts[i].value) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005144 newE->defaultAtts[i].value
5145 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5146 if (!newE->defaultAtts[i].value)
5147 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005148 }
5149 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005150 newE->defaultAtts[i].value = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005151 }
5152 }
5153
5154 /* Copy the entity tables. */
5155 if (!copyEntityTable(&(newDtd->generalEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005156 &(newDtd->pool),
5157 &(oldDtd->generalEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005158 return 0;
5159
5160#ifdef XML_DTD
5161 if (!copyEntityTable(&(newDtd->paramEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005162 &(newDtd->pool),
5163 &(oldDtd->paramEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005164 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005165 newDtd->paramEntityRead = oldDtd->paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005166#endif /* XML_DTD */
5167
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005168 newDtd->keepProcessing = oldDtd->keepProcessing;
5169 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005170 newDtd->standalone = oldDtd->standalone;
5171
5172 /* Don't want deep copying for scaffolding */
5173 newDtd->in_eldecl = oldDtd->in_eldecl;
5174 newDtd->scaffold = oldDtd->scaffold;
5175 newDtd->contentStringLen = oldDtd->contentStringLen;
5176 newDtd->scaffSize = oldDtd->scaffSize;
5177 newDtd->scaffLevel = oldDtd->scaffLevel;
5178 newDtd->scaffIndex = oldDtd->scaffIndex;
5179
5180 return 1;
5181} /* End dtdCopy */
5182
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005183static int
5184copyEntityTable(HASH_TABLE *newTable,
5185 STRING_POOL *newPool,
5186 const HASH_TABLE *oldTable)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005187{
5188 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005189 const XML_Char *cachedOldBase = NULL;
5190 const XML_Char *cachedNewBase = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005191
5192 hashTableIterInit(&iter, oldTable);
5193
5194 for (;;) {
5195 ENTITY *newE;
5196 const XML_Char *name;
5197 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5198 if (!oldE)
5199 break;
5200 name = poolCopyString(newPool, oldE->name);
5201 if (!name)
5202 return 0;
5203 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5204 if (!newE)
5205 return 0;
5206 if (oldE->systemId) {
5207 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5208 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005209 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005210 newE->systemId = tem;
5211 if (oldE->base) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005212 if (oldE->base == cachedOldBase)
5213 newE->base = cachedNewBase;
5214 else {
5215 cachedOldBase = oldE->base;
5216 tem = poolCopyString(newPool, cachedOldBase);
5217 if (!tem)
5218 return 0;
5219 cachedNewBase = newE->base = tem;
5220 }
5221 }
5222 if (oldE->publicId) {
5223 tem = poolCopyString(newPool, oldE->publicId);
5224 if (!tem)
5225 return 0;
5226 newE->publicId = tem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005227 }
5228 }
5229 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005230 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5231 oldE->textLen);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005232 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005233 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005234 newE->textPtr = tem;
5235 newE->textLen = oldE->textLen;
5236 }
5237 if (oldE->notation) {
5238 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5239 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005240 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005241 newE->notation = tem;
5242 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005243 newE->is_param = oldE->is_param;
5244 newE->is_internal = oldE->is_internal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005245 }
5246 return 1;
5247}
5248
5249#define INIT_SIZE 64
5250
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005251static int FASTCALL
5252keyeq(KEY s1, KEY s2)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005253{
5254 for (; *s1 == *s2; s1++, s2++)
5255 if (*s1 == 0)
5256 return 1;
5257 return 0;
5258}
5259
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005260static unsigned long FASTCALL
5261hash(KEY s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005262{
5263 unsigned long h = 0;
5264 while (*s)
5265 h = (h << 5) + h + (unsigned char)*s++;
5266 return h;
5267}
5268
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005269static NAMED *
5270lookup(HASH_TABLE *table, KEY name, size_t createSize)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005271{
5272 size_t i;
5273 if (table->size == 0) {
5274 size_t tsize;
5275
5276 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005277 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005278 tsize = INIT_SIZE * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005279 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005280 if (!table->v)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005281 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005282 memset(table->v, 0, tsize);
5283 table->size = INIT_SIZE;
5284 table->usedLim = INIT_SIZE / 2;
5285 i = hash(name) & (table->size - 1);
5286 }
5287 else {
5288 unsigned long h = hash(name);
5289 for (i = h & (table->size - 1);
5290 table->v[i];
5291 i == 0 ? i = table->size - 1 : --i) {
5292 if (keyeq(name, table->v[i]->name))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005293 return table->v[i];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005294 }
5295 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005296 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005297 if (table->used == table->usedLim) {
5298 /* check for overflow */
5299 size_t newSize = table->size * 2;
5300 size_t tsize = newSize * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005301 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005302 if (!newV)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005303 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005304 memset(newV, 0, tsize);
5305 for (i = 0; i < table->size; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005306 if (table->v[i]) {
5307 size_t j;
5308 for (j = hash(table->v[i]->name) & (newSize - 1);
5309 newV[j];
5310 j == 0 ? j = newSize - 1 : --j)
5311 ;
5312 newV[j] = table->v[i];
5313 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005314 table->mem->free_fcn(table->v);
5315 table->v = newV;
5316 table->size = newSize;
5317 table->usedLim = newSize/2;
5318 for (i = h & (table->size - 1);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005319 table->v[i];
5320 i == 0 ? i = table->size - 1 : --i)
5321 ;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005322 }
5323 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005324 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005325 if (!table->v[i])
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005326 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005327 memset(table->v[i], 0, createSize);
5328 table->v[i]->name = name;
5329 (table->used)++;
5330 return table->v[i];
5331}
5332
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005333static void FASTCALL
5334hashTableClear(HASH_TABLE *table)
5335{
5336 size_t i;
5337 for (i = 0; i < table->size; i++) {
5338 NAMED *p = table->v[i];
5339 if (p) {
5340 table->mem->free_fcn(p);
5341 table->v[i] = NULL;
5342 }
5343 }
5344 table->usedLim = table->size / 2;
5345 table->used = 0;
5346}
5347
5348static void FASTCALL
5349hashTableDestroy(HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005350{
5351 size_t i;
5352 for (i = 0; i < table->size; i++) {
5353 NAMED *p = table->v[i];
5354 if (p)
5355 table->mem->free_fcn(p);
5356 }
5357 if (table->v)
5358 table->mem->free_fcn(table->v);
5359}
5360
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005361static void FASTCALL
5362hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005363{
5364 p->size = 0;
5365 p->usedLim = 0;
5366 p->used = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005367 p->v = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005368 p->mem = ms;
5369}
5370
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005371static void FASTCALL
5372hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005373{
5374 iter->p = table->v;
5375 iter->end = iter->p + table->size;
5376}
5377
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005378static NAMED * FASTCALL
5379hashTableIterNext(HASH_TABLE_ITER *iter)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005380{
5381 while (iter->p != iter->end) {
5382 NAMED *tem = *(iter->p)++;
5383 if (tem)
5384 return tem;
5385 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005386 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005387}
5388
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005389static void FASTCALL
5390poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005391{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005392 pool->blocks = NULL;
5393 pool->freeBlocks = NULL;
5394 pool->start = NULL;
5395 pool->ptr = NULL;
5396 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005397 pool->mem = ms;
5398}
5399
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005400static void FASTCALL
5401poolClear(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005402{
5403 if (!pool->freeBlocks)
5404 pool->freeBlocks = pool->blocks;
5405 else {
5406 BLOCK *p = pool->blocks;
5407 while (p) {
5408 BLOCK *tem = p->next;
5409 p->next = pool->freeBlocks;
5410 pool->freeBlocks = p;
5411 p = tem;
5412 }
5413 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005414 pool->blocks = NULL;
5415 pool->start = NULL;
5416 pool->ptr = NULL;
5417 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005418}
5419
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005420static void FASTCALL
5421poolDestroy(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005422{
5423 BLOCK *p = pool->blocks;
5424 while (p) {
5425 BLOCK *tem = p->next;
5426 pool->mem->free_fcn(p);
5427 p = tem;
5428 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005429 p = pool->freeBlocks;
5430 while (p) {
5431 BLOCK *tem = p->next;
5432 pool->mem->free_fcn(p);
5433 p = tem;
5434 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005435}
5436
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005437static XML_Char *
5438poolAppend(STRING_POOL *pool, const ENCODING *enc,
5439 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005440{
5441 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005442 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005443 for (;;) {
5444 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
5445 if (ptr == end)
5446 break;
5447 if (!poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005448 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005449 }
5450 return pool->start;
5451}
5452
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005453static const XML_Char * FASTCALL
5454poolCopyString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005455{
5456 do {
5457 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005458 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005459 } while (*s++);
5460 s = pool->start;
5461 poolFinish(pool);
5462 return s;
5463}
5464
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005465static const XML_Char *
5466poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005467{
5468 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005469 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005470 for (; n > 0; --n, s++) {
5471 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005472 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005473 }
5474 s = pool->start;
5475 poolFinish(pool);
5476 return s;
5477}
5478
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005479static const XML_Char * FASTCALL
5480poolAppendString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005481{
5482 while (*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 s++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005486 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005487 return pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005488}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005489
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005490static XML_Char *
5491poolStoreString(STRING_POOL *pool, const ENCODING *enc,
5492 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005493{
5494 if (!poolAppend(pool, enc, ptr, end))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005495 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005496 if (pool->ptr == pool->end && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005497 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005498 *(pool->ptr)++ = 0;
5499 return pool->start;
5500}
5501
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005502static XML_Bool FASTCALL
5503poolGrow(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005504{
5505 if (pool->freeBlocks) {
5506 if (pool->start == 0) {
5507 pool->blocks = pool->freeBlocks;
5508 pool->freeBlocks = pool->freeBlocks->next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005509 pool->blocks->next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005510 pool->start = pool->blocks->s;
5511 pool->end = pool->start + pool->blocks->size;
5512 pool->ptr = pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005513 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005514 }
5515 if (pool->end - pool->start < pool->freeBlocks->size) {
5516 BLOCK *tem = pool->freeBlocks->next;
5517 pool->freeBlocks->next = pool->blocks;
5518 pool->blocks = pool->freeBlocks;
5519 pool->freeBlocks = tem;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005520 memcpy(pool->blocks->s, pool->start,
5521 (pool->end - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005522 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5523 pool->start = pool->blocks->s;
5524 pool->end = pool->start + pool->blocks->size;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005525 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005526 }
5527 }
5528 if (pool->blocks && pool->start == pool->blocks->s) {
5529 int blockSize = (pool->end - pool->start)*2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005530 pool->blocks = (BLOCK *)
5531 pool->mem->realloc_fcn(pool->blocks,
5532 (offsetof(BLOCK, s)
5533 + blockSize * sizeof(XML_Char)));
5534 if (pool->blocks == NULL)
5535 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005536 pool->blocks->size = blockSize;
5537 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5538 pool->start = pool->blocks->s;
5539 pool->end = pool->start + blockSize;
5540 }
5541 else {
5542 BLOCK *tem;
5543 int blockSize = pool->end - pool->start;
5544 if (blockSize < INIT_BLOCK_SIZE)
5545 blockSize = INIT_BLOCK_SIZE;
5546 else
5547 blockSize *= 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005548 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
5549 + blockSize * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005550 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005551 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005552 tem->size = blockSize;
5553 tem->next = pool->blocks;
5554 pool->blocks = tem;
5555 if (pool->ptr != pool->start)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005556 memcpy(tem->s, pool->start,
5557 (pool->ptr - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005558 pool->ptr = tem->s + (pool->ptr - pool->start);
5559 pool->start = tem->s;
5560 pool->end = tem->s + blockSize;
5561 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005562 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005563}
5564
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005565static int FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005566nextScaffoldPart(XML_Parser parser)
5567{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005568 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005569 CONTENT_SCAFFOLD * me;
5570 int next;
5571
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005572 if (!dtd->scaffIndex) {
5573 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
5574 if (!dtd->scaffIndex)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005575 return -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005576 dtd->scaffIndex[0] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005577 }
5578
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005579 if (dtd->scaffCount >= dtd->scaffSize) {
5580 CONTENT_SCAFFOLD *temp;
5581 if (dtd->scaffold) {
5582 temp = (CONTENT_SCAFFOLD *)
5583 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
5584 if (temp == NULL)
5585 return -1;
5586 dtd->scaffSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005587 }
5588 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005589 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
5590 * sizeof(CONTENT_SCAFFOLD));
5591 if (temp == NULL)
5592 return -1;
5593 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005594 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005595 dtd->scaffold = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005596 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005597 next = dtd->scaffCount++;
5598 me = &dtd->scaffold[next];
5599 if (dtd->scaffLevel) {
5600 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005601 if (parent->lastchild) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005602 dtd->scaffold[parent->lastchild].nextsib = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005603 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005604 if (!parent->childcnt)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005605 parent->firstchild = next;
5606 parent->lastchild = next;
5607 parent->childcnt++;
5608 }
5609 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
5610 return next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005611}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005612
5613static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005614build_node(XML_Parser parser,
5615 int src_node,
5616 XML_Content *dest,
5617 XML_Content **contpos,
5618 XML_Char **strpos)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005619{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005620 DTD * const dtd = _dtd; /* save one level of indirection */
5621 dest->type = dtd->scaffold[src_node].type;
5622 dest->quant = dtd->scaffold[src_node].quant;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005623 if (dest->type == XML_CTYPE_NAME) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005624 const XML_Char *src;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005625 dest->name = *strpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005626 src = dtd->scaffold[src_node].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005627 for (;;) {
5628 *(*strpos)++ = *src;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005629 if (!*src)
5630 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005631 src++;
5632 }
5633 dest->numchildren = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005634 dest->children = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005635 }
5636 else {
5637 unsigned int i;
5638 int cn;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005639 dest->numchildren = dtd->scaffold[src_node].childcnt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005640 dest->children = *contpos;
5641 *contpos += dest->numchildren;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005642 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
5643 i < dest->numchildren;
5644 i++, cn = dtd->scaffold[cn].nextsib) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005645 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
5646 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005647 dest->name = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005648 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005649}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005650
5651static XML_Content *
5652build_model (XML_Parser parser)
5653{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005654 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005655 XML_Content *ret;
5656 XML_Content *cpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005657 XML_Char * str;
5658 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
5659 + (dtd->contentStringLen * sizeof(XML_Char)));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005660
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005661 ret = (XML_Content *)MALLOC(allocsize);
5662 if (!ret)
5663 return NULL;
5664
5665 str = (XML_Char *) (&ret[dtd->scaffCount]);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005666 cpos = &ret[1];
5667
5668 build_node(parser, 0, ret, &cpos, &str);
5669 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005670}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005671
5672static ELEMENT_TYPE *
5673getElementType(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005674 const ENCODING *enc,
5675 const char *ptr,
5676 const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005677{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005678 DTD * const dtd = _dtd; /* save one level of indirection */
5679 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005680 ELEMENT_TYPE *ret;
5681
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005682 if (!name)
5683 return NULL;
5684 ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
5685 if (!ret)
5686 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005687 if (ret->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005688 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005689 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005690 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005691 if (!setElementTypePrefix(parser, ret))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005692 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005693 }
5694 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005695}