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

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

misc updates

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