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

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

Misc changes.

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