blob: 7c6a8017eaf04764e4fe99c5e05001e26a875460 [file] [log] [blame]
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001/*
2Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
3See the file COPYING for copying permission.
4*/
5
6#ifdef COMPILED_FROM_DSP
7# include "winconfig.h"
8# define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
9# include "expat.h"
10# undef XMLPARSEAPI
11#else
12#include <config.h>
13
14#ifdef __declspec
15# define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
16#endif
17
18#include "expat.h"
19
20#ifdef __declspec
21# undef XMLPARSEAPI
22#endif
23#endif /* ndef COMPILED_FROM_DSP */
24
25#include <stddef.h>
26#include <string.h>
27
28#ifdef XML_UNICODE
29#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
30#define XmlConvert XmlUtf16Convert
31#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
32#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
33#define XmlEncode XmlUtf16Encode
34#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
35typedef unsigned short ICHAR;
36#else
37#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
38#define XmlConvert XmlUtf8Convert
39#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
40#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
41#define XmlEncode XmlUtf8Encode
42#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
43typedef char ICHAR;
44#endif
45
46
47#ifndef XML_NS
48
49#define XmlInitEncodingNS XmlInitEncoding
50#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
51#undef XmlGetInternalEncodingNS
52#define XmlGetInternalEncodingNS XmlGetInternalEncoding
53#define XmlParseXmlDeclNS XmlParseXmlDecl
54
55#endif
56
57#ifdef XML_UNICODE_WCHAR_T
58#define XML_T(x) L ## x
59#else
60#define XML_T(x) x
61#endif
62
63/* Round up n to be a multiple of sz, where sz is a power of 2. */
64#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
65
66#include "xmltok.h"
67#include "xmlrole.h"
68
69typedef const XML_Char *KEY;
70
71typedef struct {
72 KEY name;
73} NAMED;
74
75typedef struct {
76 NAMED **v;
77 size_t size;
78 size_t used;
79 size_t usedLim;
80 XML_Memory_Handling_Suite *mem;
81} HASH_TABLE;
82
83typedef struct {
84 NAMED **p;
85 NAMED **end;
86} HASH_TABLE_ITER;
87
88#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
89#define INIT_DATA_BUF_SIZE 1024
90#define INIT_ATTS_SIZE 16
91#define INIT_BLOCK_SIZE 1024
92#define INIT_BUFFER_SIZE 1024
93
94#define EXPAND_SPARE 24
95
96typedef struct binding {
97 struct prefix *prefix;
98 struct binding *nextTagBinding;
99 struct binding *prevPrefixBinding;
100 const struct attribute_id *attId;
101 XML_Char *uri;
102 int uriLen;
103 int uriAlloc;
104} BINDING;
105
106typedef struct prefix {
107 const XML_Char *name;
108 BINDING *binding;
109} PREFIX;
110
111typedef struct {
112 const XML_Char *str;
113 const XML_Char *localPart;
114 int uriLen;
115} TAG_NAME;
116
117typedef struct tag {
118 struct tag *parent;
119 const char *rawName;
120 int rawNameLength;
121 TAG_NAME name;
122 char *buf;
123 char *bufEnd;
124 BINDING *bindings;
125} TAG;
126
127typedef struct {
128 const XML_Char *name;
129 const XML_Char *textPtr;
130 int textLen;
131 const XML_Char *systemId;
132 const XML_Char *base;
133 const XML_Char *publicId;
134 const XML_Char *notation;
135 char open;
136 char is_param;
137} ENTITY;
138
139typedef struct {
140 enum XML_Content_Type type;
141 enum XML_Content_Quant quant;
142 const XML_Char * name;
143 int firstchild;
144 int lastchild;
145 int childcnt;
146 int nextsib;
147} CONTENT_SCAFFOLD;
148
149typedef struct block {
150 struct block *next;
151 int size;
152 XML_Char s[1];
153} BLOCK;
154
155typedef struct {
156 BLOCK *blocks;
157 BLOCK *freeBlocks;
158 const XML_Char *end;
159 XML_Char *ptr;
160 XML_Char *start;
161 XML_Memory_Handling_Suite *mem;
162} STRING_POOL;
163
164/* The XML_Char before the name is used to determine whether
165an attribute has been specified. */
166typedef struct attribute_id {
167 XML_Char *name;
168 PREFIX *prefix;
169 char maybeTokenized;
170 char xmlns;
171} ATTRIBUTE_ID;
172
173typedef struct {
174 const ATTRIBUTE_ID *id;
175 char isCdata;
176 const XML_Char *value;
177} DEFAULT_ATTRIBUTE;
178
179typedef struct {
180 const XML_Char *name;
181 PREFIX *prefix;
182 const ATTRIBUTE_ID *idAtt;
183 int nDefaultAtts;
184 int allocDefaultAtts;
185 DEFAULT_ATTRIBUTE *defaultAtts;
186} ELEMENT_TYPE;
187
188typedef struct {
189 HASH_TABLE generalEntities;
190 HASH_TABLE elementTypes;
191 HASH_TABLE attributeIds;
192 HASH_TABLE prefixes;
193 STRING_POOL pool;
194 int complete;
195 int standalone;
196#ifdef XML_DTD
197 HASH_TABLE paramEntities;
198#endif /* XML_DTD */
199 PREFIX defaultPrefix;
200 /* === scaffolding for building content model === */
201 int in_eldecl;
202 CONTENT_SCAFFOLD *scaffold;
203 unsigned contentStringLen;
204 unsigned scaffSize;
205 unsigned scaffCount;
206 int scaffLevel;
207 int *scaffIndex;
208} DTD;
209
210typedef struct open_internal_entity {
211 const char *internalEventPtr;
212 const char *internalEventEndPtr;
213 struct open_internal_entity *next;
214 ENTITY *entity;
215} OPEN_INTERNAL_ENTITY;
216
217typedef enum XML_Error Processor(XML_Parser parser,
218 const char *start,
219 const char *end,
220 const char **endPtr);
221
222static Processor prologProcessor;
223static Processor prologInitProcessor;
224static Processor contentProcessor;
225static Processor cdataSectionProcessor;
226#ifdef XML_DTD
227static Processor ignoreSectionProcessor;
228#endif /* XML_DTD */
229static Processor epilogProcessor;
230static Processor errorProcessor;
231static Processor externalEntityInitProcessor;
232static Processor externalEntityInitProcessor2;
233static Processor externalEntityInitProcessor3;
234static Processor externalEntityContentProcessor;
235
236static enum XML_Error
237handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
238static enum XML_Error
239processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
240static enum XML_Error
241initializeEncoding(XML_Parser parser);
242static enum XML_Error
243doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
244 const char *end, int tok, const char *next, const char **nextPtr);
245static enum XML_Error
246processInternalParamEntity(XML_Parser parser, ENTITY *entity);
247static enum XML_Error
248doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
249 const char *start, const char *end, const char **endPtr);
250static enum XML_Error
251doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
252#ifdef XML_DTD
253static enum XML_Error
254doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
255#endif /* XML_DTD */
256static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
257 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
258static
259int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
260
261static int
262defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
263 int isCdata, int isId, const XML_Char *dfltValue,
264 XML_Parser parser);
265
266static enum XML_Error
267storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
268 STRING_POOL *);
269static enum XML_Error
270appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
271 STRING_POOL *);
272static ATTRIBUTE_ID *
273getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
274static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
275static enum XML_Error
276storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
277static int
278reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
279static int
280reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
281static void
282reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
283
284static const XML_Char *getContext(XML_Parser parser);
285static int setContext(XML_Parser parser, const XML_Char *context);
286static void normalizePublicId(XML_Char *s);
287static int dtdInit(DTD *, XML_Parser parser);
288
289static void dtdDestroy(DTD *, XML_Parser parser);
290
291static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
292
293static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *,
294 XML_Parser parser);
295
296#ifdef XML_DTD
297static void dtdSwap(DTD *, DTD *);
298#endif /* XML_DTD */
299
300static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
301
302static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
303
304static void hashTableDestroy(HASH_TABLE *);
305static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
306static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
307static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
308static void poolClear(STRING_POOL *);
309static void poolDestroy(STRING_POOL *);
310static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
311 const char *ptr, const char *end);
312static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
313 const char *ptr, const char *end);
314
315static int poolGrow(STRING_POOL *pool);
316
317static int nextScaffoldPart(XML_Parser parser);
318static XML_Content *build_model(XML_Parser parser);
319
320static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
321static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
322static const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s);
323static ELEMENT_TYPE * getElementType(XML_Parser Paraser,
324 const ENCODING *enc,
325 const char *ptr,
326 const char *end);
327
328#define poolStart(pool) ((pool)->start)
329#define poolEnd(pool) ((pool)->ptr)
330#define poolLength(pool) ((pool)->ptr - (pool)->start)
331#define poolChop(pool) ((void)--(pool->ptr))
332#define poolLastChar(pool) (((pool)->ptr)[-1])
333#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
334#define poolFinish(pool) ((pool)->start = (pool)->ptr)
335#define poolAppendChar(pool, c) \
336 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
337 ? 0 \
338 : ((*((pool)->ptr)++ = c), 1))
339
340typedef struct {
341 /* The first member must be userData so that the XML_GetUserData macro works. */
342 void *m_userData;
343 void *m_handlerArg;
344 char *m_buffer;
345 XML_Memory_Handling_Suite m_mem;
346 /* first character to be parsed */
347 const char *m_bufferPtr;
348 /* past last character to be parsed */
349 char *m_bufferEnd;
350 /* allocated end of buffer */
351 const char *m_bufferLim;
352 long m_parseEndByteIndex;
353 const char *m_parseEndPtr;
354 XML_Char *m_dataBuf;
355 XML_Char *m_dataBufEnd;
356 XML_StartElementHandler m_startElementHandler;
357 XML_EndElementHandler m_endElementHandler;
358 XML_CharacterDataHandler m_characterDataHandler;
359 XML_ProcessingInstructionHandler m_processingInstructionHandler;
360 XML_CommentHandler m_commentHandler;
361 XML_StartCdataSectionHandler m_startCdataSectionHandler;
362 XML_EndCdataSectionHandler m_endCdataSectionHandler;
363 XML_DefaultHandler m_defaultHandler;
364 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
365 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
366 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
367 XML_NotationDeclHandler m_notationDeclHandler;
368 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
369 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
370 XML_NotStandaloneHandler m_notStandaloneHandler;
371 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
372 void *m_externalEntityRefHandlerArg;
373 XML_UnknownEncodingHandler m_unknownEncodingHandler;
374 XML_ElementDeclHandler m_elementDeclHandler;
375 XML_AttlistDeclHandler m_attlistDeclHandler;
376 XML_EntityDeclHandler m_entityDeclHandler;
377 XML_XmlDeclHandler m_xmlDeclHandler;
378 const ENCODING *m_encoding;
379 INIT_ENCODING m_initEncoding;
380 const ENCODING *m_internalEncoding;
381 const XML_Char *m_protocolEncodingName;
382 int m_ns;
383 int m_ns_triplets;
384 void *m_unknownEncodingMem;
385 void *m_unknownEncodingData;
386 void *m_unknownEncodingHandlerData;
387 void (*m_unknownEncodingRelease)(void *);
388 PROLOG_STATE m_prologState;
389 Processor *m_processor;
390 enum XML_Error m_errorCode;
391 const char *m_eventPtr;
392 const char *m_eventEndPtr;
393 const char *m_positionPtr;
394 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
395 int m_defaultExpandInternalEntities;
396 int m_tagLevel;
397 ENTITY *m_declEntity;
398 const XML_Char *m_doctypeName;
399 const XML_Char *m_doctypeSysid;
400 const XML_Char *m_doctypePubid;
401 const XML_Char *m_declAttributeType;
402 const XML_Char *m_declNotationName;
403 const XML_Char *m_declNotationPublicId;
404 ELEMENT_TYPE *m_declElementType;
405 ATTRIBUTE_ID *m_declAttributeId;
406 char m_declAttributeIsCdata;
407 char m_declAttributeIsId;
408 DTD m_dtd;
409 const XML_Char *m_curBase;
410 TAG *m_tagStack;
411 TAG *m_freeTagList;
412 BINDING *m_inheritedBindings;
413 BINDING *m_freeBindingList;
414 int m_attsSize;
415 int m_nSpecifiedAtts;
416 int m_idAttIndex;
417 ATTRIBUTE *m_atts;
418 POSITION m_position;
419 STRING_POOL m_tempPool;
420 STRING_POOL m_temp2Pool;
421 char *m_groupConnector;
422 unsigned m_groupSize;
423 int m_hadExternalDoctype;
424 XML_Char m_namespaceSeparator;
425#ifdef XML_DTD
426 enum XML_ParamEntityParsing m_paramEntityParsing;
427 XML_Parser m_parentParser;
428#endif
429} Parser;
430
431#define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
432#define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
433#define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
434
435#define userData (((Parser *)parser)->m_userData)
436#define handlerArg (((Parser *)parser)->m_handlerArg)
437#define startElementHandler (((Parser *)parser)->m_startElementHandler)
438#define endElementHandler (((Parser *)parser)->m_endElementHandler)
439#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
440#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
441#define commentHandler (((Parser *)parser)->m_commentHandler)
442#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
443#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
444#define defaultHandler (((Parser *)parser)->m_defaultHandler)
445#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
446#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
447#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
448#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
449#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
450#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
451#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
452#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
453#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
454#define internalEntityRefHandler (((Parser *)parser)->m_internalEntityRefHandler)
455#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
456#define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
457#define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
458#define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
459#define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
460#define encoding (((Parser *)parser)->m_encoding)
461#define initEncoding (((Parser *)parser)->m_initEncoding)
462#define internalEncoding (((Parser *)parser)->m_internalEncoding)
463#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
464#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
465#define unknownEncodingHandlerData \
466 (((Parser *)parser)->m_unknownEncodingHandlerData)
467#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
468#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
469#define ns (((Parser *)parser)->m_ns)
470#define ns_triplets (((Parser *)parser)->m_ns_triplets)
471#define prologState (((Parser *)parser)->m_prologState)
472#define processor (((Parser *)parser)->m_processor)
473#define errorCode (((Parser *)parser)->m_errorCode)
474#define eventPtr (((Parser *)parser)->m_eventPtr)
475#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
476#define positionPtr (((Parser *)parser)->m_positionPtr)
477#define position (((Parser *)parser)->m_position)
478#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
479#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
480#define tagLevel (((Parser *)parser)->m_tagLevel)
481#define buffer (((Parser *)parser)->m_buffer)
482#define bufferPtr (((Parser *)parser)->m_bufferPtr)
483#define bufferEnd (((Parser *)parser)->m_bufferEnd)
484#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
485#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
486#define bufferLim (((Parser *)parser)->m_bufferLim)
487#define dataBuf (((Parser *)parser)->m_dataBuf)
488#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
489#define dtd (((Parser *)parser)->m_dtd)
490#define curBase (((Parser *)parser)->m_curBase)
491#define declEntity (((Parser *)parser)->m_declEntity)
492#define doctypeName (((Parser *)parser)->m_doctypeName)
493#define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
494#define doctypePubid (((Parser *)parser)->m_doctypePubid)
495#define declAttributeType (((Parser *)parser)->m_declAttributeType)
496#define declNotationName (((Parser *)parser)->m_declNotationName)
497#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
498#define declElementType (((Parser *)parser)->m_declElementType)
499#define declAttributeId (((Parser *)parser)->m_declAttributeId)
500#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
501#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
502#define freeTagList (((Parser *)parser)->m_freeTagList)
503#define freeBindingList (((Parser *)parser)->m_freeBindingList)
504#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
505#define tagStack (((Parser *)parser)->m_tagStack)
506#define atts (((Parser *)parser)->m_atts)
507#define attsSize (((Parser *)parser)->m_attsSize)
508#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
509#define idAttIndex (((Parser *)parser)->m_idAttIndex)
510#define tempPool (((Parser *)parser)->m_tempPool)
511#define temp2Pool (((Parser *)parser)->m_temp2Pool)
512#define groupConnector (((Parser *)parser)->m_groupConnector)
513#define groupSize (((Parser *)parser)->m_groupSize)
514#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
515#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
516#ifdef XML_DTD
517#define parentParser (((Parser *)parser)->m_parentParser)
518#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
519#endif /* XML_DTD */
520
521#ifdef COMPILED_FROM_DSP
522BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p) {
523 return TRUE;
524}
525#endif /* def COMPILED_FROM_DSP */
526
527#ifdef _MSC_VER
528#ifdef _DEBUG
529Parser *asParser(XML_Parser parser)
530{
531 return parser;
532}
533#endif
534#endif
535
536XML_Parser XML_ParserCreate(const XML_Char *encodingName)
537{
538 return XML_ParserCreate_MM(encodingName, NULL, NULL);
539}
540
541XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
542{
543 XML_Char tmp[2];
544 *tmp = nsSep;
545 return XML_ParserCreate_MM(encodingName, NULL, tmp);
546}
547
548XML_Parser
549XML_ParserCreate_MM(const XML_Char *encodingName,
550 const XML_Memory_Handling_Suite *memsuite,
551 const XML_Char *nameSep) {
552
553 XML_Parser parser;
554 static
555 const XML_Char implicitContext[] = {
556 XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
557 XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
558 XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
559 XML_T('.'), XML_T('w'), XML_T('3'),
560 XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
561 XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
562 XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
563 XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
564 XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
565 XML_T('\0')
566 };
567
568
569 if (memsuite) {
570 XML_Memory_Handling_Suite *mtemp;
571 parser = memsuite->malloc_fcn(sizeof(Parser));
572 mtemp = &(((Parser *) parser)->m_mem);
573 mtemp->malloc_fcn = memsuite->malloc_fcn;
574 mtemp->realloc_fcn = memsuite->realloc_fcn;
575 mtemp->free_fcn = memsuite->free_fcn;
576 }
577 else {
578 XML_Memory_Handling_Suite *mtemp;
579 parser = malloc(sizeof(Parser));
580 mtemp = &(((Parser *) parser)->m_mem);
581 mtemp->malloc_fcn = malloc;
582 mtemp->realloc_fcn = realloc;
583 mtemp->free_fcn = free;
584 }
585
586 if (!parser)
587 return parser;
588 processor = prologInitProcessor;
589 XmlPrologStateInit(&prologState);
590 userData = 0;
591 handlerArg = 0;
592 startElementHandler = 0;
593 endElementHandler = 0;
594 characterDataHandler = 0;
595 processingInstructionHandler = 0;
596 commentHandler = 0;
597 startCdataSectionHandler = 0;
598 endCdataSectionHandler = 0;
599 defaultHandler = 0;
600 startDoctypeDeclHandler = 0;
601 endDoctypeDeclHandler = 0;
602 unparsedEntityDeclHandler = 0;
603 notationDeclHandler = 0;
604 startNamespaceDeclHandler = 0;
605 endNamespaceDeclHandler = 0;
606 notStandaloneHandler = 0;
607 externalEntityRefHandler = 0;
608 externalEntityRefHandlerArg = parser;
609 unknownEncodingHandler = 0;
610 elementDeclHandler = 0;
611 attlistDeclHandler = 0;
612 entityDeclHandler = 0;
613 xmlDeclHandler = 0;
614 buffer = 0;
615 bufferPtr = 0;
616 bufferEnd = 0;
617 parseEndByteIndex = 0;
618 parseEndPtr = 0;
619 bufferLim = 0;
620 declElementType = 0;
621 declAttributeId = 0;
622 declEntity = 0;
623 doctypeName = 0;
624 doctypeSysid = 0;
625 doctypePubid = 0;
626 declAttributeType = 0;
627 declNotationName = 0;
628 declNotationPublicId = 0;
629 memset(&position, 0, sizeof(POSITION));
630 errorCode = XML_ERROR_NONE;
631 eventPtr = 0;
632 eventEndPtr = 0;
633 positionPtr = 0;
634 openInternalEntities = 0;
635 tagLevel = 0;
636 tagStack = 0;
637 freeTagList = 0;
638 freeBindingList = 0;
639 inheritedBindings = 0;
640 attsSize = INIT_ATTS_SIZE;
641 atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
642 nSpecifiedAtts = 0;
643 dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
644 groupSize = 0;
645 groupConnector = 0;
646 hadExternalDoctype = 0;
647 unknownEncodingMem = 0;
648 unknownEncodingRelease = 0;
649 unknownEncodingData = 0;
650 unknownEncodingHandlerData = 0;
651 namespaceSeparator = '!';
652#ifdef XML_DTD
653 parentParser = 0;
654 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
655#endif
656 ns = 0;
657 ns_triplets = 0;
658 poolInit(&tempPool, &(((Parser *) parser)->m_mem));
659 poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
660 protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
661 curBase = 0;
662 if (!dtdInit(&dtd, parser) || !atts || !dataBuf
663 || (encodingName && !protocolEncodingName)) {
664 XML_ParserFree(parser);
665 return 0;
666 }
667 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
668
669 if (nameSep) {
670 XmlInitEncodingNS(&initEncoding, &encoding, 0);
671 ns = 1;
672 internalEncoding = XmlGetInternalEncodingNS();
673 namespaceSeparator = *nameSep;
674
675 if (! setContext(parser, implicitContext)) {
676 XML_ParserFree(parser);
677 return 0;
678 }
679 }
680 else {
681 XmlInitEncoding(&initEncoding, &encoding, 0);
682 internalEncoding = XmlGetInternalEncoding();
683 }
684
685 return parser;
686} /* End XML_ParserCreate_MM */
687
688int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
689{
690 if (!encodingName)
691 protocolEncodingName = 0;
692 else {
693 protocolEncodingName = poolCopyString(&tempPool, encodingName);
694 if (!protocolEncodingName)
695 return 0;
696 }
697 return 1;
698}
699
700XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
701 const XML_Char *context,
702 const XML_Char *encodingName)
703{
704 XML_Parser parser = oldParser;
705 DTD *oldDtd = &dtd;
706 XML_StartElementHandler oldStartElementHandler = startElementHandler;
707 XML_EndElementHandler oldEndElementHandler = endElementHandler;
708 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
709 XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
710 XML_CommentHandler oldCommentHandler = commentHandler;
711 XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
712 XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
713 XML_DefaultHandler oldDefaultHandler = defaultHandler;
714 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
715 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
716 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
717 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
718 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
719 XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
720 XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
721 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
722 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
723 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
724 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
725 ELEMENT_TYPE * oldDeclElementType = declElementType;
726
727 void *oldUserData = userData;
728 void *oldHandlerArg = handlerArg;
729 int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
730 void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
731#ifdef XML_DTD
732 int oldParamEntityParsing = paramEntityParsing;
733#endif
734 int oldns_triplets = ns_triplets;
735
736 if (ns) {
737 XML_Char tmp[2];
738
739 *tmp = namespaceSeparator;
740 parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
741 tmp);
742 }
743 else {
744 parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
745 NULL);
746 }
747
748 if (!parser)
749 return 0;
750
751 startElementHandler = oldStartElementHandler;
752 endElementHandler = oldEndElementHandler;
753 characterDataHandler = oldCharacterDataHandler;
754 processingInstructionHandler = oldProcessingInstructionHandler;
755 commentHandler = oldCommentHandler;
756 startCdataSectionHandler = oldStartCdataSectionHandler;
757 endCdataSectionHandler = oldEndCdataSectionHandler;
758 defaultHandler = oldDefaultHandler;
759 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
760 notationDeclHandler = oldNotationDeclHandler;
761 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
762 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
763 notStandaloneHandler = oldNotStandaloneHandler;
764 externalEntityRefHandler = oldExternalEntityRefHandler;
765 unknownEncodingHandler = oldUnknownEncodingHandler;
766 elementDeclHandler = oldElementDeclHandler;
767 attlistDeclHandler = oldAttlistDeclHandler;
768 entityDeclHandler = oldEntityDeclHandler;
769 xmlDeclHandler = oldXmlDeclHandler;
770 declElementType = oldDeclElementType;
771 userData = oldUserData;
772 if (oldUserData == oldHandlerArg)
773 handlerArg = userData;
774 else
775 handlerArg = parser;
776 if (oldExternalEntityRefHandlerArg != oldParser)
777 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
778 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
779 ns_triplets = oldns_triplets;
780#ifdef XML_DTD
781 paramEntityParsing = oldParamEntityParsing;
782 if (context) {
783#endif /* XML_DTD */
784 if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
785 XML_ParserFree(parser);
786 return 0;
787 }
788 processor = externalEntityInitProcessor;
789#ifdef XML_DTD
790 }
791 else {
792 dtdSwap(&dtd, oldDtd);
793 parentParser = oldParser;
794 XmlPrologStateInitExternalEntity(&prologState);
795 dtd.complete = 1;
796 hadExternalDoctype = 1;
797 }
798#endif /* XML_DTD */
799 return parser;
800}
801
802static
803void destroyBindings(BINDING *bindings, XML_Parser parser)
804{
805 for (;;) {
806 BINDING *b = bindings;
807 if (!b)
808 break;
809 bindings = b->nextTagBinding;
810 FREE(b->uri);
811 FREE(b);
812 }
813}
814
815void XML_ParserFree(XML_Parser parser)
816{
817 for (;;) {
818 TAG *p;
819 if (tagStack == 0) {
820 if (freeTagList == 0)
821 break;
822 tagStack = freeTagList;
823 freeTagList = 0;
824 }
825 p = tagStack;
826 tagStack = tagStack->parent;
827 FREE(p->buf);
828 destroyBindings(p->bindings, parser);
829 FREE(p);
830 }
831 destroyBindings(freeBindingList, parser);
832 destroyBindings(inheritedBindings, parser);
833 poolDestroy(&tempPool);
834 poolDestroy(&temp2Pool);
835#ifdef XML_DTD
836 if (parentParser) {
837 if (hadExternalDoctype)
838 dtd.complete = 0;
839 dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
840 }
841#endif /* XML_DTD */
842 dtdDestroy(&dtd, parser);
843 FREE((void *)atts);
844 if (groupConnector)
845 FREE(groupConnector);
846 if (buffer)
847 FREE(buffer);
848 FREE(dataBuf);
849 if (unknownEncodingMem)
850 FREE(unknownEncodingMem);
851 if (unknownEncodingRelease)
852 unknownEncodingRelease(unknownEncodingData);
853 FREE(parser);
854}
855
856void XML_UseParserAsHandlerArg(XML_Parser parser)
857{
858 handlerArg = parser;
859}
860
861void
862XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
863 ns_triplets = do_nst;
864}
865
866void XML_SetUserData(XML_Parser parser, void *p)
867{
868 if (handlerArg == userData)
869 handlerArg = userData = p;
870 else
871 userData = p;
872}
873
874int XML_SetBase(XML_Parser parser, const XML_Char *p)
875{
876 if (p) {
877 p = poolCopyString(&dtd.pool, p);
878 if (!p)
879 return 0;
880 curBase = p;
881 }
882 else
883 curBase = 0;
884 return 1;
885}
886
887const XML_Char *XML_GetBase(XML_Parser parser)
888{
889 return curBase;
890}
891
892int XML_GetSpecifiedAttributeCount(XML_Parser parser)
893{
894 return nSpecifiedAtts;
895}
896
897int XML_GetIdAttributeIndex(XML_Parser parser)
898{
899 return idAttIndex;
900}
901
902void XML_SetElementHandler(XML_Parser parser,
903 XML_StartElementHandler start,
904 XML_EndElementHandler end)
905{
906 startElementHandler = start;
907 endElementHandler = end;
908}
909
910void XML_SetStartElementHandler(XML_Parser parser,
911 XML_StartElementHandler start) {
912 startElementHandler = start;
913}
914
915void XML_SetEndElementHandler(XML_Parser parser,
916 XML_EndElementHandler end) {
917 endElementHandler = end;
918}
919
920void XML_SetCharacterDataHandler(XML_Parser parser,
921 XML_CharacterDataHandler handler)
922{
923 characterDataHandler = handler;
924}
925
926void XML_SetProcessingInstructionHandler(XML_Parser parser,
927 XML_ProcessingInstructionHandler handler)
928{
929 processingInstructionHandler = handler;
930}
931
932void XML_SetCommentHandler(XML_Parser parser,
933 XML_CommentHandler handler)
934{
935 commentHandler = handler;
936}
937
938void XML_SetCdataSectionHandler(XML_Parser parser,
939 XML_StartCdataSectionHandler start,
940 XML_EndCdataSectionHandler end)
941{
942 startCdataSectionHandler = start;
943 endCdataSectionHandler = end;
944}
945
946void XML_SetStartCdataSectionHandler(XML_Parser parser,
947 XML_StartCdataSectionHandler start) {
948 startCdataSectionHandler = start;
949}
950
951void XML_SetEndCdataSectionHandler(XML_Parser parser,
952 XML_EndCdataSectionHandler end) {
953 endCdataSectionHandler = end;
954}
955
956void XML_SetDefaultHandler(XML_Parser parser,
957 XML_DefaultHandler handler)
958{
959 defaultHandler = handler;
960 defaultExpandInternalEntities = 0;
961}
962
963void XML_SetDefaultHandlerExpand(XML_Parser parser,
964 XML_DefaultHandler handler)
965{
966 defaultHandler = handler;
967 defaultExpandInternalEntities = 1;
968}
969
970void XML_SetDoctypeDeclHandler(XML_Parser parser,
971 XML_StartDoctypeDeclHandler start,
972 XML_EndDoctypeDeclHandler end)
973{
974 startDoctypeDeclHandler = start;
975 endDoctypeDeclHandler = end;
976}
977
978void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
979 XML_StartDoctypeDeclHandler start) {
980 startDoctypeDeclHandler = start;
981}
982
983void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
984 XML_EndDoctypeDeclHandler end) {
985 endDoctypeDeclHandler = end;
986}
987
988void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
989 XML_UnparsedEntityDeclHandler handler)
990{
991 unparsedEntityDeclHandler = handler;
992}
993
994void XML_SetNotationDeclHandler(XML_Parser parser,
995 XML_NotationDeclHandler handler)
996{
997 notationDeclHandler = handler;
998}
999
1000void XML_SetNamespaceDeclHandler(XML_Parser parser,
1001 XML_StartNamespaceDeclHandler start,
1002 XML_EndNamespaceDeclHandler end)
1003{
1004 startNamespaceDeclHandler = start;
1005 endNamespaceDeclHandler = end;
1006}
1007
1008void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1009 XML_StartNamespaceDeclHandler start) {
1010 startNamespaceDeclHandler = start;
1011}
1012
1013void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1014 XML_EndNamespaceDeclHandler end) {
1015 endNamespaceDeclHandler = end;
1016}
1017
1018
1019void XML_SetNotStandaloneHandler(XML_Parser parser,
1020 XML_NotStandaloneHandler handler)
1021{
1022 notStandaloneHandler = handler;
1023}
1024
1025void XML_SetExternalEntityRefHandler(XML_Parser parser,
1026 XML_ExternalEntityRefHandler handler)
1027{
1028 externalEntityRefHandler = handler;
1029}
1030
1031void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1032{
1033 if (arg)
1034 externalEntityRefHandlerArg = arg;
1035 else
1036 externalEntityRefHandlerArg = parser;
1037}
1038
1039void XML_SetUnknownEncodingHandler(XML_Parser parser,
1040 XML_UnknownEncodingHandler handler,
1041 void *data)
1042{
1043 unknownEncodingHandler = handler;
1044 unknownEncodingHandlerData = data;
1045}
1046
1047void XML_SetElementDeclHandler(XML_Parser parser,
1048 XML_ElementDeclHandler eldecl)
1049{
1050 elementDeclHandler = eldecl;
1051}
1052
1053void XML_SetAttlistDeclHandler(XML_Parser parser,
1054 XML_AttlistDeclHandler attdecl)
1055{
1056 attlistDeclHandler = attdecl;
1057}
1058
1059void XML_SetEntityDeclHandler(XML_Parser parser,
1060 XML_EntityDeclHandler handler)
1061{
1062 entityDeclHandler = handler;
1063}
1064
1065void XML_SetXmlDeclHandler(XML_Parser parser,
1066 XML_XmlDeclHandler handler) {
1067 xmlDeclHandler = handler;
1068}
1069
1070int XML_SetParamEntityParsing(XML_Parser parser,
1071 enum XML_ParamEntityParsing parsing)
1072{
1073#ifdef XML_DTD
1074 paramEntityParsing = parsing;
1075 return 1;
1076#else
1077 return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
1078#endif
1079}
1080
1081int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1082{
1083 if (len == 0) {
1084 if (!isFinal)
1085 return 1;
1086 positionPtr = bufferPtr;
1087 errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
1088 if (errorCode == XML_ERROR_NONE)
1089 return 1;
1090 eventEndPtr = eventPtr;
1091 processor = errorProcessor;
1092 return 0;
1093 }
1094#ifndef XML_CONTEXT_BYTES
1095 else if (bufferPtr == bufferEnd) {
1096 const char *end;
1097 int nLeftOver;
1098 parseEndByteIndex += len;
1099 positionPtr = s;
1100 if (isFinal) {
1101 errorCode = processor(parser, s, parseEndPtr = s + len, 0);
1102 if (errorCode == XML_ERROR_NONE)
1103 return 1;
1104 eventEndPtr = eventPtr;
1105 processor = errorProcessor;
1106 return 0;
1107 }
1108 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1109 if (errorCode != XML_ERROR_NONE) {
1110 eventEndPtr = eventPtr;
1111 processor = errorProcessor;
1112 return 0;
1113 }
1114 XmlUpdatePosition(encoding, positionPtr, end, &position);
1115 nLeftOver = s + len - end;
1116 if (nLeftOver) {
1117 if (buffer == 0 || nLeftOver > bufferLim - buffer) {
1118 /* FIXME avoid integer overflow */
1119 buffer = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
1120 /* FIXME storage leak if realloc fails */
1121 if (!buffer) {
1122 errorCode = XML_ERROR_NO_MEMORY;
1123 eventPtr = eventEndPtr = 0;
1124 processor = errorProcessor;
1125 return 0;
1126 }
1127 bufferLim = buffer + len * 2;
1128 }
1129 memcpy(buffer, end, nLeftOver);
1130 bufferPtr = buffer;
1131 bufferEnd = buffer + nLeftOver;
1132 }
1133 return 1;
1134 }
1135#endif /* not defined XML_CONTEXT_BYTES */
1136 else {
1137 memcpy(XML_GetBuffer(parser, len), s, len);
1138 return XML_ParseBuffer(parser, len, isFinal);
1139 }
1140}
1141
1142int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1143{
1144 const char *start = bufferPtr;
1145 positionPtr = start;
1146 bufferEnd += len;
1147 parseEndByteIndex += len;
1148 errorCode = processor(parser, start, parseEndPtr = bufferEnd,
1149 isFinal ? (const char **)0 : &bufferPtr);
1150 if (errorCode == XML_ERROR_NONE) {
1151 if (!isFinal)
1152 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1153 return 1;
1154 }
1155 else {
1156 eventEndPtr = eventPtr;
1157 processor = errorProcessor;
1158 return 0;
1159 }
1160}
1161
1162void *XML_GetBuffer(XML_Parser parser, int len)
1163{
1164 if (len > bufferLim - bufferEnd) {
1165 /* FIXME avoid integer overflow */
1166 int neededSize = len + (bufferEnd - bufferPtr);
1167#ifdef XML_CONTEXT_BYTES
1168 int keep = bufferPtr - buffer;
1169
1170 if (keep > XML_CONTEXT_BYTES)
1171 keep = XML_CONTEXT_BYTES;
1172 neededSize += keep;
1173#endif /* defined XML_CONTEXT_BYTES */
1174 if (neededSize <= bufferLim - buffer) {
1175#ifdef XML_CONTEXT_BYTES
1176 if (keep < bufferPtr - buffer) {
1177 int offset = (bufferPtr - buffer) - keep;
1178 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1179 bufferEnd -= offset;
1180 bufferPtr -= offset;
1181 }
1182#else
1183 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1184 bufferEnd = buffer + (bufferEnd - bufferPtr);
1185 bufferPtr = buffer;
1186#endif /* not defined XML_CONTEXT_BYTES */
1187 }
1188 else {
1189 char *newBuf;
1190 int bufferSize = bufferLim - bufferPtr;
1191 if (bufferSize == 0)
1192 bufferSize = INIT_BUFFER_SIZE;
1193 do {
1194 bufferSize *= 2;
1195 } while (bufferSize < neededSize);
1196 newBuf = MALLOC(bufferSize);
1197 if (newBuf == 0) {
1198 errorCode = XML_ERROR_NO_MEMORY;
1199 return 0;
1200 }
1201 bufferLim = newBuf + bufferSize;
1202#ifdef XML_CONTEXT_BYTES
1203 if (bufferPtr) {
1204 int keep = bufferPtr - buffer;
1205 if (keep > XML_CONTEXT_BYTES)
1206 keep = XML_CONTEXT_BYTES;
1207 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1208 FREE(buffer);
1209 buffer = newBuf;
1210 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1211 bufferPtr = buffer + keep;
1212 }
1213 else {
1214 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1215 bufferPtr = buffer = newBuf;
1216 }
1217#else
1218 if (bufferPtr) {
1219 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1220 FREE(buffer);
1221 }
1222 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1223 bufferPtr = buffer = newBuf;
1224#endif /* not defined XML_CONTEXT_BYTES */
1225 }
1226 }
1227 return bufferEnd;
1228}
1229
1230enum XML_Error XML_GetErrorCode(XML_Parser parser)
1231{
1232 return errorCode;
1233}
1234
1235long XML_GetCurrentByteIndex(XML_Parser parser)
1236{
1237 if (eventPtr)
1238 return parseEndByteIndex - (parseEndPtr - eventPtr);
1239 return -1;
1240}
1241
1242int XML_GetCurrentByteCount(XML_Parser parser)
1243{
1244 if (eventEndPtr && eventPtr)
1245 return eventEndPtr - eventPtr;
1246 return 0;
1247}
1248
1249const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1250{
1251#ifdef XML_CONTEXT_BYTES
1252 if (eventPtr && buffer) {
1253 *offset = eventPtr - buffer;
1254 *size = bufferEnd - buffer;
1255 return buffer;
1256 }
1257#endif /* defined XML_CONTEXT_BYTES */
1258 return (char *) 0;
1259}
1260
1261int XML_GetCurrentLineNumber(XML_Parser parser)
1262{
1263 if (eventPtr) {
1264 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1265 positionPtr = eventPtr;
1266 }
1267 return position.lineNumber + 1;
1268}
1269
1270int XML_GetCurrentColumnNumber(XML_Parser parser)
1271{
1272 if (eventPtr) {
1273 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1274 positionPtr = eventPtr;
1275 }
1276 return position.columnNumber;
1277}
1278
1279void XML_DefaultCurrent(XML_Parser parser)
1280{
1281 if (defaultHandler) {
1282 if (openInternalEntities)
1283 reportDefault(parser,
1284 internalEncoding,
1285 openInternalEntities->internalEventPtr,
1286 openInternalEntities->internalEventEndPtr);
1287 else
1288 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1289 }
1290}
1291
1292const XML_LChar *XML_ErrorString(int code)
1293{
1294 static const XML_LChar *message[] = {
1295 0,
1296 XML_T("out of memory"),
1297 XML_T("syntax error"),
1298 XML_T("no element found"),
1299 XML_T("not well-formed (invalid token)"),
1300 XML_T("unclosed token"),
1301 XML_T("unclosed token"),
1302 XML_T("mismatched tag"),
1303 XML_T("duplicate attribute"),
1304 XML_T("junk after document element"),
1305 XML_T("illegal parameter entity reference"),
1306 XML_T("undefined entity"),
1307 XML_T("recursive entity reference"),
1308 XML_T("asynchronous entity"),
1309 XML_T("reference to invalid character number"),
1310 XML_T("reference to binary entity"),
1311 XML_T("reference to external entity in attribute"),
1312 XML_T("xml processing instruction not at start of external entity"),
1313 XML_T("unknown encoding"),
1314 XML_T("encoding specified in XML declaration is incorrect"),
1315 XML_T("unclosed CDATA section"),
1316 XML_T("error in processing external entity reference"),
1317 XML_T("document is not standalone"),
1318 XML_T("unexpected parser state - please send a bug report")
1319 };
1320 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1321 return message[code];
1322 return 0;
1323}
1324
1325const XML_LChar *
1326XML_ExpatVersion(void) {
1327 return VERSION;
1328}
1329
1330XML_Expat_Version
1331XML_ExpatVersionInfo(void) {
1332 XML_Expat_Version version;
1333
1334 version.major = XML_MAJOR_VERSION;
1335 version.minor = XML_MINOR_VERSION;
1336 version.micro = XML_MICRO_VERSION;
1337
1338 return version;
1339}
1340
1341static
1342enum XML_Error contentProcessor(XML_Parser parser,
1343 const char *start,
1344 const char *end,
1345 const char **endPtr)
1346{
1347 return doContent(parser, 0, encoding, start, end, endPtr);
1348}
1349
1350static
1351enum XML_Error externalEntityInitProcessor(XML_Parser parser,
1352 const char *start,
1353 const char *end,
1354 const char **endPtr)
1355{
1356 enum XML_Error result = initializeEncoding(parser);
1357 if (result != XML_ERROR_NONE)
1358 return result;
1359 processor = externalEntityInitProcessor2;
1360 return externalEntityInitProcessor2(parser, start, end, endPtr);
1361}
1362
1363static
1364enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
1365 const char *start,
1366 const char *end,
1367 const char **endPtr)
1368{
1369 const char *next;
1370 int tok = XmlContentTok(encoding, start, end, &next);
1371 switch (tok) {
1372 case XML_TOK_BOM:
1373 start = next;
1374 break;
1375 case XML_TOK_PARTIAL:
1376 if (endPtr) {
1377 *endPtr = start;
1378 return XML_ERROR_NONE;
1379 }
1380 eventPtr = start;
1381 return XML_ERROR_UNCLOSED_TOKEN;
1382 case XML_TOK_PARTIAL_CHAR:
1383 if (endPtr) {
1384 *endPtr = start;
1385 return XML_ERROR_NONE;
1386 }
1387 eventPtr = start;
1388 return XML_ERROR_PARTIAL_CHAR;
1389 }
1390 processor = externalEntityInitProcessor3;
1391 return externalEntityInitProcessor3(parser, start, end, endPtr);
1392}
1393
1394static
1395enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
1396 const char *start,
1397 const char *end,
1398 const char **endPtr)
1399{
1400 const char *next;
1401 int tok = XmlContentTok(encoding, start, end, &next);
1402 switch (tok) {
1403 case XML_TOK_XML_DECL:
1404 {
1405 enum XML_Error result = processXmlDecl(parser, 1, start, next);
1406 if (result != XML_ERROR_NONE)
1407 return result;
1408 start = next;
1409 }
1410 break;
1411 case XML_TOK_PARTIAL:
1412 if (endPtr) {
1413 *endPtr = start;
1414 return XML_ERROR_NONE;
1415 }
1416 eventPtr = start;
1417 return XML_ERROR_UNCLOSED_TOKEN;
1418 case XML_TOK_PARTIAL_CHAR:
1419 if (endPtr) {
1420 *endPtr = start;
1421 return XML_ERROR_NONE;
1422 }
1423 eventPtr = start;
1424 return XML_ERROR_PARTIAL_CHAR;
1425 }
1426 processor = externalEntityContentProcessor;
1427 tagLevel = 1;
1428 return doContent(parser, 1, encoding, start, end, endPtr);
1429}
1430
1431static
1432enum XML_Error externalEntityContentProcessor(XML_Parser parser,
1433 const char *start,
1434 const char *end,
1435 const char **endPtr)
1436{
1437 return doContent(parser, 1, encoding, start, end, endPtr);
1438}
1439
1440static enum XML_Error
1441doContent(XML_Parser parser,
1442 int startTagLevel,
1443 const ENCODING *enc,
1444 const char *s,
1445 const char *end,
1446 const char **nextPtr)
1447{
1448 const char **eventPP;
1449 const char **eventEndPP;
1450 if (enc == encoding) {
1451 eventPP = &eventPtr;
1452 eventEndPP = &eventEndPtr;
1453 }
1454 else {
1455 eventPP = &(openInternalEntities->internalEventPtr);
1456 eventEndPP = &(openInternalEntities->internalEventEndPtr);
1457 }
1458 *eventPP = s;
1459 for (;;) {
1460 const char *next = s; /* XmlContentTok doesn't always set the last arg */
1461 int tok = XmlContentTok(enc, s, end, &next);
1462 *eventEndPP = next;
1463 switch (tok) {
1464 case XML_TOK_TRAILING_CR:
1465 if (nextPtr) {
1466 *nextPtr = s;
1467 return XML_ERROR_NONE;
1468 }
1469 *eventEndPP = end;
1470 if (characterDataHandler) {
1471 XML_Char c = 0xA;
1472 characterDataHandler(handlerArg, &c, 1);
1473 }
1474 else if (defaultHandler)
1475 reportDefault(parser, enc, s, end);
1476 if (startTagLevel == 0)
1477 return XML_ERROR_NO_ELEMENTS;
1478 if (tagLevel != startTagLevel)
1479 return XML_ERROR_ASYNC_ENTITY;
1480 return XML_ERROR_NONE;
1481 case XML_TOK_NONE:
1482 if (nextPtr) {
1483 *nextPtr = s;
1484 return XML_ERROR_NONE;
1485 }
1486 if (startTagLevel > 0) {
1487 if (tagLevel != startTagLevel)
1488 return XML_ERROR_ASYNC_ENTITY;
1489 return XML_ERROR_NONE;
1490 }
1491 return XML_ERROR_NO_ELEMENTS;
1492 case XML_TOK_INVALID:
1493 *eventPP = next;
1494 return XML_ERROR_INVALID_TOKEN;
1495 case XML_TOK_PARTIAL:
1496 if (nextPtr) {
1497 *nextPtr = s;
1498 return XML_ERROR_NONE;
1499 }
1500 return XML_ERROR_UNCLOSED_TOKEN;
1501 case XML_TOK_PARTIAL_CHAR:
1502 if (nextPtr) {
1503 *nextPtr = s;
1504 return XML_ERROR_NONE;
1505 }
1506 return XML_ERROR_PARTIAL_CHAR;
1507 case XML_TOK_ENTITY_REF:
1508 {
1509 const XML_Char *name;
1510 ENTITY *entity;
1511 XML_Char ch = XmlPredefinedEntityName(enc,
1512 s + enc->minBytesPerChar,
1513 next - enc->minBytesPerChar);
1514 if (ch) {
1515 if (characterDataHandler)
1516 characterDataHandler(handlerArg, &ch, 1);
1517 else if (defaultHandler)
1518 reportDefault(parser, enc, s, next);
1519 break;
1520 }
1521 name = poolStoreString(&dtd.pool, enc,
1522 s + enc->minBytesPerChar,
1523 next - enc->minBytesPerChar);
1524 if (!name)
1525 return XML_ERROR_NO_MEMORY;
1526 entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
1527 poolDiscard(&dtd.pool);
1528 if (!entity) {
1529 if (dtd.complete || dtd.standalone)
1530 return XML_ERROR_UNDEFINED_ENTITY;
1531 if (defaultHandler)
1532 reportDefault(parser, enc, s, next);
1533 break;
1534 }
1535 if (entity->open)
1536 return XML_ERROR_RECURSIVE_ENTITY_REF;
1537 if (entity->notation)
1538 return XML_ERROR_BINARY_ENTITY_REF;
1539 if (entity) {
1540 if (entity->textPtr) {
1541 enum XML_Error result;
1542 OPEN_INTERNAL_ENTITY openEntity;
1543 if (defaultHandler && !defaultExpandInternalEntities) {
1544 reportDefault(parser, enc, s, next);
1545 break;
1546 }
1547 entity->open = 1;
1548 openEntity.next = openInternalEntities;
1549 openInternalEntities = &openEntity;
1550 openEntity.entity = entity;
1551 openEntity.internalEventPtr = 0;
1552 openEntity.internalEventEndPtr = 0;
1553 result = doContent(parser,
1554 tagLevel,
1555 internalEncoding,
1556 (char *)entity->textPtr,
1557 (char *)(entity->textPtr + entity->textLen),
1558 0);
1559 entity->open = 0;
1560 openInternalEntities = openEntity.next;
1561 if (result)
1562 return result;
1563 }
1564 else if (externalEntityRefHandler) {
1565 const XML_Char *context;
1566 entity->open = 1;
1567 context = getContext(parser);
1568 entity->open = 0;
1569 if (!context)
1570 return XML_ERROR_NO_MEMORY;
1571 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
1572 context,
1573 entity->base,
1574 entity->systemId,
1575 entity->publicId))
1576 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
1577 poolDiscard(&tempPool);
1578 }
1579 else if (defaultHandler)
1580 reportDefault(parser, enc, s, next);
1581 }
1582 break;
1583 }
1584 case XML_TOK_START_TAG_WITH_ATTS:
1585 if (!startElementHandler) {
1586 enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
1587 if (result)
1588 return result;
1589 }
1590 /* fall through */
1591 case XML_TOK_START_TAG_NO_ATTS:
1592 {
1593 TAG *tag;
1594 if (freeTagList) {
1595 tag = freeTagList;
1596 freeTagList = freeTagList->parent;
1597 }
1598 else {
1599 tag = MALLOC(sizeof(TAG));
1600 if (!tag)
1601 return XML_ERROR_NO_MEMORY;
1602 tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
1603 if (!tag->buf)
1604 return XML_ERROR_NO_MEMORY;
1605 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
1606 }
1607 tag->bindings = 0;
1608 tag->parent = tagStack;
1609 tagStack = tag;
1610 tag->name.localPart = 0;
1611 tag->rawName = s + enc->minBytesPerChar;
1612 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
1613 if (nextPtr) {
1614 /* Need to guarantee that:
1615 tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
1616 if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
1617 int bufSize = tag->rawNameLength * 4;
1618 bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
1619 tag->buf = REALLOC(tag->buf, bufSize);
1620 if (!tag->buf)
1621 return XML_ERROR_NO_MEMORY;
1622 tag->bufEnd = tag->buf + bufSize;
1623 }
1624 memcpy(tag->buf, tag->rawName, tag->rawNameLength);
1625 tag->rawName = tag->buf;
1626 }
1627 ++tagLevel;
1628 if (startElementHandler) {
1629 enum XML_Error result;
1630 XML_Char *toPtr;
1631 for (;;) {
1632 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
1633 const char *fromPtr = tag->rawName;
1634 int bufSize;
1635 if (nextPtr)
1636 toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
1637 else
1638 toPtr = (XML_Char *)tag->buf;
1639 tag->name.str = toPtr;
1640 XmlConvert(enc,
1641 &fromPtr, rawNameEnd,
1642 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
1643 if (fromPtr == rawNameEnd)
1644 break;
1645 bufSize = (tag->bufEnd - tag->buf) << 1;
1646 tag->buf = REALLOC(tag->buf, bufSize);
1647 if (!tag->buf)
1648 return XML_ERROR_NO_MEMORY;
1649 tag->bufEnd = tag->buf + bufSize;
1650 if (nextPtr)
1651 tag->rawName = tag->buf;
1652 }
1653 *toPtr = XML_T('\0');
1654 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
1655 if (result)
1656 return result;
1657 startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
1658 poolClear(&tempPool);
1659 }
1660 else {
1661 tag->name.str = 0;
1662 if (defaultHandler)
1663 reportDefault(parser, enc, s, next);
1664 }
1665 break;
1666 }
1667 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
1668 if (!startElementHandler) {
1669 enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
1670 if (result)
1671 return result;
1672 }
1673 /* fall through */
1674 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
1675 if (startElementHandler || endElementHandler) {
1676 const char *rawName = s + enc->minBytesPerChar;
1677 enum XML_Error result;
1678 BINDING *bindings = 0;
1679 TAG_NAME name;
1680 name.str = poolStoreString(&tempPool, enc, rawName,
1681 rawName + XmlNameLength(enc, rawName));
1682 if (!name.str)
1683 return XML_ERROR_NO_MEMORY;
1684 poolFinish(&tempPool);
1685 result = storeAtts(parser, enc, s, &name, &bindings);
1686 if (result)
1687 return result;
1688 poolFinish(&tempPool);
1689 if (startElementHandler)
1690 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
1691 if (endElementHandler) {
1692 if (startElementHandler)
1693 *eventPP = *eventEndPP;
1694 endElementHandler(handlerArg, name.str);
1695 }
1696 poolClear(&tempPool);
1697 while (bindings) {
1698 BINDING *b = bindings;
1699 if (endNamespaceDeclHandler)
1700 endNamespaceDeclHandler(handlerArg, b->prefix->name);
1701 bindings = bindings->nextTagBinding;
1702 b->nextTagBinding = freeBindingList;
1703 freeBindingList = b;
1704 b->prefix->binding = b->prevPrefixBinding;
1705 }
1706 }
1707 else if (defaultHandler)
1708 reportDefault(parser, enc, s, next);
1709 if (tagLevel == 0)
1710 return epilogProcessor(parser, next, end, nextPtr);
1711 break;
1712 case XML_TOK_END_TAG:
1713 if (tagLevel == startTagLevel)
1714 return XML_ERROR_ASYNC_ENTITY;
1715 else {
1716 int len;
1717 const char *rawName;
1718 TAG *tag = tagStack;
1719 tagStack = tag->parent;
1720 tag->parent = freeTagList;
1721 freeTagList = tag;
1722 rawName = s + enc->minBytesPerChar*2;
1723 len = XmlNameLength(enc, rawName);
1724 if (len != tag->rawNameLength
1725 || memcmp(tag->rawName, rawName, len) != 0) {
1726 *eventPP = rawName;
1727 return XML_ERROR_TAG_MISMATCH;
1728 }
1729 --tagLevel;
1730 if (endElementHandler && tag->name.str) {
1731 if (tag->name.localPart) {
1732 XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
1733 const XML_Char *from = tag->name.localPart;
1734 while ((*to++ = *from++) != 0)
1735 ;
1736 }
1737 endElementHandler(handlerArg, tag->name.str);
1738 }
1739 else if (defaultHandler)
1740 reportDefault(parser, enc, s, next);
1741 while (tag->bindings) {
1742 BINDING *b = tag->bindings;
1743 if (endNamespaceDeclHandler)
1744 endNamespaceDeclHandler(handlerArg, b->prefix->name);
1745 tag->bindings = tag->bindings->nextTagBinding;
1746 b->nextTagBinding = freeBindingList;
1747 freeBindingList = b;
1748 b->prefix->binding = b->prevPrefixBinding;
1749 }
1750 if (tagLevel == 0)
1751 return epilogProcessor(parser, next, end, nextPtr);
1752 }
1753 break;
1754 case XML_TOK_CHAR_REF:
1755 {
1756 int n = XmlCharRefNumber(enc, s);
1757 if (n < 0)
1758 return XML_ERROR_BAD_CHAR_REF;
1759 if (characterDataHandler) {
1760 XML_Char buf[XML_ENCODE_MAX];
1761 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
1762 }
1763 else if (defaultHandler)
1764 reportDefault(parser, enc, s, next);
1765 }
1766 break;
1767 case XML_TOK_XML_DECL:
1768 return XML_ERROR_MISPLACED_XML_PI;
1769 case XML_TOK_DATA_NEWLINE:
1770 if (characterDataHandler) {
1771 XML_Char c = 0xA;
1772 characterDataHandler(handlerArg, &c, 1);
1773 }
1774 else if (defaultHandler)
1775 reportDefault(parser, enc, s, next);
1776 break;
1777 case XML_TOK_CDATA_SECT_OPEN:
1778 {
1779 enum XML_Error result;
1780 if (startCdataSectionHandler)
1781 startCdataSectionHandler(handlerArg);
1782#if 0
1783 /* Suppose you doing a transformation on a document that involves
1784 changing only the character data. You set up a defaultHandler
1785 and a characterDataHandler. The defaultHandler simply copies
1786 characters through. The characterDataHandler does the transformation
1787 and writes the characters out escaping them as necessary. This case
1788 will fail to work if we leave out the following two lines (because &
1789 and < inside CDATA sections will be incorrectly escaped).
1790
1791 However, now we have a start/endCdataSectionHandler, so it seems
1792 easier to let the user deal with this. */
1793
1794 else if (characterDataHandler)
1795 characterDataHandler(handlerArg, dataBuf, 0);
1796#endif
1797 else if (defaultHandler)
1798 reportDefault(parser, enc, s, next);
1799 result = doCdataSection(parser, enc, &next, end, nextPtr);
1800 if (!next) {
1801 processor = cdataSectionProcessor;
1802 return result;
1803 }
1804 }
1805 break;
1806 case XML_TOK_TRAILING_RSQB:
1807 if (nextPtr) {
1808 *nextPtr = s;
1809 return XML_ERROR_NONE;
1810 }
1811 if (characterDataHandler) {
1812 if (MUST_CONVERT(enc, s)) {
1813 ICHAR *dataPtr = (ICHAR *)dataBuf;
1814 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
1815 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1816 }
1817 else
1818 characterDataHandler(handlerArg,
1819 (XML_Char *)s,
1820 (XML_Char *)end - (XML_Char *)s);
1821 }
1822 else if (defaultHandler)
1823 reportDefault(parser, enc, s, end);
1824 if (startTagLevel == 0) {
1825 *eventPP = end;
1826 return XML_ERROR_NO_ELEMENTS;
1827 }
1828 if (tagLevel != startTagLevel) {
1829 *eventPP = end;
1830 return XML_ERROR_ASYNC_ENTITY;
1831 }
1832 return XML_ERROR_NONE;
1833 case XML_TOK_DATA_CHARS:
1834 if (characterDataHandler) {
1835 if (MUST_CONVERT(enc, s)) {
1836 for (;;) {
1837 ICHAR *dataPtr = (ICHAR *)dataBuf;
1838 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
1839 *eventEndPP = s;
1840 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1841 if (s == next)
1842 break;
1843 *eventPP = s;
1844 }
1845 }
1846 else
1847 characterDataHandler(handlerArg,
1848 (XML_Char *)s,
1849 (XML_Char *)next - (XML_Char *)s);
1850 }
1851 else if (defaultHandler)
1852 reportDefault(parser, enc, s, next);
1853 break;
1854 case XML_TOK_PI:
1855 if (!reportProcessingInstruction(parser, enc, s, next))
1856 return XML_ERROR_NO_MEMORY;
1857 break;
1858 case XML_TOK_COMMENT:
1859 if (!reportComment(parser, enc, s, next))
1860 return XML_ERROR_NO_MEMORY;
1861 break;
1862 default:
1863 if (defaultHandler)
1864 reportDefault(parser, enc, s, next);
1865 break;
1866 }
1867 *eventPP = s = next;
1868 }
1869 /* not reached */
1870}
1871
1872/* If tagNamePtr is non-null, build a real list of attributes,
1873otherwise just check the attributes for well-formedness. */
1874
1875static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
1876 const char *attStr, TAG_NAME *tagNamePtr,
1877 BINDING **bindingsPtr)
1878{
1879 ELEMENT_TYPE *elementType = 0;
1880 int nDefaultAtts = 0;
1881 const XML_Char **appAtts; /* the attribute list to pass to the application */
1882 int attIndex = 0;
1883 int i;
1884 int n;
1885 int nPrefixes = 0;
1886 BINDING *binding;
1887 const XML_Char *localPart;
1888
1889 /* lookup the element type name */
1890 if (tagNamePtr) {
1891 elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
1892 if (!elementType) {
1893 tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
1894 if (!tagNamePtr->str)
1895 return XML_ERROR_NO_MEMORY;
1896 elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
1897 if (!elementType)
1898 return XML_ERROR_NO_MEMORY;
1899 if (ns && !setElementTypePrefix(parser, elementType))
1900 return XML_ERROR_NO_MEMORY;
1901 }
1902 nDefaultAtts = elementType->nDefaultAtts;
1903 }
1904 /* get the attributes from the tokenizer */
1905 n = XmlGetAttributes(enc, attStr, attsSize, atts);
1906 if (n + nDefaultAtts > attsSize) {
1907 int oldAttsSize = attsSize;
1908 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
1909 atts = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
1910 if (!atts)
1911 return XML_ERROR_NO_MEMORY;
1912 if (n > oldAttsSize)
1913 XmlGetAttributes(enc, attStr, n, atts);
1914 }
1915 appAtts = (const XML_Char **)atts;
1916 for (i = 0; i < n; i++) {
1917 /* add the name and value to the attribute list */
1918 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
1919 atts[i].name
1920 + XmlNameLength(enc, atts[i].name));
1921 if (!attId)
1922 return XML_ERROR_NO_MEMORY;
1923 /* detect duplicate attributes */
1924 if ((attId->name)[-1]) {
1925 if (enc == encoding)
1926 eventPtr = atts[i].name;
1927 return XML_ERROR_DUPLICATE_ATTRIBUTE;
1928 }
1929 (attId->name)[-1] = 1;
1930 appAtts[attIndex++] = attId->name;
1931 if (!atts[i].normalized) {
1932 enum XML_Error result;
1933 int isCdata = 1;
1934
1935 /* figure out whether declared as other than CDATA */
1936 if (attId->maybeTokenized) {
1937 int j;
1938 for (j = 0; j < nDefaultAtts; j++) {
1939 if (attId == elementType->defaultAtts[j].id) {
1940 isCdata = elementType->defaultAtts[j].isCdata;
1941 break;
1942 }
1943 }
1944 }
1945
1946 /* normalize the attribute value */
1947 result = storeAttributeValue(parser, enc, isCdata,
1948 atts[i].valuePtr, atts[i].valueEnd,
1949 &tempPool);
1950 if (result)
1951 return result;
1952 if (tagNamePtr) {
1953 appAtts[attIndex] = poolStart(&tempPool);
1954 poolFinish(&tempPool);
1955 }
1956 else
1957 poolDiscard(&tempPool);
1958 }
1959 else if (tagNamePtr) {
1960 /* the value did not need normalizing */
1961 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
1962 if (appAtts[attIndex] == 0)
1963 return XML_ERROR_NO_MEMORY;
1964 poolFinish(&tempPool);
1965 }
1966 /* handle prefixed attribute names */
1967 if (attId->prefix && tagNamePtr) {
1968 if (attId->xmlns) {
1969 /* deal with namespace declarations here */
1970 if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
1971 return XML_ERROR_NO_MEMORY;
1972 --attIndex;
1973 }
1974 else {
1975 /* deal with other prefixed names later */
1976 attIndex++;
1977 nPrefixes++;
1978 (attId->name)[-1] = 2;
1979 }
1980 }
1981 else
1982 attIndex++;
1983 }
1984 if (tagNamePtr) {
1985 int j;
1986 nSpecifiedAtts = attIndex;
1987 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
1988 for (i = 0; i < attIndex; i += 2)
1989 if (appAtts[i] == elementType->idAtt->name) {
1990 idAttIndex = i;
1991 break;
1992 }
1993 }
1994 else
1995 idAttIndex = -1;
1996 /* do attribute defaulting */
1997 for (j = 0; j < nDefaultAtts; j++) {
1998 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
1999 if (!(da->id->name)[-1] && da->value) {
2000 if (da->id->prefix) {
2001 if (da->id->xmlns) {
2002 if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
2003 return XML_ERROR_NO_MEMORY;
2004 }
2005 else {
2006 (da->id->name)[-1] = 2;
2007 nPrefixes++;
2008 appAtts[attIndex++] = da->id->name;
2009 appAtts[attIndex++] = da->value;
2010 }
2011 }
2012 else {
2013 (da->id->name)[-1] = 1;
2014 appAtts[attIndex++] = da->id->name;
2015 appAtts[attIndex++] = da->value;
2016 }
2017 }
2018 }
2019 appAtts[attIndex] = 0;
2020 }
2021 i = 0;
2022 if (nPrefixes) {
2023 /* expand prefixed attribute names */
2024 for (; i < attIndex; i += 2) {
2025 if (appAtts[i][-1] == 2) {
2026 ATTRIBUTE_ID *id;
2027 ((XML_Char *)(appAtts[i]))[-1] = 0;
2028 id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
2029 if (id->prefix->binding) {
2030 int j;
2031 const BINDING *b = id->prefix->binding;
2032 const XML_Char *s = appAtts[i];
2033 for (j = 0; j < b->uriLen; j++) {
2034 if (!poolAppendChar(&tempPool, b->uri[j]))
2035 return XML_ERROR_NO_MEMORY;
2036 }
2037 while (*s++ != ':')
2038 ;
2039 do {
2040 if (!poolAppendChar(&tempPool, *s))
2041 return XML_ERROR_NO_MEMORY;
2042 } while (*s++);
2043 if (ns_triplets) {
2044 tempPool.ptr[-1] = namespaceSeparator;
2045 s = b->prefix->name;
2046 do {
2047 if (!poolAppendChar(&tempPool, *s))
2048 return XML_ERROR_NO_MEMORY;
2049 } while (*s++);
2050 }
2051
2052 appAtts[i] = poolStart(&tempPool);
2053 poolFinish(&tempPool);
2054 }
2055 if (!--nPrefixes)
2056 break;
2057 }
2058 else
2059 ((XML_Char *)(appAtts[i]))[-1] = 0;
2060 }
2061 }
2062 /* clear the flags that say whether attributes were specified */
2063 for (; i < attIndex; i += 2)
2064 ((XML_Char *)(appAtts[i]))[-1] = 0;
2065 if (!tagNamePtr)
2066 return XML_ERROR_NONE;
2067 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2068 binding->attId->name[-1] = 0;
2069 /* expand the element type name */
2070 if (elementType->prefix) {
2071 binding = elementType->prefix->binding;
2072 if (!binding)
2073 return XML_ERROR_NONE;
2074 localPart = tagNamePtr->str;
2075 while (*localPart++ != XML_T(':'))
2076 ;
2077 }
2078 else if (dtd.defaultPrefix.binding) {
2079 binding = dtd.defaultPrefix.binding;
2080 localPart = tagNamePtr->str;
2081 }
2082 else
2083 return XML_ERROR_NONE;
2084 tagNamePtr->localPart = localPart;
2085 tagNamePtr->uriLen = binding->uriLen;
2086 for (i = 0; localPart[i++];)
2087 ;
2088 n = i + binding->uriLen;
2089 if (n > binding->uriAlloc) {
2090 TAG *p;
2091 XML_Char *uri = MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
2092 if (!uri)
2093 return XML_ERROR_NO_MEMORY;
2094 binding->uriAlloc = n + EXPAND_SPARE;
2095 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2096 for (p = tagStack; p; p = p->parent)
2097 if (p->name.str == binding->uri)
2098 p->name.str = uri;
2099 FREE(binding->uri);
2100 binding->uri = uri;
2101 }
2102 memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
2103 tagNamePtr->str = binding->uri;
2104 return XML_ERROR_NONE;
2105}
2106
2107static
2108int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
2109{
2110 BINDING *b;
2111 int len;
2112 for (len = 0; uri[len]; len++)
2113 ;
2114 if (namespaceSeparator)
2115 len++;
2116 if (freeBindingList) {
2117 b = freeBindingList;
2118 if (len > b->uriAlloc) {
2119 b->uri = REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
2120 if (!b->uri)
2121 return 0;
2122 b->uriAlloc = len + EXPAND_SPARE;
2123 }
2124 freeBindingList = b->nextTagBinding;
2125 }
2126 else {
2127 b = MALLOC(sizeof(BINDING));
2128 if (!b)
2129 return 0;
2130 b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
2131 if (!b->uri) {
2132 FREE(b);
2133 return 0;
2134 }
2135 b->uriAlloc = len + EXPAND_SPARE;
2136 }
2137 b->uriLen = len;
2138 memcpy(b->uri, uri, len * sizeof(XML_Char));
2139 if (namespaceSeparator)
2140 b->uri[len - 1] = namespaceSeparator;
2141 b->prefix = prefix;
2142 b->attId = attId;
2143 b->prevPrefixBinding = prefix->binding;
2144 if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
2145 prefix->binding = 0;
2146 else
2147 prefix->binding = b;
2148 b->nextTagBinding = *bindingsPtr;
2149 *bindingsPtr = b;
2150 if (startNamespaceDeclHandler)
2151 startNamespaceDeclHandler(handlerArg, prefix->name,
2152 prefix->binding ? uri : 0);
2153 return 1;
2154}
2155
2156/* The idea here is to avoid using stack for each CDATA section when
2157the whole file is parsed with one call. */
2158
2159static
2160enum XML_Error cdataSectionProcessor(XML_Parser parser,
2161 const char *start,
2162 const char *end,
2163 const char **endPtr)
2164{
2165 enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
2166 if (start) {
2167 processor = contentProcessor;
2168 return contentProcessor(parser, start, end, endPtr);
2169 }
2170 return result;
2171}
2172
2173/* startPtr gets set to non-null is the section is closed, and to null if
2174the section is not yet closed. */
2175
2176static
2177enum XML_Error doCdataSection(XML_Parser parser,
2178 const ENCODING *enc,
2179 const char **startPtr,
2180 const char *end,
2181 const char **nextPtr)
2182{
2183 const char *s = *startPtr;
2184 const char **eventPP;
2185 const char **eventEndPP;
2186 if (enc == encoding) {
2187 eventPP = &eventPtr;
2188 *eventPP = s;
2189 eventEndPP = &eventEndPtr;
2190 }
2191 else {
2192 eventPP = &(openInternalEntities->internalEventPtr);
2193 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2194 }
2195 *eventPP = s;
2196 *startPtr = 0;
2197 for (;;) {
2198 const char *next;
2199 int tok = XmlCdataSectionTok(enc, s, end, &next);
2200 *eventEndPP = next;
2201 switch (tok) {
2202 case XML_TOK_CDATA_SECT_CLOSE:
2203 if (endCdataSectionHandler)
2204 endCdataSectionHandler(handlerArg);
2205#if 0
2206 /* see comment under XML_TOK_CDATA_SECT_OPEN */
2207 else if (characterDataHandler)
2208 characterDataHandler(handlerArg, dataBuf, 0);
2209#endif
2210 else if (defaultHandler)
2211 reportDefault(parser, enc, s, next);
2212 *startPtr = next;
2213 return XML_ERROR_NONE;
2214 case XML_TOK_DATA_NEWLINE:
2215 if (characterDataHandler) {
2216 XML_Char c = 0xA;
2217 characterDataHandler(handlerArg, &c, 1);
2218 }
2219 else if (defaultHandler)
2220 reportDefault(parser, enc, s, next);
2221 break;
2222 case XML_TOK_DATA_CHARS:
2223 if (characterDataHandler) {
2224 if (MUST_CONVERT(enc, s)) {
2225 for (;;) {
2226 ICHAR *dataPtr = (ICHAR *)dataBuf;
2227 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2228 *eventEndPP = next;
2229 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
2230 if (s == next)
2231 break;
2232 *eventPP = s;
2233 }
2234 }
2235 else
2236 characterDataHandler(handlerArg,
2237 (XML_Char *)s,
2238 (XML_Char *)next - (XML_Char *)s);
2239 }
2240 else if (defaultHandler)
2241 reportDefault(parser, enc, s, next);
2242 break;
2243 case XML_TOK_INVALID:
2244 *eventPP = next;
2245 return XML_ERROR_INVALID_TOKEN;
2246 case XML_TOK_PARTIAL_CHAR:
2247 if (nextPtr) {
2248 *nextPtr = s;
2249 return XML_ERROR_NONE;
2250 }
2251 return XML_ERROR_PARTIAL_CHAR;
2252 case XML_TOK_PARTIAL:
2253 case XML_TOK_NONE:
2254 if (nextPtr) {
2255 *nextPtr = s;
2256 return XML_ERROR_NONE;
2257 }
2258 return XML_ERROR_UNCLOSED_CDATA_SECTION;
2259 default:
2260 *eventPP = next;
2261 return XML_ERROR_UNEXPECTED_STATE;
2262 }
2263 *eventPP = s = next;
2264 }
2265 /* not reached */
2266}
2267
2268#ifdef XML_DTD
2269
2270/* The idea here is to avoid using stack for each IGNORE section when
2271the whole file is parsed with one call. */
2272
2273static
2274enum XML_Error ignoreSectionProcessor(XML_Parser parser,
2275 const char *start,
2276 const char *end,
2277 const char **endPtr)
2278{
2279 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
2280 if (start) {
2281 processor = prologProcessor;
2282 return prologProcessor(parser, start, end, endPtr);
2283 }
2284 return result;
2285}
2286
2287/* startPtr gets set to non-null is the section is closed, and to null if
2288the section is not yet closed. */
2289
2290static
2291enum XML_Error doIgnoreSection(XML_Parser parser,
2292 const ENCODING *enc,
2293 const char **startPtr,
2294 const char *end,
2295 const char **nextPtr)
2296{
2297 const char *next;
2298 int tok;
2299 const char *s = *startPtr;
2300 const char **eventPP;
2301 const char **eventEndPP;
2302 if (enc == encoding) {
2303 eventPP = &eventPtr;
2304 *eventPP = s;
2305 eventEndPP = &eventEndPtr;
2306 }
2307 else {
2308 eventPP = &(openInternalEntities->internalEventPtr);
2309 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2310 }
2311 *eventPP = s;
2312 *startPtr = 0;
2313 tok = XmlIgnoreSectionTok(enc, s, end, &next);
2314 *eventEndPP = next;
2315 switch (tok) {
2316 case XML_TOK_IGNORE_SECT:
2317 if (defaultHandler)
2318 reportDefault(parser, enc, s, next);
2319 *startPtr = next;
2320 return XML_ERROR_NONE;
2321 case XML_TOK_INVALID:
2322 *eventPP = next;
2323 return XML_ERROR_INVALID_TOKEN;
2324 case XML_TOK_PARTIAL_CHAR:
2325 if (nextPtr) {
2326 *nextPtr = s;
2327 return XML_ERROR_NONE;
2328 }
2329 return XML_ERROR_PARTIAL_CHAR;
2330 case XML_TOK_PARTIAL:
2331 case XML_TOK_NONE:
2332 if (nextPtr) {
2333 *nextPtr = s;
2334 return XML_ERROR_NONE;
2335 }
2336 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2337 default:
2338 *eventPP = next;
2339 return XML_ERROR_UNEXPECTED_STATE;
2340 }
2341 /* not reached */
2342}
2343
2344#endif /* XML_DTD */
2345
2346static enum XML_Error
2347initializeEncoding(XML_Parser parser)
2348{
2349 const char *s;
2350#ifdef XML_UNICODE
2351 char encodingBuf[128];
2352 if (!protocolEncodingName)
2353 s = 0;
2354 else {
2355 int i;
2356 for (i = 0; protocolEncodingName[i]; i++) {
2357 if (i == sizeof(encodingBuf) - 1
2358 || (protocolEncodingName[i] & ~0x7f) != 0) {
2359 encodingBuf[0] = '\0';
2360 break;
2361 }
2362 encodingBuf[i] = (char)protocolEncodingName[i];
2363 }
2364 encodingBuf[i] = '\0';
2365 s = encodingBuf;
2366 }
2367#else
2368 s = protocolEncodingName;
2369#endif
2370 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
2371 return XML_ERROR_NONE;
2372 return handleUnknownEncoding(parser, protocolEncodingName);
2373}
2374
2375static enum XML_Error
2376processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
2377 const char *s, const char *next)
2378{
2379 const char *encodingName = 0;
2380 const char *storedEncName = 0;
2381 const ENCODING *newEncoding = 0;
2382 const char *version = 0;
2383 const char *versionend;
2384 const char *storedversion = 0;
2385 int standalone = -1;
2386 if (!(ns
2387 ? XmlParseXmlDeclNS
2388 : XmlParseXmlDecl)(isGeneralTextEntity,
2389 encoding,
2390 s,
2391 next,
2392 &eventPtr,
2393 &version,
2394 &versionend,
2395 &encodingName,
2396 &newEncoding,
2397 &standalone))
2398 return XML_ERROR_SYNTAX;
2399 if (!isGeneralTextEntity && standalone == 1) {
2400 dtd.standalone = 1;
2401#ifdef XML_DTD
2402 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
2403 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
2404#endif /* XML_DTD */
2405 }
2406 if (xmlDeclHandler) {
2407 if (encodingName) {
2408 storedEncName = poolStoreString(&temp2Pool,
2409 encoding,
2410 encodingName,
2411 encodingName
2412 + XmlNameLength(encoding, encodingName));
2413 if (! storedEncName)
2414 return XML_ERROR_NO_MEMORY;
2415 poolFinish(&temp2Pool);
2416 }
2417 if (version) {
2418 storedversion = poolStoreString(&temp2Pool,
2419 encoding,
2420 version,
2421 versionend - encoding->minBytesPerChar);
2422 if (! storedversion)
2423 return XML_ERROR_NO_MEMORY;
2424 }
2425 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
2426 }
2427 else if (defaultHandler)
2428 reportDefault(parser, encoding, s, next);
2429 if (!protocolEncodingName) {
2430 if (newEncoding) {
2431 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
2432 eventPtr = encodingName;
2433 return XML_ERROR_INCORRECT_ENCODING;
2434 }
2435 encoding = newEncoding;
2436 }
2437 else if (encodingName) {
2438 enum XML_Error result;
2439 if (! storedEncName) {
2440 storedEncName = poolStoreString(&temp2Pool,
2441 encoding,
2442 encodingName,
2443 encodingName
2444 + XmlNameLength(encoding, encodingName));
2445 if (! storedEncName)
2446 return XML_ERROR_NO_MEMORY;
2447 }
2448 result = handleUnknownEncoding(parser, storedEncName);
2449 poolClear(&tempPool);
2450 if (result == XML_ERROR_UNKNOWN_ENCODING)
2451 eventPtr = encodingName;
2452 return result;
2453 }
2454 }
2455
2456 if (storedEncName || storedversion)
2457 poolClear(&temp2Pool);
2458
2459 return XML_ERROR_NONE;
2460}
2461
2462static enum XML_Error
2463handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
2464{
2465 if (unknownEncodingHandler) {
2466 XML_Encoding info;
2467 int i;
2468 for (i = 0; i < 256; i++)
2469 info.map[i] = -1;
2470 info.convert = 0;
2471 info.data = 0;
2472 info.release = 0;
2473 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
2474 ENCODING *enc;
2475 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
2476 if (!unknownEncodingMem) {
2477 if (info.release)
2478 info.release(info.data);
2479 return XML_ERROR_NO_MEMORY;
2480 }
2481 enc = (ns
2482 ? XmlInitUnknownEncodingNS
2483 : XmlInitUnknownEncoding)(unknownEncodingMem,
2484 info.map,
2485 info.convert,
2486 info.data);
2487 if (enc) {
2488 unknownEncodingData = info.data;
2489 unknownEncodingRelease = info.release;
2490 encoding = enc;
2491 return XML_ERROR_NONE;
2492 }
2493 }
2494 if (info.release)
2495 info.release(info.data);
2496 }
2497 return XML_ERROR_UNKNOWN_ENCODING;
2498}
2499
2500static enum XML_Error
2501prologInitProcessor(XML_Parser parser,
2502 const char *s,
2503 const char *end,
2504 const char **nextPtr)
2505{
2506 enum XML_Error result = initializeEncoding(parser);
2507 if (result != XML_ERROR_NONE)
2508 return result;
2509 processor = prologProcessor;
2510 return prologProcessor(parser, s, end, nextPtr);
2511}
2512
2513static enum XML_Error
2514prologProcessor(XML_Parser parser,
2515 const char *s,
2516 const char *end,
2517 const char **nextPtr)
2518{
2519 const char *next;
2520 int tok = XmlPrologTok(encoding, s, end, &next);
2521 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
2522}
2523
2524static enum XML_Error
2525doProlog(XML_Parser parser,
2526 const ENCODING *enc,
2527 const char *s,
2528 const char *end,
2529 int tok,
2530 const char *next,
2531 const char **nextPtr)
2532{
2533#ifdef XML_DTD
2534 static const XML_Char externalSubsetName[] = { '#' , '\0' };
2535#endif /* XML_DTD */
2536
2537 const char **eventPP;
2538 const char **eventEndPP;
2539 enum XML_Content_Quant quant;
2540
2541 if (enc == encoding) {
2542 eventPP = &eventPtr;
2543 eventEndPP = &eventEndPtr;
2544 }
2545 else {
2546 eventPP = &(openInternalEntities->internalEventPtr);
2547 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2548 }
2549 for (;;) {
2550 int role;
2551 *eventPP = s;
2552 *eventEndPP = next;
2553 if (tok <= 0) {
2554 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
2555 *nextPtr = s;
2556 return XML_ERROR_NONE;
2557 }
2558 switch (tok) {
2559 case XML_TOK_INVALID:
2560 *eventPP = next;
2561 return XML_ERROR_INVALID_TOKEN;
2562 case XML_TOK_PARTIAL:
2563 return XML_ERROR_UNCLOSED_TOKEN;
2564 case XML_TOK_PARTIAL_CHAR:
2565 return XML_ERROR_PARTIAL_CHAR;
2566 case XML_TOK_NONE:
2567#ifdef XML_DTD
2568 if (enc != encoding)
2569 return XML_ERROR_NONE;
2570 if (parentParser) {
2571 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
2572 == XML_ROLE_ERROR)
2573 return XML_ERROR_SYNTAX;
2574 hadExternalDoctype = 0;
2575 return XML_ERROR_NONE;
2576 }
2577#endif /* XML_DTD */
2578 return XML_ERROR_NO_ELEMENTS;
2579 default:
2580 tok = -tok;
2581 next = end;
2582 break;
2583 }
2584 }
2585 role = XmlTokenRole(&prologState, tok, s, next, enc);
2586 switch (role) {
2587 case XML_ROLE_XML_DECL:
2588 {
2589 enum XML_Error result = processXmlDecl(parser, 0, s, next);
2590 if (result != XML_ERROR_NONE)
2591 return result;
2592 enc = encoding;
2593 }
2594 break;
2595 case XML_ROLE_DOCTYPE_NAME:
2596 if (startDoctypeDeclHandler) {
2597 doctypeName = poolStoreString(&tempPool, enc, s, next);
2598 if (! doctypeName)
2599 return XML_ERROR_NO_MEMORY;
2600 poolFinish(&tempPool);
2601 doctypeSysid = 0;
2602 doctypePubid = 0;
2603 }
2604 break;
2605 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
2606 if (startDoctypeDeclHandler) {
2607 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
2608 doctypePubid, 1);
2609 doctypeName = 0;
2610 poolClear(&tempPool);
2611 }
2612 break;
2613#ifdef XML_DTD
2614 case XML_ROLE_TEXT_DECL:
2615 {
2616 enum XML_Error result = processXmlDecl(parser, 1, s, next);
2617 if (result != XML_ERROR_NONE)
2618 return result;
2619 enc = encoding;
2620 }
2621 break;
2622#endif /* XML_DTD */
2623 case XML_ROLE_DOCTYPE_PUBLIC_ID:
2624 if (startDoctypeDeclHandler) {
2625 doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1);
2626 if (! doctypePubid)
2627 return XML_ERROR_NO_MEMORY;
2628 poolFinish(&tempPool);
2629 }
2630#ifdef XML_DTD
2631 declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2632 externalSubsetName,
2633 sizeof(ENTITY));
2634 if (!declEntity)
2635 return XML_ERROR_NO_MEMORY;
2636#endif /* XML_DTD */
2637 /* fall through */
2638 case XML_ROLE_ENTITY_PUBLIC_ID:
2639 if (!XmlIsPublicId(enc, s, next, eventPP))
2640 return XML_ERROR_SYNTAX;
2641 if (declEntity) {
2642 XML_Char *tem = poolStoreString(&dtd.pool,
2643 enc,
2644 s + enc->minBytesPerChar,
2645 next - enc->minBytesPerChar);
2646 if (!tem)
2647 return XML_ERROR_NO_MEMORY;
2648 normalizePublicId(tem);
2649 declEntity->publicId = tem;
2650 poolFinish(&dtd.pool);
2651 }
2652 break;
2653 case XML_ROLE_DOCTYPE_CLOSE:
2654 if (doctypeName) {
2655 startDoctypeDeclHandler(handlerArg, doctypeName,
2656 doctypeSysid, doctypePubid, 0);
2657 poolClear(&tempPool);
2658 }
2659 if (dtd.complete && hadExternalDoctype) {
2660 dtd.complete = 0;
2661#ifdef XML_DTD
2662 if (paramEntityParsing && externalEntityRefHandler) {
2663 ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
2664 externalSubsetName,
2665 0);
2666 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2667 0,
2668 entity->base,
2669 entity->systemId,
2670 entity->publicId))
2671 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2672 }
2673#endif /* XML_DTD */
2674 if (!dtd.complete
2675 && !dtd.standalone
2676 && notStandaloneHandler
2677 && !notStandaloneHandler(handlerArg))
2678 return XML_ERROR_NOT_STANDALONE;
2679 }
2680 if (endDoctypeDeclHandler)
2681 endDoctypeDeclHandler(handlerArg);
2682 break;
2683 case XML_ROLE_INSTANCE_START:
2684 processor = contentProcessor;
2685 return contentProcessor(parser, s, end, nextPtr);
2686 case XML_ROLE_ATTLIST_ELEMENT_NAME:
2687 declElementType = getElementType(parser, enc, s, next);
2688 if (!declElementType)
2689 return XML_ERROR_NO_MEMORY;
2690 break;
2691 case XML_ROLE_ATTRIBUTE_NAME:
2692 declAttributeId = getAttributeId(parser, enc, s, next);
2693 if (!declAttributeId)
2694 return XML_ERROR_NO_MEMORY;
2695 declAttributeIsCdata = 0;
2696 declAttributeType = 0;
2697 declAttributeIsId = 0;
2698 break;
2699 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
2700 declAttributeIsCdata = 1;
2701 declAttributeType = "CDATA";
2702 break;
2703 case XML_ROLE_ATTRIBUTE_TYPE_ID:
2704 declAttributeIsId = 1;
2705 declAttributeType = "ID";
2706 break;
2707 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
2708 declAttributeType = "IDREF";
2709 break;
2710 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
2711 declAttributeType = "IDREFS";
2712 break;
2713 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
2714 declAttributeType = "ENTITY";
2715 break;
2716 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
2717 declAttributeType = "ENTITIES";
2718 break;
2719 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
2720 declAttributeType = "NMTOKEN";
2721 break;
2722 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
2723 declAttributeType = "NMTOKENS";
2724 break;
2725
2726 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
2727 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
2728 if (attlistDeclHandler)
2729 {
2730 char *prefix;
2731 if (declAttributeType) {
2732 prefix = "|";
2733 }
2734 else {
2735 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
2736 ? "NOTATION("
2737 : "(");
2738 }
2739 if (! poolAppendString(&tempPool, prefix))
2740 return XML_ERROR_NO_MEMORY;
2741 if (! poolAppend(&tempPool, enc, s, next))
2742 return XML_ERROR_NO_MEMORY;
2743 declAttributeType = tempPool.start;
2744 }
2745 break;
2746 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
2747 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
2748 if (dtd.complete
2749 && !defineAttribute(declElementType, declAttributeId,
2750 declAttributeIsCdata, declAttributeIsId, 0,
2751 parser))
2752 return XML_ERROR_NO_MEMORY;
2753 if (attlistDeclHandler && declAttributeType) {
2754 if (*declAttributeType == '('
2755 || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
2756 /* Enumerated or Notation type */
2757 if (! poolAppendChar(&tempPool, ')')
2758 || ! poolAppendChar(&tempPool, '\0'))
2759 return XML_ERROR_NO_MEMORY;
2760 declAttributeType = tempPool.start;
2761 poolFinish(&tempPool);
2762 }
2763 *eventEndPP = s;
2764 attlistDeclHandler(handlerArg, declElementType->name,
2765 declAttributeId->name, declAttributeType,
2766 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
2767 poolClear(&tempPool);
2768 }
2769 break;
2770 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
2771 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
2772 {
2773 const XML_Char *attVal;
2774 enum XML_Error result
2775 = storeAttributeValue(parser, enc, declAttributeIsCdata,
2776 s + enc->minBytesPerChar,
2777 next - enc->minBytesPerChar,
2778 &dtd.pool);
2779 if (result)
2780 return result;
2781 attVal = poolStart(&dtd.pool);
2782 poolFinish(&dtd.pool);
2783 if (dtd.complete
2784 /* ID attributes aren't allowed to have a default */
2785 && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
2786 return XML_ERROR_NO_MEMORY;
2787 if (attlistDeclHandler && declAttributeType) {
2788 if (*declAttributeType == '('
2789 || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
2790 /* Enumerated or Notation type */
2791 if (! poolAppendChar(&tempPool, ')')
2792 || ! poolAppendChar(&tempPool, '\0'))
2793 return XML_ERROR_NO_MEMORY;
2794 declAttributeType = tempPool.start;
2795 poolFinish(&tempPool);
2796 }
2797 *eventEndPP = s;
2798 attlistDeclHandler(handlerArg, declElementType->name,
2799 declAttributeId->name, declAttributeType,
2800 attVal,
2801 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
2802 poolClear(&tempPool);
2803 }
2804 break;
2805 }
2806 case XML_ROLE_ENTITY_VALUE:
2807 {
2808 enum XML_Error result = storeEntityValue(parser, enc,
2809 s + enc->minBytesPerChar,
2810 next - enc->minBytesPerChar);
2811 if (declEntity) {
2812 declEntity->textPtr = poolStart(&dtd.pool);
2813 declEntity->textLen = poolLength(&dtd.pool);
2814 poolFinish(&dtd.pool);
2815 if (entityDeclHandler) {
2816 *eventEndPP = s;
2817 entityDeclHandler(handlerArg,
2818 declEntity->name,
2819 declEntity->is_param,
2820 declEntity->textPtr,
2821 declEntity->textLen,
2822 curBase, 0, 0, 0);
2823 }
2824 }
2825 else
2826 poolDiscard(&dtd.pool);
2827 if (result != XML_ERROR_NONE)
2828 return result;
2829 }
2830 break;
2831 case XML_ROLE_DOCTYPE_SYSTEM_ID:
2832 if (startDoctypeDeclHandler) {
2833 doctypeSysid = poolStoreString(&tempPool, enc, s + 1, next - 1);
2834 if (! doctypeSysid)
2835 return XML_ERROR_NO_MEMORY;
2836 poolFinish(&tempPool);
2837 }
2838 if (!dtd.standalone
2839#ifdef XML_DTD
2840 && !paramEntityParsing
2841#endif /* XML_DTD */
2842 && notStandaloneHandler
2843 && !notStandaloneHandler(handlerArg))
2844 return XML_ERROR_NOT_STANDALONE;
2845 hadExternalDoctype = 1;
2846#ifndef XML_DTD
2847 break;
2848#else /* XML_DTD */
2849 if (!declEntity) {
2850 declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2851 externalSubsetName,
2852 sizeof(ENTITY));
2853 declEntity->publicId = 0;
2854 if (!declEntity)
2855 return XML_ERROR_NO_MEMORY;
2856 }
2857 /* fall through */
2858#endif /* XML_DTD */
2859 case XML_ROLE_ENTITY_SYSTEM_ID:
2860 if (declEntity) {
2861 declEntity->systemId = poolStoreString(&dtd.pool, enc,
2862 s + enc->minBytesPerChar,
2863 next - enc->minBytesPerChar);
2864 if (!declEntity->systemId)
2865 return XML_ERROR_NO_MEMORY;
2866 declEntity->base = curBase;
2867 poolFinish(&dtd.pool);
2868 }
2869 break;
2870 case XML_ROLE_ENTITY_COMPLETE:
2871 if (declEntity && entityDeclHandler) {
2872 *eventEndPP = s;
2873 entityDeclHandler(handlerArg,
2874 declEntity->name,
2875 0,0,0,
2876 declEntity->base,
2877 declEntity->systemId,
2878 declEntity->publicId,
2879 0);
2880 }
2881 break;
2882 case XML_ROLE_ENTITY_NOTATION_NAME:
2883 if (declEntity) {
2884 declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
2885 if (!declEntity->notation)
2886 return XML_ERROR_NO_MEMORY;
2887 poolFinish(&dtd.pool);
2888 if (unparsedEntityDeclHandler) {
2889 *eventEndPP = s;
2890 unparsedEntityDeclHandler(handlerArg,
2891 declEntity->name,
2892 declEntity->base,
2893 declEntity->systemId,
2894 declEntity->publicId,
2895 declEntity->notation);
2896 }
2897 else if (entityDeclHandler) {
2898 *eventEndPP = s;
2899 entityDeclHandler(handlerArg,
2900 declEntity->name,
2901 0,0,0,
2902 declEntity->base,
2903 declEntity->systemId,
2904 declEntity->publicId,
2905 declEntity->notation);
2906 }
2907 }
2908 break;
2909 case XML_ROLE_GENERAL_ENTITY_NAME:
2910 {
2911 const XML_Char *name;
2912 if (XmlPredefinedEntityName(enc, s, next)) {
2913 declEntity = 0;
2914 break;
2915 }
2916 name = poolStoreString(&dtd.pool, enc, s, next);
2917 if (!name)
2918 return XML_ERROR_NO_MEMORY;
2919 if (dtd.complete) {
2920 declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
2921 if (!declEntity)
2922 return XML_ERROR_NO_MEMORY;
2923 if (declEntity->name != name) {
2924 poolDiscard(&dtd.pool);
2925 declEntity = 0;
2926 }
2927 else {
2928 poolFinish(&dtd.pool);
2929 declEntity->publicId = 0;
2930 declEntity->is_param = 0;
2931 }
2932 }
2933 else {
2934 poolDiscard(&dtd.pool);
2935 declEntity = 0;
2936 }
2937 }
2938 break;
2939 case XML_ROLE_PARAM_ENTITY_NAME:
2940#ifdef XML_DTD
2941 if (dtd.complete) {
2942 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
2943 if (!name)
2944 return XML_ERROR_NO_MEMORY;
2945 declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2946 name, sizeof(ENTITY));
2947 if (!declEntity)
2948 return XML_ERROR_NO_MEMORY;
2949 if (declEntity->name != name) {
2950 poolDiscard(&dtd.pool);
2951 declEntity = 0;
2952 }
2953 else {
2954 poolFinish(&dtd.pool);
2955 declEntity->publicId = 0;
2956 declEntity->is_param = 1;
2957 }
2958 }
2959#else /* not XML_DTD */
2960 declEntity = 0;
2961#endif /* not XML_DTD */
2962 break;
2963 case XML_ROLE_NOTATION_NAME:
2964 declNotationPublicId = 0;
2965 declNotationName = 0;
2966 if (notationDeclHandler) {
2967 declNotationName = poolStoreString(&tempPool, enc, s, next);
2968 if (!declNotationName)
2969 return XML_ERROR_NO_MEMORY;
2970 poolFinish(&tempPool);
2971 }
2972 break;
2973 case XML_ROLE_NOTATION_PUBLIC_ID:
2974 if (!XmlIsPublicId(enc, s, next, eventPP))
2975 return XML_ERROR_SYNTAX;
2976 if (declNotationName) {
2977 XML_Char *tem = poolStoreString(&tempPool,
2978 enc,
2979 s + enc->minBytesPerChar,
2980 next - enc->minBytesPerChar);
2981 if (!tem)
2982 return XML_ERROR_NO_MEMORY;
2983 normalizePublicId(tem);
2984 declNotationPublicId = tem;
2985 poolFinish(&tempPool);
2986 }
2987 break;
2988 case XML_ROLE_NOTATION_SYSTEM_ID:
2989 if (declNotationName && notationDeclHandler) {
2990 const XML_Char *systemId
2991 = poolStoreString(&tempPool, enc,
2992 s + enc->minBytesPerChar,
2993 next - enc->minBytesPerChar);
2994 if (!systemId)
2995 return XML_ERROR_NO_MEMORY;
2996 *eventEndPP = s;
2997 notationDeclHandler(handlerArg,
2998 declNotationName,
2999 curBase,
3000 systemId,
3001 declNotationPublicId);
3002 }
3003 poolClear(&tempPool);
3004 break;
3005 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
3006 if (declNotationPublicId && notationDeclHandler) {
3007 *eventEndPP = s;
3008 notationDeclHandler(handlerArg,
3009 declNotationName,
3010 curBase,
3011 0,
3012 declNotationPublicId);
3013 }
3014 poolClear(&tempPool);
3015 break;
3016 case XML_ROLE_ERROR:
3017 switch (tok) {
3018 case XML_TOK_PARAM_ENTITY_REF:
3019 return XML_ERROR_PARAM_ENTITY_REF;
3020 case XML_TOK_XML_DECL:
3021 return XML_ERROR_MISPLACED_XML_PI;
3022 default:
3023 return XML_ERROR_SYNTAX;
3024 }
3025#ifdef XML_DTD
3026 case XML_ROLE_IGNORE_SECT:
3027 {
3028 enum XML_Error result;
3029 if (defaultHandler)
3030 reportDefault(parser, enc, s, next);
3031 result = doIgnoreSection(parser, enc, &next, end, nextPtr);
3032 if (!next) {
3033 processor = ignoreSectionProcessor;
3034 return result;
3035 }
3036 }
3037 break;
3038#endif /* XML_DTD */
3039 case XML_ROLE_GROUP_OPEN:
3040 if (prologState.level >= groupSize) {
3041 if (groupSize) {
3042 groupConnector = REALLOC(groupConnector, groupSize *= 2);
3043 if (dtd.scaffIndex)
3044 dtd.scaffIndex = REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
3045 }
3046 else
3047 groupConnector = MALLOC(groupSize = 32);
3048 if (!groupConnector)
3049 return XML_ERROR_NO_MEMORY;
3050 }
3051 groupConnector[prologState.level] = 0;
3052 if (dtd.in_eldecl) {
3053 int myindex = nextScaffoldPart(parser);
3054 if (myindex < 0)
3055 return XML_ERROR_NO_MEMORY;
3056 dtd.scaffIndex[dtd.scaffLevel] = myindex;
3057 dtd.scaffLevel++;
3058 dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
3059 }
3060 break;
3061 case XML_ROLE_GROUP_SEQUENCE:
3062 if (groupConnector[prologState.level] == '|')
3063 return XML_ERROR_SYNTAX;
3064 groupConnector[prologState.level] = ',';
3065 break;
3066 case XML_ROLE_GROUP_CHOICE:
3067 if (groupConnector[prologState.level] == ',')
3068 return XML_ERROR_SYNTAX;
3069 if (dtd.in_eldecl
3070 && ! groupConnector[prologState.level]
3071 && dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type != XML_CTYPE_MIXED
3072 ) {
3073 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_CHOICE;
3074 }
3075 groupConnector[prologState.level] = '|';
3076 break;
3077 case XML_ROLE_PARAM_ENTITY_REF:
3078#ifdef XML_DTD
3079 case XML_ROLE_INNER_PARAM_ENTITY_REF:
3080 if (paramEntityParsing
3081 && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
3082 const XML_Char *name;
3083 ENTITY *entity;
3084 name = poolStoreString(&dtd.pool, enc,
3085 s + enc->minBytesPerChar,
3086 next - enc->minBytesPerChar);
3087 if (!name)
3088 return XML_ERROR_NO_MEMORY;
3089 entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
3090 poolDiscard(&dtd.pool);
3091 if (!entity) {
3092 /* FIXME what to do if !dtd.complete? */
3093 return XML_ERROR_UNDEFINED_ENTITY;
3094 }
3095 if (entity->open)
3096 return XML_ERROR_RECURSIVE_ENTITY_REF;
3097 if (entity->textPtr) {
3098 enum XML_Error result;
3099 result = processInternalParamEntity(parser, entity);
3100 if (result != XML_ERROR_NONE)
3101 return result;
3102 break;
3103 }
3104 if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
3105 return XML_ERROR_PARAM_ENTITY_REF;
3106 if (externalEntityRefHandler) {
3107 dtd.complete = 0;
3108 entity->open = 1;
3109 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3110 0,
3111 entity->base,
3112 entity->systemId,
3113 entity->publicId)) {
3114 entity->open = 0;
3115 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3116 }
3117 entity->open = 0;
3118 if (dtd.complete)
3119 break;
3120 }
3121 }
3122#endif /* XML_DTD */
3123 if (!dtd.standalone
3124 && notStandaloneHandler
3125 && !notStandaloneHandler(handlerArg))
3126 return XML_ERROR_NOT_STANDALONE;
3127 dtd.complete = 0;
3128 if (defaultHandler)
3129 reportDefault(parser, enc, s, next);
3130 break;
3131
3132 /* Element declaration stuff */
3133
3134 case XML_ROLE_ELEMENT_NAME:
3135 if (elementDeclHandler) {
3136 declElementType = getElementType(parser, enc, s, next);
3137 if (! declElementType)
3138 return XML_ERROR_NO_MEMORY;
3139 dtd.scaffLevel = 0;
3140 dtd.scaffCount = 0;
3141 dtd.in_eldecl = 1;
3142 }
3143 break;
3144
3145 case XML_ROLE_CONTENT_ANY:
3146 case XML_ROLE_CONTENT_EMPTY:
3147 if (dtd.in_eldecl) {
3148 if (elementDeclHandler) {
3149 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
3150 if (! content)
3151 return XML_ERROR_NO_MEMORY;
3152 content->quant = XML_CQUANT_NONE;
3153 content->name = 0;
3154 content->numchildren = 0;
3155 content->children = 0;
3156 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
3157 XML_CTYPE_ANY :
3158 XML_CTYPE_EMPTY);
3159 *eventEndPP = s;
3160 elementDeclHandler(handlerArg, declElementType->name, content);
3161 }
3162 dtd.in_eldecl = 0;
3163 }
3164 break;
3165
3166 case XML_ROLE_CONTENT_PCDATA:
3167 if (dtd.in_eldecl) {
3168 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_MIXED;
3169 }
3170 break;
3171
3172 case XML_ROLE_CONTENT_ELEMENT:
3173 quant = XML_CQUANT_NONE;
3174 goto elementContent;
3175 case XML_ROLE_CONTENT_ELEMENT_OPT:
3176 quant = XML_CQUANT_OPT;
3177 goto elementContent;
3178 case XML_ROLE_CONTENT_ELEMENT_REP:
3179 quant = XML_CQUANT_REP;
3180 goto elementContent;
3181 case XML_ROLE_CONTENT_ELEMENT_PLUS:
3182 quant = XML_CQUANT_PLUS;
3183 elementContent:
3184 if (dtd.in_eldecl)
3185 {
3186 ELEMENT_TYPE *el;
3187 const char *nxt = quant == XML_CQUANT_NONE ? next : next - 1;
3188 int myindex = nextScaffoldPart(parser);
3189 if (myindex < 0)
3190 return XML_ERROR_NO_MEMORY;
3191 dtd.scaffold[myindex].type = XML_CTYPE_NAME;
3192 dtd.scaffold[myindex].quant = quant;
3193 el = getElementType(parser, enc, s, nxt);
3194 if (! el)
3195 return XML_ERROR_NO_MEMORY;
3196 dtd.scaffold[myindex].name = el->name;
3197 dtd.contentStringLen += nxt - s + 1;
3198 }
3199 break;
3200
3201 case XML_ROLE_GROUP_CLOSE:
3202 quant = XML_CQUANT_NONE;
3203 goto closeGroup;
3204 case XML_ROLE_GROUP_CLOSE_OPT:
3205 quant = XML_CQUANT_OPT;
3206 goto closeGroup;
3207 case XML_ROLE_GROUP_CLOSE_REP:
3208 quant = XML_CQUANT_REP;
3209 goto closeGroup;
3210 case XML_ROLE_GROUP_CLOSE_PLUS:
3211 quant = XML_CQUANT_PLUS;
3212 closeGroup:
3213 if (dtd.in_eldecl) {
3214 dtd.scaffLevel--;
3215 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
3216 if (dtd.scaffLevel == 0) {
3217 if (elementDeclHandler) {
3218 XML_Content *model = build_model(parser);
3219 if (! model)
3220 return XML_ERROR_NO_MEMORY;
3221 *eventEndPP = s;
3222 elementDeclHandler(handlerArg, declElementType->name, model);
3223 }
3224 dtd.in_eldecl = 0;
3225 dtd.contentStringLen = 0;
3226 }
3227 }
3228 break;
3229 /* End element declaration stuff */
3230
3231 case XML_ROLE_NONE:
3232 switch (tok) {
3233 case XML_TOK_PI:
3234 if (!reportProcessingInstruction(parser, enc, s, next))
3235 return XML_ERROR_NO_MEMORY;
3236 break;
3237 case XML_TOK_COMMENT:
3238 if (!reportComment(parser, enc, s, next))
3239 return XML_ERROR_NO_MEMORY;
3240 break;
3241 }
3242 break;
3243 }
3244 if (defaultHandler) {
3245 switch (tok) {
3246 case XML_TOK_PI:
3247 case XML_TOK_COMMENT:
3248 case XML_TOK_BOM:
3249 case XML_TOK_XML_DECL:
3250#ifdef XML_DTD
3251 case XML_TOK_IGNORE_SECT:
3252#endif /* XML_DTD */
3253 case XML_TOK_PARAM_ENTITY_REF:
3254 break;
3255 default:
3256#ifdef XML_DTD
3257 if (role != XML_ROLE_IGNORE_SECT)
3258#endif /* XML_DTD */
3259 reportDefault(parser, enc, s, next);
3260 }
3261 }
3262 s = next;
3263 tok = XmlPrologTok(enc, s, end, &next);
3264 }
3265 /* not reached */
3266}
3267
3268static
3269enum XML_Error epilogProcessor(XML_Parser parser,
3270 const char *s,
3271 const char *end,
3272 const char **nextPtr)
3273{
3274 processor = epilogProcessor;
3275 eventPtr = s;
3276 for (;;) {
3277 const char *next;
3278 int tok = XmlPrologTok(encoding, s, end, &next);
3279 eventEndPtr = next;
3280 switch (tok) {
3281 case -XML_TOK_PROLOG_S:
3282 if (defaultHandler) {
3283 eventEndPtr = end;
3284 reportDefault(parser, encoding, s, end);
3285 }
3286 /* fall through */
3287 case XML_TOK_NONE:
3288 if (nextPtr)
3289 *nextPtr = end;
3290 return XML_ERROR_NONE;
3291 case XML_TOK_PROLOG_S:
3292 if (defaultHandler)
3293 reportDefault(parser, encoding, s, next);
3294 break;
3295 case XML_TOK_PI:
3296 if (!reportProcessingInstruction(parser, encoding, s, next))
3297 return XML_ERROR_NO_MEMORY;
3298 break;
3299 case XML_TOK_COMMENT:
3300 if (!reportComment(parser, encoding, s, next))
3301 return XML_ERROR_NO_MEMORY;
3302 break;
3303 case XML_TOK_INVALID:
3304 eventPtr = next;
3305 return XML_ERROR_INVALID_TOKEN;
3306 case XML_TOK_PARTIAL:
3307 if (nextPtr) {
3308 *nextPtr = s;
3309 return XML_ERROR_NONE;
3310 }
3311 return XML_ERROR_UNCLOSED_TOKEN;
3312 case XML_TOK_PARTIAL_CHAR:
3313 if (nextPtr) {
3314 *nextPtr = s;
3315 return XML_ERROR_NONE;
3316 }
3317 return XML_ERROR_PARTIAL_CHAR;
3318 default:
3319 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
3320 }
3321 eventPtr = s = next;
3322 }
3323}
3324
3325#ifdef XML_DTD
3326
3327static enum XML_Error
3328processInternalParamEntity(XML_Parser parser, ENTITY *entity)
3329{
3330 const char *s, *end, *next;
3331 int tok;
3332 enum XML_Error result;
3333 OPEN_INTERNAL_ENTITY openEntity;
3334 entity->open = 1;
3335 openEntity.next = openInternalEntities;
3336 openInternalEntities = &openEntity;
3337 openEntity.entity = entity;
3338 openEntity.internalEventPtr = 0;
3339 openEntity.internalEventEndPtr = 0;
3340 s = (char *)entity->textPtr;
3341 end = (char *)(entity->textPtr + entity->textLen);
3342 tok = XmlPrologTok(internalEncoding, s, end, &next);
3343 result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
3344 entity->open = 0;
3345 openInternalEntities = openEntity.next;
3346 return result;
3347}
3348
3349#endif /* XML_DTD */
3350
3351static
3352enum XML_Error errorProcessor(XML_Parser parser,
3353 const char *s,
3354 const char *end,
3355 const char **nextPtr)
3356{
3357 return errorCode;
3358}
3359
3360static enum XML_Error
3361storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
3362 const char *ptr, const char *end,
3363 STRING_POOL *pool)
3364{
3365 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
3366 if (result)
3367 return result;
3368 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
3369 poolChop(pool);
3370 if (!poolAppendChar(pool, XML_T('\0')))
3371 return XML_ERROR_NO_MEMORY;
3372 return XML_ERROR_NONE;
3373}
3374
3375static enum XML_Error
3376appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
3377 const char *ptr, const char *end,
3378 STRING_POOL *pool)
3379{
3380 for (;;) {
3381 const char *next;
3382 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
3383 switch (tok) {
3384 case XML_TOK_NONE:
3385 return XML_ERROR_NONE;
3386 case XML_TOK_INVALID:
3387 if (enc == encoding)
3388 eventPtr = next;
3389 return XML_ERROR_INVALID_TOKEN;
3390 case XML_TOK_PARTIAL:
3391 if (enc == encoding)
3392 eventPtr = ptr;
3393 return XML_ERROR_INVALID_TOKEN;
3394 case XML_TOK_CHAR_REF:
3395 {
3396 XML_Char buf[XML_ENCODE_MAX];
3397 int i;
3398 int n = XmlCharRefNumber(enc, ptr);
3399 if (n < 0) {
3400 if (enc == encoding)
3401 eventPtr = ptr;
3402 return XML_ERROR_BAD_CHAR_REF;
3403 }
3404 if (!isCdata
3405 && n == 0x20 /* space */
3406 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
3407 break;
3408 n = XmlEncode(n, (ICHAR *)buf);
3409 if (!n) {
3410 if (enc == encoding)
3411 eventPtr = ptr;
3412 return XML_ERROR_BAD_CHAR_REF;
3413 }
3414 for (i = 0; i < n; i++) {
3415 if (!poolAppendChar(pool, buf[i]))
3416 return XML_ERROR_NO_MEMORY;
3417 }
3418 }
3419 break;
3420 case XML_TOK_DATA_CHARS:
3421 if (!poolAppend(pool, enc, ptr, next))
3422 return XML_ERROR_NO_MEMORY;
3423 break;
3424 break;
3425 case XML_TOK_TRAILING_CR:
3426 next = ptr + enc->minBytesPerChar;
3427 /* fall through */
3428 case XML_TOK_ATTRIBUTE_VALUE_S:
3429 case XML_TOK_DATA_NEWLINE:
3430 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
3431 break;
3432 if (!poolAppendChar(pool, 0x20))
3433 return XML_ERROR_NO_MEMORY;
3434 break;
3435 case XML_TOK_ENTITY_REF:
3436 {
3437 const XML_Char *name;
3438 ENTITY *entity;
3439 XML_Char ch = XmlPredefinedEntityName(enc,
3440 ptr + enc->minBytesPerChar,
3441 next - enc->minBytesPerChar);
3442 if (ch) {
3443 if (!poolAppendChar(pool, ch))
3444 return XML_ERROR_NO_MEMORY;
3445 break;
3446 }
3447 name = poolStoreString(&temp2Pool, enc,
3448 ptr + enc->minBytesPerChar,
3449 next - enc->minBytesPerChar);
3450 if (!name)
3451 return XML_ERROR_NO_MEMORY;
3452 entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
3453 poolDiscard(&temp2Pool);
3454 if (!entity) {
3455 if (dtd.complete) {
3456 if (enc == encoding)
3457 eventPtr = ptr;
3458 return XML_ERROR_UNDEFINED_ENTITY;
3459 }
3460 }
3461 else if (entity->open) {
3462 if (enc == encoding)
3463 eventPtr = ptr;
3464 return XML_ERROR_RECURSIVE_ENTITY_REF;
3465 }
3466 else if (entity->notation) {
3467 if (enc == encoding)
3468 eventPtr = ptr;
3469 return XML_ERROR_BINARY_ENTITY_REF;
3470 }
3471 else if (!entity->textPtr) {
3472 if (enc == encoding)
3473 eventPtr = ptr;
3474 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
3475 }
3476 else {
3477 enum XML_Error result;
3478 const XML_Char *textEnd = entity->textPtr + entity->textLen;
3479 entity->open = 1;
3480 result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
3481 entity->open = 0;
3482 if (result)
3483 return result;
3484 }
3485 }
3486 break;
3487 default:
3488 if (enc == encoding)
3489 eventPtr = ptr;
3490 return XML_ERROR_UNEXPECTED_STATE;
3491 }
3492 ptr = next;
3493 }
3494 /* not reached */
3495}
3496
3497static
3498enum XML_Error storeEntityValue(XML_Parser parser,
3499 const ENCODING *enc,
3500 const char *entityTextPtr,
3501 const char *entityTextEnd)
3502{
3503 STRING_POOL *pool = &(dtd.pool);
3504 for (;;) {
3505 const char *next;
3506 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
3507 switch (tok) {
3508 case XML_TOK_PARAM_ENTITY_REF:
3509#ifdef XML_DTD
3510 if (parentParser || enc != encoding) {
3511 enum XML_Error result;
3512 const XML_Char *name;
3513 ENTITY *entity;
3514 name = poolStoreString(&tempPool, enc,
3515 entityTextPtr + enc->minBytesPerChar,
3516 next - enc->minBytesPerChar);
3517 if (!name)
3518 return XML_ERROR_NO_MEMORY;
3519 entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
3520 poolDiscard(&tempPool);
3521 if (!entity) {
3522 if (enc == encoding)
3523 eventPtr = entityTextPtr;
3524 return XML_ERROR_UNDEFINED_ENTITY;
3525 }
3526 if (entity->open) {
3527 if (enc == encoding)
3528 eventPtr = entityTextPtr;
3529 return XML_ERROR_RECURSIVE_ENTITY_REF;
3530 }
3531 if (entity->systemId) {
3532 if (enc == encoding)
3533 eventPtr = entityTextPtr;
3534 return XML_ERROR_PARAM_ENTITY_REF;
3535 }
3536 entity->open = 1;
3537 result = storeEntityValue(parser,
3538 internalEncoding,
3539 (char *)entity->textPtr,
3540 (char *)(entity->textPtr + entity->textLen));
3541 entity->open = 0;
3542 if (result)
3543 return result;
3544 break;
3545 }
3546#endif /* XML_DTD */
3547 eventPtr = entityTextPtr;
3548 return XML_ERROR_SYNTAX;
3549 case XML_TOK_NONE:
3550 return XML_ERROR_NONE;
3551 case XML_TOK_ENTITY_REF:
3552 case XML_TOK_DATA_CHARS:
3553 if (!poolAppend(pool, enc, entityTextPtr, next))
3554 return XML_ERROR_NO_MEMORY;
3555 break;
3556 case XML_TOK_TRAILING_CR:
3557 next = entityTextPtr + enc->minBytesPerChar;
3558 /* fall through */
3559 case XML_TOK_DATA_NEWLINE:
3560 if (pool->end == pool->ptr && !poolGrow(pool))
3561 return XML_ERROR_NO_MEMORY;
3562 *(pool->ptr)++ = 0xA;
3563 break;
3564 case XML_TOK_CHAR_REF:
3565 {
3566 XML_Char buf[XML_ENCODE_MAX];
3567 int i;
3568 int n = XmlCharRefNumber(enc, entityTextPtr);
3569 if (n < 0) {
3570 if (enc == encoding)
3571 eventPtr = entityTextPtr;
3572 return XML_ERROR_BAD_CHAR_REF;
3573 }
3574 n = XmlEncode(n, (ICHAR *)buf);
3575 if (!n) {
3576 if (enc == encoding)
3577 eventPtr = entityTextPtr;
3578 return XML_ERROR_BAD_CHAR_REF;
3579 }
3580 for (i = 0; i < n; i++) {
3581 if (pool->end == pool->ptr && !poolGrow(pool))
3582 return XML_ERROR_NO_MEMORY;
3583 *(pool->ptr)++ = buf[i];
3584 }
3585 }
3586 break;
3587 case XML_TOK_PARTIAL:
3588 if (enc == encoding)
3589 eventPtr = entityTextPtr;
3590 return XML_ERROR_INVALID_TOKEN;
3591 case XML_TOK_INVALID:
3592 if (enc == encoding)
3593 eventPtr = next;
3594 return XML_ERROR_INVALID_TOKEN;
3595 default:
3596 if (enc == encoding)
3597 eventPtr = entityTextPtr;
3598 return XML_ERROR_UNEXPECTED_STATE;
3599 }
3600 entityTextPtr = next;
3601 }
3602 /* not reached */
3603}
3604
3605static void
3606normalizeLines(XML_Char *s)
3607{
3608 XML_Char *p;
3609 for (;; s++) {
3610 if (*s == XML_T('\0'))
3611 return;
3612 if (*s == 0xD)
3613 break;
3614 }
3615 p = s;
3616 do {
3617 if (*s == 0xD) {
3618 *p++ = 0xA;
3619 if (*++s == 0xA)
3620 s++;
3621 }
3622 else
3623 *p++ = *s++;
3624 } while (*s);
3625 *p = XML_T('\0');
3626}
3627
3628static int
3629reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3630{
3631 const XML_Char *target;
3632 XML_Char *data;
3633 const char *tem;
3634 if (!processingInstructionHandler) {
3635 if (defaultHandler)
3636 reportDefault(parser, enc, start, end);
3637 return 1;
3638 }
3639 start += enc->minBytesPerChar * 2;
3640 tem = start + XmlNameLength(enc, start);
3641 target = poolStoreString(&tempPool, enc, start, tem);
3642 if (!target)
3643 return 0;
3644 poolFinish(&tempPool);
3645 data = poolStoreString(&tempPool, enc,
3646 XmlSkipS(enc, tem),
3647 end - enc->minBytesPerChar*2);
3648 if (!data)
3649 return 0;
3650 normalizeLines(data);
3651 processingInstructionHandler(handlerArg, target, data);
3652 poolClear(&tempPool);
3653 return 1;
3654}
3655
3656static int
3657reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3658{
3659 XML_Char *data;
3660 if (!commentHandler) {
3661 if (defaultHandler)
3662 reportDefault(parser, enc, start, end);
3663 return 1;
3664 }
3665 data = poolStoreString(&tempPool,
3666 enc,
3667 start + enc->minBytesPerChar * 4,
3668 end - enc->minBytesPerChar * 3);
3669 if (!data)
3670 return 0;
3671 normalizeLines(data);
3672 commentHandler(handlerArg, data);
3673 poolClear(&tempPool);
3674 return 1;
3675}
3676
3677static void
3678reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
3679{
3680 if (MUST_CONVERT(enc, s)) {
3681 const char **eventPP;
3682 const char **eventEndPP;
3683 if (enc == encoding) {
3684 eventPP = &eventPtr;
3685 eventEndPP = &eventEndPtr;
3686 }
3687 else {
3688 eventPP = &(openInternalEntities->internalEventPtr);
3689 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3690 }
3691 do {
3692 ICHAR *dataPtr = (ICHAR *)dataBuf;
3693 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
3694 *eventEndPP = s;
3695 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
3696 *eventPP = s;
3697 } while (s != end);
3698 }
3699 else
3700 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
3701}
3702
3703
3704static int
3705defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata,
3706 int isId, const XML_Char *value, XML_Parser parser)
3707{
3708 DEFAULT_ATTRIBUTE *att;
3709 if (value || isId) {
3710 /* The handling of default attributes gets messed up if we have
3711 a default which duplicates a non-default. */
3712 int i;
3713 for (i = 0; i < type->nDefaultAtts; i++)
3714 if (attId == type->defaultAtts[i].id)
3715 return 1;
3716 if (isId && !type->idAtt && !attId->xmlns)
3717 type->idAtt = attId;
3718 }
3719 if (type->nDefaultAtts == type->allocDefaultAtts) {
3720 if (type->allocDefaultAtts == 0) {
3721 type->allocDefaultAtts = 8;
3722 type->defaultAtts = MALLOC(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
3723 }
3724 else {
3725 type->allocDefaultAtts *= 2;
3726 type->defaultAtts = REALLOC(type->defaultAtts,
3727 type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
3728 }
3729 if (!type->defaultAtts)
3730 return 0;
3731 }
3732 att = type->defaultAtts + type->nDefaultAtts;
3733 att->id = attId;
3734 att->value = value;
3735 att->isCdata = isCdata;
3736 if (!isCdata)
3737 attId->maybeTokenized = 1;
3738 type->nDefaultAtts += 1;
3739 return 1;
3740}
3741
3742static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
3743{
3744 const XML_Char *name;
3745 for (name = elementType->name; *name; name++) {
3746 if (*name == XML_T(':')) {
3747 PREFIX *prefix;
3748 const XML_Char *s;
3749 for (s = elementType->name; s != name; s++) {
3750 if (!poolAppendChar(&dtd.pool, *s))
3751 return 0;
3752 }
3753 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3754 return 0;
3755 prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
3756 if (!prefix)
3757 return 0;
3758 if (prefix->name == poolStart(&dtd.pool))
3759 poolFinish(&dtd.pool);
3760 else
3761 poolDiscard(&dtd.pool);
3762 elementType->prefix = prefix;
3763
3764 }
3765 }
3766 return 1;
3767}
3768
3769static ATTRIBUTE_ID *
3770getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3771{
3772 ATTRIBUTE_ID *id;
3773 const XML_Char *name;
3774 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3775 return 0;
3776 name = poolStoreString(&dtd.pool, enc, start, end);
3777 if (!name)
3778 return 0;
3779 ++name;
3780 id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
3781 if (!id)
3782 return 0;
3783 if (id->name != name)
3784 poolDiscard(&dtd.pool);
3785 else {
3786 poolFinish(&dtd.pool);
3787 if (!ns)
3788 ;
3789 else if (name[0] == 'x'
3790 && name[1] == 'm'
3791 && name[2] == 'l'
3792 && name[3] == 'n'
3793 && name[4] == 's'
3794 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
3795 if (name[5] == '\0')
3796 id->prefix = &dtd.defaultPrefix;
3797 else
3798 id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
3799 id->xmlns = 1;
3800 }
3801 else {
3802 int i;
3803 for (i = 0; name[i]; i++) {
3804 if (name[i] == XML_T(':')) {
3805 int j;
3806 for (j = 0; j < i; j++) {
3807 if (!poolAppendChar(&dtd.pool, name[j]))
3808 return 0;
3809 }
3810 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3811 return 0;
3812 id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
3813 if (id->prefix->name == poolStart(&dtd.pool))
3814 poolFinish(&dtd.pool);
3815 else
3816 poolDiscard(&dtd.pool);
3817 break;
3818 }
3819 }
3820 }
3821 }
3822 return id;
3823}
3824
3825#define CONTEXT_SEP XML_T('\f')
3826
3827static
3828const XML_Char *getContext(XML_Parser parser)
3829{
3830 HASH_TABLE_ITER iter;
3831 int needSep = 0;
3832
3833 if (dtd.defaultPrefix.binding) {
3834 int i;
3835 int len;
3836 if (!poolAppendChar(&tempPool, XML_T('=')))
3837 return 0;
3838 len = dtd.defaultPrefix.binding->uriLen;
3839 if (namespaceSeparator != XML_T('\0'))
3840 len--;
3841 for (i = 0; i < len; i++)
3842 if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
3843 return 0;
3844 needSep = 1;
3845 }
3846
3847 hashTableIterInit(&iter, &(dtd.prefixes));
3848 for (;;) {
3849 int i;
3850 int len;
3851 const XML_Char *s;
3852 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
3853 if (!prefix)
3854 break;
3855 if (!prefix->binding)
3856 continue;
3857 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
3858 return 0;
3859 for (s = prefix->name; *s; s++)
3860 if (!poolAppendChar(&tempPool, *s))
3861 return 0;
3862 if (!poolAppendChar(&tempPool, XML_T('=')))
3863 return 0;
3864 len = prefix->binding->uriLen;
3865 if (namespaceSeparator != XML_T('\0'))
3866 len--;
3867 for (i = 0; i < len; i++)
3868 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
3869 return 0;
3870 needSep = 1;
3871 }
3872
3873
3874 hashTableIterInit(&iter, &(dtd.generalEntities));
3875 for (;;) {
3876 const XML_Char *s;
3877 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
3878 if (!e)
3879 break;
3880 if (!e->open)
3881 continue;
3882 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
3883 return 0;
3884 for (s = e->name; *s; s++)
3885 if (!poolAppendChar(&tempPool, *s))
3886 return 0;
3887 needSep = 1;
3888 }
3889
3890 if (!poolAppendChar(&tempPool, XML_T('\0')))
3891 return 0;
3892 return tempPool.start;
3893}
3894
3895static
3896int setContext(XML_Parser parser, const XML_Char *context)
3897{
3898 const XML_Char *s = context;
3899
3900 while (*context != XML_T('\0')) {
3901 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
3902 ENTITY *e;
3903 if (!poolAppendChar(&tempPool, XML_T('\0')))
3904 return 0;
3905 e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
3906 if (e)
3907 e->open = 1;
3908 if (*s != XML_T('\0'))
3909 s++;
3910 context = s;
3911 poolDiscard(&tempPool);
3912 }
3913 else if (*s == '=') {
3914 PREFIX *prefix;
3915 if (poolLength(&tempPool) == 0)
3916 prefix = &dtd.defaultPrefix;
3917 else {
3918 if (!poolAppendChar(&tempPool, XML_T('\0')))
3919 return 0;
3920 prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
3921 if (!prefix)
3922 return 0;
3923 if (prefix->name == poolStart(&tempPool)) {
3924 prefix->name = poolCopyString(&dtd.pool, prefix->name);
3925 if (!prefix->name)
3926 return 0;
3927 }
3928 poolDiscard(&tempPool);
3929 }
3930 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
3931 if (!poolAppendChar(&tempPool, *context))
3932 return 0;
3933 if (!poolAppendChar(&tempPool, XML_T('\0')))
3934 return 0;
3935 if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
3936 return 0;
3937 poolDiscard(&tempPool);
3938 if (*context != XML_T('\0'))
3939 ++context;
3940 s = context;
3941 }
3942 else {
3943 if (!poolAppendChar(&tempPool, *s))
3944 return 0;
3945 s++;
3946 }
3947 }
3948 return 1;
3949}
3950
3951
3952static
3953void normalizePublicId(XML_Char *publicId)
3954{
3955 XML_Char *p = publicId;
3956 XML_Char *s;
3957 for (s = publicId; *s; s++) {
3958 switch (*s) {
3959 case 0x20:
3960 case 0xD:
3961 case 0xA:
3962 if (p != publicId && p[-1] != 0x20)
3963 *p++ = 0x20;
3964 break;
3965 default:
3966 *p++ = *s;
3967 }
3968 }
3969 if (p != publicId && p[-1] == 0x20)
3970 --p;
3971 *p = XML_T('\0');
3972}
3973
3974static int dtdInit(DTD *p, XML_Parser parser)
3975{
3976 XML_Memory_Handling_Suite *ms = &((Parser *) parser)->m_mem;
3977 poolInit(&(p->pool), ms);
3978 hashTableInit(&(p->generalEntities), ms);
3979 hashTableInit(&(p->elementTypes), ms);
3980 hashTableInit(&(p->attributeIds), ms);
3981 hashTableInit(&(p->prefixes), ms);
3982 p->complete = 1;
3983 p->standalone = 0;
3984#ifdef XML_DTD
3985 hashTableInit(&(p->paramEntities), ms);
3986#endif /* XML_DTD */
3987 p->defaultPrefix.name = 0;
3988 p->defaultPrefix.binding = 0;
3989
3990 p->in_eldecl = 0;
3991 p->scaffIndex = 0;
3992 p->scaffLevel = 0;
3993 p->scaffold = 0;
3994 p->contentStringLen = 0;
3995 p->scaffSize = 0;
3996 p->scaffCount = 0;
3997
3998 return 1;
3999}
4000
4001#ifdef XML_DTD
4002
4003static void dtdSwap(DTD *p1, DTD *p2)
4004{
4005 DTD tem;
4006 memcpy(&tem, p1, sizeof(DTD));
4007 memcpy(p1, p2, sizeof(DTD));
4008 memcpy(p2, &tem, sizeof(DTD));
4009}
4010
4011#endif /* XML_DTD */
4012
4013static void dtdDestroy(DTD *p, XML_Parser parser)
4014{
4015 HASH_TABLE_ITER iter;
4016 hashTableIterInit(&iter, &(p->elementTypes));
4017 for (;;) {
4018 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4019 if (!e)
4020 break;
4021 if (e->allocDefaultAtts != 0)
4022 FREE(e->defaultAtts);
4023 }
4024 hashTableDestroy(&(p->generalEntities));
4025#ifdef XML_DTD
4026 hashTableDestroy(&(p->paramEntities));
4027#endif /* XML_DTD */
4028 hashTableDestroy(&(p->elementTypes));
4029 hashTableDestroy(&(p->attributeIds));
4030 hashTableDestroy(&(p->prefixes));
4031 poolDestroy(&(p->pool));
4032 if (p->scaffIndex)
4033 FREE(p->scaffIndex);
4034 if (p->scaffold)
4035 FREE(p->scaffold);
4036}
4037
4038/* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.
4039The new DTD has already been initialized. */
4040
4041static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser)
4042{
4043 HASH_TABLE_ITER iter;
4044
4045 /* Copy the prefix table. */
4046
4047 hashTableIterInit(&iter, &(oldDtd->prefixes));
4048 for (;;) {
4049 const XML_Char *name;
4050 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
4051 if (!oldP)
4052 break;
4053 name = poolCopyString(&(newDtd->pool), oldP->name);
4054 if (!name)
4055 return 0;
4056 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
4057 return 0;
4058 }
4059
4060 hashTableIterInit(&iter, &(oldDtd->attributeIds));
4061
4062 /* Copy the attribute id table. */
4063
4064 for (;;) {
4065 ATTRIBUTE_ID *newA;
4066 const XML_Char *name;
4067 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
4068
4069 if (!oldA)
4070 break;
4071 /* Remember to allocate the scratch byte before the name. */
4072 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
4073 return 0;
4074 name = poolCopyString(&(newDtd->pool), oldA->name);
4075 if (!name)
4076 return 0;
4077 ++name;
4078 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
4079 if (!newA)
4080 return 0;
4081 newA->maybeTokenized = oldA->maybeTokenized;
4082 if (oldA->prefix) {
4083 newA->xmlns = oldA->xmlns;
4084 if (oldA->prefix == &oldDtd->defaultPrefix)
4085 newA->prefix = &newDtd->defaultPrefix;
4086 else
4087 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
4088 }
4089 }
4090
4091 /* Copy the element type table. */
4092
4093 hashTableIterInit(&iter, &(oldDtd->elementTypes));
4094
4095 for (;;) {
4096 int i;
4097 ELEMENT_TYPE *newE;
4098 const XML_Char *name;
4099 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4100 if (!oldE)
4101 break;
4102 name = poolCopyString(&(newDtd->pool), oldE->name);
4103 if (!name)
4104 return 0;
4105 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
4106 if (!newE)
4107 return 0;
4108 if (oldE->nDefaultAtts) {
4109 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
4110 if (!newE->defaultAtts)
4111 return 0;
4112 }
4113 if (oldE->idAtt)
4114 newE->idAtt = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
4115 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
4116 if (oldE->prefix)
4117 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
4118 for (i = 0; i < newE->nDefaultAtts; i++) {
4119 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
4120 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
4121 if (oldE->defaultAtts[i].value) {
4122 newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
4123 if (!newE->defaultAtts[i].value)
4124 return 0;
4125 }
4126 else
4127 newE->defaultAtts[i].value = 0;
4128 }
4129 }
4130
4131 /* Copy the entity tables. */
4132 if (!copyEntityTable(&(newDtd->generalEntities),
4133 &(newDtd->pool),
4134 &(oldDtd->generalEntities), parser))
4135 return 0;
4136
4137#ifdef XML_DTD
4138 if (!copyEntityTable(&(newDtd->paramEntities),
4139 &(newDtd->pool),
4140 &(oldDtd->paramEntities), parser))
4141 return 0;
4142#endif /* XML_DTD */
4143
4144 newDtd->complete = oldDtd->complete;
4145 newDtd->standalone = oldDtd->standalone;
4146
4147 /* Don't want deep copying for scaffolding */
4148 newDtd->in_eldecl = oldDtd->in_eldecl;
4149 newDtd->scaffold = oldDtd->scaffold;
4150 newDtd->contentStringLen = oldDtd->contentStringLen;
4151 newDtd->scaffSize = oldDtd->scaffSize;
4152 newDtd->scaffLevel = oldDtd->scaffLevel;
4153 newDtd->scaffIndex = oldDtd->scaffIndex;
4154
4155 return 1;
4156} /* End dtdCopy */
4157
4158static int copyEntityTable(HASH_TABLE *newTable,
4159 STRING_POOL *newPool,
4160 const HASH_TABLE *oldTable,
4161 XML_Parser parser)
4162{
4163 HASH_TABLE_ITER iter;
4164 const XML_Char *cachedOldBase = 0;
4165 const XML_Char *cachedNewBase = 0;
4166
4167 hashTableIterInit(&iter, oldTable);
4168
4169 for (;;) {
4170 ENTITY *newE;
4171 const XML_Char *name;
4172 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
4173 if (!oldE)
4174 break;
4175 name = poolCopyString(newPool, oldE->name);
4176 if (!name)
4177 return 0;
4178 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
4179 if (!newE)
4180 return 0;
4181 if (oldE->systemId) {
4182 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
4183 if (!tem)
4184 return 0;
4185 newE->systemId = tem;
4186 if (oldE->base) {
4187 if (oldE->base == cachedOldBase)
4188 newE->base = cachedNewBase;
4189 else {
4190 cachedOldBase = oldE->base;
4191 tem = poolCopyString(newPool, cachedOldBase);
4192 if (!tem)
4193 return 0;
4194 cachedNewBase = newE->base = tem;
4195 }
4196 }
4197 }
4198 else {
4199 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
4200 if (!tem)
4201 return 0;
4202 newE->textPtr = tem;
4203 newE->textLen = oldE->textLen;
4204 }
4205 if (oldE->notation) {
4206 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
4207 if (!tem)
4208 return 0;
4209 newE->notation = tem;
4210 }
4211 }
4212 return 1;
4213}
4214
4215#define INIT_SIZE 64
4216
4217static
4218int keyeq(KEY s1, KEY s2)
4219{
4220 for (; *s1 == *s2; s1++, s2++)
4221 if (*s1 == 0)
4222 return 1;
4223 return 0;
4224}
4225
4226static
4227unsigned long hash(KEY s)
4228{
4229 unsigned long h = 0;
4230 while (*s)
4231 h = (h << 5) + h + (unsigned char)*s++;
4232 return h;
4233}
4234
4235static
4236NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
4237{
4238 size_t i;
4239 if (table->size == 0) {
4240 size_t tsize;
4241
4242 if (!createSize)
4243 return 0;
4244 tsize = INIT_SIZE * sizeof(NAMED *);
4245 table->v = table->mem->malloc_fcn(tsize);
4246 if (!table->v)
4247 return 0;
4248 memset(table->v, 0, tsize);
4249 table->size = INIT_SIZE;
4250 table->usedLim = INIT_SIZE / 2;
4251 i = hash(name) & (table->size - 1);
4252 }
4253 else {
4254 unsigned long h = hash(name);
4255 for (i = h & (table->size - 1);
4256 table->v[i];
4257 i == 0 ? i = table->size - 1 : --i) {
4258 if (keyeq(name, table->v[i]->name))
4259 return table->v[i];
4260 }
4261 if (!createSize)
4262 return 0;
4263 if (table->used == table->usedLim) {
4264 /* check for overflow */
4265 size_t newSize = table->size * 2;
4266 size_t tsize = newSize * sizeof(NAMED *);
4267 NAMED **newV = table->mem->malloc_fcn(tsize);
4268 if (!newV)
4269 return 0;
4270 memset(newV, 0, tsize);
4271 for (i = 0; i < table->size; i++)
4272 if (table->v[i]) {
4273 size_t j;
4274 for (j = hash(table->v[i]->name) & (newSize - 1);
4275 newV[j];
4276 j == 0 ? j = newSize - 1 : --j)
4277 ;
4278 newV[j] = table->v[i];
4279 }
4280 table->mem->free_fcn(table->v);
4281 table->v = newV;
4282 table->size = newSize;
4283 table->usedLim = newSize/2;
4284 for (i = h & (table->size - 1);
4285 table->v[i];
4286 i == 0 ? i = table->size - 1 : --i)
4287 ;
4288 }
4289 }
4290 table->v[i] = table->mem->malloc_fcn(createSize);
4291 if (!table->v[i])
4292 return 0;
4293 memset(table->v[i], 0, createSize);
4294 table->v[i]->name = name;
4295 (table->used)++;
4296 return table->v[i];
4297}
4298
4299static
4300void hashTableDestroy(HASH_TABLE *table)
4301{
4302 size_t i;
4303 for (i = 0; i < table->size; i++) {
4304 NAMED *p = table->v[i];
4305 if (p)
4306 table->mem->free_fcn(p);
4307 }
4308 if (table->v)
4309 table->mem->free_fcn(table->v);
4310}
4311
4312static
4313void hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms)
4314{
4315 p->size = 0;
4316 p->usedLim = 0;
4317 p->used = 0;
4318 p->v = 0;
4319 p->mem = ms;
4320}
4321
4322static
4323void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
4324{
4325 iter->p = table->v;
4326 iter->end = iter->p + table->size;
4327}
4328
4329static
4330NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
4331{
4332 while (iter->p != iter->end) {
4333 NAMED *tem = *(iter->p)++;
4334 if (tem)
4335 return tem;
4336 }
4337 return 0;
4338}
4339
4340
4341static
4342void poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms)
4343{
4344 pool->blocks = 0;
4345 pool->freeBlocks = 0;
4346 pool->start = 0;
4347 pool->ptr = 0;
4348 pool->end = 0;
4349 pool->mem = ms;
4350}
4351
4352static
4353void poolClear(STRING_POOL *pool)
4354{
4355 if (!pool->freeBlocks)
4356 pool->freeBlocks = pool->blocks;
4357 else {
4358 BLOCK *p = pool->blocks;
4359 while (p) {
4360 BLOCK *tem = p->next;
4361 p->next = pool->freeBlocks;
4362 pool->freeBlocks = p;
4363 p = tem;
4364 }
4365 }
4366 pool->blocks = 0;
4367 pool->start = 0;
4368 pool->ptr = 0;
4369 pool->end = 0;
4370}
4371
4372static
4373void poolDestroy(STRING_POOL *pool)
4374{
4375 BLOCK *p = pool->blocks;
4376 while (p) {
4377 BLOCK *tem = p->next;
4378 pool->mem->free_fcn(p);
4379 p = tem;
4380 }
4381 pool->blocks = 0;
4382 p = pool->freeBlocks;
4383 while (p) {
4384 BLOCK *tem = p->next;
4385 pool->mem->free_fcn(p);
4386 p = tem;
4387 }
4388 pool->freeBlocks = 0;
4389 pool->ptr = 0;
4390 pool->start = 0;
4391 pool->end = 0;
4392}
4393
4394static
4395XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
4396 const char *ptr, const char *end)
4397{
4398 if (!pool->ptr && !poolGrow(pool))
4399 return 0;
4400 for (;;) {
4401 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
4402 if (ptr == end)
4403 break;
4404 if (!poolGrow(pool))
4405 return 0;
4406 }
4407 return pool->start;
4408}
4409
4410static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
4411{
4412 do {
4413 if (!poolAppendChar(pool, *s))
4414 return 0;
4415 } while (*s++);
4416 s = pool->start;
4417 poolFinish(pool);
4418 return s;
4419}
4420
4421static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
4422{
4423 if (!pool->ptr && !poolGrow(pool))
4424 return 0;
4425 for (; n > 0; --n, s++) {
4426 if (!poolAppendChar(pool, *s))
4427 return 0;
4428
4429 }
4430 s = pool->start;
4431 poolFinish(pool);
4432 return s;
4433}
4434
4435static
4436const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s)
4437{
4438 while (*s) {
4439 if (!poolAppendChar(pool, *s))
4440 return 0;
4441 s++;
4442 }
4443 return pool->start;
4444} /* End poolAppendString */
4445
4446static
4447XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
4448 const char *ptr, const char *end)
4449{
4450 if (!poolAppend(pool, enc, ptr, end))
4451 return 0;
4452 if (pool->ptr == pool->end && !poolGrow(pool))
4453 return 0;
4454 *(pool->ptr)++ = 0;
4455 return pool->start;
4456}
4457
4458static
4459int poolGrow(STRING_POOL *pool)
4460{
4461 if (pool->freeBlocks) {
4462 if (pool->start == 0) {
4463 pool->blocks = pool->freeBlocks;
4464 pool->freeBlocks = pool->freeBlocks->next;
4465 pool->blocks->next = 0;
4466 pool->start = pool->blocks->s;
4467 pool->end = pool->start + pool->blocks->size;
4468 pool->ptr = pool->start;
4469 return 1;
4470 }
4471 if (pool->end - pool->start < pool->freeBlocks->size) {
4472 BLOCK *tem = pool->freeBlocks->next;
4473 pool->freeBlocks->next = pool->blocks;
4474 pool->blocks = pool->freeBlocks;
4475 pool->freeBlocks = tem;
4476 memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
4477 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
4478 pool->start = pool->blocks->s;
4479 pool->end = pool->start + pool->blocks->size;
4480 return 1;
4481 }
4482 }
4483 if (pool->blocks && pool->start == pool->blocks->s) {
4484 int blockSize = (pool->end - pool->start)*2;
4485 pool->blocks = pool->mem->realloc_fcn(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
4486 if (!pool->blocks)
4487 return 0;
4488 pool->blocks->size = blockSize;
4489 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
4490 pool->start = pool->blocks->s;
4491 pool->end = pool->start + blockSize;
4492 }
4493 else {
4494 BLOCK *tem;
4495 int blockSize = pool->end - pool->start;
4496 if (blockSize < INIT_BLOCK_SIZE)
4497 blockSize = INIT_BLOCK_SIZE;
4498 else
4499 blockSize *= 2;
4500 tem = pool->mem->malloc_fcn(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
4501 if (!tem)
4502 return 0;
4503 tem->size = blockSize;
4504 tem->next = pool->blocks;
4505 pool->blocks = tem;
4506 if (pool->ptr != pool->start)
4507 memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
4508 pool->ptr = tem->s + (pool->ptr - pool->start);
4509 pool->start = tem->s;
4510 pool->end = tem->s + blockSize;
4511 }
4512 return 1;
4513}
4514
4515static int
4516nextScaffoldPart(XML_Parser parser)
4517{
4518 CONTENT_SCAFFOLD * me;
4519 int next;
4520
4521 if (! dtd.scaffIndex) {
4522 dtd.scaffIndex = MALLOC(groupSize * sizeof(int));
4523 if (! dtd.scaffIndex)
4524 return -1;
4525 dtd.scaffIndex[0] = 0;
4526 }
4527
4528 if (dtd.scaffCount >= dtd.scaffSize) {
4529 if (dtd.scaffold) {
4530 dtd.scaffSize *= 2;
4531 dtd.scaffold = (CONTENT_SCAFFOLD *) REALLOC(dtd.scaffold,
4532 dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
4533 }
4534 else {
4535 dtd.scaffSize = 32;
4536 dtd.scaffold = (CONTENT_SCAFFOLD *) MALLOC(dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
4537 }
4538 if (! dtd.scaffold)
4539 return -1;
4540 }
4541 next = dtd.scaffCount++;
4542 me = &dtd.scaffold[next];
4543 if (dtd.scaffLevel) {
4544 CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]];
4545 if (parent->lastchild) {
4546 dtd.scaffold[parent->lastchild].nextsib = next;
4547 }
4548 if (! parent->childcnt)
4549 parent->firstchild = next;
4550 parent->lastchild = next;
4551 parent->childcnt++;
4552 }
4553 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
4554 return next;
4555} /* End nextScaffoldPart */
4556
4557static void
4558build_node (XML_Parser parser,
4559 int src_node,
4560 XML_Content *dest,
4561 XML_Content **contpos,
4562 char **strpos)
4563{
4564 dest->type = dtd.scaffold[src_node].type;
4565 dest->quant = dtd.scaffold[src_node].quant;
4566 if (dest->type == XML_CTYPE_NAME) {
4567 const char *src;
4568 dest->name = *strpos;
4569 src = dtd.scaffold[src_node].name;
4570 for (;;) {
4571 *(*strpos)++ = *src;
4572 if (! *src)
4573 break;
4574 src++;
4575 }
4576 dest->numchildren = 0;
4577 dest->children = 0;
4578 }
4579 else {
4580 unsigned int i;
4581 int cn;
4582 dest->numchildren = dtd.scaffold[src_node].childcnt;
4583 dest->children = *contpos;
4584 *contpos += dest->numchildren;
4585 for (i = 0, cn = dtd.scaffold[src_node].firstchild;
4586 i < dest->numchildren;
4587 i++, cn = dtd.scaffold[cn].nextsib) {
4588 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
4589 }
4590 dest->name = 0;
4591 }
4592} /* End build_node */
4593
4594static XML_Content *
4595build_model (XML_Parser parser)
4596{
4597 XML_Content *ret;
4598 XML_Content *cpos;
4599 char * str;
4600 int allocsize = dtd.scaffCount * sizeof(XML_Content) + dtd.contentStringLen;
4601
4602 ret = MALLOC(allocsize);
4603 if (! ret)
4604 return 0;
4605
4606 str = (char *) (&ret[dtd.scaffCount]);
4607 cpos = &ret[1];
4608
4609 build_node(parser, 0, ret, &cpos, &str);
4610 return ret;
4611} /* End build_model */
4612
4613static ELEMENT_TYPE *
4614getElementType(XML_Parser parser,
4615 const ENCODING *enc,
4616 const char *ptr,
4617 const char *end)
4618{
4619 const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
4620 ELEMENT_TYPE *ret;
4621
4622 if (! name)
4623 return 0;
4624 ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
4625 if (! ret)
4626 return 0;
4627 if (ret->name != name)
4628 poolDiscard(&dtd.pool);
4629 else {
4630 poolFinish(&dtd.pool);
4631 if (!setElementTypePrefix(parser, ret))
4632 return 0;
4633 }
4634 return ret;
4635} /* End getElementType */