source: trunk/src/helpers/xmlparse.c@ 36

Last change on this file since 36 was 36, checked in by umoeller, 25 years ago

Added XML.

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 214.1 KB
Line 
1
2/*
3 *@@sourcefile xmlparse.c:
4 * contains the API of the expat XML parser 1.95.1, as released on
5 * SourceForge Oct 22, 2000.
6 *
7 * Expat is a library, written in C, for parsing XML documents. It's
8 * the underlying XML parser for the open source Mozilla project,
9 * perl's XML::Parser, and other open-source XML parsers.
10 *
11 * Expat was written by James Clark, who also wrote groff (an nroff
12 * look-alike), Jade (an implemention of ISO's DSSSL stylesheet
13 * language for SGML), XP (a Java XML parser package), XT (a Java
14 * XSL engine). He was also the technical lead on the XML Working
15 * Group at W3 that produced the XML specification.
16 *
17 * Most of this documentation is the original documentation
18 * that comes with expat as an HTML file. I (umoeller)
19 * have integrated the docs into the sources and added a
20 * couple of remarks on the way.
21 *
22 * See XML_ParserCreate for an introduction to expat.
23 *
24 *@@added V0.9.9 (2001-02-10) [umoeller]
25 */
26
27/*
28 * Copyright (C) 2001 Ulrich M”ller.
29 * Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
30 * and Clark Cooper.
31 *
32 * Permission is hereby granted, free of charge, to any person obtaining
33 * a copy of this software and associated documentation files (the
34 * "Software"), to deal in the Software without restriction, including
35 * without limitation the rights to use, copy, modify, merge, publish,
36 * distribute, sublicense, and/or sell copies of the Software, and to
37 * permit persons to whom the Software is furnished to do so, subject to
38 * the following conditions:
39 *
40 * The above copyright notice and this permission notice shall be included
41 * in all copies or substantial portions of the Software.
42 *
43 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
44 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
45 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
46 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
47 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
48 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
49 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
50 */
51
52#include "setup.h"
53
54#pragma info(norea, nogen)
55 // disable "statement unreachable" and "missing break statement"
56 // this code generates those options HEAVILY
57
58#ifdef COMPILED_FROM_DSP
59 #include "winconfig.h"
60 #define XMLPARSEAPI __declspec(dllexport)
61 #include "expat.h"
62 #undef XMLPARSEAPI
63#else
64 // #include <config.h>
65
66 #ifdef __declspec
67 #define XMLPARSEAPI __declspec(dllexport)
68 #endif
69
70 #include "expat\expat.h"
71
72 #ifdef __declspec
73 #undef XMLPARSEAPI
74 #endif
75#endif /* ndef COMPILED_FROM_DSP */
76
77#include <stddef.h>
78#include <string.h>
79
80#ifdef XML_UNICODE
81 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
82 #define XmlConvert XmlUtf16Convert
83 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
84 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
85 #define XmlEncode XmlUtf16Encode
86 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
87 typedef unsigned short ICHAR;
88#else
89 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
90 #define XmlConvert XmlUtf8Convert
91 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
92 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
93 #define XmlEncode XmlUtf8Encode
94 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
95 typedef char ICHAR;
96#endif
97
98
99#ifndef XML_NS
100 #define XmlInitEncodingNS XmlInitEncoding
101 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
102 #undef XmlGetInternalEncodingNS
103 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
104 #define XmlParseXmlDeclNS XmlParseXmlDecl
105#endif
106
107#ifdef XML_UNICODE_WCHAR_T
108 #define XML_T(x) L ## x
109#else
110 #define XML_T(x) x
111#endif
112
113/* Round up n to be a multiple of sz, where sz is a power of 2. */
114#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
115
116#include "expat\xmltok.h"
117#include "expat\xmlrole.h"
118
119typedef const XML_Char *KEY;
120
121typedef struct _NAMED
122{
123 KEY name;
124} NAMED, *PNAMED;
125
126typedef struct _HASH_TABLE
127{
128 NAMED **v;
129 size_t size;
130 size_t used;
131 size_t usedLim;
132 XML_Memory_Handling_Suite *mem;
133} HASH_TABLE, *PHASH_TABLE;
134
135typedef struct _HASH_TABLE_ITER
136{
137 NAMED **p;
138 NAMED **end;
139} HASH_TABLE_ITER, *PHASH_TABLE_ITER;
140
141#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
142#define INIT_DATA_BUF_SIZE 1024
143#define INIT_ATTS_SIZE 16
144#define INIT_BLOCK_SIZE 1024
145#define INIT_BUFFER_SIZE 1024
146
147#define EXPAND_SPARE 24
148
149typedef struct binding
150{
151 struct prefix *prefix;
152 struct binding *nextTagBinding;
153 struct binding *prevPrefixBinding;
154 const struct attribute_id *attId;
155 XML_Char *uri;
156 int uriLen;
157 int uriAlloc;
158} BINDING, *PBINDING;
159
160typedef struct prefix
161{
162 const XML_Char *name;
163 BINDING *binding;
164} PREFIX, *PPREFIX;
165
166typedef struct
167{
168 const XML_Char *str;
169 const XML_Char *localPart;
170 int uriLen;
171} TAG_NAME, *PTAG_NAME;
172
173typedef struct tag
174{
175 struct tag *parent;
176 const char *rawName;
177 int rawNameLength;
178 TAG_NAME name;
179 char *buf;
180 char *bufEnd;
181 BINDING *bindings;
182} TAG, *PTAG;
183
184typedef struct
185{
186 const XML_Char *name;
187 const XML_Char *textPtr;
188 int textLen;
189 const XML_Char *systemId;
190 const XML_Char *base;
191 const XML_Char *publicId;
192 const XML_Char *notation;
193 char open;
194 char is_param;
195} ENTITY, *PENTITY;
196
197typedef struct
198{
199 enum XML_Content_Type type;
200 enum XML_Content_Quant quant;
201 const XML_Char *name;
202 int firstchild;
203 int lastchild;
204 int childcnt;
205 int nextsib;
206} CONTENT_SCAFFOLD, *PCONTENT_SCAFFOLD;
207
208typedef struct block
209{
210 struct block *next;
211 int size;
212 XML_Char s[1];
213} BLOCK, *PBLOCK;
214
215typedef struct
216{
217 BLOCK *blocks;
218 BLOCK *freeBlocks;
219 const XML_Char *end;
220 XML_Char *ptr;
221 XML_Char *start;
222 XML_Memory_Handling_Suite *mem;
223} STRING_POOL, *PSTRING_POOL;
224
225/* The XML_Char before the name is used to determine whether
226 * an attribute has been specified. */
227typedef struct attribute_id
228{
229 XML_Char *name;
230 PREFIX *prefix;
231 char maybeTokenized;
232 char xmlns;
233} ATTRIBUTE_ID, *PATTRIBUTE_ID;
234
235typedef struct
236{
237 const ATTRIBUTE_ID *id;
238 char isCdata;
239 const XML_Char *value;
240} DEFAULT_ATTRIBUTE, *PDEFAULT_ATTRIBUTE;
241
242typedef struct
243{
244 const XML_Char *name;
245 PREFIX *prefix;
246 const ATTRIBUTE_ID *idAtt;
247 int nDefaultAtts;
248 int allocDefaultAtts;
249 DEFAULT_ATTRIBUTE *defaultAtts;
250} ELEMENT_TYPE, *PELEMENT_TYPE;
251
252typedef struct
253{
254 HASH_TABLE generalEntities;
255 HASH_TABLE elementTypes;
256 HASH_TABLE attributeIds;
257 HASH_TABLE prefixes;
258 STRING_POOL pool;
259 int complete;
260 int standalone;
261#ifdef XML_DTD
262 HASH_TABLE paramEntities;
263#endif /* XML_DTD */
264 PREFIX defaultPrefix;
265 /* === scaffolding for building content model === */
266 int in_eldecl;
267 CONTENT_SCAFFOLD *scaffold;
268 unsigned contentStringLen;
269 unsigned scaffSize;
270 unsigned scaffCount;
271 int scaffLevel;
272 int *scaffIndex;
273} DTD, *PDTD;
274
275typedef struct open_internal_entity
276{
277 const char *internalEventPtr;
278 const char *internalEventEndPtr;
279 struct open_internal_entity *next;
280 ENTITY *entity;
281} OPEN_INTERNAL_ENTITY, *POPEN_INTERNAL_ENTITY;
282
283typedef enum XML_Error Processor(XML_Parser parser,
284 const char *start,
285 const char *end,
286 const char **endPtr);
287
288static Processor prologProcessor;
289static Processor prologInitProcessor;
290static Processor contentProcessor;
291static Processor cdataSectionProcessor;
292
293#ifdef XML_DTD
294static Processor ignoreSectionProcessor;
295#endif /* XML_DTD */
296
297static Processor epilogProcessor;
298static Processor errorProcessor;
299static Processor externalEntityInitProcessor;
300static Processor externalEntityInitProcessor2;
301static Processor externalEntityInitProcessor3;
302static Processor externalEntityContentProcessor;
303
304static enum XML_Error handleUnknownEncoding(XML_Parser parser,
305 const XML_Char * encodingName);
306static enum XML_Error processXmlDecl(XML_Parser parser,
307 int isGeneralTextEntity,
308 const char *,
309 const char *);
310static enum XML_Error initializeEncoding(XML_Parser parser);
311static enum XML_Error doProlog(XML_Parser parser,
312 const ENCODING * enc,
313 const char *s,
314 const char *end,
315 int tok,
316 const char *next,
317 const char **nextPtr);
318static enum XML_Error processInternalParamEntity(XML_Parser parser,
319 ENTITY * entity);
320static enum XML_Error doContent(XML_Parser parser,
321 int startTagLevel,
322 const ENCODING * enc,
323 const char *start,
324 const char *end,
325 const char **endPtr);
326static enum XML_Error doCdataSection(XML_Parser parser,
327 const ENCODING *,
328 const char **startPtr,
329 const char *end,
330 const char **nextPtr);
331
332#ifdef XML_DTD
333static enum XML_Error doIgnoreSection(XML_Parser parser,
334 const ENCODING *,
335 const char **startPtr,
336 const char *end,
337 const char **nextPtr);
338#endif /* XML_DTD */
339
340static enum XML_Error storeAtts(XML_Parser parser,
341 const ENCODING *,
342 const char *s,
343 TAG_NAME * tagNamePtr,
344 BINDING ** bindingsPtr);
345static int addBinding(XML_Parser parser,
346 PREFIX * prefix,
347 const ATTRIBUTE_ID * attId,
348 const XML_Char * uri,
349 BINDING ** bindingsPtr);
350
351static int defineAttribute(ELEMENT_TYPE * type,
352 ATTRIBUTE_ID *,
353 int isCdata,
354 int isId,
355 const XML_Char * dfltValue,
356 XML_Parser parser);
357
358static enum XML_Error storeAttributeValue(XML_Parser parser,
359 const ENCODING *,
360 int isCdata,
361 const char *,
362 const char *,
363 STRING_POOL *);
364static enum XML_Error appendAttributeValue(XML_Parser parser,
365 const ENCODING *,
366 int isCdata,
367 const char *,
368 const char *,
369 STRING_POOL *);
370static ATTRIBUTE_ID * getAttributeId(XML_Parser parser,
371 const ENCODING * enc,
372 const char *start,
373 const char *end);
374static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
375static enum XML_Error storeEntityValue(XML_Parser parser,
376 const ENCODING * enc,
377 const char *start,
378 const char *end);
379static int reportProcessingInstruction(XML_Parser parser,
380 const ENCODING * enc,
381 const char *start,
382 const char *end);
383static int reportComment(XML_Parser parser,
384 const ENCODING * enc,
385 const char *start,
386 const char *end);
387static void reportDefault(XML_Parser parser,
388 const ENCODING * enc,
389 const char *start,
390 const char *end);
391
392static const XML_Char *getContext(XML_Parser parser);
393static int setContext(XML_Parser parser, const XML_Char * context);
394static void normalizePublicId(XML_Char * s);
395static int dtdInit(DTD *, XML_Parser parser);
396
397static void dtdDestroy(DTD *, XML_Parser parser);
398
399static int dtdCopy(DTD * newDtd, const DTD * oldDtd, XML_Parser parser);
400
401static int copyEntityTable(HASH_TABLE *,
402 STRING_POOL *,
403 const HASH_TABLE *,
404 XML_Parser parser);
405
406#ifdef XML_DTD
407static void dtdSwap(DTD *, DTD *);
408#endif /* XML_DTD */
409
410static NAMED *lookup(HASH_TABLE * table, KEY name, size_t createSize);
411
412static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite * ms);
413
414static void hashTableDestroy(HASH_TABLE *);
415static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
416static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
417static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite * ms);
418static void poolClear(STRING_POOL *);
419static void poolDestroy(STRING_POOL *);
420static XML_Char *poolAppend(STRING_POOL * pool, const ENCODING * enc,
421 const char *ptr, const char *end);
422static XML_Char *poolStoreString(STRING_POOL * pool, const ENCODING * enc,
423 const char *ptr, const char *end);
424
425static int poolGrow(STRING_POOL * pool);
426
427static int nextScaffoldPart(XML_Parser parser);
428static XML_Content *build_model(XML_Parser parser);
429
430static const XML_Char *poolCopyString(STRING_POOL * pool, const XML_Char * s);
431static const XML_Char *poolCopyStringN(STRING_POOL * pool, const XML_Char * s, int n);
432static const XML_Char *poolAppendString(STRING_POOL * pool, const XML_Char * s);
433static ELEMENT_TYPE *getElementType(XML_Parser Paraser,
434 const ENCODING * enc,
435 const char *ptr,
436 const char *end);
437
438#define poolStart(pool) ((pool)->start)
439#define poolEnd(pool) ((pool)->ptr)
440#define poolLength(pool) ((pool)->ptr - (pool)->start)
441#define poolChop(pool) ((void)--(pool->ptr))
442#define poolLastChar(pool) (((pool)->ptr)[-1])
443#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
444#define poolFinish(pool) ((pool)->start = (pool)->ptr)
445#define poolAppendChar(pool, c) \
446 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
447 ? 0 \
448 : ((*((pool)->ptr)++ = c), 1))
449
450typedef struct
451{
452 /* The first member must be userData so that the XML_GetUserData macro works. */
453 void *m_userData;
454 void *m_handlerArg;
455 char *m_buffer;
456 XML_Memory_Handling_Suite m_mem;
457 /* first character to be parsed */
458 const char *m_bufferPtr;
459 /* past last character to be parsed */
460 char *m_bufferEnd;
461 /* allocated end of buffer */
462 const char *m_bufferLim;
463 long m_parseEndByteIndex;
464 const char *m_parseEndPtr;
465 XML_Char *m_dataBuf;
466 XML_Char *m_dataBufEnd;
467 XML_StartElementHandler m_startElementHandler;
468 XML_EndElementHandler m_endElementHandler;
469 XML_CharacterDataHandler m_characterDataHandler;
470 XML_ProcessingInstructionHandler m_processingInstructionHandler;
471 XML_CommentHandler m_commentHandler;
472 XML_StartCdataSectionHandler m_startCdataSectionHandler;
473 XML_EndCdataSectionHandler m_endCdataSectionHandler;
474 XML_DefaultHandler m_defaultHandler;
475 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
476 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
477 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
478 XML_NotationDeclHandler m_notationDeclHandler;
479 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
480 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
481 XML_NotStandaloneHandler m_notStandaloneHandler;
482 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
483 void *m_externalEntityRefHandlerArg;
484 XML_UnknownEncodingHandler m_unknownEncodingHandler;
485 XML_ElementDeclHandler m_elementDeclHandler;
486 XML_AttlistDeclHandler m_attlistDeclHandler;
487 XML_EntityDeclHandler m_entityDeclHandler;
488 XML_XmlDeclHandler m_xmlDeclHandler;
489 const ENCODING *m_encoding;
490 INIT_ENCODING m_initEncoding;
491 const ENCODING *m_internalEncoding;
492 const XML_Char *m_protocolEncodingName;
493 int m_ns;
494 int m_ns_triplets;
495 void *m_unknownEncodingMem;
496 void *m_unknownEncodingData;
497 void *m_unknownEncodingHandlerData;
498 void (* EXPATENTRY m_unknownEncodingRelease) (void *);
499 PROLOG_STATE m_prologState;
500 Processor *m_processor;
501 enum XML_Error m_errorCode;
502 const char *m_eventPtr;
503 const char *m_eventEndPtr;
504 const char *m_positionPtr;
505 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
506 int m_defaultExpandInternalEntities;
507 int m_tagLevel;
508 ENTITY *m_declEntity;
509 const XML_Char *m_doctypeName;
510 const XML_Char *m_doctypeSysid;
511 const XML_Char *m_doctypePubid;
512 const XML_Char *m_declAttributeType;
513 const XML_Char *m_declNotationName;
514 const XML_Char *m_declNotationPublicId;
515 ELEMENT_TYPE *m_declElementType;
516 ATTRIBUTE_ID *m_declAttributeId;
517 char m_declAttributeIsCdata;
518 char m_declAttributeIsId;
519 DTD m_dtd;
520 const XML_Char *m_curBase;
521 TAG *m_tagStack;
522 TAG *m_freeTagList;
523 BINDING *m_inheritedBindings;
524 BINDING *m_freeBindingList;
525 int m_attsSize;
526 int m_nSpecifiedAtts;
527 int m_idAttIndex;
528 ATTRIBUTE *m_atts;
529 POSITION m_position;
530 STRING_POOL m_tempPool;
531 STRING_POOL m_temp2Pool;
532 char *m_groupConnector;
533 unsigned m_groupSize;
534 int m_hadExternalDoctype;
535 XML_Char m_namespaceSeparator;
536#ifdef XML_DTD
537 enum XML_ParamEntityParsing m_paramEntityParsing;
538 XML_Parser m_parentParser;
539#endif
540} Parser, *PParser;
541
542#define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
543#define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
544#define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
545
546#define userData (((Parser *)parser)->m_userData)
547#define handlerArg (((Parser *)parser)->m_handlerArg)
548#define startElementHandler (((Parser *)parser)->m_startElementHandler)
549#define endElementHandler (((Parser *)parser)->m_endElementHandler)
550#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
551#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
552#define commentHandler (((Parser *)parser)->m_commentHandler)
553#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
554#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
555#define defaultHandler (((Parser *)parser)->m_defaultHandler)
556#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
557#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
558#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
559#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
560#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
561#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
562#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
563#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
564#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
565#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
566#define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
567#define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
568#define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
569#define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
570#define encoding (((Parser *)parser)->m_encoding)
571#define initEncoding (((Parser *)parser)->m_initEncoding)
572#define internalEncoding (((Parser *)parser)->m_internalEncoding)
573#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
574#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
575#define unknownEncodingHandlerData (((Parser *)parser)->m_unknownEncodingHandlerData)
576#define unknownEncodingRelease (((Parser*)parser)->m_unknownEncodingRelease)
577#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
578#define ns (((Parser *)parser)->m_ns)
579#define ns_triplets (((Parser *)parser)->m_ns_triplets)
580#define prologState (((Parser *)parser)->m_prologState)
581#define processor (((Parser *)parser)->m_processor)
582#define errorCode (((Parser *)parser)->m_errorCode)
583#define eventPtr (((Parser *)parser)->m_eventPtr)
584#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
585#define positionPtr (((Parser *)parser)->m_positionPtr)
586#define position (((Parser *)parser)->m_position)
587#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
588#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
589#define tagLevel (((Parser *)parser)->m_tagLevel)
590#define buffer (((Parser*)parser)->m_buffer)
591#define bufferPtr (((Parser *)parser)->m_bufferPtr)
592#define bufferEnd (((Parser *)parser)->m_bufferEnd)
593#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
594#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
595#define bufferLim (((Parser *)parser)->m_bufferLim)
596#define dataBuf (((Parser *)parser)->m_dataBuf)
597#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
598#define dtd (((Parser *)parser)->m_dtd)
599#define curBase (((Parser *)parser)->m_curBase)
600#define declEntity (((Parser *)parser)->m_declEntity)
601#define doctypeName (((Parser *)parser)->m_doctypeName)
602#define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
603#define doctypePubid (((Parser *)parser)->m_doctypePubid)
604#define declAttributeType (((Parser *)parser)->m_declAttributeType)
605#define declNotationName (((Parser *)parser)->m_declNotationName)
606#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
607#define declElementType (((Parser *)parser)->m_declElementType)
608#define declAttributeId (((Parser *)parser)->m_declAttributeId)
609#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
610#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
611#define freeTagList (((Parser *)parser)->m_freeTagList)
612#define freeBindingList (((Parser *)parser)->m_freeBindingList)
613#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
614#define tagStack (((Parser *)parser)->m_tagStack)
615#define atts (((Parser *)parser)->m_atts)
616#define attsSize (((Parser *)parser)->m_attsSize)
617#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
618#define idAttIndex (((Parser *)parser)->m_idAttIndex)
619#define tempPool (((Parser *)parser)->m_tempPool)
620#define temp2Pool (((Parser *)parser)->m_temp2Pool)
621#define groupConnector (((Parser *)parser)->m_groupConnector)
622#define groupSize (((Parser *)parser)->m_groupSize)
623#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
624#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
625#ifdef XML_DTD
626#define parentParser (((Parser *)parser)->m_parentParser)
627#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
628#endif /* XML_DTD */
629
630/*
631 *@@ XML_ParserCreate:
632 * constructs a new parser. If encoding is non-null, it specifies
633 * a character encoding to use for the document. This overrides
634 * the document encoding declaration.
635 *
636 * Expat is a stream-oriented parser. You register callback (or
637 * handler) functions with the parser and then start feeding it
638 * the document. As the parser recognizes parts of the document,
639 * it will call the appropriate handler for that part (if you've
640 * registered one.) The document is fed to the parser in pieces,
641 * so you can start parsing before you have all the document.
642 * This also allows you to parse really huge documents that won't
643 * fit into memory.
644 *
645 * Expat can be intimidating due to the many kinds of handlers
646 * and options you can set. But you only need to learn four
647 * functions in order to do 90% of what you'll want to do with it:
648 *
649 * -- XML_ParserCreate: Create a new parser object.
650 *
651 * -- XML_SetElementHandler: Set handlers for start and end tags.
652 *
653 * -- XML_SetCharacterDataHandler: Set handler for text.
654 *
655 * -- XML_Parse: Pass a buffer full of document to the parser.
656 *
657 * So the first step in parsing an XML document with expat is
658 * to create a parser object. There are three functions in the
659 * expat API for creating a parser object. However, only two of
660 * these (XML_ParserCreate and XML_ParserCreateNS) can be used
661 * for constructing a parser for a top-level document. The object
662 * returned by these functions is an opaque pointer (i.e. expat.h
663 * declares it as void*) to data with further internal structure.
664 * In order to free the memory associated with this object you
665 * must call XML_ParserFree. Note that if you have provided
666 * any user data that gets stored in the parser, then your
667 * application is responsible for freeing it prior to calling
668 * XML_ParserFree.
669 *
670 * The objects returned by the parser creation functions are
671 * good for parsing only one XML document or external parsed
672 * entity. If your application needs to parse many XML documents,
673 * then it needs to create a parser object for each one. The
674 * best way to deal with this is to create a higher level object
675 * that contains all the default initialization you want for
676 * your parser objects.
677 *
678 * Walking through a document hierarchy with a stream oriented
679 * parser will require a good stack mechanism in order to keep
680 * track of current context. For instance, to answer the simple
681 * question, "What element does this text belong to?" requires
682 * a stack, since the parser may have descended into other
683 * elements that are children of the current one and has
684 * encountered this text on the way out.
685 *
686 * The things you're likely to want to keep on a stack are the
687 * currently opened element and it's attributes. You push this
688 * information onto the stack in the start handler and you pop
689 * it off in the end handler.
690 *
691 * For some tasks, it is sufficient to just keep information on
692 * what the depth of the stack is (or would be if you had one.)
693 * The outline program shown above presents one example. Another
694 * such task would be skipping over a complete element. When you
695 * see the start tag for the element you want to skip, you set a
696 * skip flag and record the depth at which the element started.
697 * When the end tag handler encounters the same depth, the
698 * skipped element has ended and the flag may be cleared. If you
699 * follow the convention that the root element starts at 1, then
700 * you can use the same variable for skip flag and skip depth.
701 *
702 * <B>Namespace Processing</B>
703 *
704 * When the parser is created using the XML_ParserCreateNS,
705 * function, expat performs namespace processing. See that
706 * function for details.
707 *
708 * <B>Character Encodings</B>
709 *
710 * While XML is based on Unicode, and every XML processor is
711 * required to recognized UTF-8 and UTF-16 (1 and 2 byte
712 * encodings of Unicode), other encodings may be declared in
713 * XML documents or entities. For the main document, an XML
714 * declaration may contain an encoding declaration in its
715 * @text_declaration:
716 *
717 + <?xml version="1.0" encoding="ISO-8859-2"?>
718 *
719 * With expat, you may also specify an encoding at the time
720 * of creating a parser. This is useful when the encoding
721 * information may come from a source outside the document
722 * itself (like a higher level protocol.)
723 *
724 * There are four built-in encodings in expat:
725 *
726 * -- UTF-8: 8-bit encoding of Unicode.
727 *
728 * -- UTF-16: 16-bit encoding of Unicode.
729 *
730 * -- ISO-8859-1: that's "latin 1".
731 *
732 * -- US-ASCII
733 *
734 * Anything else discovered in an encoding declaration or in
735 * the protocol encoding specified in the parser constructor,
736 * triggers a call to the UnknownEncodingHandler (see
737 * XML_SetUnknownEncodingHandler). This handler gets passed
738 * the encoding name and a pointer to an XML_Encoding data
739 * structure. Your handler must fill in this structure and
740 * return 1 if it knows how to deal with the encoding. Otherwise
741 * the handler should return 0. The handler also gets passed a
742 * pointer to an optional application data structure that you may
743 * indicate when you set the handler.
744 *
745 * One pitfall that novice expat users are likely to fall into is
746 * that although expat may accept input in various encodings, the
747 * strings that it passes to the handlers are always encoded in
748 * UTF-8. Your application is responsible for any translation of
749 * these strings into other encodings.
750 *
751 * <B>Handling External Entity References</B>
752 *
753 * Expat does not read or parse external entities directly. Note that
754 * any external @DTD is a special case of an external entity. If you've
755 * set no ExternalEntityRefHandler (see XML_SetExternalEntityRefHandler),
756 * then external entity references are silently ignored. Otherwise, it
757 * calls your handler with the information needed to read and parse the
758 * external entity.
759 *
760 * <B>Parsing DTDs</B>
761 *
762 * In order to parse @parameter_entities, before starting the parse,
763 * you must call XML_SetParamEntityParsing.
764 */
765
766XML_Parser XML_ParserCreate(const XML_Char* encodingName)
767{
768 return XML_ParserCreate_MM(encodingName, NULL, NULL);
769}
770
771/*
772 *@@ XML_ParserCreateNS:
773 * constructs a new parser that has namespace processing
774 * in effect. Namespace expanded element names and attribute
775 * names are returned as a concatenation of the namespace URI,
776 * sep, and the local part of the name. This means that you
777 * should pick a character for sep that can't be part of a
778 * legal URI.
779 *
780 * Under namespace processing, expat consumes xmlns and xmlns:...
781 * attributes, which declare namespaces for the scope of the
782 * element in which they occur. This means that your start
783 * handler will not see these attributes. Your application can
784 * still be informed of these declarations by setting namespace
785 * declaration handlers with XML_SetNamespaceDeclHandler.
786 *
787 * Element type and attribute names that belong to a given
788 * namespace are passed to the appropriate handler in expanded
789 * form. By default this expanded form is a concatenation of the
790 * namespace URI, the separator character (which is the 2nd
791 * argument to XML_ParserCreateNS), and the local name (i.e.
792 * the part after the colon). Names with undeclared prefixes
793 * are passed through to the handlers unchanged, with the prefix
794 * and colon still attached. Unprefixed attribute names are never
795 * expanded, and unprefixed element names are only expanded when
796 * they are in the scope of a default namespace.
797 *
798 * However if XML_SetReturnNSTriplet has been called with a
799 * non-zero do_nst parameter, then the expanded form for names
800 * with an explicit prefix is a concatenation of: URI, separator,
801 * local name, separator, prefix.
802 *
803 * You can set handlers for the start of a namespace declaration
804 * and for the end of a scope of a declaration with the
805 * XML_SetNamespaceDeclHandler function. The
806 * StartNamespaceDeclHandler is called prior to the start
807 * tag handler and the EndNamespaceDeclHandler is called before
808 * the corresponding end tag that ends the namespace's scope.
809 * The namespace start handler gets passed the prefix and URI
810 * for the namespace. For a default namespace declaration
811 * (xmlns='...'), the prefix will be null. The URI will be null
812 * for the case where the default namespace is being unset. The
813 * namespace end handler just gets the prefix for the closing
814 * scope.
815 *
816 * These handlers are called for each declaration. So if, for
817 * instance, a start tag had three namespace declarations, then
818 * the StartNamespaceDeclHandler would be called three times
819 * before the start tag handler is called, once for each
820 * declaration.
821 *
822 * The namespace.c example demonstrates the use of these
823 * features. Like outline.c, it produces an outline, but in
824 * addition it annotates when a namespace scope starts and
825 * when it ends. This example also demonstrates use of
826 * application user data.
827 */
828
829XML_Parser XML_ParserCreateNS(const XML_Char * encodingName, XML_Char nsSep)
830{
831 XML_Char tmp[2];
832
833 *tmp = nsSep;
834 return XML_ParserCreate_MM(encodingName, NULL, tmp);
835}
836
837/*
838 *@@ XML_ParserCreate_MM:
839 * constructs a new parser using the suite of memory handling
840 * functions specified in ms. If ms is NULL, then use the
841 * standard set of memory management functions. If sep is
842 * non-NULL, then namespace processing is enabled in the
843 * created parser and the character pointed at by sep is
844 * used as the separator between the namespace URI and the
845 * local part of the name.
846 */
847
848XML_Parser XML_ParserCreate_MM(const XML_Char * encodingName,
849 const XML_Memory_Handling_Suite * memsuite,
850 const XML_Char * nameSep)
851{
852
853 XML_Parser parser;
854 static
855 const XML_Char implicitContext[] =
856 {
857 XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
858 XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
859 XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
860 XML_T('.'), XML_T('w'), XML_T('3'),
861 XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
862 XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
863 XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
864 XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
865 XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
866 XML_T('\0')
867 };
868
869
870 if (memsuite)
871 {
872 XML_Memory_Handling_Suite *mtemp;
873
874 parser = memsuite->malloc_fcn(sizeof(Parser));
875 mtemp = &(((Parser*)parser)->m_mem);
876 mtemp->malloc_fcn = memsuite->malloc_fcn;
877 mtemp->realloc_fcn = memsuite->realloc_fcn;
878 mtemp->free_fcn = memsuite->free_fcn;
879 }
880 else
881 {
882 XML_Memory_Handling_Suite *mtemp;
883
884 parser = malloc(sizeof(Parser));
885 mtemp = &(((Parser*)parser)->m_mem);
886 mtemp->malloc_fcn = malloc;
887 mtemp->realloc_fcn = realloc;
888 mtemp->free_fcn = free;
889 }
890
891 if (!parser)
892 return parser;
893 processor = prologInitProcessor;
894 XmlPrologStateInit(&prologState);
895 userData = 0;
896 handlerArg = 0;
897 startElementHandler = 0;
898 endElementHandler = 0;
899 characterDataHandler = 0;
900 processingInstructionHandler = 0;
901 commentHandler = 0;
902 startCdataSectionHandler = 0;
903 endCdataSectionHandler = 0;
904 defaultHandler = 0;
905 startDoctypeDeclHandler = 0;
906 endDoctypeDeclHandler = 0;
907 unparsedEntityDeclHandler = 0;
908 notationDeclHandler = 0;
909 startNamespaceDeclHandler = 0;
910 endNamespaceDeclHandler = 0;
911 notStandaloneHandler = 0;
912 externalEntityRefHandler = 0;
913 externalEntityRefHandlerArg = parser;
914 unknownEncodingHandler = 0;
915 elementDeclHandler = 0;
916 attlistDeclHandler = 0;
917 entityDeclHandler = 0;
918 xmlDeclHandler = 0;
919 buffer = 0;
920 bufferPtr = 0;
921 bufferEnd = 0;
922 parseEndByteIndex = 0;
923 parseEndPtr = 0;
924 bufferLim = 0;
925 declElementType = 0;
926 declAttributeId = 0;
927 declEntity = 0;
928 doctypeName = 0;
929 doctypeSysid = 0;
930 doctypePubid = 0;
931 declAttributeType = 0;
932 declNotationName = 0;
933 declNotationPublicId = 0;
934 memset(&position, 0, sizeof(POSITION));
935 errorCode = XML_ERROR_NONE;
936 eventPtr = 0;
937 eventEndPtr = 0;
938 positionPtr = 0;
939 openInternalEntities = 0;
940 tagLevel = 0;
941 tagStack = 0;
942 freeTagList = 0;
943 freeBindingList = 0;
944 inheritedBindings = 0;
945 attsSize = INIT_ATTS_SIZE;
946 atts = (PATTRIBUTE)MALLOC(attsSize * sizeof(ATTRIBUTE));
947 nSpecifiedAtts = 0;
948 dataBuf = (XML_Char*)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
949 groupSize = 0;
950 groupConnector = 0;
951 hadExternalDoctype = 0;
952 unknownEncodingMem = 0;
953 unknownEncodingRelease = 0;
954 unknownEncodingData = 0;
955 unknownEncodingHandlerData = 0;
956 namespaceSeparator = '!';
957#ifdef XML_DTD
958 parentParser = 0;
959 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
960#endif
961 ns = 0;
962 ns_triplets = 0;
963 poolInit(&tempPool, &(((Parser*)parser)->m_mem));
964 poolInit(&temp2Pool, &(((Parser*)parser)->m_mem));
965 protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
966 curBase = 0;
967 if (!dtdInit(&dtd, parser) || !atts || !dataBuf
968 || (encodingName && !protocolEncodingName))
969 {
970 XML_ParserFree(parser);
971 return 0;
972 }
973 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
974
975 if (nameSep)
976 {
977 XmlInitEncodingNS(&initEncoding, &encoding, 0);
978 ns = 1;
979 internalEncoding = XmlGetInternalEncodingNS();
980 namespaceSeparator = *nameSep;
981
982 if (!setContext(parser, implicitContext))
983 {
984 XML_ParserFree(parser);
985 return 0;
986 }
987 }
988 else
989 {
990 XmlInitEncoding(&initEncoding, &encoding, 0);
991 internalEncoding = XmlGetInternalEncoding();
992 }
993
994 return parser;
995} /* End XML_ParserCreate_MM */
996
997/*
998 *@@ XML_SetEncoding:
999 * sets the encoding to be used by the parser. It is
1000 * equivalent to passing a non-null encoding argument
1001 * to the parser creation functions. It must not be
1002 * called after XML_Parser or XML_ParseBuffer have
1003 * been called on the given parser.
1004 */
1005
1006int XML_SetEncoding(XML_Parser parser, const XML_Char * encodingName)
1007{
1008 if (!encodingName)
1009 protocolEncodingName = 0;
1010 else
1011 {
1012 protocolEncodingName = poolCopyString(&tempPool, encodingName);
1013 if (!protocolEncodingName)
1014 return 0;
1015 }
1016 return 1;
1017}
1018
1019/*
1020 *@@ XML_ExternalEntityParserCreate:
1021 * constructs a new XML_Parser object for parsing an external
1022 * general entity. Context is the context argument passed in a
1023 * call to a ExternalEntityRefHandler. Other state information
1024 * such as handlers, user data, namespace processing is
1025 * inherited from the parser passed as the 1st argument. So you
1026 * shouldn't need to call any of the behavior changing
1027 * functions on this parser (unless you want it to act
1028 * differently than the parent parser.)
1029 */
1030
1031XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
1032 const XML_Char * context,
1033 const XML_Char * encodingName)
1034{
1035 XML_Parser parser = oldParser;
1036 DTD *oldDtd = &dtd;
1037 XML_StartElementHandler oldStartElementHandler = startElementHandler;
1038 XML_EndElementHandler oldEndElementHandler = endElementHandler;
1039 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
1040 XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
1041 XML_CommentHandler oldCommentHandler = commentHandler;
1042 XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
1043 XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
1044 XML_DefaultHandler oldDefaultHandler = defaultHandler;
1045 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
1046 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
1047 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
1048 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
1049 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
1050 XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
1051 XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
1052 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
1053 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
1054 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
1055 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
1056 ELEMENT_TYPE *oldDeclElementType = declElementType;
1057
1058 void *oldUserData = userData;
1059 void *oldHandlerArg = handlerArg;
1060 int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
1061 void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
1062
1063#ifdef XML_DTD
1064 int oldParamEntityParsing = paramEntityParsing;
1065
1066#endif
1067 int oldns_triplets = ns_triplets;
1068
1069 if (ns)
1070 {
1071 XML_Char tmp[2];
1072
1073 *tmp = namespaceSeparator;
1074 parser = XML_ParserCreate_MM(encodingName, &((Parser*)parser)->m_mem,
1075 tmp);
1076 }
1077 else
1078 {
1079 parser = XML_ParserCreate_MM(encodingName, &((Parser*)parser)->m_mem,
1080 NULL);
1081 }
1082
1083 if (!parser)
1084 return 0;
1085
1086 startElementHandler = oldStartElementHandler;
1087 endElementHandler = oldEndElementHandler;
1088 characterDataHandler = oldCharacterDataHandler;
1089 processingInstructionHandler = oldProcessingInstructionHandler;
1090 commentHandler = oldCommentHandler;
1091 startCdataSectionHandler = oldStartCdataSectionHandler;
1092 endCdataSectionHandler = oldEndCdataSectionHandler;
1093 defaultHandler = oldDefaultHandler;
1094 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1095 notationDeclHandler = oldNotationDeclHandler;
1096 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1097 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1098 notStandaloneHandler = oldNotStandaloneHandler;
1099 externalEntityRefHandler = oldExternalEntityRefHandler;
1100 unknownEncodingHandler = oldUnknownEncodingHandler;
1101 elementDeclHandler = oldElementDeclHandler;
1102 attlistDeclHandler = oldAttlistDeclHandler;
1103 entityDeclHandler = oldEntityDeclHandler;
1104 xmlDeclHandler = oldXmlDeclHandler;
1105 declElementType = oldDeclElementType;
1106 userData = oldUserData;
1107 if (oldUserData == oldHandlerArg)
1108 handlerArg = userData;
1109 else
1110 handlerArg = parser;
1111 if (oldExternalEntityRefHandlerArg != oldParser)
1112 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1113 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1114 ns_triplets = oldns_triplets;
1115#ifdef XML_DTD
1116 paramEntityParsing = oldParamEntityParsing;
1117 if (context)
1118 {
1119#endif /* XML_DTD */
1120 if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context))
1121 {
1122 XML_ParserFree(parser);
1123 return 0;
1124 }
1125 processor = externalEntityInitProcessor;
1126#ifdef XML_DTD
1127 }
1128 else
1129 {
1130 dtdSwap(&dtd, oldDtd);
1131 parentParser = oldParser;
1132 XmlPrologStateInitExternalEntity(&prologState);
1133 dtd.complete = 1;
1134 hadExternalDoctype = 1;
1135 }
1136#endif /* XML_DTD */
1137 return parser;
1138}
1139
1140static void destroyBindings(BINDING * bindings, XML_Parser parser)
1141{
1142 for (;;)
1143 {
1144 BINDING *b = bindings;
1145
1146 if (!b)
1147 break;
1148 bindings = b->nextTagBinding;
1149 FREE(b->uri);
1150 FREE(b);
1151 }
1152}
1153
1154/*
1155 *@@ XML_ParserFree:
1156 * free memory used by the parser. Your application is
1157 * responsible for freeing any memory associated
1158 * with UserData.
1159 */
1160
1161void XML_ParserFree(XML_Parser parser)
1162{
1163 for (;;)
1164 {
1165 TAG *p;
1166
1167 if (tagStack == 0)
1168 {
1169 if (freeTagList == 0)
1170 break;
1171 tagStack = freeTagList;
1172 freeTagList = 0;
1173 }
1174 p = tagStack;
1175 tagStack = tagStack->parent;
1176 FREE(p->buf);
1177 destroyBindings(p->bindings, parser);
1178 FREE(p);
1179 }
1180 destroyBindings(freeBindingList, parser);
1181 destroyBindings(inheritedBindings, parser);
1182 poolDestroy(&tempPool);
1183 poolDestroy(&temp2Pool);
1184#ifdef XML_DTD
1185 if (parentParser)
1186 {
1187 if (hadExternalDoctype)
1188 dtd.complete = 0;
1189 dtdSwap(&dtd, &((Parser*)parentParser)->m_dtd);
1190 }
1191#endif /* XML_DTD */
1192 dtdDestroy(&dtd, parser);
1193 FREE((void *)atts);
1194 if (groupConnector)
1195 FREE(groupConnector);
1196 if (buffer)
1197 FREE(buffer);
1198 FREE(dataBuf);
1199 if (unknownEncodingMem)
1200 FREE(unknownEncodingMem);
1201 if (unknownEncodingRelease)
1202 unknownEncodingRelease(unknownEncodingData);
1203 FREE(parser);
1204}
1205
1206/*
1207 *@@ XML_UseParserAsHandlerArg:
1208 * after this is called, handlers receive the parser in the
1209 * userData argument (see XML_SetUserData). The userData
1210 * information can still be obtained using the XML_GetUserData
1211 * function.
1212 */
1213
1214void XML_UseParserAsHandlerArg(XML_Parser parser)
1215{
1216 handlerArg = parser;
1217}
1218
1219/*
1220 *@@ XML_SetReturnNSTriplet:
1221 * this function only has an effect when using a parser
1222 * created with XML_ParserCreateNS, i.e. when namespace
1223 * processing is in effect. The do_nst sets whether or
1224 * not prefixes are returned with names qualified with
1225 * a namespace prefix. If this function is called with
1226 * do_nst non-zero, then afterwards namespace qualified
1227 * names (that is qualified with a prefix as opposed to
1228 * belonging to a default namespace) are returned as a
1229 * triplet with the three parts separated by the namespace
1230 * separator specified when the parser was created. The
1231 * order of returned parts is URI, local name, and prefix.
1232 *
1233 * If do_nst is zero, then namespaces are reported in
1234 * the default manner, URI then local_name separated by
1235 * the namespace separator.
1236 */
1237
1238void XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1239{
1240 ns_triplets = do_nst;
1241}
1242
1243/*
1244 *@@ XML_SetUserData:
1245 * sets the user data pointer that gets passed to handlers.
1246 *
1247 * It overwrites any previous value for this pointer. Note that
1248 * the application is responsible for freeing the memory
1249 * associated with userData when it is finished with the parser.
1250 * So if you call this when there's already a pointer there, and
1251 * you haven't freed the memory associated with it, then you've
1252 * probably just leaked memory.
1253 *
1254 * Also see XML_UseParserAsHandlerArg.
1255 */
1256
1257void XML_SetUserData(XML_Parser parser, void *p)
1258{
1259 if (handlerArg == userData)
1260 handlerArg = userData = p;
1261 else
1262 userData = p;
1263}
1264
1265/*
1266 *@@ XML_SetBase:
1267 * set the base to be used for resolving relative URIs in
1268 * system identifiers. The return value is 0 if there's no
1269 * memory to store base, otherwise it's non-zero.
1270 */
1271
1272int XML_SetBase(XML_Parser parser, const XML_Char * p)
1273{
1274 if (p)
1275 {
1276 p = poolCopyString(&dtd.pool, p);
1277 if (!p)
1278 return 0;
1279 curBase = p;
1280 }
1281 else
1282 curBase = 0;
1283 return 1;
1284}
1285
1286/*
1287 *@@ XML_GetBase:
1288 * returns the base for resolving relative URIs.
1289 * See XML_SetBase.
1290 */
1291
1292const XML_Char* XML_GetBase(XML_Parser parser)
1293{
1294 return curBase;
1295}
1296
1297/*
1298 *@@ XML_GetSpecifiedAttributeCount:
1299 * when attributes are reported to the start handler in the
1300 * atts vector, attributes that were explicitly set in the
1301 * element occur before any attributes that receive their
1302 * value from default information in an ATTLIST declaration.
1303 * This function returns the number of attributes that were
1304 * explicitly set times two, thus giving the offset in the
1305 * atts array passed to the start tag handler of the first
1306 * attribute set due to defaults. It supplies information
1307 * for the last call to a start handler. If called inside a
1308 * start handler, then that means the current call.
1309 */
1310
1311int XML_GetSpecifiedAttributeCount(XML_Parser parser)
1312{
1313 return nSpecifiedAtts;
1314}
1315
1316/*
1317 *@@ XML_GetIdAttributeIndex:
1318 * returns the index of the ID attribute passed in the atts
1319 * array in the last call to XML_StartElementHandler, or -1
1320 * if there is no ID attribute. If called inside a start
1321 * handler, then that means the current call.
1322 */
1323
1324int XML_GetIdAttributeIndex(XML_Parser parser)
1325{
1326 return idAttIndex;
1327}
1328
1329/*
1330 *@@ XML_SetElementHandler:
1331 * sets handlers for start and end tags with one call.
1332 *
1333 * See XML_SetStartElementHandler and XML_SetEndElementHandler
1334 * for details.
1335 */
1336
1337void XML_SetElementHandler(XML_Parser parser,
1338 XML_StartElementHandler start,
1339 XML_EndElementHandler end)
1340{
1341 startElementHandler = start;
1342 endElementHandler = end;
1343}
1344
1345/*
1346 *@@ XML_SetStartElementHandler:
1347 * sets handler for start (and empty) tags.
1348 *
1349 * This handler must have the following prototype:
1350 *
1351 + void EXPATENTRY StartElementHandler(void *userData,
1352 + const XML_Char *name,
1353 + const XML_Char **atts);
1354 +
1355 * "data" is the user data pointer set with XML_SetUserData.
1356 *
1357 * "name" is the element name.
1358 *
1359 * Attributes are passed to the start handler as a pointer
1360 * to a vector of char pointers. Each attribute seen in a
1361 * start (or empty) tag occupies 2 consecutive places in
1362 * this vector: the attribute name followed by the attribute
1363 * value. These pairs are terminated by a null pointer.
1364 *
1365 * Note that an empty tag generates a call to both start
1366 * and end handlers (in that order).
1367 *
1368 * Although handlers are typically set prior to parsing and left
1369 * alone, an application may choose to set or change the handler
1370 * for a parsing event while the parse is in progress. For
1371 * instance, your application may choose to ignore all text not
1372 * descended from a para element. One way it could do this is to
1373 * set the character handler when a para start tag is seen, and
1374 * unset it for the corresponding end tag.
1375 *
1376 * A handler may be unset by providing a NULL pointer to the
1377 * appropriate handler setter. None of the handler setting
1378 * functions have a return value.
1379 *
1380 * Your handlers will be receiving strings in arrays of type
1381 * XML_Char. This type is defined in expat.h as char* and
1382 * contains bytes encoding UTF-8. Note that you'll receive them
1383 * in this form independent of the original encoding of the
1384 * document.
1385 */
1386
1387void XML_SetStartElementHandler(XML_Parser parser,
1388 XML_StartElementHandler start)
1389{
1390 startElementHandler = start;
1391}
1392
1393/*
1394 *@@ XML_SetEndElementHandler:
1395 * sets handler for end (and empty) tags. As noted above, an
1396 * empty tag generates a call to both start and end handlers.
1397 *
1398 * Handler prototype:
1399 +
1400 + void EXPATENTRY (void *userData,
1401 + const XML_Char *name);
1402 */
1403
1404void XML_SetEndElementHandler(XML_Parser parser,
1405 XML_EndElementHandler end)
1406{
1407 endElementHandler = end;
1408}
1409
1410/*
1411 *@@ XML_SetCharacterDataHandler:
1412 * sets a character data (text) handler.
1413 *
1414 * Handler prototype:
1415 *
1416 + void EXPATENTRY CharacterDataHandler(void *userData,
1417 + const XML_Char *s,
1418 + int len);
1419 +
1420 * The string your handler receives is NOT zero terminated.
1421 * You have to use the length argument to deal with the end
1422 * of the string. A single block of contiguous text free of
1423 * markup may still result in a sequence of calls to this
1424 * handler. In other words, if you're searching for a pattern
1425 * in the text, it may be split across calls to this handler.
1426 */
1427
1428void XML_SetCharacterDataHandler(XML_Parser parser,
1429 XML_CharacterDataHandler handler)
1430{
1431 characterDataHandler = handler;
1432}
1433
1434/*
1435 *@@ XML_SetProcessingInstructionHandler:
1436 * sets a handler for processing instructions.
1437 *
1438 * Handler prototype:
1439 *
1440 + void EXPATENTRY ProcessingInstructionHandler(void *userData,
1441 + const XML_Char *target,
1442 + const XML_Char *data);
1443 +
1444 * The target is the first word in the processing instruction. The data
1445 * is the rest of the characters in it after skipping all
1446 * whitespace after the initial word.
1447 */
1448
1449void XML_SetProcessingInstructionHandler(XML_Parser parser,
1450 XML_ProcessingInstructionHandler handler)
1451{
1452 processingInstructionHandler = handler;
1453}
1454
1455/*
1456 *@@ XML_SetCommentHandler:
1457 * sets a handler for comments. The data is all text inside
1458 * the comment delimiters.
1459 *
1460 * Handler prototype:
1461 *
1462 + void EXPATENTRY CommentHandler(void *userData,
1463 + const XML_Char *data);
1464 *
1465 */
1466
1467void XML_SetCommentHandler(XML_Parser parser,
1468 XML_CommentHandler handler)
1469{
1470 commentHandler = handler;
1471}
1472
1473/*
1474 *@@ XML_SetCdataSectionHandler:
1475 * combination of XML_SetStartCdataSectionHandler and
1476 * XML_SetEndCdataSectionHandler in one call.
1477 */
1478
1479void XML_SetCdataSectionHandler(XML_Parser parser,
1480 XML_StartCdataSectionHandler start,
1481 XML_EndCdataSectionHandler end)
1482{
1483 startCdataSectionHandler = start;
1484 endCdataSectionHandler = end;
1485}
1486
1487/*
1488 *@@ XML_SetCdataSectionHandler:
1489 * sets a handler that gets called at the beginning of a CDATA
1490 * section.
1491 *
1492 * Handler prototype:
1493 *
1494 + void EXPATENTRY StartCdataSectionHandler(void *userData);
1495 *
1496 */
1497
1498void XML_SetStartCdataSectionHandler(XML_Parser parser,
1499 XML_StartCdataSectionHandler start)
1500{
1501 startCdataSectionHandler = start;
1502}
1503
1504/*
1505 *@@ XML_SetCdataSectionHandler:
1506 * sets a handler that gets called at the end of a CDATA
1507 * section.
1508 *
1509 * Handler prototype:
1510 *
1511 * void EXPATENTRY EndCdataSectionHandler(void *userData);
1512 */
1513
1514void XML_SetEndCdataSectionHandler(XML_Parser parser,
1515 XML_EndCdataSectionHandler end)
1516{
1517 endCdataSectionHandler = end;
1518}
1519
1520/*
1521 *@@ XML_SetDefaultHandler:
1522 * sets a handler for any characters in the document for
1523 * which there is no applicable handler.
1524 *
1525 * This includes both data for which no handlers can be set
1526 * (like some kinds of DTD declarations) and data which could
1527 * be reported but for which there has no handler supplied.
1528 *
1529 * Handler prototype:
1530 +
1531 + void EXPATENTRY DefaultHandler(void *userData,
1532 + const XML_Char *s,
1533 + int len);
1534 *
1535 * The characters are passed exactly as they were in the XML
1536 * document except that they will be encoded in UTF-8. Line
1537 * boundaries are not normalized.
1538 *
1539 * Note that a byte order mark character is not passed to the
1540 * default handler.
1541 *
1542 * Note that a contiguous piece of data that is destined to
1543 * be reported to the default handler may actually be reported
1544 * over several calls to the handler.
1545 *
1546 * Setting the handler with this call has the side effect of
1547 * turning off expansion of references to internally defined
1548 * general entities. Instead these references are passed to
1549 * the default handler.
1550 */
1551
1552void XML_SetDefaultHandler(XML_Parser parser,
1553 XML_DefaultHandler handler)
1554{
1555 defaultHandler = handler;
1556 defaultExpandInternalEntities = 0;
1557}
1558
1559/*
1560 *@@ XML_SetDefaultHandlerExpand:
1561 * this sets a default handler, but doesn't affect expansion of
1562 * internal entity references.
1563 *
1564 * See XML_SetDefaultHandler.
1565 */
1566
1567void XML_SetDefaultHandlerExpand(XML_Parser parser,
1568 XML_DefaultHandler handler)
1569{
1570 defaultHandler = handler;
1571 defaultExpandInternalEntities = 1;
1572}
1573
1574/*
1575 *@@ XML_SetDoctypeDeclHandler:
1576 * combination of XML_SetStartDoctypeDeclHandler and
1577 * XML_SetEndDoctypeDeclHandler.
1578 */
1579
1580void XML_SetDoctypeDeclHandler(XML_Parser parser,
1581 XML_StartDoctypeDeclHandler start,
1582 XML_EndDoctypeDeclHandler end)
1583{
1584 startDoctypeDeclHandler = start;
1585 endDoctypeDeclHandler = end;
1586}
1587
1588/*
1589 *@@ XML_SetStartDoctypeDeclHandler:
1590 * sets a handler that is called at the start of a DOCTYPE
1591 * declaration, before any external or internal subset is
1592 * parsed.
1593 *
1594 * Handler prototype:
1595 *
1596 + void EXPATENTRY StartDoctypeDeclHandler(void *userData,
1597 + const XML_Char *doctypeName,
1598 + const XML_Char *sysid,
1599 + const XML_Char *pubid,
1600 + int has_internal_subset);
1601 *
1602 * Both sysid and pubid may be NULL. The has_internal_subset
1603 * will be non-zero if the DOCTYPE declaration has an internal subset.
1604 */
1605
1606void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1607 XML_StartDoctypeDeclHandler start)
1608{
1609 startDoctypeDeclHandler = start;
1610}
1611
1612/*
1613 *@@ XML_SetEndDoctypeDeclHandler:
1614 * sets a handler that is called at the end of a DOCTYPE
1615 * declaration, after parsing any external subset.
1616 *
1617 * Handler prototype:
1618 *
1619 + void EXPATENTRY EndDoctypeDeclHandler(void *userData);
1620 *
1621 */
1622
1623void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1624 XML_EndDoctypeDeclHandler end)
1625{
1626 endDoctypeDeclHandler = end;
1627}
1628
1629/*
1630 *@@ XML_SetUnparsedEntityDeclHandler:
1631 * sets a handler that receives declarations of unparsed
1632 * entities. These are entity declarations that have a
1633 * notation (NDATA) field:
1634 *
1635 + <!ENTITY logo SYSTEM "images/logo.gif" NDATA gif>
1636 *
1637 * This handler is obsolete and is provided for backwards
1638 * compatibility. Use instead XML_SetEntityDeclHandler.
1639 */
1640
1641void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1642 XML_UnparsedEntityDeclHandler handler)
1643{
1644 unparsedEntityDeclHandler = handler;
1645}
1646
1647/*
1648 *@@ XML_SetNotationDeclHandler:
1649 * sets a handler that receives notation declarations.
1650 *
1651 * Handler prototype:
1652 +
1653 + void EXPATENTRY NotationDeclHandler(void *userData,
1654 + const XML_Char *notationName,
1655 + const XML_Char *base,
1656 + const XML_Char *systemId,
1657 + const XML_Char *publicId);
1658 +
1659 */
1660
1661void XML_SetNotationDeclHandler(XML_Parser parser,
1662 XML_NotationDeclHandler handler)
1663{
1664 notationDeclHandler = handler;
1665}
1666
1667/*
1668 *@@ XML_SetNamespaceDeclHandler:
1669 * combination of XML_SetEndNamespaceDeclHandler and
1670 * XML_SetEndNamespaceDeclHandler.
1671 */
1672
1673void XML_SetNamespaceDeclHandler(XML_Parser parser,
1674 XML_StartNamespaceDeclHandler start,
1675 XML_EndNamespaceDeclHandler end)
1676{
1677 startNamespaceDeclHandler = start;
1678 endNamespaceDeclHandler = end;
1679}
1680
1681/*
1682 *@@ XML_SetStartNamespaceDeclHandler:
1683 * sets a handler to be called when a namespace is declared.
1684 * Namespace declarations occur inside start tags. But the
1685 * namespace declaration start handler is called before the
1686 * start tag handler for each namespace declared in that start
1687 * tag.
1688 *
1689 * Handler prototype:
1690 *
1691 + void EXPATENTRY StartNamespaceDeclHandler(void *userData,
1692 + const XML_Char *prefix,
1693 + const XML_Char *uri);
1694 +
1695 */
1696
1697void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1698 XML_StartNamespaceDeclHandler start)
1699{
1700 startNamespaceDeclHandler = start;
1701}
1702
1703/*
1704 *@@ XML_SetEndNamespaceDeclHandler:
1705 * sets a handler to be called when leaving the scope of a
1706 * namespace declaration. This will be called, for each
1707 * namespace declaration, after the handler for the end tag
1708 * of the element in which the namespace was declared.
1709 *
1710 * Handler prototype:
1711 +
1712 + void EXPATENTRY EndNamespaceDeclHandler)(void *userData,
1713 + const XML_Char *prefix);
1714 */
1715
1716void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1717 XML_EndNamespaceDeclHandler end)
1718{
1719 endNamespaceDeclHandler = end;
1720}
1721
1722
1723/*
1724 *@@ XML_SetNotStandaloneHandler:
1725 * sets a handler that is called if the document is not
1726 * "standalone". This happens when there is an external
1727 * subset or a reference to a parameter entity, but does
1728 * not have standalone set to "yes" in an XML declaration.
1729 * If this handler returns 0, then the parser will throw an
1730 * XML_ERROR_NOT_STANDALONE error.
1731 *
1732 * Handler prototype:
1733 *
1734 + int EXPATENTRY NotStandaloneHandler(void *userData);
1735 */
1736
1737void XML_SetNotStandaloneHandler(XML_Parser parser,
1738 XML_NotStandaloneHandler handler)
1739{
1740 notStandaloneHandler = handler;
1741}
1742
1743/*
1744 *@@ XML_SetExternalEntityRefHandler:
1745 * sets an external entity reference handler. This handler is
1746 * also called for processing an external DTD subset if
1747 * parameter entity parsing is in effect.
1748 * (See XML_SetParamEntityParsing.)
1749 *
1750 * Handler prototype:
1751 +
1752 + int EXPATENTRY ExternalEntityRefHandler(XML_Parser parser,
1753 + const XML_Char *context,
1754 + const XML_Char *base,
1755 + const XML_Char *systemId,
1756 + const XML_Char *publicId);
1757 +
1758 * The context argument specifies the parsing context in the
1759 * format expected by the context argument to
1760 * XML_ExternalEntityParserCreate; context is valid only until
1761 * the handler returns, so if the referenced entity is to be
1762 * parsed later, it must be copied.
1763 *
1764 * The base parameter is the base to use for relative system
1765 * identifiers. It is set by XML_SetBase and may be null.
1766 *
1767 * The publicId parameter is the public id given in the entity
1768 * declaration and may be null.
1769 *
1770 * The systemId is the system identifier specified in the
1771 * entity declaration and is never null.
1772 *
1773 * There are a couple of ways in which this handler differs
1774 * from others. First, this handler returns an integer. A
1775 * non-zero value should be returned for successful handling
1776 * of the external entity reference. Returning a zero indicates
1777 * failure, and causes the calling parser to return an
1778 * XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
1779 *
1780 * Second, instead of having userData as its first argument,
1781 * it receives the parser that encountered the entity reference.
1782 * This, along with the context parameter, may be used as
1783 * arguments to a call to XML_ExternalEntityParserCreate.
1784 * Using the returned parser, the body of the external entity
1785 * can be recursively parsed.
1786 *
1787 * Since this handler may be called recursively, it should not
1788 * be saving information into global or static variables.
1789 *
1790 * Your handler isn't actually responsible for parsing the entity,
1791 * but it is responsible for creating a subsidiary parser with
1792 * XML_ExternalEntityParserCreate that will do the job. This returns
1793 * an instance of XML_Parser that has handlers and other data
1794 * structures initialized from the parent parser. You may then use
1795 * XML_Parse or XML_ParseBuffer calls against this parser. Since
1796 * external entities may refer to other external entities, your
1797 * handler should be prepared to be called recursively.
1798 */
1799
1800void XML_SetExternalEntityRefHandler(XML_Parser parser,
1801 XML_ExternalEntityRefHandler handler)
1802{
1803 externalEntityRefHandler = handler;
1804}
1805
1806void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1807{
1808 if (arg)
1809 externalEntityRefHandlerArg = arg;
1810 else
1811 externalEntityRefHandlerArg = parser;
1812}
1813
1814/*
1815 *@@ XML_SetUnknownEncodingHandler:
1816 * sets a handler to deal with encodings other than the
1817 * built in set (see XML_ParserCreate).
1818 *
1819 * Handler prototype:
1820 *
1821 + int EXPATENTRY UnknownEncodingHandler(void *encodingHandlerData,
1822 + const XML_Char *name,
1823 + XML_Encoding *info);
1824 +
1825 * The encodingHandlerData argument is that which was passed as the
1826 * second argument to XML_SetUnknownEncodingHandler.
1827 *
1828 * The name argument gives the name of the encoding as specified in
1829 * the encoding declaration.
1830 *
1831 * If the callback can provide information about the encoding,
1832 * it must fill in the XML_Encoding structure, and return 1.
1833 * Otherwise it must return 0.
1834 * If info does not describe a suitable encoding,
1835 * then the parser will return an XML_UNKNOWN_ENCODING error.
1836 *
1837 * See _XML_Encoding for more details about that structure and
1838 * what to do with it.
1839 *
1840 * Expat places restrictions on character encodings that it can
1841 * support by filling in the XML_Encoding structure.
1842 *
1843 * 1. Every ASCII character that can appear in a well-formed XML
1844 * document must be represented by a single byte, and that byte
1845 * must correspond to it's ASCII encoding (except for the
1846 * characters $@\^'{}~).
1847 *
1848 * 2. Characters must be encoded in 4 bytes or less.
1849 *
1850 * 3. All characters encoded must have Unicode scalar values less
1851 * than or equal to 65535 (0xFFFF). (This does not apply to
1852 * the built-in support for UTF-16 and UTF-8.)
1853 *
1854 * 4. No character may be encoded by more that one distinct
1855 * sequence of bytes.
1856 */
1857
1858void XML_SetUnknownEncodingHandler(XML_Parser parser,
1859 XML_UnknownEncodingHandler handler,
1860 void *data)
1861{
1862 unknownEncodingHandler = handler;
1863 unknownEncodingHandlerData = data;
1864}
1865
1866/*
1867 *@@ XML_SetElementDeclHandler:
1868 * sets a handler for element declarations in a DTD. The
1869 * handler gets called with the name of the element in
1870 * the declaration and a pointer to a structure that contains
1871 * the element model. It is the application's responsibility
1872 * to free this data structure.
1873 *
1874 * This handler must have the following prototype:
1875 *
1876 + void EXPATENTRY ElementDeclHandler(void *userData,
1877 + const XML_Char *name,
1878 + XML_Content *model);
1879 *
1880 * The model argument is the root of a tree of XML_Content
1881 * nodes. If type equals XML_CTYPE_EMPTY or XML_CTYPE_ANY,
1882 * then quant will be XML_CQUANT_NONE, and the other fields
1883 * will be zero or NULL.
1884 *
1885 * If type is XML_CTYPE_MIXED, then quant will be
1886 * XML_CQUANT_NONE or XML_CQUANT_REP and numchildren will
1887 * contain the number of elements that are allowed to be
1888 * mixed in and children points to an array of XML_Content
1889 * structures that will all have type XML_CTYPE_NAME with no
1890 * quantification. Only the root node can be type
1891 * XML_CTYPE_EMPTY, XML_CTYPE_ANY, or XML_CTYPE_MIXED.
1892 *
1893 * For type XML_CTYPE_NAME, the name field points to the
1894 * name and the numchildren and children fields will be
1895 * zero and NULL. The quant field will indicate any
1896 * quantifiers placed on the name.
1897 *
1898 * Types XML_CTYPE_CHOICE and XML_CTYPE_SEQ indicate a
1899 * choice or sequence respectively. The numchildren field
1900 * indicates how many nodes in the choice or sequence and
1901 * children points to the nodes.
1902 */
1903
1904void XML_SetElementDeclHandler(XML_Parser parser,
1905 XML_ElementDeclHandler eldecl)
1906{
1907 elementDeclHandler = eldecl;
1908}
1909
1910/*
1911 *@@ XML_SetAttlistDeclHandler:
1912 * sets a handler for attlist declarations in the DTD.
1913 *
1914 * This handler must have the following prototype:
1915 *
1916 + void EXPATENTRY AttlistDeclHandler(void *userData,
1917 + const XML_Char *elname,
1918 + const XML_Char *attname,
1919 + const XML_Char *att_type,
1920 + const XML_Char *dflt,
1921 + int isrequired);
1922 *
1923 * This handler is called for each attribute. So a single attlist
1924 * declaration with multiple attributes declared will generate
1925 * multiple calls to this handler. The elname parameter
1926 * returns the name of the element for which the attribute
1927 * is being declared. The attribute name is in the attname
1928 * parameter. The attribute type is in the att_type parameter.
1929 * It is the string representing the type in the declaration
1930 * with whitespace removed.
1931 *
1932 * The dflt parameter holds the default value. It will be
1933 * NULL in the case of "#IMPLIED" or "#REQUIRED" attributes.
1934 * You can distinguish these two cases by checking the
1935 * isrequired parameter, which will be true in the case of
1936 * "#REQUIRED" attributes. Attributes which are "#FIXED"
1937 * will have also have a true isrequired, but they will have
1938 * the non-NULL fixed value in the dflt parameter.
1939 */
1940
1941void XML_SetAttlistDeclHandler(XML_Parser parser,
1942 XML_AttlistDeclHandler attdecl)
1943{
1944 attlistDeclHandler = attdecl;
1945}
1946
1947/*
1948 *@@ XML_SetEntityDeclHandler:
1949 * sets a handler that will be called for all entity declarations.
1950 *
1951 * Handler prototype:
1952 *
1953 + void EXPATENTRY EntityDeclHandler(void *userData,
1954 + const XML_Char *entityName,
1955 + int is_parameter_entity,
1956 + const XML_Char *value,
1957 + int value_length,
1958 + const XML_Char *base,
1959 + const XML_Char *systemId,
1960 + const XML_Char *publicId,
1961 + const XML_Char *notationName);
1962 +
1963 * The is_parameter_entity argument will be non-zero in the case
1964 * of parameter entities and zero otherwise.
1965 *
1966 * For internal entities (<!ENTITY foo "bar">), value will be
1967 * non-NULL and systemId, publicId, and notationName will all
1968 * be NULL. The value string is not NULL terminated; the length
1969 * is provided in the value_length parameter. Do not use
1970 * value_length to test for internal entities, since it is legal
1971 * to have zero-length values. Instead check for whether or not
1972 * value is NULL.
1973 *
1974 * The notationName argument will have a non-NULL value only for
1975 * unparsed entity declarations.
1976 */
1977
1978void XML_SetEntityDeclHandler(XML_Parser parser,
1979 XML_EntityDeclHandler handler)
1980{
1981 entityDeclHandler = handler;
1982}
1983
1984/*
1985 *@@ XML_SetXmlDeclHandler:
1986 * sets a handler that is called for XML declarations and also
1987 * for text declarations discovered in external entities.
1988 *
1989 * Handler prototype:
1990 *
1991 + void EXPATENTRY XmlDeclHandler(void *userData,
1992 + const XML_Char *version,
1993 + const XML_Char *encoding,
1994 + int standalone);
1995 *
1996 * The way to distinguish is that the version parameter will
1997 * be NULL for text declarations. The encoding parameter may
1998 * be NULL for an XML declaration. The standalone argument will
1999 * contain -1, 0, or 1 indicating respectively that there was no
2000 * standalone parameter in the declaration, that it was given
2001 * as no, or that it was given as yes.
2002 */
2003
2004void XML_SetXmlDeclHandler(XML_Parser parser,
2005 XML_XmlDeclHandler handler)
2006{
2007 xmlDeclHandler = handler;
2008}
2009
2010/*
2011 *@@ XML_SetParamEntityParsing:
2012 * this enables parsing of parameter entities, including the
2013 * external parameter entity that is the external DTD subset,
2014 * according to code. The choices for code are:
2015 *
2016 * -- XML_PARAM_ENTITY_PARSING_NEVER:
2017 * Don't parse parameter entities or the external subset
2018 *
2019 * -- XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE:
2020 * Parse parameter entites and the external subset unless
2021 * standalone was set to "yes" in the XML declaration.
2022 *
2023 * -- XML_PARAM_ENTITY_PARSING_ALWAYS
2024 * Always parse parameter entities and the external subset.
2025 *
2026 * In order to read an external DTD, you also have to set an
2027 * external entity reference handler (XML_SetExternalEntityRefHandler).
2028 */
2029
2030int XML_SetParamEntityParsing(XML_Parser parser,
2031 enum XML_ParamEntityParsing parsing)
2032{
2033#ifdef XML_DTD
2034 paramEntityParsing = parsing;
2035 return 1;
2036#else
2037 return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
2038#endif
2039}
2040
2041/*
2042 *@@ XML_Parse:
2043 * parses some more of the document.
2044 *
2045 * The string s is a buffer containing part (or perhaps all)
2046 * of the document. The number of bytes of s that are part
2047 * of the document is indicated by len. This means that s
2048 * doesn't have to be null terminated. It also means that
2049 * if len is larger than the number of bytes in the block
2050 * of memory that s points at, then a memory fault is
2051 * likely. The isFinal parameter informs the parser that
2052 * this is the last piece of the document. Frequently, the
2053 * last piece is empty (i.e. len is zero.)
2054 *
2055 * If a parse error occurred, it returns 0. Otherwise it
2056 * returns a non-zero value.
2057 */
2058
2059int XML_Parse(XML_Parser parser,
2060 const char *s,
2061 int len,
2062 int isFinal)
2063{
2064 if (len == 0)
2065 {
2066 if (!isFinal)
2067 return 1;
2068 positionPtr = bufferPtr;
2069 errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
2070 if (errorCode == XML_ERROR_NONE)
2071 return 1;
2072 eventEndPtr = eventPtr;
2073 processor = errorProcessor;
2074 return 0;
2075 }
2076#ifndef XML_CONTEXT_BYTES
2077 else if (bufferPtr == bufferEnd)
2078 {
2079 const char *end;
2080 int nLeftOver;
2081
2082 parseEndByteIndex += len;
2083 positionPtr = s;
2084 if (isFinal)
2085 {
2086 errorCode = processor(parser, s, parseEndPtr = s + len, 0);
2087 if (errorCode == XML_ERROR_NONE)
2088 return 1;
2089 eventEndPtr = eventPtr;
2090 processor = errorProcessor;
2091 return 0;
2092 }
2093 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
2094 if (errorCode != XML_ERROR_NONE)
2095 {
2096 eventEndPtr = eventPtr;
2097 processor = errorProcessor;
2098 return 0;
2099 }
2100 XmlUpdatePosition(encoding, positionPtr, end, &position);
2101 nLeftOver = s + len - end;
2102 if (nLeftOver)
2103 {
2104 if (buffer == 0 || nLeftOver > bufferLim - buffer)
2105 {
2106 /* FIXME avoid integer overflow */
2107 buffer = buffer == 0 ? (char*)MALLOC(len * 2) : (char*)REALLOC(buffer, len * 2);
2108 /* FIXME storage leak if realloc fails */
2109 if (!buffer)
2110 {
2111 errorCode = XML_ERROR_NO_MEMORY;
2112 eventPtr = eventEndPtr = 0;
2113 processor = errorProcessor;
2114 return 0;
2115 }
2116 bufferLim = buffer + len * 2;
2117 }
2118 memcpy(buffer, end, nLeftOver);
2119 bufferPtr = buffer;
2120 bufferEnd = buffer + nLeftOver;
2121 }
2122 return 1;
2123 }
2124#endif /* not defined XML_CONTEXT_BYTES */
2125 else
2126 {
2127 memcpy(XML_GetBuffer(parser, len), s, len);
2128 return XML_ParseBuffer(parser, len, isFinal);
2129 }
2130}
2131
2132/*
2133 *@@ XML_ParseBuffer:
2134 * this is just like XML_Parse, except in this case expat
2135 * provides the buffer. By obtaining the buffer from expat
2136 * with the XML_GetBuffer function, the application can
2137 * avoid double copying of the input.
2138 */
2139
2140int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
2141{
2142 const char *start = bufferPtr;
2143
2144 positionPtr = start;
2145 bufferEnd += len;
2146 parseEndByteIndex += len;
2147 errorCode = processor(parser, start, parseEndPtr = bufferEnd,
2148 isFinal ? (const char **)0 : &bufferPtr);
2149 if (errorCode == XML_ERROR_NONE)
2150 {
2151 if (!isFinal)
2152 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
2153 return 1;
2154 }
2155 else
2156 {
2157 eventEndPtr = eventPtr;
2158 processor = errorProcessor;
2159 return 0;
2160 }
2161}
2162
2163/*
2164 *@@ XML_GetBuffer:
2165 * obtains a buffer of size len to read a piece of the
2166 * document into. A NULL value is returned if expat can't
2167 * allocate enough memory for this buffer. This has to be
2168 * called prior to every call to XML_ParseBuffer.
2169 *
2170 * A typical use would look like this:
2171 *
2172 + for (;;)
2173 + {
2174 + int bytes_read;
2175 + void *buff = XML_GetBuffer(p, BUFF_SIZE);
2176 + if (buff == NULL)
2177 + // handle error
2178 +
2179 + bytes_read = read(docfd, buff, BUFF_SIZE);
2180 + if (bytes_read < 0)
2181 + // handle error
2182 +
2183 + if (!XML_ParseBuffer(p, bytes_read, bytes_read == 0))
2184 + // handle parse error
2185 +
2186 + if (bytes_read == 0)
2187 + break;
2188 + }
2189 *
2190 */
2191
2192void* XML_GetBuffer(XML_Parser parser, int len)
2193{
2194 if (len > bufferLim - bufferEnd)
2195 {
2196 /* FIXME avoid integer overflow */
2197 int neededSize = len + (bufferEnd - bufferPtr);
2198
2199#ifdef XML_CONTEXT_BYTES
2200 int keep = bufferPtr - buffer;
2201
2202 if (keep > XML_CONTEXT_BYTES)
2203 keep = XML_CONTEXT_BYTES;
2204 neededSize += keep;
2205#endif /* defined XML_CONTEXT_BYTES */
2206 if (neededSize <= bufferLim - buffer)
2207 {
2208#ifdef XML_CONTEXT_BYTES
2209 if (keep < bufferPtr - buffer)
2210 {
2211 int offset = (bufferPtr - buffer) - keep;
2212
2213 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
2214 bufferEnd -= offset;
2215 bufferPtr -= offset;
2216 }
2217#else
2218 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
2219 bufferEnd = buffer + (bufferEnd - bufferPtr);
2220 bufferPtr = buffer;
2221#endif /* not defined XML_CONTEXT_BYTES */
2222 }
2223 else
2224 {
2225 char *newBuf;
2226 int bufferSize = bufferLim - bufferPtr;
2227
2228 if (bufferSize == 0)
2229 bufferSize = INIT_BUFFER_SIZE;
2230 do
2231 {
2232 bufferSize *= 2;
2233 }
2234 while (bufferSize < neededSize);
2235 newBuf = (char*)MALLOC(bufferSize);
2236 if (newBuf == 0)
2237 {
2238 errorCode = XML_ERROR_NO_MEMORY;
2239 return 0;
2240 }
2241 bufferLim = newBuf + bufferSize;
2242#ifdef XML_CONTEXT_BYTES
2243 if (bufferPtr)
2244 {
2245 int keep = bufferPtr - buffer;
2246
2247 if (keep > XML_CONTEXT_BYTES)
2248 keep = XML_CONTEXT_BYTES;
2249 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
2250 FREE(buffer);
2251 buffer = newBuf;
2252 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
2253 bufferPtr = buffer + keep;
2254 }
2255 else
2256 {
2257 bufferEnd = newBuf + (bufferEnd - bufferPtr);
2258 bufferPtr = buffer = newBuf;
2259 }
2260#else
2261 if (bufferPtr)
2262 {
2263 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
2264 FREE(buffer);
2265 }
2266 bufferEnd = newBuf + (bufferEnd - bufferPtr);
2267 bufferPtr = buffer = newBuf;
2268#endif /* not defined XML_CONTEXT_BYTES */
2269 }
2270 }
2271 return bufferEnd;
2272}
2273
2274/*
2275 *@@ XML_GetErrorCode:
2276 * returns what type of error has occurred.
2277 *
2278 * To be called when the parse functions return 0 (i.e. a
2279 * parse error has ocurred), although the position reporting
2280 * functions are useful outside of errors. The position reported
2281 * is the byte position (in the original document or entity
2282 * encoding) of the first of the sequence of characters that
2283 * generated the current event (or the error that caused the
2284 * parse functions to return 0.)
2285 *
2286 * The position reporting functions are accurate only outside
2287 * of the DTD. In other words, they usually return bogus
2288 * information when called from within a DTD declaration handler.
2289 */
2290
2291enum XML_Error XML_GetErrorCode(XML_Parser parser)
2292{
2293 return errorCode;
2294}
2295
2296/*
2297 *@@ XML_GetCurrentByteIndex:
2298 * returns the byte offset of the position.
2299 *
2300 * To be called on parser errors. See XML_GetErrorCode.
2301 */
2302
2303long XML_GetCurrentByteIndex(XML_Parser parser)
2304{
2305 if (eventPtr)
2306 return parseEndByteIndex - (parseEndPtr - eventPtr);
2307 return -1;
2308}
2309
2310/*
2311 *@@ XML_GetCurrentByteCount:
2312 * return the number of bytes in the current event. Returns
2313 * 0 if the event is inside a reference to an internal entity.
2314 *
2315 * To be called on parser errors. See XML_GetErrorCode.
2316 */
2317
2318int XML_GetCurrentByteCount(XML_Parser parser)
2319{
2320 if (eventEndPtr && eventPtr)
2321 return eventEndPtr - eventPtr;
2322 return 0;
2323}
2324
2325/*
2326 *@@ XML_GetInputContext:
2327 * returns the parser's input buffer, sets the integer pointed
2328 * at by offset to the offset within this buffer of the current
2329 * parse position, and set the integer pointed at by size to the
2330 * size of the returned buffer.
2331 *
2332 * This should only be called from within a handler during an
2333 * active parse and the returned buffer should only be referred
2334 * to from within the handler that made the call. This input
2335 * buffer contains the untranslated bytes of the input.
2336 *
2337 * Only a limited amount of context is kept, so if the event
2338 * triggering a call spans over a very large amount of input,
2339 * the actual parse position may be before the beginning of the buffer.
2340 */
2341
2342const char* XML_GetInputContext(XML_Parser parser, int *offset, int *size)
2343{
2344#ifdef XML_CONTEXT_BYTES
2345 if (eventPtr && buffer)
2346 {
2347 *offset = eventPtr - buffer;
2348 *size = bufferEnd - buffer;
2349 return buffer;
2350 }
2351#endif /* defined XML_CONTEXT_BYTES */
2352 return (char *)0;
2353}
2354
2355/*
2356 *@@ XML_GetCurrentLineNumber:
2357 * returns the line number of the position.
2358 *
2359 * To be called on parser errors. See XML_GetErrorCode.
2360 */
2361
2362int XML_GetCurrentLineNumber(XML_Parser parser)
2363{
2364 if (eventPtr)
2365 {
2366 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
2367 positionPtr = eventPtr;
2368 }
2369 return position.lineNumber + 1;
2370}
2371
2372/*
2373 *@@ XML_GetCurrentColumnNumber:
2374 * returns the offset, from the beginning of the current
2375 * line, of the position.
2376 *
2377 * To be called on parser errors. See XML_GetErrorCode.
2378 */
2379
2380int XML_GetCurrentColumnNumber(XML_Parser parser)
2381{
2382 if (eventPtr)
2383 {
2384 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
2385 positionPtr = eventPtr;
2386 }
2387 return position.columnNumber;
2388}
2389
2390/*
2391 *@@ XML_DefaultCurrent:
2392 * not in the expat docs.
2393 */
2394
2395void XML_DefaultCurrent(XML_Parser parser)
2396{
2397 if (defaultHandler)
2398 {
2399 if (openInternalEntities)
2400 reportDefault(parser,
2401 internalEncoding,
2402 openInternalEntities->internalEventPtr,
2403 openInternalEntities->internalEventEndPtr);
2404 else
2405 reportDefault(parser, encoding, eventPtr, eventEndPtr);
2406 }
2407}
2408
2409/*
2410 *@@ XML_ErrorString:
2411 * returns a string describing the error corresponding to code.
2412 * The code should be one of the enums that can be returned from
2413 * XML_GetErrorCode.
2414 */
2415
2416const XML_LChar* XML_ErrorString(int code)
2417{
2418 static const XML_LChar *message[] =
2419 {
2420 0,
2421 XML_T("out of memory"),
2422 XML_T("syntax error"),
2423 XML_T("no element found"),
2424 XML_T("not well-formed (invalid token)"),
2425 XML_T("unclosed token"),
2426 XML_T("unclosed token"),
2427 XML_T("mismatched tag"),
2428 XML_T("duplicate attribute"),
2429 XML_T("junk after document element"),
2430 XML_T("illegal parameter entity reference"),
2431 XML_T("undefined entity"),
2432 XML_T("recursive entity reference"),
2433 XML_T("asynchronous entity"),
2434 XML_T("reference to invalid character number"),
2435 XML_T("reference to binary entity"),
2436 XML_T("reference to external entity in attribute"),
2437 XML_T("xml processing instruction not at start of external entity"),
2438 XML_T("unknown encoding"),
2439 XML_T("encoding specified in XML declaration is incorrect"),
2440 XML_T("unclosed CDATA section"),
2441 XML_T("error in processing external entity reference"),
2442 XML_T("document is not standalone"),
2443 XML_T("unexpected parser state - please send a bug report")
2444 };
2445
2446 if (code > 0 && code < sizeof(message) / sizeof(message[0]))
2447 return message[code];
2448 return 0;
2449}
2450
2451/*
2452 *@@ XML_ExpatVersion:
2453 * returns the library version string (e.g. "expat_1.95.1").
2454 */
2455
2456const XML_LChar* XML_ExpatVersion(void)
2457{
2458 return "expat_1.95.1";
2459}
2460
2461static enum XML_Error contentProcessor(XML_Parser parser,
2462 const char *start,
2463 const char *end,
2464 const char **endPtr)
2465{
2466 return doContent(parser, 0, encoding, start, end, endPtr);
2467}
2468
2469static enum XML_Error externalEntityInitProcessor(XML_Parser parser,
2470 const char *start,
2471 const char *end,
2472 const char **endPtr)
2473{
2474 enum XML_Error result = initializeEncoding(parser);
2475
2476 if (result != XML_ERROR_NONE)
2477 return result;
2478 processor = externalEntityInitProcessor2;
2479 return externalEntityInitProcessor2(parser, start, end, endPtr);
2480}
2481
2482static enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
2483 const char *start,
2484 const char *end,
2485 const char **endPtr)
2486{
2487 const char *next;
2488 int tok = XmlContentTok(encoding, start, end, &next);
2489
2490 switch (tok)
2491 {
2492 case XML_TOK_BOM:
2493 start = next;
2494 break;
2495 case XML_TOK_PARTIAL:
2496 if (endPtr)
2497 {
2498 *endPtr = start;
2499 return XML_ERROR_NONE;
2500 }
2501 eventPtr = start;
2502 return XML_ERROR_UNCLOSED_TOKEN;
2503 case XML_TOK_PARTIAL_CHAR:
2504 if (endPtr)
2505 {
2506 *endPtr = start;
2507 return XML_ERROR_NONE;
2508 }
2509 eventPtr = start;
2510 return XML_ERROR_PARTIAL_CHAR;
2511 }
2512 processor = externalEntityInitProcessor3;
2513 return externalEntityInitProcessor3(parser, start, end, endPtr);
2514}
2515
2516static enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
2517 const char *start,
2518 const char *end,
2519 const char **endPtr)
2520{
2521 const char *next;
2522 int tok = XmlContentTok(encoding, start, end, &next);
2523
2524 switch (tok)
2525 {
2526 case XML_TOK_XML_DECL:
2527 {
2528 enum XML_Error result = processXmlDecl(parser, 1, start, next);
2529
2530 if (result != XML_ERROR_NONE)
2531 return result;
2532 start = next;
2533 }
2534 break;
2535 case XML_TOK_PARTIAL:
2536 if (endPtr)
2537 {
2538 *endPtr = start;
2539 return XML_ERROR_NONE;
2540 }
2541 eventPtr = start;
2542 return XML_ERROR_UNCLOSED_TOKEN;
2543 case XML_TOK_PARTIAL_CHAR:
2544 if (endPtr)
2545 {
2546 *endPtr = start;
2547 return XML_ERROR_NONE;
2548 }
2549 eventPtr = start;
2550 return XML_ERROR_PARTIAL_CHAR;
2551 }
2552 processor = externalEntityContentProcessor;
2553 tagLevel = 1;
2554 return doContent(parser, 1, encoding, start, end, endPtr);
2555}
2556
2557static enum XML_Error externalEntityContentProcessor(XML_Parser parser,
2558 const char *start,
2559 const char *end,
2560 const char **endPtr)
2561{
2562 return doContent(parser, 1, encoding, start, end, endPtr);
2563}
2564
2565static enum XML_Error
2566 doContent(XML_Parser parser,
2567 int startTagLevel,
2568 const ENCODING * enc,
2569 const char *s,
2570 const char *end,
2571 const char **nextPtr)
2572{
2573 const char **eventPP;
2574 const char **eventEndPP;
2575
2576 if (enc == encoding)
2577 {
2578 eventPP = &eventPtr;
2579 eventEndPP = &eventEndPtr;
2580 }
2581 else
2582 {
2583 eventPP = &(openInternalEntities->internalEventPtr);
2584 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2585 }
2586 *eventPP = s;
2587 for (;;)
2588 {
2589 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2590 int tok = XmlContentTok(enc, s, end, &next);
2591
2592 *eventEndPP = next;
2593 switch (tok)
2594 {
2595 case XML_TOK_TRAILING_CR:
2596 if (nextPtr)
2597 {
2598 *nextPtr = s;
2599 return XML_ERROR_NONE;
2600 }
2601 *eventEndPP = end;
2602 if (characterDataHandler)
2603 {
2604 XML_Char c = 0xA;
2605
2606 characterDataHandler(handlerArg, &c, 1);
2607 }
2608 else if (defaultHandler)
2609 reportDefault(parser, enc, s, end);
2610 if (startTagLevel == 0)
2611 return XML_ERROR_NO_ELEMENTS;
2612 if (tagLevel != startTagLevel)
2613 return XML_ERROR_ASYNC_ENTITY;
2614 return XML_ERROR_NONE;
2615 case XML_TOK_NONE:
2616 if (nextPtr)
2617 {
2618 *nextPtr = s;
2619 return XML_ERROR_NONE;
2620 }
2621 if (startTagLevel > 0)
2622 {
2623 if (tagLevel != startTagLevel)
2624 return XML_ERROR_ASYNC_ENTITY;
2625 return XML_ERROR_NONE;
2626 }
2627 return XML_ERROR_NO_ELEMENTS;
2628 case XML_TOK_INVALID:
2629 *eventPP = next;
2630 return XML_ERROR_INVALID_TOKEN;
2631 case XML_TOK_PARTIAL:
2632 if (nextPtr)
2633 {
2634 *nextPtr = s;
2635 return XML_ERROR_NONE;
2636 }
2637 return XML_ERROR_UNCLOSED_TOKEN;
2638 case XML_TOK_PARTIAL_CHAR:
2639 if (nextPtr)
2640 {
2641 *nextPtr = s;
2642 return XML_ERROR_NONE;
2643 }
2644 return XML_ERROR_PARTIAL_CHAR;
2645 case XML_TOK_ENTITY_REF:
2646 {
2647 const XML_Char *name;
2648 ENTITY *entity;
2649 XML_Char ch = XmlPredefinedEntityName(enc,
2650 s + enc->minBytesPerChar,
2651 next - enc->minBytesPerChar);
2652
2653 if (ch)
2654 {
2655 if (characterDataHandler)
2656 characterDataHandler(handlerArg, &ch, 1);
2657 else if (defaultHandler)
2658 reportDefault(parser, enc, s, next);
2659 break;
2660 }
2661 name = poolStoreString(&dtd.pool, enc,
2662 s + enc->minBytesPerChar,
2663 next - enc->minBytesPerChar);
2664 if (!name)
2665 return XML_ERROR_NO_MEMORY;
2666 entity = (ENTITY*)lookup(&dtd.generalEntities, name, 0);
2667 poolDiscard(&dtd.pool);
2668 if (!entity)
2669 {
2670 if (dtd.complete || dtd.standalone)
2671 return XML_ERROR_UNDEFINED_ENTITY;
2672 if (defaultHandler)
2673 reportDefault(parser, enc, s, next);
2674 break;
2675 }
2676 if (entity->open)
2677 return XML_ERROR_RECURSIVE_ENTITY_REF;
2678 if (entity->notation)
2679 return XML_ERROR_BINARY_ENTITY_REF;
2680 if (entity)
2681 {
2682 if (entity->textPtr)
2683 {
2684 enum XML_Error result;
2685 OPEN_INTERNAL_ENTITY openEntity;
2686
2687 if (defaultHandler && !defaultExpandInternalEntities)
2688 {
2689 reportDefault(parser, enc, s, next);
2690 break;
2691 }
2692 entity->open = 1;
2693 openEntity.next = openInternalEntities;
2694 openInternalEntities = &openEntity;
2695 openEntity.entity = entity;
2696 openEntity.internalEventPtr = 0;
2697 openEntity.internalEventEndPtr = 0;
2698 result = doContent(parser,
2699 tagLevel,
2700 internalEncoding,
2701 (char *)entity->textPtr,
2702 (char *)(entity->textPtr + entity->textLen),
2703 0);
2704 entity->open = 0;
2705 openInternalEntities = openEntity.next;
2706 if (result)
2707 return result;
2708 }
2709 else if (externalEntityRefHandler)
2710 {
2711 const XML_Char *context;
2712
2713 entity->open = 1;
2714 context = getContext(parser);
2715 entity->open = 0;
2716 if (!context)
2717 return XML_ERROR_NO_MEMORY;
2718 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2719 context,
2720 entity->base,
2721 entity->systemId,
2722 entity->publicId))
2723 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2724 poolDiscard(&tempPool);
2725 }
2726 else if (defaultHandler)
2727 reportDefault(parser, enc, s, next);
2728 }
2729 break;
2730 }
2731 case XML_TOK_START_TAG_WITH_ATTS:
2732 if (!startElementHandler)
2733 {
2734 enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
2735
2736 if (result)
2737 return result;
2738 }
2739 /* fall through */
2740 case XML_TOK_START_TAG_NO_ATTS:
2741 {
2742 TAG *tag;
2743
2744 if (freeTagList)
2745 {
2746 tag = freeTagList;
2747 freeTagList = freeTagList->parent;
2748 }
2749 else
2750 {
2751 tag = (TAG*)MALLOC(sizeof(TAG));
2752 if (!tag)
2753 return XML_ERROR_NO_MEMORY;
2754 tag->buf = (char*)MALLOC(INIT_TAG_BUF_SIZE);
2755 if (!tag->buf)
2756 return XML_ERROR_NO_MEMORY;
2757 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2758 }
2759 tag->bindings = 0;
2760 tag->parent = tagStack;
2761 tagStack = tag;
2762 tag->name.localPart = 0;
2763 tag->rawName = s + enc->minBytesPerChar;
2764 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2765 if (nextPtr)
2766 {
2767 /* Need to guarantee that:
2768 * tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
2769 if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf)
2770 {
2771 int bufSize = tag->rawNameLength * 4;
2772
2773 bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
2774 tag->buf = (char*)REALLOC(tag->buf, bufSize);
2775 if (!tag->buf)
2776 return XML_ERROR_NO_MEMORY;
2777 tag->bufEnd = tag->buf + bufSize;
2778 }
2779 memcpy(tag->buf, tag->rawName, tag->rawNameLength);
2780 tag->rawName = tag->buf;
2781 }
2782 ++tagLevel;
2783 if (startElementHandler)
2784 {
2785 enum XML_Error result;
2786 XML_Char *toPtr;
2787
2788 for (;;)
2789 {
2790 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2791 const char *fromPtr = tag->rawName;
2792 int bufSize;
2793
2794 if (nextPtr)
2795 toPtr = (XML_Char*)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
2796 else
2797 toPtr = (XML_Char*)tag->buf;
2798 tag->name.str = toPtr;
2799 XmlConvert(enc,
2800 &fromPtr, rawNameEnd,
2801 (ICHAR **) & toPtr, (ICHAR*)tag->bufEnd - 1);
2802 if (fromPtr == rawNameEnd)
2803 break;
2804 bufSize = (tag->bufEnd - tag->buf) << 1;
2805 tag->buf = (char*)REALLOC(tag->buf, bufSize);
2806 if (!tag->buf)
2807 return XML_ERROR_NO_MEMORY;
2808 tag->bufEnd = tag->buf + bufSize;
2809 if (nextPtr)
2810 tag->rawName = tag->buf;
2811 }
2812 *toPtr = XML_T('\0');
2813 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2814 if (result)
2815 return result;
2816 startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
2817 poolClear(&tempPool);
2818 }
2819 else
2820 {
2821 tag->name.str = 0;
2822 if (defaultHandler)
2823 reportDefault(parser, enc, s, next);
2824 }
2825 break;
2826 }
2827 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2828 if (!startElementHandler)
2829 {
2830 enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
2831
2832 if (result)
2833 return result;
2834 }
2835 /* fall through */
2836 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2837 if (startElementHandler || endElementHandler)
2838 {
2839 const char *rawName = s + enc->minBytesPerChar;
2840 enum XML_Error result;
2841 BINDING *bindings = 0;
2842 TAG_NAME name;
2843
2844 name.str = poolStoreString(&tempPool, enc, rawName,
2845 rawName + XmlNameLength(enc, rawName));
2846 if (!name.str)
2847 return XML_ERROR_NO_MEMORY;
2848 poolFinish(&tempPool);
2849 result = storeAtts(parser, enc, s, &name, &bindings);
2850 if (result)
2851 return result;
2852 poolFinish(&tempPool);
2853 if (startElementHandler)
2854 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2855 if (endElementHandler)
2856 {
2857 if (startElementHandler)
2858 *eventPP = *eventEndPP;
2859 endElementHandler(handlerArg, name.str);
2860 }
2861 poolClear(&tempPool);
2862 while (bindings)
2863 {
2864 BINDING *b = bindings;
2865
2866 if (endNamespaceDeclHandler)
2867 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2868 bindings = bindings->nextTagBinding;
2869 b->nextTagBinding = freeBindingList;
2870 freeBindingList = b;
2871 b->prefix->binding = b->prevPrefixBinding;
2872 }
2873 }
2874 else if (defaultHandler)
2875 reportDefault(parser, enc, s, next);
2876 if (tagLevel == 0)
2877 return epilogProcessor(parser, next, end, nextPtr);
2878 break;
2879 case XML_TOK_END_TAG:
2880 if (tagLevel == startTagLevel)
2881 return XML_ERROR_ASYNC_ENTITY;
2882 else
2883 {
2884 int len;
2885 const char *rawName;
2886 TAG *tag = tagStack;
2887
2888 tagStack = tag->parent;
2889 tag->parent = freeTagList;
2890 freeTagList = tag;
2891 rawName = s + enc->minBytesPerChar * 2;
2892 len = XmlNameLength(enc, rawName);
2893 if (len != tag->rawNameLength
2894 || memcmp(tag->rawName, rawName, len) != 0)
2895 {
2896 *eventPP = rawName;
2897 return XML_ERROR_TAG_MISMATCH;
2898 }
2899 --tagLevel;
2900 if (endElementHandler && tag->name.str)
2901 {
2902 if (tag->name.localPart)
2903 {
2904 XML_Char *to = (XML_Char*)tag->name.str + tag->name.uriLen;
2905 const XML_Char *from = tag->name.localPart;
2906
2907 while ((*to++ = *from++) != 0)
2908 ;
2909 }
2910 endElementHandler(handlerArg, tag->name.str);
2911 }
2912 else if (defaultHandler)
2913 reportDefault(parser, enc, s, next);
2914 while (tag->bindings)
2915 {
2916 BINDING *b = tag->bindings;
2917
2918 if (endNamespaceDeclHandler)
2919 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2920 tag->bindings = tag->bindings->nextTagBinding;
2921 b->nextTagBinding = freeBindingList;
2922 freeBindingList = b;
2923 b->prefix->binding = b->prevPrefixBinding;
2924 }
2925 if (tagLevel == 0)
2926 return epilogProcessor(parser, next, end, nextPtr);
2927 }
2928 break;
2929 case XML_TOK_CHAR_REF:
2930 {
2931 int n = XmlCharRefNumber(enc, s);
2932
2933 if (n < 0)
2934 return XML_ERROR_BAD_CHAR_REF;
2935 if (characterDataHandler)
2936 {
2937 XML_Char buf[XML_ENCODE_MAX];
2938
2939 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR*)buf));
2940 }
2941 else if (defaultHandler)
2942 reportDefault(parser, enc, s, next);
2943 }
2944 break;
2945 case XML_TOK_XML_DECL:
2946 return XML_ERROR_MISPLACED_XML_PI;
2947 case XML_TOK_DATA_NEWLINE:
2948 if (characterDataHandler)
2949 {
2950 XML_Char c = 0xA;
2951
2952 characterDataHandler(handlerArg, &c, 1);
2953 }
2954 else if (defaultHandler)
2955 reportDefault(parser, enc, s, next);
2956 break;
2957 case XML_TOK_CDATA_SECT_OPEN:
2958 {
2959 enum XML_Error result;
2960
2961 if (startCdataSectionHandler)
2962 startCdataSectionHandler(handlerArg);
2963#if 0
2964 /* Suppose you doing a transformation on a document that involves
2965 * changing only the character data. You set up a defaultHandler
2966 * and a characterDataHandler. The defaultHandler simply copies
2967 * characters through. The characterDataHandler does the transformation
2968 * and writes the characters out escaping them as necessary. This case
2969 * will fail to work if we leave out the following two lines (because &
2970 * and < inside CDATA sections will be incorrectly escaped).
2971 *
2972 * However, now we have a start/endCdataSectionHandler, so it seems
2973 * easier to let the user deal with this. */
2974
2975 else if (characterDataHandler)
2976 characterDataHandler(handlerArg, dataBuf, 0);
2977#endif
2978 else if (defaultHandler)
2979 reportDefault(parser, enc, s, next);
2980 result = doCdataSection(parser, enc, &next, end, nextPtr);
2981 if (!next)
2982 {
2983 processor = cdataSectionProcessor;
2984 return result;
2985 }
2986 }
2987 break;
2988 case XML_TOK_TRAILING_RSQB:
2989 if (nextPtr)
2990 {
2991 *nextPtr = s;
2992 return XML_ERROR_NONE;
2993 }
2994 if (characterDataHandler)
2995 {
2996 if (MUST_CONVERT(enc, s))
2997 {
2998 ICHAR *dataPtr = (ICHAR*)dataBuf;
2999
3000 XmlConvert(enc, &s, end, &dataPtr, (ICHAR*)dataBufEnd);
3001 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR*)dataBuf);
3002 }
3003 else
3004 characterDataHandler(handlerArg,
3005 (XML_Char*)s,
3006 (XML_Char*)end - (XML_Char*)s);
3007 }
3008 else if (defaultHandler)
3009 reportDefault(parser, enc, s, end);
3010 if (startTagLevel == 0)
3011 {
3012 *eventPP = end;
3013 return XML_ERROR_NO_ELEMENTS;
3014 }
3015 if (tagLevel != startTagLevel)
3016 {
3017 *eventPP = end;
3018 return XML_ERROR_ASYNC_ENTITY;
3019 }
3020 return XML_ERROR_NONE;
3021 case XML_TOK_DATA_CHARS:
3022 if (characterDataHandler)
3023 {
3024 if (MUST_CONVERT(enc, s))
3025 {
3026 for (;;)
3027 {
3028 ICHAR *dataPtr = (ICHAR*)dataBuf;
3029
3030 XmlConvert(enc, &s, next, &dataPtr, (ICHAR*)dataBufEnd);
3031 *eventEndPP = s;
3032 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR*)dataBuf);
3033 if (s == next)
3034 break;
3035 *eventPP = s;
3036 }
3037 }
3038 else
3039 characterDataHandler(handlerArg,
3040 (XML_Char*)s,
3041 (XML_Char*)next - (XML_Char*)s);
3042 }
3043 else if (defaultHandler)
3044 reportDefault(parser, enc, s, next);
3045 break;
3046 case XML_TOK_PI:
3047 if (!reportProcessingInstruction(parser, enc, s, next))
3048 return XML_ERROR_NO_MEMORY;
3049 break;
3050 case XML_TOK_COMMENT:
3051 if (!reportComment(parser, enc, s, next))
3052 return XML_ERROR_NO_MEMORY;
3053 break;
3054 default:
3055 if (defaultHandler)
3056 reportDefault(parser, enc, s, next);
3057 break;
3058 }
3059 *eventPP = s = next;
3060 }
3061 /* not reached */
3062}
3063
3064/* If tagNamePtr is non-null, build a real list of attributes,
3065 * otherwise just check the attributes for well-formedness. */
3066
3067static enum XML_Error storeAtts(XML_Parser parser,
3068 const ENCODING * enc,
3069 const char *attStr,
3070 TAG_NAME * tagNamePtr,
3071 BINDING ** bindingsPtr)
3072{
3073 ELEMENT_TYPE *elementType = 0;
3074 int nDefaultAtts = 0;
3075 const XML_Char **appAtts; /* the attribute list to pass to the application */
3076 int attIndex = 0;
3077 int i;
3078 int n;
3079 int nPrefixes = 0;
3080 BINDING *binding;
3081 const XML_Char *localPart;
3082
3083 /* lookup the element type name */
3084 if (tagNamePtr)
3085 {
3086 elementType = (ELEMENT_TYPE*)lookup(&dtd.elementTypes, tagNamePtr->str, 0);
3087 if (!elementType)
3088 {
3089 tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
3090 if (!tagNamePtr->str)
3091 return XML_ERROR_NO_MEMORY;
3092 elementType = (ELEMENT_TYPE*)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
3093 if (!elementType)
3094 return XML_ERROR_NO_MEMORY;
3095 if (ns && !setElementTypePrefix(parser, elementType))
3096 return XML_ERROR_NO_MEMORY;
3097 }
3098 nDefaultAtts = elementType->nDefaultAtts;
3099 }
3100 /* get the attributes from the tokenizer */
3101 n = XmlGetAttributes(enc, attStr, attsSize, atts);
3102 if (n + nDefaultAtts > attsSize)
3103 {
3104 int oldAttsSize = attsSize;
3105
3106 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
3107 atts = (PATTRIBUTE)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
3108 if (!atts)
3109 return XML_ERROR_NO_MEMORY;
3110 if (n > oldAttsSize)
3111 XmlGetAttributes(enc, attStr, n, atts);
3112 }
3113 appAtts = (const XML_Char **)atts;
3114 for (i = 0; i < n; i++)
3115 {
3116 /* add the name and value to the attribute list */
3117 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
3118 atts[i].name
3119 + XmlNameLength(enc, atts[i].name));
3120
3121 if (!attId)
3122 return XML_ERROR_NO_MEMORY;
3123 /* detect duplicate attributes */
3124 if ((attId->name)[-1])
3125 {
3126 if (enc == encoding)
3127 eventPtr = atts[i].name;
3128 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3129 }
3130 (attId->name)[-1] = 1;
3131 appAtts[attIndex++] = attId->name;
3132 if (!atts[i].normalized)
3133 {
3134 enum XML_Error result;
3135 int isCdata = 1;
3136
3137 /* figure out whether declared as other than CDATA */
3138 if (attId->maybeTokenized)
3139 {
3140 int j;
3141
3142 for (j = 0; j < nDefaultAtts; j++)
3143 {
3144 if (attId == elementType->defaultAtts[j].id)
3145 {
3146 isCdata = elementType->defaultAtts[j].isCdata;
3147 break;
3148 }
3149 }
3150 }
3151
3152 /* normalize the attribute value */
3153 result = storeAttributeValue(parser, enc, isCdata,
3154 atts[i].valuePtr, atts[i].valueEnd,
3155 &tempPool);
3156 if (result)
3157 return result;
3158 if (tagNamePtr)
3159 {
3160 appAtts[attIndex] = poolStart(&tempPool);
3161 poolFinish(&tempPool);
3162 }
3163 else
3164 poolDiscard(&tempPool);
3165 }
3166 else if (tagNamePtr)
3167 {
3168 /* the value did not need normalizing */
3169 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
3170 if (appAtts[attIndex] == 0)
3171 return XML_ERROR_NO_MEMORY;
3172 poolFinish(&tempPool);
3173 }
3174 /* handle prefixed attribute names */
3175 if (attId->prefix && tagNamePtr)
3176 {
3177 if (attId->xmlns)
3178 {
3179 /* deal with namespace declarations here */
3180 if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
3181 return XML_ERROR_NO_MEMORY;
3182 --attIndex;
3183 }
3184 else
3185 {
3186 /* deal with other prefixed names later */
3187 attIndex++;
3188 nPrefixes++;
3189 (attId->name)[-1] = 2;
3190 }
3191 }
3192 else
3193 attIndex++;
3194 }
3195 if (tagNamePtr)
3196 {
3197 int j;
3198
3199 nSpecifiedAtts = attIndex;
3200 if (elementType->idAtt && (elementType->idAtt->name)[-1])
3201 {
3202 for (i = 0; i < attIndex; i += 2)
3203 if (appAtts[i] == elementType->idAtt->name)
3204 {
3205 idAttIndex = i;
3206 break;
3207 }
3208 }
3209 else
3210 idAttIndex = -1;
3211 /* do attribute defaulting */
3212 for (j = 0; j < nDefaultAtts; j++)
3213 {
3214 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
3215
3216 if (!(da->id->name)[-1] && da->value)
3217 {
3218 if (da->id->prefix)
3219 {
3220 if (da->id->xmlns)
3221 {
3222 if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
3223 return XML_ERROR_NO_MEMORY;
3224 }
3225 else
3226 {
3227 (da->id->name)[-1] = 2;
3228 nPrefixes++;
3229 appAtts[attIndex++] = da->id->name;
3230 appAtts[attIndex++] = da->value;
3231 }
3232 }
3233 else
3234 {
3235 (da->id->name)[-1] = 1;
3236 appAtts[attIndex++] = da->id->name;
3237 appAtts[attIndex++] = da->value;
3238 }
3239 }
3240 }
3241 appAtts[attIndex] = 0;
3242 }
3243 i = 0;
3244 if (nPrefixes)
3245 {
3246 /* expand prefixed attribute names */
3247 for (; i < attIndex; i += 2)
3248 {
3249 if (appAtts[i][-1] == 2)
3250 {
3251 ATTRIBUTE_ID *id;
3252
3253 ((XML_Char*)(appAtts[i]))[-1] = 0;
3254 id = (ATTRIBUTE_ID*)lookup(&dtd.attributeIds, appAtts[i], 0);
3255 if (id->prefix->binding)
3256 {
3257 int j;
3258 const BINDING *b = id->prefix->binding;
3259 const XML_Char *s = appAtts[i];
3260
3261 for (j = 0; j < b->uriLen; j++)
3262 {
3263 if (!poolAppendChar(&tempPool, b->uri[j]))
3264 return XML_ERROR_NO_MEMORY;
3265 }
3266 while (*s++ != ':')
3267 ;
3268 do
3269 {
3270 if (!poolAppendChar(&tempPool, *s))
3271 return XML_ERROR_NO_MEMORY;
3272 }
3273 while (*s++);
3274 if (ns_triplets)
3275 {
3276 tempPool.ptr[-1] = namespaceSeparator;
3277 s = b->prefix->name;
3278 do
3279 {
3280 if (!poolAppendChar(&tempPool, *s))
3281 return XML_ERROR_NO_MEMORY;
3282 }
3283 while (*s++);
3284 }
3285
3286 appAtts[i] = poolStart(&tempPool);
3287 poolFinish(&tempPool);
3288 }
3289 if (!--nPrefixes)
3290 break;
3291 }
3292 else
3293 ((XML_Char*)(appAtts[i]))[-1] = 0;
3294 }
3295 }
3296 /* clear the flags that say whether attributes were specified */
3297 for (; i < attIndex; i += 2)
3298 ((XML_Char*)(appAtts[i]))[-1] = 0;
3299 if (!tagNamePtr)
3300 return XML_ERROR_NONE;
3301 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3302 binding->attId->name[-1] = 0;
3303 /* expand the element type name */
3304 if (elementType->prefix)
3305 {
3306 binding = elementType->prefix->binding;
3307 if (!binding)
3308 return XML_ERROR_NONE;
3309 localPart = tagNamePtr->str;
3310 while (*localPart++ != XML_T(':'))
3311 ;
3312 }
3313 else if (dtd.defaultPrefix.binding)
3314 {
3315 binding = dtd.defaultPrefix.binding;
3316 localPart = tagNamePtr->str;
3317 }
3318 else
3319 return XML_ERROR_NONE;
3320 tagNamePtr->localPart = localPart;
3321 tagNamePtr->uriLen = binding->uriLen;
3322 for (i = 0; localPart[i++];)
3323 ;
3324 n = i + binding->uriLen;
3325 if (n > binding->uriAlloc)
3326 {
3327 TAG *p;
3328 XML_Char *uri = (XML_Char*)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
3329
3330 if (!uri)
3331 return XML_ERROR_NO_MEMORY;
3332 binding->uriAlloc = n + EXPAND_SPARE;
3333 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3334 for (p = tagStack; p; p = p->parent)
3335 if (p->name.str == binding->uri)
3336 p->name.str = uri;
3337 FREE(binding->uri);
3338 binding->uri = uri;
3339 }
3340 memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
3341 tagNamePtr->str = binding->uri;
3342 return XML_ERROR_NONE;
3343}
3344
3345static int addBinding(XML_Parser parser, PREFIX * prefix, const ATTRIBUTE_ID * attId, const XML_Char * uri, BINDING ** bindingsPtr)
3346{
3347 BINDING *b;
3348 int len;
3349
3350 for (len = 0; uri[len]; len++)
3351 ;
3352 if (namespaceSeparator)
3353 len++;
3354 if (freeBindingList)
3355 {
3356 b = freeBindingList;
3357 if (len > b->uriAlloc)
3358 {
3359 b->uri = (XML_Char*)REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
3360 if (!b->uri)
3361 return 0;
3362 b->uriAlloc = len + EXPAND_SPARE;
3363 }
3364 freeBindingList = b->nextTagBinding;
3365 }
3366 else
3367 {
3368 b = (PBINDING)MALLOC(sizeof(BINDING));
3369 if (!b)
3370 return 0;
3371 b->uri = (XML_Char*)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
3372 if (!b->uri)
3373 {
3374 FREE(b);
3375 return 0;
3376 }
3377 b->uriAlloc = len + EXPAND_SPARE;
3378 }
3379 b->uriLen = len;
3380 memcpy(b->uri, uri, len * sizeof(XML_Char));
3381 if (namespaceSeparator)
3382 b->uri[len - 1] = namespaceSeparator;
3383 b->prefix = prefix;
3384 b->attId = attId;
3385 b->prevPrefixBinding = prefix->binding;
3386 if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
3387 prefix->binding = 0;
3388 else
3389 prefix->binding = b;
3390 b->nextTagBinding = *bindingsPtr;
3391 *bindingsPtr = b;
3392 if (startNamespaceDeclHandler)
3393 startNamespaceDeclHandler(handlerArg, prefix->name,
3394 prefix->binding ? uri : 0);
3395 return 1;
3396}
3397
3398/* The idea here is to avoid using stack for each CDATA section when
3399 * the whole file is parsed with one call. */
3400
3401static enum XML_Error cdataSectionProcessor(XML_Parser parser,
3402 const char *start,
3403 const char *end,
3404 const char **endPtr)
3405{
3406 enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
3407
3408 if (start)
3409 {
3410 processor = contentProcessor;
3411 return contentProcessor(parser, start, end, endPtr);
3412 }
3413 return result;
3414}
3415
3416/* startPtr gets set to non-null is the section is closed, and to null if
3417 * the section is not yet closed. */
3418
3419static enum XML_Error doCdataSection(XML_Parser parser,
3420 const ENCODING * enc,
3421 const char **startPtr,
3422 const char *end,
3423 const char **nextPtr)
3424{
3425 const char *s = *startPtr;
3426 const char **eventPP;
3427 const char **eventEndPP;
3428
3429 if (enc == encoding)
3430 {
3431 eventPP = &eventPtr;
3432 *eventPP = s;
3433 eventEndPP = &eventEndPtr;
3434 }
3435 else
3436 {
3437 eventPP = &(openInternalEntities->internalEventPtr);
3438 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3439 }
3440 *eventPP = s;
3441 *startPtr = 0;
3442 for (;;)
3443 {
3444 const char *next;
3445 int tok = XmlCdataSectionTok(enc, s, end, &next);
3446
3447 *eventEndPP = next;
3448 switch (tok)
3449 {
3450 case XML_TOK_CDATA_SECT_CLOSE:
3451 if (endCdataSectionHandler)
3452 endCdataSectionHandler(handlerArg);
3453#if 0
3454 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3455 else if (characterDataHandler)
3456 characterDataHandler(handlerArg, dataBuf, 0);
3457#endif
3458 else if (defaultHandler)
3459 reportDefault(parser, enc, s, next);
3460 *startPtr = next;
3461 return XML_ERROR_NONE;
3462 case XML_TOK_DATA_NEWLINE:
3463 if (characterDataHandler)
3464 {
3465 XML_Char c = 0xA;
3466
3467 characterDataHandler(handlerArg, &c, 1);
3468 }
3469 else if (defaultHandler)
3470 reportDefault(parser, enc, s, next);
3471 break;
3472 case XML_TOK_DATA_CHARS:
3473 if (characterDataHandler)
3474 {
3475 if (MUST_CONVERT(enc, s))
3476 {
3477 for (;;)
3478 {
3479 ICHAR *dataPtr = (ICHAR*)dataBuf;
3480
3481 XmlConvert(enc, &s, next, &dataPtr, (ICHAR*)dataBufEnd);
3482 *eventEndPP = next;
3483 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR*)dataBuf);
3484 if (s == next)
3485 break;
3486 *eventPP = s;
3487 }
3488 }
3489 else
3490 characterDataHandler(handlerArg,
3491 (XML_Char*)s,
3492 (XML_Char*)next - (XML_Char*)s);
3493 }
3494 else if (defaultHandler)
3495 reportDefault(parser, enc, s, next);
3496 break;
3497 case XML_TOK_INVALID:
3498 *eventPP = next;
3499 return XML_ERROR_INVALID_TOKEN;
3500 case XML_TOK_PARTIAL_CHAR:
3501 if (nextPtr)
3502 {
3503 *nextPtr = s;
3504 return XML_ERROR_NONE;
3505 }
3506 return XML_ERROR_PARTIAL_CHAR;
3507 case XML_TOK_PARTIAL:
3508 case XML_TOK_NONE:
3509 if (nextPtr)
3510 {
3511 *nextPtr = s;
3512 return XML_ERROR_NONE;
3513 }
3514 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3515 default:
3516 *eventPP = next;
3517 return XML_ERROR_UNEXPECTED_STATE;
3518 }
3519 *eventPP = s = next;
3520 }
3521 /* not reached */
3522}
3523
3524#ifdef XML_DTD
3525
3526/* The idea here is to avoid using stack for each IGNORE section when
3527 * the whole file is parsed with one call. */
3528
3529static enum XML_Error ignoreSectionProcessor(XML_Parser parser,
3530 const char *start,
3531 const char *end,
3532 const char **endPtr)
3533{
3534 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
3535
3536 if (start)
3537 {
3538 processor = prologProcessor;
3539 return prologProcessor(parser, start, end, endPtr);
3540 }
3541 return result;
3542}
3543
3544/* startPtr gets set to non-null is the section is closed, and to null if
3545 * the section is not yet closed. */
3546
3547static enum XML_Error doIgnoreSection(XML_Parser parser,
3548 const ENCODING * enc,
3549 const char **startPtr,
3550 const char *end,
3551 const char **nextPtr)
3552{
3553 const char *next;
3554 int tok;
3555 const char *s = *startPtr;
3556 const char **eventPP;
3557 const char **eventEndPP;
3558
3559 if (enc == encoding)
3560 {
3561 eventPP = &eventPtr;
3562 *eventPP = s;
3563 eventEndPP = &eventEndPtr;
3564 }
3565 else
3566 {
3567 eventPP = &(openInternalEntities->internalEventPtr);
3568 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3569 }
3570 *eventPP = s;
3571 *startPtr = 0;
3572 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3573 *eventEndPP = next;
3574 switch (tok)
3575 {
3576 case XML_TOK_IGNORE_SECT:
3577 if (defaultHandler)
3578 reportDefault(parser, enc, s, next);
3579 *startPtr = next;
3580 return XML_ERROR_NONE;
3581 case XML_TOK_INVALID:
3582 *eventPP = next;
3583 return XML_ERROR_INVALID_TOKEN;
3584 case XML_TOK_PARTIAL_CHAR:
3585 if (nextPtr)
3586 {
3587 *nextPtr = s;
3588 return XML_ERROR_NONE;
3589 }
3590 return XML_ERROR_PARTIAL_CHAR;
3591 case XML_TOK_PARTIAL:
3592 case XML_TOK_NONE:
3593 if (nextPtr)
3594 {
3595 *nextPtr = s;
3596 return XML_ERROR_NONE;
3597 }
3598 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3599 default:
3600 *eventPP = next;
3601 return XML_ERROR_UNEXPECTED_STATE;
3602 }
3603 /* not reached */
3604}
3605
3606#endif /* XML_DTD */
3607
3608static enum XML_Error initializeEncoding(XML_Parser parser)
3609{
3610 const char *s;
3611
3612#ifdef XML_UNICODE
3613 char encodingBuf[128];
3614
3615 if (!protocolEncodingName)
3616 s = 0;
3617 else
3618 {
3619 int i;
3620
3621 for (i = 0; protocolEncodingName[i]; i++)
3622 {
3623 if (i == sizeof(encodingBuf) - 1
3624 || (protocolEncodingName[i] & ~0x7f) != 0)
3625 {
3626 encodingBuf[0] = '\0';
3627 break;
3628 }
3629 encodingBuf[i] = (char)protocolEncodingName[i];
3630 }
3631 encodingBuf[i] = '\0';
3632 s = encodingBuf;
3633 }
3634#else
3635 s = protocolEncodingName;
3636#endif
3637 if ((ns ? XmlInitEncodingNS : XmlInitEncoding) (&initEncoding, &encoding, s))
3638 return XML_ERROR_NONE;
3639 return handleUnknownEncoding(parser, protocolEncodingName);
3640}
3641
3642static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3643 const char *s, const char *next)
3644{
3645 const char *encodingName = 0;
3646 const char *storedEncName = 0;
3647 const ENCODING *newEncoding = 0;
3648 const char *version = 0;
3649 const char *versionend;
3650 const char *storedversion = 0;
3651 int standalone = -1;
3652
3653 if (!(ns
3654 ? XmlParseXmlDeclNS
3655 : XmlParseXmlDecl) (isGeneralTextEntity,
3656 encoding,
3657 s,
3658 next,
3659 &eventPtr,
3660 &version,
3661 &versionend,
3662 &encodingName,
3663 &newEncoding,
3664 &standalone))
3665 return XML_ERROR_SYNTAX;
3666 if (!isGeneralTextEntity && standalone == 1)
3667 {
3668 dtd.standalone = 1;
3669#ifdef XML_DTD
3670 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3671 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3672#endif /* XML_DTD */
3673 }
3674 if (xmlDeclHandler)
3675 {
3676 if (encodingName)
3677 {
3678 storedEncName = poolStoreString(&temp2Pool,
3679 encoding,
3680 encodingName,
3681 encodingName
3682 + XmlNameLength(encoding, encodingName));
3683 if (!storedEncName)
3684 return XML_ERROR_NO_MEMORY;
3685 poolFinish(&temp2Pool);
3686 }
3687 if (version)
3688 {
3689 storedversion = poolStoreString(&temp2Pool,
3690 encoding,
3691 version,
3692 versionend - encoding->minBytesPerChar);
3693 if (!storedversion)
3694 return XML_ERROR_NO_MEMORY;
3695 }
3696 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3697 }
3698 else if (defaultHandler)
3699 reportDefault(parser, encoding, s, next);
3700 if (!protocolEncodingName)
3701 {
3702 if (newEncoding)
3703 {
3704 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar)
3705 {
3706 eventPtr = encodingName;
3707 return XML_ERROR_INCORRECT_ENCODING;
3708 }
3709 encoding = newEncoding;
3710 }
3711 else if (encodingName)
3712 {
3713 enum XML_Error result;
3714
3715 if (!storedEncName)
3716 {
3717 storedEncName = poolStoreString(&temp2Pool,
3718 encoding,
3719 encodingName,
3720 encodingName
3721 + XmlNameLength(encoding, encodingName));
3722 if (!storedEncName)
3723 return XML_ERROR_NO_MEMORY;
3724 }
3725 result = handleUnknownEncoding(parser, storedEncName);
3726 poolClear(&tempPool);
3727 if (result == XML_ERROR_UNKNOWN_ENCODING)
3728 eventPtr = encodingName;
3729 return result;
3730 }
3731 }
3732
3733 if (storedEncName || storedversion)
3734 poolClear(&temp2Pool);
3735
3736 return XML_ERROR_NONE;
3737}
3738
3739static enum XML_Error handleUnknownEncoding(XML_Parser parser,
3740 const XML_Char* encodingName)
3741{
3742 if (unknownEncodingHandler)
3743 {
3744 XML_Encoding info;
3745 int i;
3746
3747 for (i = 0; i < 256; i++)
3748 info.map[i] = -1;
3749 info.convert = 0;
3750 info.data = 0;
3751 info.release = 0;
3752 if (unknownEncodingHandler(unknownEncodingHandlerData,
3753 encodingName,
3754 &info))
3755 {
3756 ENCODING *enc;
3757
3758 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3759 if (!unknownEncodingMem)
3760 {
3761 if (info.release)
3762 info.release(info.data);
3763 return XML_ERROR_NO_MEMORY;
3764 }
3765 enc = (ns
3766 ? XmlInitUnknownEncodingNS
3767 : XmlInitUnknownEncoding) (unknownEncodingMem,
3768 info.map,
3769 info.convert,
3770 info.data);
3771 if (enc)
3772 {
3773 unknownEncodingData = info.data;
3774 unknownEncodingRelease = info.release;
3775 encoding = enc;
3776 return XML_ERROR_NONE;
3777 }
3778 }
3779 if (info.release)
3780 info.release(info.data);
3781 }
3782 return XML_ERROR_UNKNOWN_ENCODING;
3783}
3784
3785static enum XML_Error prologInitProcessor(XML_Parser parser,
3786 const char *s,
3787 const char *end,
3788 const char **nextPtr)
3789{
3790 enum XML_Error result = initializeEncoding(parser);
3791
3792 if (result != XML_ERROR_NONE)
3793 return result;
3794 processor = prologProcessor;
3795 return prologProcessor(parser, s, end, nextPtr);
3796}
3797
3798static enum XML_Error prologProcessor(XML_Parser parser,
3799 const char *s,
3800 const char *end,
3801 const char **nextPtr)
3802{
3803 const char *next;
3804 int tok = XmlPrologTok(encoding, s, end, &next);
3805
3806 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
3807}
3808
3809static enum XML_Error doProlog(XML_Parser parser,
3810 const ENCODING * enc,
3811 const char *s,
3812 const char *end,
3813 int tok,
3814 const char *next,
3815 const char **nextPtr)
3816{
3817#ifdef XML_DTD
3818 static const XML_Char externalSubsetName[] =
3819 {'#', '\0'};
3820
3821#endif /* XML_DTD */
3822
3823 const char **eventPP;
3824 const char **eventEndPP;
3825 enum XML_Content_Quant quant;
3826
3827 if (enc == encoding)
3828 {
3829 eventPP = &eventPtr;
3830 eventEndPP = &eventEndPtr;
3831 }
3832 else
3833 {
3834 eventPP = &(openInternalEntities->internalEventPtr);
3835 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3836 }
3837 for (;;)
3838 {
3839 int role;
3840
3841 *eventPP = s;
3842 *eventEndPP = next;
3843 if (tok <= 0)
3844 {
3845 if (nextPtr != 0 && tok != XML_TOK_INVALID)
3846 {
3847 *nextPtr = s;
3848 return XML_ERROR_NONE;
3849 }
3850 switch (tok)
3851 {
3852 case XML_TOK_INVALID:
3853 *eventPP = next;
3854 return XML_ERROR_INVALID_TOKEN;
3855 case XML_TOK_PARTIAL:
3856 return XML_ERROR_UNCLOSED_TOKEN;
3857 case XML_TOK_PARTIAL_CHAR:
3858 return XML_ERROR_PARTIAL_CHAR;
3859 case XML_TOK_NONE:
3860#ifdef XML_DTD
3861 if (enc != encoding)
3862 return XML_ERROR_NONE;
3863 if (parentParser)
3864 {
3865 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3866 == XML_ROLE_ERROR)
3867 return XML_ERROR_SYNTAX;
3868 hadExternalDoctype = 0;
3869 return XML_ERROR_NONE;
3870 }
3871#endif /* XML_DTD */
3872 return XML_ERROR_NO_ELEMENTS;
3873 default:
3874 tok = -tok;
3875 next = end;
3876 break;
3877 }
3878 }
3879 role = XmlTokenRole(&prologState, tok, s, next, enc);
3880 switch (role)
3881 {
3882 case XML_ROLE_XML_DECL:
3883 {
3884 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3885
3886 if (result != XML_ERROR_NONE)
3887 return result;
3888 enc = encoding;
3889 }
3890 break;
3891 case XML_ROLE_DOCTYPE_NAME:
3892 if (startDoctypeDeclHandler)
3893 {
3894 doctypeName = poolStoreString(&tempPool, enc, s, next);
3895 if (!doctypeName)
3896 return XML_ERROR_NO_MEMORY;
3897 poolFinish(&tempPool);
3898 doctypeSysid = 0;
3899 doctypePubid = 0;
3900 }
3901 break;
3902 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3903 if (startDoctypeDeclHandler)
3904 {
3905 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3906 doctypePubid, 1);
3907 doctypeName = 0;
3908 poolClear(&tempPool);
3909 }
3910 break;
3911#ifdef XML_DTD
3912 case XML_ROLE_TEXT_DECL:
3913 {
3914 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3915
3916 if (result != XML_ERROR_NONE)
3917 return result;
3918 enc = encoding;
3919 }
3920 break;
3921#endif /* XML_DTD */
3922 case XML_ROLE_DOCTYPE_PUBLIC_ID:
3923 if (startDoctypeDeclHandler)
3924 {
3925 doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1);
3926 if (!doctypePubid)
3927 return XML_ERROR_NO_MEMORY;
3928 poolFinish(&tempPool);
3929 }
3930#ifdef XML_DTD
3931 declEntity = (ENTITY*)lookup(&dtd.paramEntities,
3932 externalSubsetName,
3933 sizeof(ENTITY));
3934 if (!declEntity)
3935 return XML_ERROR_NO_MEMORY;
3936#endif /* XML_DTD */
3937 /* fall through */
3938 case XML_ROLE_ENTITY_PUBLIC_ID:
3939 if (!XmlIsPublicId(enc, s, next, eventPP))
3940 return XML_ERROR_SYNTAX;
3941 if (declEntity)
3942 {
3943 XML_Char *tem = poolStoreString(&dtd.pool,
3944 enc,
3945 s + enc->minBytesPerChar,
3946 next - enc->minBytesPerChar);
3947
3948 if (!tem)
3949 return XML_ERROR_NO_MEMORY;
3950 normalizePublicId(tem);
3951 declEntity->publicId = tem;
3952 poolFinish(&dtd.pool);
3953 }
3954 break;
3955 case XML_ROLE_DOCTYPE_CLOSE:
3956 if (doctypeName)
3957 {
3958 startDoctypeDeclHandler(handlerArg, doctypeName,
3959 doctypeSysid, doctypePubid, 0);
3960 poolClear(&tempPool);
3961 }
3962 if (dtd.complete && hadExternalDoctype)
3963 {
3964 dtd.complete = 0;
3965#ifdef XML_DTD
3966 if (paramEntityParsing && externalEntityRefHandler)
3967 {
3968 ENTITY *entity = (ENTITY*)lookup(&dtd.paramEntities,
3969 externalSubsetName,
3970 0);
3971
3972 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3973 0,
3974 entity->base,
3975 entity->systemId,
3976 entity->publicId))
3977 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3978 }
3979#endif /* XML_DTD */
3980 if (!dtd.complete
3981 && !dtd.standalone
3982 && notStandaloneHandler
3983 && !notStandaloneHandler(handlerArg))
3984 return XML_ERROR_NOT_STANDALONE;
3985 }
3986 if (endDoctypeDeclHandler)
3987 endDoctypeDeclHandler(handlerArg);
3988 break;
3989 case XML_ROLE_INSTANCE_START:
3990 processor = contentProcessor;
3991 return contentProcessor(parser, s, end, nextPtr);
3992 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3993 declElementType = getElementType(parser, enc, s, next);
3994 if (!declElementType)
3995 return XML_ERROR_NO_MEMORY;
3996 break;
3997 case XML_ROLE_ATTRIBUTE_NAME:
3998 declAttributeId = getAttributeId(parser, enc, s, next);
3999 if (!declAttributeId)
4000 return XML_ERROR_NO_MEMORY;
4001 declAttributeIsCdata = 0;
4002 declAttributeType = 0;
4003 declAttributeIsId = 0;
4004 break;
4005 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4006 declAttributeIsCdata = 1;
4007 declAttributeType = "CDATA";
4008 break;
4009 case XML_ROLE_ATTRIBUTE_TYPE_ID:
4010 declAttributeIsId = 1;
4011 declAttributeType = "ID";
4012 break;
4013 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4014 declAttributeType = "IDREF";
4015 break;
4016 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4017 declAttributeType = "IDREFS";
4018 break;
4019 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
4020 declAttributeType = "ENTITY";
4021 break;
4022 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
4023 declAttributeType = "ENTITIES";
4024 break;
4025 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
4026 declAttributeType = "NMTOKEN";
4027 break;
4028 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
4029 declAttributeType = "NMTOKENS";
4030 break;
4031
4032 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4033 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
4034 if (attlistDeclHandler)
4035 {
4036 char *prefix;
4037
4038 if (declAttributeType)
4039 {
4040 prefix = "|";
4041 }
4042 else
4043 {
4044 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4045 ? "NOTATION("
4046 : "(");
4047 }
4048 if (!poolAppendString(&tempPool, prefix))
4049 return XML_ERROR_NO_MEMORY;
4050 if (!poolAppend(&tempPool, enc, s, next))
4051 return XML_ERROR_NO_MEMORY;
4052 declAttributeType = tempPool.start;
4053 }
4054 break;
4055 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4056 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4057 if (dtd.complete
4058 && !defineAttribute(declElementType, declAttributeId,
4059 declAttributeIsCdata, declAttributeIsId, 0,
4060 parser))
4061 return XML_ERROR_NO_MEMORY;
4062 if (attlistDeclHandler && declAttributeType)
4063 {
4064 if (*declAttributeType == '('
4065 || *declAttributeType == 'N' && declAttributeType[1] == 'O')
4066 {
4067 /* Enumerated or Notation type */
4068 if (!poolAppendChar(&tempPool, ')')
4069 || !poolAppendChar(&tempPool, '\0'))
4070 return XML_ERROR_NO_MEMORY;
4071 declAttributeType = tempPool.start;
4072 poolFinish(&tempPool);
4073 }
4074 *eventEndPP = s;
4075 attlistDeclHandler(handlerArg, declElementType->name,
4076 declAttributeId->name, declAttributeType,
4077 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4078 poolClear(&tempPool);
4079 }
4080 break;
4081 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4082 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4083 {
4084 const XML_Char *attVal;
4085 enum XML_Error result
4086 = storeAttributeValue(parser, enc, declAttributeIsCdata,
4087 s + enc->minBytesPerChar,
4088 next - enc->minBytesPerChar,
4089 &dtd.pool);
4090
4091 if (result)
4092 return result;
4093 attVal = poolStart(&dtd.pool);
4094 poolFinish(&dtd.pool);
4095 if (dtd.complete
4096 /* ID attributes aren't allowed to have a default */
4097 && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
4098 return XML_ERROR_NO_MEMORY;
4099 if (attlistDeclHandler && declAttributeType)
4100 {
4101 if (*declAttributeType == '('
4102 || *declAttributeType == 'N' && declAttributeType[1] == 'O')
4103 {
4104 /* Enumerated or Notation type */
4105 if (!poolAppendChar(&tempPool, ')')
4106 || !poolAppendChar(&tempPool, '\0'))
4107 return XML_ERROR_NO_MEMORY;
4108 declAttributeType = tempPool.start;
4109 poolFinish(&tempPool);
4110 }
4111 *eventEndPP = s;
4112 attlistDeclHandler(handlerArg, declElementType->name,
4113 declAttributeId->name, declAttributeType,
4114 attVal,
4115 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4116 poolClear(&tempPool);
4117 }
4118 break;
4119 }
4120 case XML_ROLE_ENTITY_VALUE:
4121 {
4122 enum XML_Error result = storeEntityValue(parser, enc,
4123 s + enc->minBytesPerChar,
4124 next - enc->minBytesPerChar);
4125
4126 if (declEntity)
4127 {
4128 declEntity->textPtr = poolStart(&dtd.pool);
4129 declEntity->textLen = poolLength(&dtd.pool);
4130 poolFinish(&dtd.pool);
4131 if (entityDeclHandler)
4132 {
4133 *eventEndPP = s;
4134 entityDeclHandler(handlerArg,
4135 declEntity->name,
4136 declEntity->is_param,
4137 declEntity->textPtr,
4138 declEntity->textLen,
4139 curBase, 0, 0, 0);
4140 }
4141 }
4142 else
4143 poolDiscard(&dtd.pool);
4144 if (result != XML_ERROR_NONE)
4145 return result;
4146 }
4147 break;
4148 case XML_ROLE_DOCTYPE_SYSTEM_ID:
4149 if (startDoctypeDeclHandler)
4150 {
4151 doctypeSysid = poolStoreString(&tempPool, enc, s + 1, next - 1);
4152 if (!doctypeSysid)
4153 return XML_ERROR_NO_MEMORY;
4154 poolFinish(&tempPool);
4155 }
4156 if (!dtd.standalone
4157#ifdef XML_DTD
4158 && !paramEntityParsing
4159#endif /* XML_DTD */
4160 && notStandaloneHandler
4161 && !notStandaloneHandler(handlerArg))
4162 return XML_ERROR_NOT_STANDALONE;
4163 hadExternalDoctype = 1;
4164#ifndef XML_DTD
4165 break;
4166#else /* XML_DTD */
4167 if (!declEntity)
4168 {
4169 declEntity = (ENTITY*)lookup(&dtd.paramEntities,
4170 externalSubsetName,
4171 sizeof(ENTITY));
4172 declEntity->publicId = 0;
4173 if (!declEntity)
4174 return XML_ERROR_NO_MEMORY;
4175 }
4176 /* fall through */
4177#endif /* XML_DTD */
4178 case XML_ROLE_ENTITY_SYSTEM_ID:
4179 if (declEntity)
4180 {
4181 declEntity->systemId = poolStoreString(&dtd.pool, enc,
4182 s + enc->minBytesPerChar,
4183 next - enc->minBytesPerChar);
4184 if (!declEntity->systemId)
4185 return XML_ERROR_NO_MEMORY;
4186 declEntity->base = curBase;
4187 poolFinish(&dtd.pool);
4188 }
4189 break;
4190 case XML_ROLE_ENTITY_COMPLETE:
4191 if (declEntity && entityDeclHandler)
4192 {
4193 *eventEndPP = s;
4194 entityDeclHandler(handlerArg,
4195 declEntity->name,
4196 0, 0, 0,
4197 declEntity->base,
4198 declEntity->systemId,
4199 declEntity->publicId,
4200 0);
4201 }
4202 break;
4203 case XML_ROLE_ENTITY_NOTATION_NAME:
4204 if (declEntity)
4205 {
4206 declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
4207 if (!declEntity->notation)
4208 return XML_ERROR_NO_MEMORY;
4209 poolFinish(&dtd.pool);
4210 if (unparsedEntityDeclHandler)
4211 {
4212 *eventEndPP = s;
4213 unparsedEntityDeclHandler(handlerArg,
4214 declEntity->name,
4215 declEntity->base,
4216 declEntity->systemId,
4217 declEntity->publicId,
4218 declEntity->notation);
4219 }
4220 else if (entityDeclHandler)
4221 {
4222 *eventEndPP = s;
4223 entityDeclHandler(handlerArg,
4224 declEntity->name,
4225 0, 0, 0,
4226 declEntity->base,
4227 declEntity->systemId,
4228 declEntity->publicId,
4229 declEntity->notation);
4230 }
4231 }
4232 break;
4233 case XML_ROLE_GENERAL_ENTITY_NAME:
4234 {
4235 const XML_Char *name;
4236
4237 if (XmlPredefinedEntityName(enc, s, next))
4238 {
4239 declEntity = 0;
4240 break;
4241 }
4242 name = poolStoreString(&dtd.pool, enc, s, next);
4243 if (!name)
4244 return XML_ERROR_NO_MEMORY;
4245 if (dtd.complete)
4246 {
4247 declEntity = (ENTITY*)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
4248 if (!declEntity)
4249 return XML_ERROR_NO_MEMORY;
4250 if (declEntity->name != name)
4251 {
4252 poolDiscard(&dtd.pool);
4253 declEntity = 0;
4254 }
4255 else
4256 {
4257 poolFinish(&dtd.pool);
4258 declEntity->publicId = 0;
4259 declEntity->is_param = 0;
4260 }
4261 }
4262 else
4263 {
4264 poolDiscard(&dtd.pool);
4265 declEntity = 0;
4266 }
4267 }
4268 break;
4269 case XML_ROLE_PARAM_ENTITY_NAME:
4270#ifdef XML_DTD
4271 if (dtd.complete)
4272 {
4273 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
4274
4275 if (!name)
4276 return XML_ERROR_NO_MEMORY;
4277 declEntity = (ENTITY*)lookup(&dtd.paramEntities,
4278 name, sizeof(ENTITY));
4279 if (!declEntity)
4280 return XML_ERROR_NO_MEMORY;
4281 if (declEntity->name != name)
4282 {
4283 poolDiscard(&dtd.pool);
4284 declEntity = 0;
4285 }
4286 else
4287 {
4288 poolFinish(&dtd.pool);
4289 declEntity->publicId = 0;
4290 declEntity->is_param = 1;
4291 }
4292 }
4293#else /* not XML_DTD */
4294 declEntity = 0;
4295#endif /* not XML_DTD */
4296 break;
4297 case XML_ROLE_NOTATION_NAME:
4298 declNotationPublicId = 0;
4299 declNotationName = 0;
4300 if (notationDeclHandler)
4301 {
4302 declNotationName = poolStoreString(&tempPool, enc, s, next);
4303 if (!declNotationName)
4304 return XML_ERROR_NO_MEMORY;
4305 poolFinish(&tempPool);
4306 }
4307 break;
4308 case XML_ROLE_NOTATION_PUBLIC_ID:
4309 if (!XmlIsPublicId(enc, s, next, eventPP))
4310 return XML_ERROR_SYNTAX;
4311 if (declNotationName)
4312 {
4313 XML_Char *tem = poolStoreString(&tempPool,
4314 enc,
4315 s + enc->minBytesPerChar,
4316 next - enc->minBytesPerChar);
4317
4318 if (!tem)
4319 return XML_ERROR_NO_MEMORY;
4320 normalizePublicId(tem);
4321 declNotationPublicId = tem;
4322 poolFinish(&tempPool);
4323 }
4324 break;
4325 case XML_ROLE_NOTATION_SYSTEM_ID:
4326 if (declNotationName && notationDeclHandler)
4327 {
4328 const XML_Char *systemId
4329 = poolStoreString(&tempPool, enc,
4330 s + enc->minBytesPerChar,
4331 next - enc->minBytesPerChar);
4332
4333 if (!systemId)
4334 return XML_ERROR_NO_MEMORY;
4335 *eventEndPP = s;
4336 notationDeclHandler(handlerArg,
4337 declNotationName,
4338 curBase,
4339 systemId,
4340 declNotationPublicId);
4341 }
4342 poolClear(&tempPool);
4343 break;
4344 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4345 if (declNotationPublicId && notationDeclHandler)
4346 {
4347 *eventEndPP = s;
4348 notationDeclHandler(handlerArg,
4349 declNotationName,
4350 curBase,
4351 0,
4352 declNotationPublicId);
4353 }
4354 poolClear(&tempPool);
4355 break;
4356 case XML_ROLE_ERROR:
4357 switch (tok)
4358 {
4359 case XML_TOK_PARAM_ENTITY_REF:
4360 return XML_ERROR_PARAM_ENTITY_REF;
4361 case XML_TOK_XML_DECL:
4362 return XML_ERROR_MISPLACED_XML_PI;
4363 default:
4364 return XML_ERROR_SYNTAX;
4365 }
4366#ifdef XML_DTD
4367 case XML_ROLE_IGNORE_SECT:
4368 {
4369 enum XML_Error result;
4370
4371 if (defaultHandler)
4372 reportDefault(parser, enc, s, next);
4373 result = doIgnoreSection(parser, enc, &next, end, nextPtr);
4374 if (!next)
4375 {
4376 processor = ignoreSectionProcessor;
4377 return result;
4378 }
4379 }
4380 break;
4381#endif /* XML_DTD */
4382 case XML_ROLE_GROUP_OPEN:
4383 if (prologState.level >= groupSize)
4384 {
4385 if (groupSize)
4386 {
4387 groupConnector = (char*)REALLOC(groupConnector, groupSize *= 2);
4388 if (dtd.scaffIndex)
4389 dtd.scaffIndex = (int*)REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
4390 }
4391 else
4392 groupConnector = (char*)MALLOC(groupSize = 32);
4393 if (!groupConnector)
4394 return XML_ERROR_NO_MEMORY;
4395 }
4396 groupConnector[prologState.level] = 0;
4397 if (dtd.in_eldecl)
4398 {
4399 int myindex = nextScaffoldPart(parser);
4400
4401 if (myindex < 0)
4402 return XML_ERROR_NO_MEMORY;
4403 dtd.scaffIndex[dtd.scaffLevel] = myindex;
4404 dtd.scaffLevel++;
4405 dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
4406 }
4407 break;
4408 case XML_ROLE_GROUP_SEQUENCE:
4409 if (groupConnector[prologState.level] == '|')
4410 return XML_ERROR_SYNTAX;
4411 groupConnector[prologState.level] = ',';
4412 break;
4413 case XML_ROLE_GROUP_CHOICE:
4414 if (groupConnector[prologState.level] == ',')
4415 return XML_ERROR_SYNTAX;
4416 if (dtd.in_eldecl
4417 && !groupConnector[prologState.level]
4418 && dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type != XML_CTYPE_MIXED
4419 )
4420 {
4421 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_CHOICE;
4422 }
4423 groupConnector[prologState.level] = '|';
4424 break;
4425 case XML_ROLE_PARAM_ENTITY_REF:
4426#ifdef XML_DTD
4427 case XML_ROLE_INNER_PARAM_ENTITY_REF:
4428 if (paramEntityParsing
4429 && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF))
4430 {
4431 const XML_Char *name;
4432 ENTITY *entity;
4433
4434 name = poolStoreString(&dtd.pool, enc,
4435 s + enc->minBytesPerChar,
4436 next - enc->minBytesPerChar);
4437 if (!name)
4438 return XML_ERROR_NO_MEMORY;
4439 entity = (ENTITY*)lookup(&dtd.paramEntities, name, 0);
4440 poolDiscard(&dtd.pool);
4441 if (!entity)
4442 {
4443 /* FIXME what to do if !dtd.complete? */
4444 return XML_ERROR_UNDEFINED_ENTITY;
4445 }
4446 if (entity->open)
4447 return XML_ERROR_RECURSIVE_ENTITY_REF;
4448 if (entity->textPtr)
4449 {
4450 enum XML_Error result;
4451
4452 result = processInternalParamEntity(parser, entity);
4453 if (result != XML_ERROR_NONE)
4454 return result;
4455 break;
4456 }
4457 if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
4458 return XML_ERROR_PARAM_ENTITY_REF;
4459 if (externalEntityRefHandler)
4460 {
4461 dtd.complete = 0;
4462 entity->open = 1;
4463 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4464 0,
4465 entity->base,
4466 entity->systemId,
4467 entity->publicId))
4468 {
4469 entity->open = 0;
4470 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4471 }
4472 entity->open = 0;
4473 if (dtd.complete)
4474 break;
4475 }
4476 }
4477#endif /* XML_DTD */
4478 if (!dtd.standalone
4479 && notStandaloneHandler
4480 && !notStandaloneHandler(handlerArg))
4481 return XML_ERROR_NOT_STANDALONE;
4482 dtd.complete = 0;
4483 if (defaultHandler)
4484 reportDefault(parser, enc, s, next);
4485 break;
4486
4487 /* Element declaration stuff */
4488
4489 case XML_ROLE_ELEMENT_NAME:
4490 if (elementDeclHandler)
4491 {
4492 declElementType = getElementType(parser, enc, s, next);
4493 if (!declElementType)
4494 return XML_ERROR_NO_MEMORY;
4495 dtd.scaffLevel = 0;
4496 dtd.scaffCount = 0;
4497 dtd.in_eldecl = 1;
4498 }
4499 break;
4500
4501 case XML_ROLE_CONTENT_ANY:
4502 case XML_ROLE_CONTENT_EMPTY:
4503 if (dtd.in_eldecl)
4504 {
4505 if (elementDeclHandler)
4506 {
4507 XML_Content *content = (XML_Content*)MALLOC(sizeof(XML_Content));
4508
4509 if (!content)
4510 return XML_ERROR_NO_MEMORY;
4511 content->quant = XML_CQUANT_NONE;
4512 content->name = 0;
4513 content->numchildren = 0;
4514 content->children = 0;
4515 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4516 XML_CTYPE_ANY :
4517 XML_CTYPE_EMPTY);
4518 *eventEndPP = s;
4519 elementDeclHandler(handlerArg, declElementType->name, content);
4520 }
4521 dtd.in_eldecl = 0;
4522 }
4523 break;
4524
4525 case XML_ROLE_CONTENT_PCDATA:
4526 if (dtd.in_eldecl)
4527 {
4528 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_MIXED;
4529 }
4530 break;
4531
4532 case XML_ROLE_CONTENT_ELEMENT:
4533 quant = XML_CQUANT_NONE;
4534 goto elementContent;
4535 case XML_ROLE_CONTENT_ELEMENT_OPT:
4536 quant = XML_CQUANT_OPT;
4537 goto elementContent;
4538 case XML_ROLE_CONTENT_ELEMENT_REP:
4539 quant = XML_CQUANT_REP;
4540 goto elementContent;
4541 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4542 quant = XML_CQUANT_PLUS;
4543 elementContent:
4544 if (dtd.in_eldecl)
4545 {
4546 ELEMENT_TYPE *el;
4547 const char *nxt = quant == XML_CQUANT_NONE ? next : next - 1;
4548 int myindex = nextScaffoldPart(parser);
4549
4550 if (myindex < 0)
4551 return XML_ERROR_NO_MEMORY;
4552 dtd.scaffold[myindex].type = XML_CTYPE_NAME;
4553 dtd.scaffold[myindex].quant = quant;
4554 el = getElementType(parser, enc, s, nxt);
4555 if (!el)
4556 return XML_ERROR_NO_MEMORY;
4557 dtd.scaffold[myindex].name = el->name;
4558 dtd.contentStringLen += nxt - s + 1;
4559 }
4560 break;
4561
4562 case XML_ROLE_GROUP_CLOSE:
4563 quant = XML_CQUANT_NONE;
4564 goto closeGroup;
4565 case XML_ROLE_GROUP_CLOSE_OPT:
4566 quant = XML_CQUANT_OPT;
4567 goto closeGroup;
4568 case XML_ROLE_GROUP_CLOSE_REP:
4569 quant = XML_CQUANT_REP;
4570 goto closeGroup;
4571 case XML_ROLE_GROUP_CLOSE_PLUS:
4572 quant = XML_CQUANT_PLUS;
4573 closeGroup:
4574 if (dtd.in_eldecl)
4575 {
4576 dtd.scaffLevel--;
4577 dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
4578 if (dtd.scaffLevel == 0)
4579 {
4580 if (elementDeclHandler)
4581 {
4582 XML_Content *model = build_model(parser);
4583
4584 if (!model)
4585 return XML_ERROR_NO_MEMORY;
4586 *eventEndPP = s;
4587 elementDeclHandler(handlerArg, declElementType->name, model);
4588 }
4589 dtd.in_eldecl = 0;
4590 dtd.contentStringLen = 0;
4591 }
4592 }
4593 break;
4594 /* End element declaration stuff */
4595
4596 case XML_ROLE_NONE:
4597 switch (tok)
4598 {
4599 case XML_TOK_PI:
4600 if (!reportProcessingInstruction(parser, enc, s, next))
4601 return XML_ERROR_NO_MEMORY;
4602 break;
4603 case XML_TOK_COMMENT:
4604 if (!reportComment(parser, enc, s, next))
4605 return XML_ERROR_NO_MEMORY;
4606 break;
4607 }
4608 break;
4609 }
4610 if (defaultHandler)
4611 {
4612 switch (tok)
4613 {
4614 case XML_TOK_PI:
4615 case XML_TOK_COMMENT:
4616 case XML_TOK_BOM:
4617 case XML_TOK_XML_DECL:
4618#ifdef XML_DTD
4619 case XML_TOK_IGNORE_SECT:
4620#endif /* XML_DTD */
4621 case XML_TOK_PARAM_ENTITY_REF:
4622 break;
4623 default:
4624#ifdef XML_DTD
4625 if (role != XML_ROLE_IGNORE_SECT)
4626#endif /* XML_DTD */
4627 reportDefault(parser, enc, s, next);
4628 }
4629 }
4630 s = next;
4631 tok = XmlPrologTok(enc, s, end, &next);
4632 }
4633 /* not reached */
4634}
4635
4636static enum XML_Error epilogProcessor(XML_Parser parser,
4637 const char *s,
4638 const char *end,
4639 const char **nextPtr)
4640{
4641 processor = epilogProcessor;
4642 eventPtr = s;
4643 for (;;)
4644 {
4645 const char *next;
4646 int tok = XmlPrologTok(encoding, s, end, &next);
4647
4648 eventEndPtr = next;
4649 switch (tok)
4650 {
4651 case -XML_TOK_PROLOG_S:
4652 if (defaultHandler)
4653 {
4654 eventEndPtr = end;
4655 reportDefault(parser, encoding, s, end);
4656 }
4657 /* fall through */
4658 case XML_TOK_NONE:
4659 if (nextPtr)
4660 *nextPtr = end;
4661 return XML_ERROR_NONE;
4662 case XML_TOK_PROLOG_S:
4663 if (defaultHandler)
4664 reportDefault(parser, encoding, s, next);
4665 break;
4666 case XML_TOK_PI:
4667 if (!reportProcessingInstruction(parser, encoding, s, next))
4668 return XML_ERROR_NO_MEMORY;
4669 break;
4670 case XML_TOK_COMMENT:
4671 if (!reportComment(parser, encoding, s, next))
4672 return XML_ERROR_NO_MEMORY;
4673 break;
4674 case XML_TOK_INVALID:
4675 eventPtr = next;
4676 return XML_ERROR_INVALID_TOKEN;
4677 case XML_TOK_PARTIAL:
4678 if (nextPtr)
4679 {
4680 *nextPtr = s;
4681 return XML_ERROR_NONE;
4682 }
4683 return XML_ERROR_UNCLOSED_TOKEN;
4684 case XML_TOK_PARTIAL_CHAR:
4685 if (nextPtr)
4686 {
4687 *nextPtr = s;
4688 return XML_ERROR_NONE;
4689 }
4690 return XML_ERROR_PARTIAL_CHAR;
4691 default:
4692 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4693 }
4694 eventPtr = s = next;
4695 }
4696}
4697
4698#ifdef XML_DTD
4699
4700static enum XML_Error processInternalParamEntity(XML_Parser parser, ENTITY * entity)
4701{
4702 const char *s, *end, *next;
4703 int tok;
4704 enum XML_Error result;
4705 OPEN_INTERNAL_ENTITY openEntity;
4706
4707 entity->open = 1;
4708 openEntity.next = openInternalEntities;
4709 openInternalEntities = &openEntity;
4710 openEntity.entity = entity;
4711 openEntity.internalEventPtr = 0;
4712 openEntity.internalEventEndPtr = 0;
4713 s = (char *)entity->textPtr;
4714 end = (char *)(entity->textPtr + entity->textLen);
4715 tok = XmlPrologTok(internalEncoding, s, end, &next);
4716 result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
4717 entity->open = 0;
4718 openInternalEntities = openEntity.next;
4719 return result;
4720}
4721
4722#endif /* XML_DTD */
4723
4724static enum XML_Error errorProcessor(XML_Parser parser,
4725 const char *s,
4726 const char *end,
4727 const char **nextPtr)
4728{
4729 return errorCode;
4730}
4731
4732static enum XML_Error storeAttributeValue(XML_Parser parser,
4733 const ENCODING * enc,
4734 int isCdata,
4735 const char *ptr,
4736 const char *end,
4737 STRING_POOL * pool)
4738{
4739 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
4740
4741 if (result)
4742 return result;
4743 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4744 poolChop(pool);
4745 if (!poolAppendChar(pool, XML_T('\0')))
4746 return XML_ERROR_NO_MEMORY;
4747 return XML_ERROR_NONE;
4748}
4749
4750static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING * enc, int isCdata,
4751 const char *ptr, const char *end,
4752 STRING_POOL * pool)
4753{
4754 for (;;)
4755 {
4756 const char *next;
4757 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4758
4759 switch (tok)
4760 {
4761 case XML_TOK_NONE:
4762 return XML_ERROR_NONE;
4763 case XML_TOK_INVALID:
4764 if (enc == encoding)
4765 eventPtr = next;
4766 return XML_ERROR_INVALID_TOKEN;
4767 case XML_TOK_PARTIAL:
4768 if (enc == encoding)
4769 eventPtr = ptr;
4770 return XML_ERROR_INVALID_TOKEN;
4771 case XML_TOK_CHAR_REF:
4772 {
4773 XML_Char buf[XML_ENCODE_MAX];
4774 int i;
4775 int n = XmlCharRefNumber(enc, ptr);
4776
4777 if (n < 0)
4778 {
4779 if (enc == encoding)
4780 eventPtr = ptr;
4781 return XML_ERROR_BAD_CHAR_REF;
4782 }
4783 if (!isCdata
4784 && n == 0x20 /* space */
4785 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4786 break;
4787 n = XmlEncode(n, (ICHAR*)buf);
4788 if (!n)
4789 {
4790 if (enc == encoding)
4791 eventPtr = ptr;
4792 return XML_ERROR_BAD_CHAR_REF;
4793 }
4794 for (i = 0; i < n; i++)
4795 {
4796 if (!poolAppendChar(pool, buf[i]))
4797 return XML_ERROR_NO_MEMORY;
4798 }
4799 }
4800 break;
4801 case XML_TOK_DATA_CHARS:
4802 if (!poolAppend(pool, enc, ptr, next))
4803 return XML_ERROR_NO_MEMORY;
4804 break;
4805 case XML_TOK_TRAILING_CR:
4806 next = ptr + enc->minBytesPerChar;
4807 /* fall through */
4808 case XML_TOK_ATTRIBUTE_VALUE_S:
4809 case XML_TOK_DATA_NEWLINE:
4810 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4811 break;
4812 if (!poolAppendChar(pool, 0x20))
4813 return XML_ERROR_NO_MEMORY;
4814 break;
4815 case XML_TOK_ENTITY_REF:
4816 {
4817 const XML_Char *name;
4818 ENTITY *entity;
4819 XML_Char ch = XmlPredefinedEntityName(enc,
4820 ptr + enc->minBytesPerChar,
4821 next - enc->minBytesPerChar);
4822
4823 if (ch)
4824 {
4825 if (!poolAppendChar(pool, ch))
4826 return XML_ERROR_NO_MEMORY;
4827 break;
4828 }
4829 name = poolStoreString(&temp2Pool, enc,
4830 ptr + enc->minBytesPerChar,
4831 next - enc->minBytesPerChar);
4832 if (!name)
4833 return XML_ERROR_NO_MEMORY;
4834 entity = (ENTITY*)lookup(&dtd.generalEntities, name, 0);
4835 poolDiscard(&temp2Pool);
4836 if (!entity)
4837 {
4838 if (dtd.complete)
4839 {
4840 if (enc == encoding)
4841 eventPtr = ptr;
4842 return XML_ERROR_UNDEFINED_ENTITY;
4843 }
4844 }
4845 else if (entity->open)
4846 {
4847 if (enc == encoding)
4848 eventPtr = ptr;
4849 return XML_ERROR_RECURSIVE_ENTITY_REF;
4850 }
4851 else if (entity->notation)
4852 {
4853 if (enc == encoding)
4854 eventPtr = ptr;
4855 return XML_ERROR_BINARY_ENTITY_REF;
4856 }
4857 else if (!entity->textPtr)
4858 {
4859 if (enc == encoding)
4860 eventPtr = ptr;
4861 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4862 }
4863 else
4864 {
4865 enum XML_Error result;
4866 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4867
4868 entity->open = 1;
4869 result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
4870 entity->open = 0;
4871 if (result)
4872 return result;
4873 }
4874 }
4875 break;
4876 default:
4877 if (enc == encoding)
4878 eventPtr = ptr;
4879 return XML_ERROR_UNEXPECTED_STATE;
4880 }
4881 ptr = next;
4882 }
4883 /* not reached */
4884}
4885
4886static enum XML_Error storeEntityValue(XML_Parser parser,
4887 const ENCODING * enc,
4888 const char *entityTextPtr,
4889 const char *entityTextEnd)
4890{
4891 STRING_POOL *pool = &(dtd.pool);
4892
4893 for (;;)
4894 {
4895 const char *next;
4896 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4897
4898 switch (tok)
4899 {
4900 case XML_TOK_PARAM_ENTITY_REF:
4901#ifdef XML_DTD
4902 if (parentParser || enc != encoding)
4903 {
4904 enum XML_Error result;
4905 const XML_Char *name;
4906 ENTITY *entity;
4907
4908 name = poolStoreString(&tempPool, enc,
4909 entityTextPtr + enc->minBytesPerChar,
4910 next - enc->minBytesPerChar);
4911 if (!name)
4912 return XML_ERROR_NO_MEMORY;
4913 entity = (ENTITY*)lookup(&dtd.paramEntities, name, 0);
4914 poolDiscard(&tempPool);
4915 if (!entity)
4916 {
4917 if (enc == encoding)
4918 eventPtr = entityTextPtr;
4919 return XML_ERROR_UNDEFINED_ENTITY;
4920 }
4921 if (entity->open)
4922 {
4923 if (enc == encoding)
4924 eventPtr = entityTextPtr;
4925 return XML_ERROR_RECURSIVE_ENTITY_REF;
4926 }
4927 if (entity->systemId)
4928 {
4929 if (enc == encoding)
4930 eventPtr = entityTextPtr;
4931 return XML_ERROR_PARAM_ENTITY_REF;
4932 }
4933 entity->open = 1;
4934 result = storeEntityValue(parser,
4935 internalEncoding,
4936 (char *)entity->textPtr,
4937 (char *)(entity->textPtr + entity->textLen));
4938 entity->open = 0;
4939 if (result)
4940 return result;
4941 break;
4942 }
4943#endif /* XML_DTD */
4944 eventPtr = entityTextPtr;
4945 return XML_ERROR_SYNTAX;
4946 case XML_TOK_NONE:
4947 return XML_ERROR_NONE;
4948 case XML_TOK_ENTITY_REF:
4949 case XML_TOK_DATA_CHARS:
4950 if (!poolAppend(pool, enc, entityTextPtr, next))
4951 return XML_ERROR_NO_MEMORY;
4952 break;
4953 case XML_TOK_TRAILING_CR:
4954 next = entityTextPtr + enc->minBytesPerChar;
4955 /* fall through */
4956 case XML_TOK_DATA_NEWLINE:
4957 if (pool->end == pool->ptr && !poolGrow(pool))
4958 return XML_ERROR_NO_MEMORY;
4959 *(pool->ptr)++ = 0xA;
4960 break;
4961 case XML_TOK_CHAR_REF:
4962 {
4963 XML_Char buf[XML_ENCODE_MAX];
4964 int i;
4965 int n = XmlCharRefNumber(enc, entityTextPtr);
4966
4967 if (n < 0)
4968 {
4969 if (enc == encoding)
4970 eventPtr = entityTextPtr;
4971 return XML_ERROR_BAD_CHAR_REF;
4972 }
4973 n = XmlEncode(n, (ICHAR*)buf);
4974 if (!n)
4975 {
4976 if (enc == encoding)
4977 eventPtr = entityTextPtr;
4978 return XML_ERROR_BAD_CHAR_REF;
4979 }
4980 for (i = 0; i < n; i++)
4981 {
4982 if (pool->end == pool->ptr && !poolGrow(pool))
4983 return XML_ERROR_NO_MEMORY;
4984 *(pool->ptr)++ = buf[i];
4985 }
4986 }
4987 break;
4988 case XML_TOK_PARTIAL:
4989 if (enc == encoding)
4990 eventPtr = entityTextPtr;
4991 return XML_ERROR_INVALID_TOKEN;
4992 case XML_TOK_INVALID:
4993 if (enc == encoding)
4994 eventPtr = next;
4995 return XML_ERROR_INVALID_TOKEN;
4996 default:
4997 if (enc == encoding)
4998 eventPtr = entityTextPtr;
4999 return XML_ERROR_UNEXPECTED_STATE;
5000 }
5001 entityTextPtr = next;
5002 }
5003 /* not reached */
5004}
5005
5006static void normalizeLines(XML_Char * s)
5007{
5008 XML_Char *p;
5009
5010 for (;; s++)
5011 {
5012 if (*s == XML_T('\0'))
5013 return;
5014 if (*s == 0xD)
5015 break;
5016 }
5017 p = s;
5018 do
5019 {
5020 if (*s == 0xD)
5021 {
5022 *p++ = 0xA;
5023 if (*++s == 0xA)
5024 s++;
5025 }
5026 else
5027 *p++ = *s++;
5028 }
5029 while (*s);
5030 *p = XML_T('\0');
5031}
5032
5033static int reportProcessingInstruction(XML_Parser parser, const ENCODING * enc, const char *start, const char *end)
5034{
5035 const XML_Char *target;
5036 XML_Char *data;
5037 const char *tem;
5038
5039 if (!processingInstructionHandler)
5040 {
5041 if (defaultHandler)
5042 reportDefault(parser, enc, start, end);
5043 return 1;
5044 }
5045 start += enc->minBytesPerChar * 2;
5046 tem = start + XmlNameLength(enc, start);
5047 target = poolStoreString(&tempPool, enc, start, tem);
5048 if (!target)
5049 return 0;
5050 poolFinish(&tempPool);
5051 data = poolStoreString(&tempPool, enc,
5052 XmlSkipS(enc, tem),
5053 end - enc->minBytesPerChar * 2);
5054 if (!data)
5055 return 0;
5056 normalizeLines(data);
5057 processingInstructionHandler(handlerArg, target, data);
5058 poolClear(&tempPool);
5059 return 1;
5060}
5061
5062static int reportComment(XML_Parser parser, const ENCODING * enc, const char *start, const char *end)
5063{
5064 XML_Char *data;
5065
5066 if (!commentHandler)
5067 {
5068 if (defaultHandler)
5069 reportDefault(parser, enc, start, end);
5070 return 1;
5071 }
5072 data = poolStoreString(&tempPool,
5073 enc,
5074 start + enc->minBytesPerChar * 4,
5075 end - enc->minBytesPerChar * 3);
5076 if (!data)
5077 return 0;
5078 normalizeLines(data);
5079 commentHandler(handlerArg, data);
5080 poolClear(&tempPool);
5081 return 1;
5082}
5083
5084static void reportDefault(XML_Parser parser, const ENCODING * enc, const char *s, const char *end)
5085{
5086 if (MUST_CONVERT(enc, s))
5087 {
5088 const char **eventPP;
5089 const char **eventEndPP;
5090
5091 if (enc == encoding)
5092 {
5093 eventPP = &eventPtr;
5094 eventEndPP = &eventEndPtr;
5095 }
5096 else
5097 {
5098 eventPP = &(openInternalEntities->internalEventPtr);
5099 eventEndPP = &(openInternalEntities->internalEventEndPtr);
5100 }
5101 do
5102 {
5103 ICHAR *dataPtr = (ICHAR*)dataBuf;
5104
5105 XmlConvert(enc, &s, end, &dataPtr, (ICHAR*)dataBufEnd);
5106 *eventEndPP = s;
5107 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR*)dataBuf);
5108 *eventPP = s;
5109 }
5110 while (s != end);
5111 }
5112 else
5113 defaultHandler(handlerArg, (XML_Char*)s, (XML_Char*)end - (XML_Char*)s);
5114}
5115
5116
5117static int defineAttribute(ELEMENT_TYPE * type, ATTRIBUTE_ID * attId, int isCdata,
5118 int isId, const XML_Char * value, XML_Parser parser)
5119{
5120 DEFAULT_ATTRIBUTE *att;
5121
5122 if (value || isId)
5123 {
5124 /* The handling of default attributes gets messed up if we have
5125 * a default which duplicates a non-default. */
5126 int i;
5127
5128 for (i = 0; i < type->nDefaultAtts; i++)
5129 if (attId == type->defaultAtts[i].id)
5130 return 1;
5131 if (isId && !type->idAtt && !attId->xmlns)
5132 type->idAtt = attId;
5133 }
5134 if (type->nDefaultAtts == type->allocDefaultAtts)
5135 {
5136 if (type->allocDefaultAtts == 0)
5137 {
5138 type->allocDefaultAtts = 8;
5139 type->defaultAtts = (PDEFAULT_ATTRIBUTE)MALLOC(type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5140 }
5141 else
5142 {
5143 type->allocDefaultAtts *= 2;
5144 type->defaultAtts = (PDEFAULT_ATTRIBUTE)REALLOC(type->defaultAtts,
5145 type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5146 }
5147 if (!type->defaultAtts)
5148 return 0;
5149 }
5150 att = type->defaultAtts + type->nDefaultAtts;
5151 att->id = attId;
5152 att->value = value;
5153 att->isCdata = isCdata;
5154 if (!isCdata)
5155 attId->maybeTokenized = 1;
5156 type->nDefaultAtts += 1;
5157 return 1;
5158}
5159
5160static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE * elementType)
5161{
5162 const XML_Char *name;
5163
5164 for (name = elementType->name; *name; name++)
5165 {
5166 if (*name == XML_T(':'))
5167 {
5168 PREFIX *prefix;
5169 const XML_Char *s;
5170
5171 for (s = elementType->name; s != name; s++)
5172 {
5173 if (!poolAppendChar(&dtd.pool, *s))
5174 return 0;
5175 }
5176 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
5177 return 0;
5178 prefix = (PREFIX*)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
5179 if (!prefix)
5180 return 0;
5181 if (prefix->name == poolStart(&dtd.pool))
5182 poolFinish(&dtd.pool);
5183 else
5184 poolDiscard(&dtd.pool);
5185 elementType->prefix = prefix;
5186
5187 }
5188 }
5189 return 1;
5190}
5191
5192static ATTRIBUTE_ID* getAttributeId(XML_Parser parser, const ENCODING * enc, const char *start, const char *end)
5193{
5194 ATTRIBUTE_ID *id;
5195 const XML_Char *name;
5196
5197 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
5198 return 0;
5199 name = poolStoreString(&dtd.pool, enc, start, end);
5200 if (!name)
5201 return 0;
5202 ++name;
5203 id = (ATTRIBUTE_ID*)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
5204 if (!id)
5205 return 0;
5206 if (id->name != name)
5207 poolDiscard(&dtd.pool);
5208 else
5209 {
5210 poolFinish(&dtd.pool);
5211 if (!ns)
5212 ;
5213 else if (name[0] == 'x'
5214 && name[1] == 'm'
5215 && name[2] == 'l'
5216 && name[3] == 'n'
5217 && name[4] == 's'
5218 && (name[5] == XML_T('\0') || name[5] == XML_T(':')))
5219 {
5220 if (name[5] == '\0')
5221 id->prefix = &dtd.defaultPrefix;
5222 else
5223 id->prefix = (PREFIX*)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
5224 id->xmlns = 1;
5225 }
5226 else
5227 {
5228 int i;
5229
5230 for (i = 0; name[i]; i++)
5231 {
5232 if (name[i] == XML_T(':'))
5233 {
5234 int j;
5235
5236 for (j = 0; j < i; j++)
5237 {
5238 if (!poolAppendChar(&dtd.pool, name[j]))
5239 return 0;
5240 }
5241 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
5242 return 0;
5243 id->prefix = (PREFIX*)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
5244 if (id->prefix->name == poolStart(&dtd.pool))
5245 poolFinish(&dtd.pool);
5246 else
5247 poolDiscard(&dtd.pool);
5248 break;
5249 }
5250 }
5251 }
5252 }
5253 return id;
5254}
5255
5256#define CONTEXT_SEP XML_T('\f')
5257
5258static const XML_Char *getContext(XML_Parser parser)
5259{
5260 HASH_TABLE_ITER iter;
5261 int needSep = 0;
5262
5263 if (dtd.defaultPrefix.binding)
5264 {
5265 int i;
5266 int len;
5267
5268 if (!poolAppendChar(&tempPool, XML_T('=')))
5269 return 0;
5270 len = dtd.defaultPrefix.binding->uriLen;
5271 if (namespaceSeparator != XML_T('\0'))
5272 len--;
5273 for (i = 0; i < len; i++)
5274 if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
5275 return 0;
5276 needSep = 1;
5277 }
5278
5279 hashTableIterInit(&iter, &(dtd.prefixes));
5280 for (;;)
5281 {
5282 int i;
5283 int len;
5284 const XML_Char *s;
5285 PREFIX *prefix = (PREFIX*)hashTableIterNext(&iter);
5286
5287 if (!prefix)
5288 break;
5289 if (!prefix->binding)
5290 continue;
5291 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5292 return 0;
5293 for (s = prefix->name; *s; s++)
5294 if (!poolAppendChar(&tempPool, *s))
5295 return 0;
5296 if (!poolAppendChar(&tempPool, XML_T('=')))
5297 return 0;
5298 len = prefix->binding->uriLen;
5299 if (namespaceSeparator != XML_T('\0'))
5300 len--;
5301 for (i = 0; i < len; i++)
5302 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
5303 return 0;
5304 needSep = 1;
5305 }
5306
5307
5308 hashTableIterInit(&iter, &(dtd.generalEntities));
5309 for (;;)
5310 {
5311 const XML_Char *s;
5312 ENTITY *e = (ENTITY*)hashTableIterNext(&iter);
5313
5314 if (!e)
5315 break;
5316 if (!e->open)
5317 continue;
5318 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5319 return 0;
5320 for (s = e->name; *s; s++)
5321 if (!poolAppendChar(&tempPool, *s))
5322 return 0;
5323 needSep = 1;
5324 }
5325
5326 if (!poolAppendChar(&tempPool, XML_T('\0')))
5327 return 0;
5328 return tempPool.start;
5329}
5330
5331static int setContext(XML_Parser parser, const XML_Char * context)
5332{
5333 const XML_Char *s = context;
5334
5335 while (*context != XML_T('\0'))
5336 {
5337 if (*s == CONTEXT_SEP || *s == XML_T('\0'))
5338 {
5339 ENTITY *e;
5340
5341 if (!poolAppendChar(&tempPool, XML_T('\0')))
5342 return 0;
5343 e = (ENTITY*)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
5344 if (e)
5345 e->open = 1;
5346 if (*s != XML_T('\0'))
5347 s++;
5348 context = s;
5349 poolDiscard(&tempPool);
5350 }
5351 else if (*s == '=')
5352 {
5353 PREFIX *prefix;
5354
5355 if (poolLength(&tempPool) == 0)
5356 prefix = &dtd.defaultPrefix;
5357 else
5358 {
5359 if (!poolAppendChar(&tempPool, XML_T('\0')))
5360 return 0;
5361 prefix = (PREFIX*)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
5362 if (!prefix)
5363 return 0;
5364 if (prefix->name == poolStart(&tempPool))
5365 {
5366 prefix->name = poolCopyString(&dtd.pool, prefix->name);
5367 if (!prefix->name)
5368 return 0;
5369 }
5370 poolDiscard(&tempPool);
5371 }
5372 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
5373 if (!poolAppendChar(&tempPool, *context))
5374 return 0;
5375 if (!poolAppendChar(&tempPool, XML_T('\0')))
5376 return 0;
5377 if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
5378 return 0;
5379 poolDiscard(&tempPool);
5380 if (*context != XML_T('\0'))
5381 ++context;
5382 s = context;
5383 }
5384 else
5385 {
5386 if (!poolAppendChar(&tempPool, *s))
5387 return 0;
5388 s++;
5389 }
5390 }
5391 return 1;
5392}
5393
5394
5395static void normalizePublicId(XML_Char * publicId)
5396{
5397 XML_Char *p = publicId;
5398 XML_Char *s;
5399
5400 for (s = publicId; *s; s++)
5401 {
5402 switch (*s)
5403 {
5404 case 0x20:
5405 case 0xD:
5406 case 0xA:
5407 if (p != publicId && p[-1] != 0x20)
5408 *p++ = 0x20;
5409 break;
5410 default:
5411 *p++ = *s;
5412 }
5413 }
5414 if (p != publicId && p[-1] == 0x20)
5415 --p;
5416 *p = XML_T('\0');
5417}
5418
5419static int dtdInit(DTD * p, XML_Parser parser)
5420{
5421 XML_Memory_Handling_Suite *ms = &((Parser*)parser)->m_mem;
5422
5423 poolInit(&(p->pool), ms);
5424 hashTableInit(&(p->generalEntities), ms);
5425 hashTableInit(&(p->elementTypes), ms);
5426 hashTableInit(&(p->attributeIds), ms);
5427 hashTableInit(&(p->prefixes), ms);
5428 p->complete = 1;
5429 p->standalone = 0;
5430#ifdef XML_DTD
5431 hashTableInit(&(p->paramEntities), ms);
5432#endif /* XML_DTD */
5433 p->defaultPrefix.name = 0;
5434 p->defaultPrefix.binding = 0;
5435
5436 p->in_eldecl = 0;
5437 p->scaffIndex = 0;
5438 p->scaffLevel = 0;
5439 p->scaffold = 0;
5440 p->contentStringLen = 0;
5441 p->scaffSize = 0;
5442 p->scaffCount = 0;
5443
5444 return 1;
5445}
5446
5447#ifdef XML_DTD
5448
5449static void dtdSwap(DTD * p1, DTD * p2)
5450{
5451 DTD tem;
5452
5453 memcpy(&tem, p1, sizeof(DTD));
5454 memcpy(p1, p2, sizeof(DTD));
5455 memcpy(p2, &tem, sizeof(DTD));
5456}
5457
5458#endif /* XML_DTD */
5459
5460static void dtdDestroy(DTD * p, XML_Parser parser)
5461{
5462 HASH_TABLE_ITER iter;
5463
5464 hashTableIterInit(&iter, &(p->elementTypes));
5465 for (;;)
5466 {
5467 ELEMENT_TYPE *e = (ELEMENT_TYPE*)hashTableIterNext(&iter);
5468
5469 if (!e)
5470 break;
5471 if (e->allocDefaultAtts != 0)
5472 FREE(e->defaultAtts);
5473 }
5474 hashTableDestroy(&(p->generalEntities));
5475#ifdef XML_DTD
5476 hashTableDestroy(&(p->paramEntities));
5477#endif /* XML_DTD */
5478 hashTableDestroy(&(p->elementTypes));
5479 hashTableDestroy(&(p->attributeIds));
5480 hashTableDestroy(&(p->prefixes));
5481 poolDestroy(&(p->pool));
5482 if (p->scaffIndex)
5483 FREE(p->scaffIndex);
5484 if (p->scaffold)
5485 FREE(p->scaffold);
5486}
5487
5488/* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.
5489 * The new DTD has already been initialized. */
5490
5491static int dtdCopy(DTD * newDtd, const DTD * oldDtd, XML_Parser parser)
5492{
5493 HASH_TABLE_ITER iter;
5494
5495 /* Copy the prefix table. */
5496
5497 hashTableIterInit(&iter, &(oldDtd->prefixes));
5498 for (;;)
5499 {
5500 const XML_Char *name;
5501 const PREFIX *oldP = (PREFIX*)hashTableIterNext(&iter);
5502
5503 if (!oldP)
5504 break;
5505 name = poolCopyString(&(newDtd->pool), oldP->name);
5506 if (!name)
5507 return 0;
5508 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5509 return 0;
5510 }
5511
5512 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5513
5514 /* Copy the attribute id table. */
5515
5516 for (;;)
5517 {
5518 ATTRIBUTE_ID *newA;
5519 const XML_Char *name;
5520 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID*)hashTableIterNext(&iter);
5521
5522 if (!oldA)
5523 break;
5524 /* Remember to allocate the scratch byte before the name. */
5525 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5526 return 0;
5527 name = poolCopyString(&(newDtd->pool), oldA->name);
5528 if (!name)
5529 return 0;
5530 ++name;
5531 newA = (ATTRIBUTE_ID*)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
5532 if (!newA)
5533 return 0;
5534 newA->maybeTokenized = oldA->maybeTokenized;
5535 if (oldA->prefix)
5536 {
5537 newA->xmlns = oldA->xmlns;
5538 if (oldA->prefix == &oldDtd->defaultPrefix)
5539 newA->prefix = &newDtd->defaultPrefix;
5540 else
5541 newA->prefix = (PREFIX*)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
5542 }
5543 }
5544
5545 /* Copy the element type table. */
5546
5547 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5548
5549 for (;;)
5550 {
5551 int i;
5552 ELEMENT_TYPE *newE;
5553 const XML_Char *name;
5554 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE*)hashTableIterNext(&iter);
5555
5556 if (!oldE)
5557 break;
5558 name = poolCopyString(&(newDtd->pool), oldE->name);
5559 if (!name)
5560 return 0;
5561 newE = (ELEMENT_TYPE*)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
5562 if (!newE)
5563 return 0;
5564 if (oldE->nDefaultAtts)
5565 {
5566 newE->defaultAtts = (DEFAULT_ATTRIBUTE*)MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5567 if (!newE->defaultAtts)
5568 return 0;
5569 }
5570 if (oldE->idAtt)
5571 newE->idAtt = (ATTRIBUTE_ID*)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
5572 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5573 if (oldE->prefix)
5574 newE->prefix = (PREFIX*)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
5575 for (i = 0; i < newE->nDefaultAtts; i++)
5576 {
5577 newE->defaultAtts[i].id = (ATTRIBUTE_ID*)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5578 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5579 if (oldE->defaultAtts[i].value)
5580 {
5581 newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5582 if (!newE->defaultAtts[i].value)
5583 return 0;
5584 }
5585 else
5586 newE->defaultAtts[i].value = 0;
5587 }
5588 }
5589
5590 /* Copy the entity tables. */
5591 if (!copyEntityTable(&(newDtd->generalEntities),
5592 &(newDtd->pool),
5593 &(oldDtd->generalEntities), parser))
5594 return 0;
5595
5596#ifdef XML_DTD
5597 if (!copyEntityTable(&(newDtd->paramEntities),
5598 &(newDtd->pool),
5599 &(oldDtd->paramEntities), parser))
5600 return 0;
5601#endif /* XML_DTD */
5602
5603 newDtd->complete = oldDtd->complete;
5604 newDtd->standalone = oldDtd->standalone;
5605
5606 /* Don't want deep copying for scaffolding */
5607 newDtd->in_eldecl = oldDtd->in_eldecl;
5608 newDtd->scaffold = oldDtd->scaffold;
5609 newDtd->contentStringLen = oldDtd->contentStringLen;
5610 newDtd->scaffSize = oldDtd->scaffSize;
5611 newDtd->scaffLevel = oldDtd->scaffLevel;
5612 newDtd->scaffIndex = oldDtd->scaffIndex;
5613
5614 return 1;
5615} /* End dtdCopy */
5616
5617static int copyEntityTable(HASH_TABLE * newTable,
5618 STRING_POOL * newPool,
5619 const HASH_TABLE * oldTable,
5620 XML_Parser parser)
5621{
5622 HASH_TABLE_ITER iter;
5623 const XML_Char *cachedOldBase = 0;
5624 const XML_Char *cachedNewBase = 0;
5625
5626 hashTableIterInit(&iter, oldTable);
5627
5628 for (;;)
5629 {
5630 ENTITY *newE;
5631 const XML_Char *name;
5632 const ENTITY *oldE = (ENTITY*)hashTableIterNext(&iter);
5633
5634 if (!oldE)
5635 break;
5636 name = poolCopyString(newPool, oldE->name);
5637 if (!name)
5638 return 0;
5639 newE = (ENTITY*)lookup(newTable, name, sizeof(ENTITY));
5640 if (!newE)
5641 return 0;
5642 if (oldE->systemId)
5643 {
5644 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5645
5646 if (!tem)
5647 return 0;
5648 newE->systemId = tem;
5649 if (oldE->base)
5650 {
5651 if (oldE->base == cachedOldBase)
5652 newE->base = cachedNewBase;
5653 else
5654 {
5655 cachedOldBase = oldE->base;
5656 tem = poolCopyString(newPool, cachedOldBase);
5657 if (!tem)
5658 return 0;
5659 cachedNewBase = newE->base = tem;
5660 }
5661 }
5662 }
5663 else
5664 {
5665 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
5666
5667 if (!tem)
5668 return 0;
5669 newE->textPtr = tem;
5670 newE->textLen = oldE->textLen;
5671 }
5672 if (oldE->notation)
5673 {
5674 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5675
5676 if (!tem)
5677 return 0;
5678 newE->notation = tem;
5679 }
5680 }
5681 return 1;
5682}
5683
5684#define INIT_SIZE 64
5685
5686static int keyeq(KEY s1, KEY s2)
5687{
5688 for (; *s1 == *s2; s1++, s2++)
5689 if (*s1 == 0)
5690 return 1;
5691 return 0;
5692}
5693
5694static unsigned long hash(KEY s)
5695{
5696 unsigned long h = 0;
5697
5698 while (*s)
5699 h = (h << 5) + h + (unsigned char)*s++;
5700 return h;
5701}
5702
5703static NAMED *lookup(HASH_TABLE * table, KEY name, size_t createSize)
5704{
5705 size_t i;
5706
5707 if (table->size == 0)
5708 {
5709 size_t tsize;
5710
5711 if (!createSize)
5712 return 0;
5713 tsize = INIT_SIZE * sizeof(NAMED *);
5714 table->v = (NAMED**)table->mem->malloc_fcn(tsize);
5715 if (!table->v)
5716 return 0;
5717 memset(table->v, 0, tsize);
5718 table->size = INIT_SIZE;
5719 table->usedLim = INIT_SIZE / 2;
5720 i = hash(name) & (table->size - 1);
5721 }
5722 else
5723 {
5724 unsigned long h = hash(name);
5725
5726 for (i = h & (table->size - 1);
5727 table->v[i];
5728 i == 0 ? i = table->size - 1 : --i)
5729 {
5730 if (keyeq(name, table->v[i]->name))
5731 return table->v[i];
5732 }
5733 if (!createSize)
5734 return 0;
5735 if (table->used == table->usedLim)
5736 {
5737 /* check for overflow */
5738 size_t newSize = table->size * 2;
5739 size_t tsize = newSize * sizeof(NAMED *);
5740 NAMED **newV = (NAMED**)table->mem->malloc_fcn(tsize);
5741
5742 if (!newV)
5743 return 0;
5744 memset(newV, 0, tsize);
5745 for (i = 0; i < table->size; i++)
5746 if (table->v[i])
5747 {
5748 size_t j;
5749
5750 for (j = hash(table->v[i]->name) & (newSize - 1);
5751 newV[j];
5752 j == 0 ? j = newSize - 1 : --j)
5753 ;
5754 newV[j] = table->v[i];
5755 }
5756 table->mem->free_fcn(table->v);
5757 table->v = newV;
5758 table->size = newSize;
5759 table->usedLim = newSize / 2;
5760 for (i = h & (table->size - 1);
5761 table->v[i];
5762 i == 0 ? i = table->size - 1 : --i)
5763 ;
5764 }
5765 }
5766 table->v[i] = (NAMED*)table->mem->malloc_fcn(createSize);
5767 if (!table->v[i])
5768 return 0;
5769 memset(table->v[i], 0, createSize);
5770 table->v[i]->name = name;
5771 (table->used)++;
5772 return table->v[i];
5773}
5774
5775static void hashTableDestroy(HASH_TABLE * table)
5776{
5777 size_t i;
5778
5779 for (i = 0; i < table->size; i++)
5780 {
5781 NAMED *p = table->v[i];
5782
5783 if (p)
5784 table->mem->free_fcn(p);
5785 }
5786 if (table->v)
5787 table->mem->free_fcn(table->v);
5788}
5789
5790static void hashTableInit(HASH_TABLE * p, XML_Memory_Handling_Suite * ms)
5791{
5792 p->size = 0;
5793 p->usedLim = 0;
5794 p->used = 0;
5795 p->v = 0;
5796 p->mem = ms;
5797}
5798
5799static void hashTableIterInit(HASH_TABLE_ITER * iter, const HASH_TABLE * table)
5800{
5801 iter->p = table->v;
5802 iter->end = iter->p + table->size;
5803}
5804
5805static NAMED* hashTableIterNext(HASH_TABLE_ITER * iter)
5806{
5807 while (iter->p != iter->end)
5808 {
5809 NAMED *tem = *(iter->p)++;
5810
5811 if (tem)
5812 return tem;
5813 }
5814 return 0;
5815}
5816
5817
5818static void poolInit(STRING_POOL * pool, XML_Memory_Handling_Suite * ms)
5819{
5820 pool->blocks = 0;
5821 pool->freeBlocks = 0;
5822 pool->start = 0;
5823 pool->ptr = 0;
5824 pool->end = 0;
5825 pool->mem = ms;
5826}
5827
5828static void poolClear(STRING_POOL * pool)
5829{
5830 if (!pool->freeBlocks)
5831 pool->freeBlocks = pool->blocks;
5832 else
5833 {
5834 BLOCK *p = pool->blocks;
5835
5836 while (p)
5837 {
5838 BLOCK *tem = p->next;
5839
5840 p->next = pool->freeBlocks;
5841 pool->freeBlocks = p;
5842 p = tem;
5843 }
5844 }
5845 pool->blocks = 0;
5846 pool->start = 0;
5847 pool->ptr = 0;
5848 pool->end = 0;
5849}
5850
5851static void poolDestroy(STRING_POOL * pool)
5852{
5853 BLOCK *p = pool->blocks;
5854
5855 while (p)
5856 {
5857 BLOCK *tem = p->next;
5858
5859 pool->mem->free_fcn(p);
5860 p = tem;
5861 }
5862 pool->blocks = 0;
5863 p = pool->freeBlocks;
5864 while (p)
5865 {
5866 BLOCK *tem = p->next;
5867
5868 pool->mem->free_fcn(p);
5869 p = tem;
5870 }
5871 pool->freeBlocks = 0;
5872 pool->ptr = 0;
5873 pool->start = 0;
5874 pool->end = 0;
5875}
5876
5877static XML_Char *poolAppend(STRING_POOL * pool, const ENCODING * enc,
5878 const char *ptr, const char *end)
5879{
5880 if (!pool->ptr && !poolGrow(pool))
5881 return 0;
5882 for (;;)
5883 {
5884 XmlConvert(enc, &ptr, end, (ICHAR **) & (pool->ptr), (ICHAR*)pool->end);
5885 if (ptr == end)
5886 break;
5887 if (!poolGrow(pool))
5888 return 0;
5889 }
5890 return pool->start;
5891}
5892
5893static const XML_Char *poolCopyString(STRING_POOL * pool, const XML_Char * s)
5894{
5895 do
5896 {
5897 if (!poolAppendChar(pool, *s))
5898 return 0;
5899 }
5900 while (*s++);
5901 s = pool->start;
5902 poolFinish(pool);
5903 return s;
5904}
5905
5906static const XML_Char *poolCopyStringN(STRING_POOL * pool, const XML_Char * s, int n)
5907{
5908 if (!pool->ptr && !poolGrow(pool))
5909 return 0;
5910 for (; n > 0; --n, s++)
5911 {
5912 if (!poolAppendChar(pool, *s))
5913 return 0;
5914
5915 }
5916 s = pool->start;
5917 poolFinish(pool);
5918 return s;
5919}
5920
5921static const XML_Char* poolAppendString(STRING_POOL * pool, const XML_Char * s)
5922{
5923 while (*s)
5924 {
5925 if (!poolAppendChar(pool, *s))
5926 return 0;
5927 s++;
5928 }
5929 return pool->start;
5930} /* End poolAppendString */
5931
5932static XML_Char* poolStoreString(STRING_POOL * pool, const ENCODING * enc,
5933 const char *ptr, const char *end)
5934{
5935 if (!poolAppend(pool, enc, ptr, end))
5936 return 0;
5937 if (pool->ptr == pool->end && !poolGrow(pool))
5938 return 0;
5939 *(pool->ptr)++ = 0;
5940 return pool->start;
5941}
5942
5943static int poolGrow(STRING_POOL * pool)
5944{
5945 if (pool->freeBlocks)
5946 {
5947 if (pool->start == 0)
5948 {
5949 pool->blocks = pool->freeBlocks;
5950 pool->freeBlocks = pool->freeBlocks->next;
5951 pool->blocks->next = 0;
5952 pool->start = pool->blocks->s;
5953 pool->end = pool->start + pool->blocks->size;
5954 pool->ptr = pool->start;
5955 return 1;
5956 }
5957 if (pool->end - pool->start < pool->freeBlocks->size)
5958 {
5959 BLOCK *tem = pool->freeBlocks->next;
5960
5961 pool->freeBlocks->next = pool->blocks;
5962 pool->blocks = pool->freeBlocks;
5963 pool->freeBlocks = tem;
5964 memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
5965 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5966 pool->start = pool->blocks->s;
5967 pool->end = pool->start + pool->blocks->size;
5968 return 1;
5969 }
5970 }
5971 if (pool->blocks && pool->start == pool->blocks->s)
5972 {
5973 int blockSize = (pool->end - pool->start) * 2;
5974
5975 pool->blocks = (BLOCK*)pool->mem->realloc_fcn(pool->blocks,
5976 offsetof(BLOCK, s)
5977 + blockSize * sizeof(XML_Char));
5978 if (!pool->blocks)
5979 return 0;
5980 pool->blocks->size = blockSize;
5981 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
5982 pool->start = pool->blocks->s;
5983 pool->end = pool->start + blockSize;
5984 }
5985 else
5986 {
5987 BLOCK *tem;
5988 int blockSize = pool->end - pool->start;
5989
5990 if (blockSize < INIT_BLOCK_SIZE)
5991 blockSize = INIT_BLOCK_SIZE;
5992 else
5993 blockSize *= 2;
5994 tem = (BLOCK*)pool->mem->malloc_fcn(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
5995 if (!tem)
5996 return 0;
5997 tem->size = blockSize;
5998 tem->next = pool->blocks;
5999 pool->blocks = tem;
6000 if (pool->ptr != pool->start)
6001 memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
6002 pool->ptr = tem->s + (pool->ptr - pool->start);
6003 pool->start = tem->s;
6004 pool->end = tem->s + blockSize;
6005 }
6006 return 1;
6007}
6008
6009static int nextScaffoldPart(XML_Parser parser)
6010{
6011 CONTENT_SCAFFOLD *me;
6012 int next;
6013
6014 if (!dtd.scaffIndex)
6015 {
6016 dtd.scaffIndex = (int*)MALLOC(groupSize * sizeof(int));
6017
6018 if (!dtd.scaffIndex)
6019 return -1;
6020 dtd.scaffIndex[0] = 0;
6021 }
6022
6023 if (dtd.scaffCount >= dtd.scaffSize)
6024 {
6025 if (dtd.scaffold)
6026 {
6027 dtd.scaffSize *= 2;
6028 dtd.scaffold = (CONTENT_SCAFFOLD*)REALLOC(dtd.scaffold,
6029 dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
6030 }
6031 else
6032 {
6033 dtd.scaffSize = 32;
6034 dtd.scaffold = (CONTENT_SCAFFOLD*)MALLOC(dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
6035 }
6036 if (!dtd.scaffold)
6037 return -1;
6038 }
6039 next = dtd.scaffCount++;
6040 me = &dtd.scaffold[next];
6041 if (dtd.scaffLevel)
6042 {
6043 CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]];
6044
6045 if (parent->lastchild)
6046 {
6047 dtd.scaffold[parent->lastchild].nextsib = next;
6048 }
6049 if (!parent->childcnt)
6050 parent->firstchild = next;
6051 parent->lastchild = next;
6052 parent->childcnt++;
6053 }
6054 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6055 return next;
6056} /* End nextScaffoldPart */
6057
6058static void build_node(XML_Parser parser,
6059 int src_node,
6060 XML_Content * dest,
6061 XML_Content ** contpos,
6062 char **strpos)
6063{
6064 dest->type = dtd.scaffold[src_node].type;
6065 dest->quant = dtd.scaffold[src_node].quant;
6066 if (dest->type == XML_CTYPE_NAME)
6067 {
6068 const char *src;
6069
6070 dest->name = *strpos;
6071 src = dtd.scaffold[src_node].name;
6072 for (;;)
6073 {
6074 *(*strpos)++ = *src;
6075 if (!*src)
6076 break;
6077 src++;
6078 }
6079 dest->numchildren = 0;
6080 dest->children = 0;
6081 }
6082 else
6083 {
6084 unsigned int i;
6085 int cn;
6086
6087 dest->numchildren = dtd.scaffold[src_node].childcnt;
6088 dest->children = *contpos;
6089 *contpos += dest->numchildren;
6090 for (i = 0, cn = dtd.scaffold[src_node].firstchild;
6091 i < dest->numchildren;
6092 i++, cn = dtd.scaffold[cn].nextsib)
6093 {
6094 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6095 }
6096 dest->name = 0;
6097 }
6098} /* End build_node */
6099
6100static XML_Content * build_model(XML_Parser parser)
6101{
6102 XML_Content *ret;
6103 XML_Content *cpos;
6104 char *str;
6105 int allocsize = dtd.scaffCount * sizeof(XML_Content) + dtd.contentStringLen;
6106
6107 ret = (XML_Content*)MALLOC(allocsize);
6108 if (!ret)
6109 return 0;
6110
6111 str = (char *)(&ret[dtd.scaffCount]);
6112 cpos = &ret[1];
6113
6114 build_node(parser, 0, ret, &cpos, &str);
6115 return ret;
6116} /* End build_model */
6117
6118static ELEMENT_TYPE * getElementType(XML_Parser parser,
6119 const ENCODING * enc,
6120 const char *ptr,
6121 const char *end)
6122{
6123 const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
6124 ELEMENT_TYPE *ret;
6125
6126 if (!name)
6127 return 0;
6128 ret = (ELEMENT_TYPE*)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
6129 if (!ret)
6130 return 0;
6131 if (ret->name != name)
6132 poolDiscard(&dtd.pool);
6133 else
6134 {
6135 poolFinish(&dtd.pool);
6136 if (!setElementTypePrefix(parser, ret))
6137 return 0;
6138 }
6139 return ret;
6140} /* End getElementType */
6141
Note: See TracBrowser for help on using the repository browser.