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

Last change on this file since 55 was 39, checked in by umoeller, 24 years ago

Misc. fixes.

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