• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500-V1.0.1.40_1.0.68/ap/gpl/timemachine/gettext-0.17/gettext-tools/gnulib-lib/libxml/
1/*
2 * SAX2.c : Default SAX2 handler to build a tree.
3 *
4 * See Copyright for the status of this software.
5 *
6 * Daniel Veillard <daniel@veillard.com>
7 */
8
9
10#define IN_LIBXML
11#include "libxml.h"
12#include <stdlib.h>
13#include <string.h>
14#include <libxml/xmlmemory.h>
15#include <libxml/tree.h>
16#include <libxml/parser.h>
17#include <libxml/parserInternals.h>
18#include <libxml/valid.h>
19#include <libxml/entities.h>
20#include <libxml/xmlerror.h>
21#include <libxml/debugXML.h>
22#include <libxml/xmlIO.h>
23#include <libxml/SAX.h>
24#include <libxml/uri.h>
25#include <libxml/valid.h>
26#include <libxml/HTMLtree.h>
27#include <libxml/globals.h>
28
29/* #define DEBUG_SAX2 */
30/* #define DEBUG_SAX2_TREE */
31
32/**
33 * TODO:
34 *
35 * macro to flag unimplemented blocks
36 * XML_CATALOG_PREFER user env to select between system/public prefered
37 * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
38 *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
39 *> values "system" and "public".  I have made the default be "system" to
40 *> match yours.
41 */
42#define TODO 								\
43    xmlGenericError(xmlGenericErrorContext,				\
44	    "Unimplemented block at %s:%d\n",				\
45            __FILE__, __LINE__);
46
47/*
48 * xmlSAX2ErrMemory:
49 * @ctxt:  an XML validation parser context
50 * @msg:   a string to accompany the error message
51 */
52static void
53xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
54    if (ctxt != NULL) {
55	if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
56	    ctxt->sax->error(ctxt->userData, "%s: out of memory\n", msg);
57	ctxt->errNo = XML_ERR_NO_MEMORY;
58	ctxt->instate = XML_PARSER_EOF;
59	ctxt->disableSAX = 1;
60    }
61}
62
63/**
64 * xmlValidError:
65 * @ctxt:  an XML validation parser context
66 * @error:  the error number
67 * @msg:  the error message
68 * @str1:  extra data
69 * @str2:  extra data
70 *
71 * Handle a validation error
72 */
73static void
74xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
75            const char *msg, const char *str1, const char *str2)
76{
77    xmlStructuredErrorFunc schannel = NULL;
78
79    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
80        (ctxt->instate == XML_PARSER_EOF))
81	return;
82    if (ctxt != NULL) {
83	ctxt->errNo = error;
84	if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
85	    schannel = ctxt->sax->serror;
86	__xmlRaiseError(schannel,
87			ctxt->vctxt.error, ctxt->vctxt.userData,
88			ctxt, NULL, XML_FROM_DTD, error,
89			XML_ERR_ERROR, NULL, 0, (const char *) str1,
90			(const char *) str2, NULL, 0, 0,
91			msg, (const char *) str1, (const char *) str2);
92	ctxt->valid = 0;
93    } else {
94	__xmlRaiseError(schannel,
95			NULL, NULL,
96			ctxt, NULL, XML_FROM_DTD, error,
97			XML_ERR_ERROR, NULL, 0, (const char *) str1,
98			(const char *) str2, NULL, 0, 0,
99			msg, (const char *) str1, (const char *) str2);
100    }
101}
102
103/**
104 * xmlFatalErrMsg:
105 * @ctxt:  an XML parser context
106 * @error:  the error number
107 * @msg:  the error message
108 * @str1:  an error string
109 * @str2:  an error string
110 *
111 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
112 */
113static void
114xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
115               const char *msg, const xmlChar *str1, const xmlChar *str2)
116{
117    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
118        (ctxt->instate == XML_PARSER_EOF))
119	return;
120    if (ctxt != NULL)
121	ctxt->errNo = error;
122    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
123                    XML_ERR_FATAL, NULL, 0,
124		    (const char *) str1, (const char *) str2,
125		    NULL, 0, 0, msg, str1, str2);
126    if (ctxt != NULL) {
127	ctxt->wellFormed = 0;
128	ctxt->valid = 0;
129	if (ctxt->recovery == 0)
130	    ctxt->disableSAX = 1;
131    }
132}
133
134/**
135 * xmlWarnMsg:
136 * @ctxt:  an XML parser context
137 * @error:  the error number
138 * @msg:  the error message
139 * @str1:  an error string
140 * @str2:  an error string
141 *
142 * Handle a parser warning
143 */
144static void
145xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
146               const char *msg, const xmlChar *str1)
147{
148    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
149        (ctxt->instate == XML_PARSER_EOF))
150	return;
151    if (ctxt != NULL)
152	ctxt->errNo = error;
153    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
154                    XML_ERR_WARNING, NULL, 0,
155		    (const char *) str1, NULL,
156		    NULL, 0, 0, msg, str1);
157}
158
159/**
160 * xmlNsErrMsg:
161 * @ctxt:  an XML parser context
162 * @error:  the error number
163 * @msg:  the error message
164 * @str1:  an error string
165 * @str2:  an error string
166 *
167 * Handle a namespace error
168 */
169static void
170xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
171            const char *msg, const xmlChar *str1, const xmlChar *str2)
172{
173    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
174        (ctxt->instate == XML_PARSER_EOF))
175	return;
176    if (ctxt != NULL)
177	ctxt->errNo = error;
178    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
179                    XML_ERR_ERROR, NULL, 0,
180		    (const char *) str1, (const char *) str2,
181		    NULL, 0, 0, msg, str1, str2);
182}
183
184/**
185 * xmlNsWarnMsg:
186 * @ctxt:  an XML parser context
187 * @error:  the error number
188 * @msg:  the error message
189 * @str1:  an error string
190 *
191 * Handle a namespace warning
192 */
193static void
194xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
195             const char *msg, const xmlChar *str1, const xmlChar *str2)
196{
197    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
198        (ctxt->instate == XML_PARSER_EOF))
199	return;
200    if (ctxt != NULL)
201	ctxt->errNo = error;
202    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
203                    XML_ERR_WARNING, NULL, 0,
204		    (const char *) str1, (const char *) str2,
205		    NULL, 0, 0, msg, str1, str2);
206}
207
208/**
209 * xmlSAX2GetPublicId:
210 * @ctx: the user data (XML parser context)
211 *
212 * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
213 *
214 * Returns a xmlChar *
215 */
216const xmlChar *
217xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED)
218{
219    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
220    return(NULL);
221}
222
223/**
224 * xmlSAX2GetSystemId:
225 * @ctx: the user data (XML parser context)
226 *
227 * Provides the system ID, basically URL or filename e.g.
228 * http://www.sgmlsource.com/dtds/memo.dtd
229 *
230 * Returns a xmlChar *
231 */
232const xmlChar *
233xmlSAX2GetSystemId(void *ctx)
234{
235    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
236    if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL);
237    return((const xmlChar *) ctxt->input->filename);
238}
239
240/**
241 * xmlSAX2GetLineNumber:
242 * @ctx: the user data (XML parser context)
243 *
244 * Provide the line number of the current parsing point.
245 *
246 * Returns an int
247 */
248int
249xmlSAX2GetLineNumber(void *ctx)
250{
251    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
252    if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
253    return(ctxt->input->line);
254}
255
256/**
257 * xmlSAX2GetColumnNumber:
258 * @ctx: the user data (XML parser context)
259 *
260 * Provide the column number of the current parsing point.
261 *
262 * Returns an int
263 */
264int
265xmlSAX2GetColumnNumber(void *ctx)
266{
267    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
268    if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
269    return(ctxt->input->col);
270}
271
272/**
273 * xmlSAX2IsStandalone:
274 * @ctx: the user data (XML parser context)
275 *
276 * Is this document tagged standalone ?
277 *
278 * Returns 1 if true
279 */
280int
281xmlSAX2IsStandalone(void *ctx)
282{
283    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
284    if ((ctx == NULL) || (ctxt->myDoc == NULL)) return(0);
285    return(ctxt->myDoc->standalone == 1);
286}
287
288/**
289 * xmlSAX2HasInternalSubset:
290 * @ctx: the user data (XML parser context)
291 *
292 * Does this document has an internal subset
293 *
294 * Returns 1 if true
295 */
296int
297xmlSAX2HasInternalSubset(void *ctx)
298{
299    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
300    if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
301    return(ctxt->myDoc->intSubset != NULL);
302}
303
304/**
305 * xmlSAX2HasExternalSubset:
306 * @ctx: the user data (XML parser context)
307 *
308 * Does this document has an external subset
309 *
310 * Returns 1 if true
311 */
312int
313xmlSAX2HasExternalSubset(void *ctx)
314{
315    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
316    if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
317    return(ctxt->myDoc->extSubset != NULL);
318}
319
320/**
321 * xmlSAX2InternalSubset:
322 * @ctx:  the user data (XML parser context)
323 * @name:  the root element name
324 * @ExternalID:  the external ID
325 * @SystemID:  the SYSTEM ID (e.g. filename or URL)
326 *
327 * Callback on internal subset declaration.
328 */
329void
330xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
331	       const xmlChar *ExternalID, const xmlChar *SystemID)
332{
333    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
334    xmlDtdPtr dtd;
335    if (ctx == NULL) return;
336#ifdef DEBUG_SAX
337    xmlGenericError(xmlGenericErrorContext,
338	    "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
339            name, ExternalID, SystemID);
340#endif
341
342    if (ctxt->myDoc == NULL)
343	return;
344    dtd = xmlGetIntSubset(ctxt->myDoc);
345    if (dtd != NULL) {
346	if (ctxt->html)
347	    return;
348	xmlUnlinkNode((xmlNodePtr) dtd);
349	xmlFreeDtd(dtd);
350	ctxt->myDoc->intSubset = NULL;
351    }
352    ctxt->myDoc->intSubset =
353	xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
354    if (ctxt->myDoc->intSubset == NULL)
355        xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset");
356}
357
358/**
359 * xmlSAX2ExternalSubset:
360 * @ctx: the user data (XML parser context)
361 * @name:  the root element name
362 * @ExternalID:  the external ID
363 * @SystemID:  the SYSTEM ID (e.g. filename or URL)
364 *
365 * Callback on external subset declaration.
366 */
367void
368xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
369	       const xmlChar *ExternalID, const xmlChar *SystemID)
370{
371    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
372    if (ctx == NULL) return;
373#ifdef DEBUG_SAX
374    xmlGenericError(xmlGenericErrorContext,
375	    "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
376            name, ExternalID, SystemID);
377#endif
378    if (((ExternalID != NULL) || (SystemID != NULL)) &&
379        (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
380	 (ctxt->wellFormed && ctxt->myDoc))) {
381	/*
382	 * Try to fetch and parse the external subset.
383	 */
384	xmlParserInputPtr oldinput;
385	int oldinputNr;
386	int oldinputMax;
387	xmlParserInputPtr *oldinputTab;
388	xmlParserInputPtr input = NULL;
389	xmlCharEncoding enc;
390	int oldcharset;
391
392	/*
393	 * Ask the Entity resolver to load the damn thing
394	 */
395	if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
396	    input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
397	                                        SystemID);
398	if (input == NULL) {
399	    return;
400	}
401
402	xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
403
404	/*
405	 * make sure we won't destroy the main document context
406	 */
407	oldinput = ctxt->input;
408	oldinputNr = ctxt->inputNr;
409	oldinputMax = ctxt->inputMax;
410	oldinputTab = ctxt->inputTab;
411	oldcharset = ctxt->charset;
412
413	ctxt->inputTab = (xmlParserInputPtr *)
414	                 xmlMalloc(5 * sizeof(xmlParserInputPtr));
415	if (ctxt->inputTab == NULL) {
416	    xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset");
417	    ctxt->input = oldinput;
418	    ctxt->inputNr = oldinputNr;
419	    ctxt->inputMax = oldinputMax;
420	    ctxt->inputTab = oldinputTab;
421	    ctxt->charset = oldcharset;
422	    return;
423	}
424	ctxt->inputNr = 0;
425	ctxt->inputMax = 5;
426	ctxt->input = NULL;
427	xmlPushInput(ctxt, input);
428
429	/*
430	 * On the fly encoding conversion if needed
431	 */
432	if (ctxt->input->length >= 4) {
433	    enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
434	    xmlSwitchEncoding(ctxt, enc);
435	}
436
437	if (input->filename == NULL)
438	    input->filename = (char *) xmlCanonicPath(SystemID);
439	input->line = 1;
440	input->col = 1;
441	input->base = ctxt->input->cur;
442	input->cur = ctxt->input->cur;
443	input->free = NULL;
444
445	/*
446	 * let's parse that entity knowing it's an external subset.
447	 */
448	xmlParseExternalSubset(ctxt, ExternalID, SystemID);
449
450        /*
451	 * Free up the external entities
452	 */
453
454	while (ctxt->inputNr > 1)
455	    xmlPopInput(ctxt);
456	xmlFreeInputStream(ctxt->input);
457        xmlFree(ctxt->inputTab);
458
459	/*
460	 * Restore the parsing context of the main entity
461	 */
462	ctxt->input = oldinput;
463	ctxt->inputNr = oldinputNr;
464	ctxt->inputMax = oldinputMax;
465	ctxt->inputTab = oldinputTab;
466	ctxt->charset = oldcharset;
467	/* ctxt->wellFormed = oldwellFormed; */
468    }
469}
470
471/**
472 * xmlSAX2ResolveEntity:
473 * @ctx: the user data (XML parser context)
474 * @publicId: The public ID of the entity
475 * @systemId: The system ID of the entity
476 *
477 * The entity loader, to control the loading of external entities,
478 * the application can either:
479 *    - override this xmlSAX2ResolveEntity() callback in the SAX block
480 *    - or better use the xmlSetExternalEntityLoader() function to
481 *      set up it's own entity resolution routine
482 *
483 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
484 */
485xmlParserInputPtr
486xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
487{
488    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
489    xmlParserInputPtr ret;
490    xmlChar *URI;
491    const char *base = NULL;
492
493    if (ctx == NULL) return(NULL);
494    if (ctxt->input != NULL)
495	base = ctxt->input->filename;
496    if (base == NULL)
497	base = ctxt->directory;
498
499    URI = xmlBuildURI(systemId, (const xmlChar *) base);
500
501#ifdef DEBUG_SAX
502    xmlGenericError(xmlGenericErrorContext,
503	    "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId);
504#endif
505
506    ret = xmlLoadExternalEntity((const char *) URI,
507				(const char *) publicId, ctxt);
508    if (URI != NULL)
509	xmlFree(URI);
510    return(ret);
511}
512
513/**
514 * xmlSAX2GetEntity:
515 * @ctx: the user data (XML parser context)
516 * @name: The entity name
517 *
518 * Get an entity by name
519 *
520 * Returns the xmlEntityPtr if found.
521 */
522xmlEntityPtr
523xmlSAX2GetEntity(void *ctx, const xmlChar *name)
524{
525    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
526    xmlEntityPtr ret = NULL;
527
528    if (ctx == NULL) return(NULL);
529#ifdef DEBUG_SAX
530    xmlGenericError(xmlGenericErrorContext,
531	    "SAX.xmlSAX2GetEntity(%s)\n", name);
532#endif
533
534    if (ctxt->inSubset == 0) {
535	ret = xmlGetPredefinedEntity(name);
536	if (ret != NULL)
537	    return(ret);
538    }
539    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
540	if (ctxt->inSubset == 2) {
541	    ctxt->myDoc->standalone = 0;
542	    ret = xmlGetDocEntity(ctxt->myDoc, name);
543	    ctxt->myDoc->standalone = 1;
544	} else {
545	    ret = xmlGetDocEntity(ctxt->myDoc, name);
546	    if (ret == NULL) {
547		ctxt->myDoc->standalone = 0;
548		ret = xmlGetDocEntity(ctxt->myDoc, name);
549		if (ret != NULL) {
550		    xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE,
551	 "Entity(%s) document marked standalone but requires external subset\n",
552				   name, NULL);
553		}
554		ctxt->myDoc->standalone = 1;
555	    }
556	}
557    } else {
558	ret = xmlGetDocEntity(ctxt->myDoc, name);
559    }
560    if ((ret != NULL) &&
561	((ctxt->validate) || (ctxt->replaceEntities)) &&
562	(ret->children == NULL) &&
563	(ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
564	int val;
565
566	/*
567	 * for validation purposes we really need to fetch and
568	 * parse the external entity
569	 */
570	xmlNodePtr children;
571
572        val = xmlParseCtxtExternalEntity(ctxt, ret->URI,
573		                         ret->ExternalID, &children);
574	if (val == 0) {
575	    xmlAddChildList((xmlNodePtr) ret, children);
576	} else {
577	    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
578		           "Failure to process entity %s\n", name, NULL);
579	    ctxt->validate = 0;
580	    return(NULL);
581	}
582	ret->owner = 1;
583	ret->checked = 1;
584    }
585    return(ret);
586}
587
588/**
589 * xmlSAX2GetParameterEntity:
590 * @ctx: the user data (XML parser context)
591 * @name: The entity name
592 *
593 * Get a parameter entity by name
594 *
595 * Returns the xmlEntityPtr if found.
596 */
597xmlEntityPtr
598xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
599{
600    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
601    xmlEntityPtr ret;
602
603    if (ctx == NULL) return(NULL);
604#ifdef DEBUG_SAX
605    xmlGenericError(xmlGenericErrorContext,
606	    "SAX.xmlSAX2GetParameterEntity(%s)\n", name);
607#endif
608
609    ret = xmlGetParameterEntity(ctxt->myDoc, name);
610    return(ret);
611}
612
613
614/**
615 * xmlSAX2EntityDecl:
616 * @ctx: the user data (XML parser context)
617 * @name:  the entity name
618 * @type:  the entity type
619 * @publicId: The public ID of the entity
620 * @systemId: The system ID of the entity
621 * @content: the entity value (without processing).
622 *
623 * An entity definition has been parsed
624 */
625void
626xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
627          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
628{
629    xmlEntityPtr ent;
630    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
631
632    if (ctx == NULL) return;
633#ifdef DEBUG_SAX
634    xmlGenericError(xmlGenericErrorContext,
635	    "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
636            name, type, publicId, systemId, content);
637#endif
638    if (ctxt->inSubset == 1) {
639	ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
640		              systemId, content);
641	if ((ent == NULL) && (ctxt->pedantic))
642	    xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED,
643	     "Entity(%s) already defined in the internal subset\n",
644	               name);
645	if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
646	    xmlChar *URI;
647	    const char *base = NULL;
648
649	    if (ctxt->input != NULL)
650		base = ctxt->input->filename;
651	    if (base == NULL)
652		base = ctxt->directory;
653
654	    URI = xmlBuildURI(systemId, (const xmlChar *) base);
655	    ent->URI = URI;
656	}
657    } else if (ctxt->inSubset == 2) {
658	ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
659		              systemId, content);
660	if ((ent == NULL) && (ctxt->pedantic) &&
661	    (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
662	    ctxt->sax->warning(ctxt->userData,
663	     "Entity(%s) already defined in the external subset\n", name);
664	if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
665	    xmlChar *URI;
666	    const char *base = NULL;
667
668	    if (ctxt->input != NULL)
669		base = ctxt->input->filename;
670	    if (base == NULL)
671		base = ctxt->directory;
672
673	    URI = xmlBuildURI(systemId, (const xmlChar *) base);
674	    ent->URI = URI;
675	}
676    } else {
677	xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
678	               "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
679		       name, NULL);
680    }
681}
682
683/**
684 * xmlSAX2AttributeDecl:
685 * @ctx: the user data (XML parser context)
686 * @elem:  the name of the element
687 * @fullname:  the attribute name
688 * @type:  the attribute type
689 * @def:  the type of default value
690 * @defaultValue: the attribute default value
691 * @tree:  the tree of enumerated value set
692 *
693 * An attribute definition has been parsed
694 */
695void
696xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
697              int type, int def, const xmlChar *defaultValue,
698	      xmlEnumerationPtr tree)
699{
700    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
701    xmlAttributePtr attr;
702    xmlChar *name = NULL, *prefix = NULL;
703
704    if ((ctxt == NULL) || (ctxt->myDoc == NULL))
705        return;
706
707#ifdef DEBUG_SAX
708    xmlGenericError(xmlGenericErrorContext,
709	    "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
710            elem, fullname, type, def, defaultValue);
711#endif
712    if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
713        (type != XML_ATTRIBUTE_ID)) {
714	/*
715	 * Raise the error but keep the validity flag
716	 */
717	int tmp = ctxt->valid;
718	xmlErrValid(ctxt, XML_DTD_XMLID_TYPE,
719	      "xml:id : attribute type should be ID\n", NULL, NULL);
720	ctxt->valid = tmp;
721    }
722    /* TODO: optimize name/prefix allocation */
723    name = xmlSplitQName(ctxt, fullname, &prefix);
724    ctxt->vctxt.valid = 1;
725    if (ctxt->inSubset == 1)
726	attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
727	       name, prefix, (xmlAttributeType) type,
728	       (xmlAttributeDefault) def, defaultValue, tree);
729    else if (ctxt->inSubset == 2)
730	attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
731	   name, prefix, (xmlAttributeType) type,
732	   (xmlAttributeDefault) def, defaultValue, tree);
733    else {
734        xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
735	     "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
736	               name, NULL);
737	xmlFreeEnumeration(tree);
738	return;
739    }
740#ifdef LIBXML_VALID_ENABLED
741    if (ctxt->vctxt.valid == 0)
742	ctxt->valid = 0;
743    if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
744        (ctxt->myDoc->intSubset != NULL))
745	ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
746	                                        attr);
747#endif /* LIBXML_VALID_ENABLED */
748    if (prefix != NULL)
749	xmlFree(prefix);
750    if (name != NULL)
751	xmlFree(name);
752}
753
754/**
755 * xmlSAX2ElementDecl:
756 * @ctx: the user data (XML parser context)
757 * @name:  the element name
758 * @type:  the element type
759 * @content: the element value tree
760 *
761 * An element definition has been parsed
762 */
763void
764xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
765            xmlElementContentPtr content)
766{
767    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
768    xmlElementPtr elem = NULL;
769
770    if ((ctxt == NULL) || (ctxt->myDoc == NULL))
771        return;
772
773#ifdef DEBUG_SAX
774    xmlGenericError(xmlGenericErrorContext,
775                    "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type);
776#endif
777
778    if (ctxt->inSubset == 1)
779        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
780                                 name, (xmlElementTypeVal) type, content);
781    else if (ctxt->inSubset == 2)
782        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
783                                 name, (xmlElementTypeVal) type, content);
784    else {
785        xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
786	     "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
787	               name, NULL);
788        return;
789    }
790#ifdef LIBXML_VALID_ENABLED
791    if (elem == NULL)
792        ctxt->valid = 0;
793    if (ctxt->validate && ctxt->wellFormed &&
794        ctxt->myDoc && ctxt->myDoc->intSubset)
795        ctxt->valid &=
796            xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
797#endif /* LIBXML_VALID_ENABLED */
798}
799
800/**
801 * xmlSAX2NotationDecl:
802 * @ctx: the user data (XML parser context)
803 * @name: The name of the notation
804 * @publicId: The public ID of the entity
805 * @systemId: The system ID of the entity
806 *
807 * What to do when a notation declaration has been parsed.
808 */
809void
810xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
811	     const xmlChar *publicId, const xmlChar *systemId)
812{
813    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
814    xmlNotationPtr nota = NULL;
815
816    if ((ctxt == NULL) || (ctxt->myDoc == NULL))
817        return;
818
819#ifdef DEBUG_SAX
820    xmlGenericError(xmlGenericErrorContext,
821	    "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId);
822#endif
823
824    if ((publicId == NULL) && (systemId == NULL)) {
825	xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
826	     "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
827	               name, NULL);
828	return;
829    } else if (ctxt->inSubset == 1)
830	nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
831                              publicId, systemId);
832    else if (ctxt->inSubset == 2)
833	nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
834                              publicId, systemId);
835    else {
836	xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
837	     "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
838	               name, NULL);
839	return;
840    }
841#ifdef LIBXML_VALID_ENABLED
842    if (nota == NULL) ctxt->valid = 0;
843    if ((ctxt->validate) && (ctxt->wellFormed) &&
844        (ctxt->myDoc->intSubset != NULL))
845	ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
846	                                       nota);
847#endif /* LIBXML_VALID_ENABLED */
848}
849
850/**
851 * xmlSAX2UnparsedEntityDecl:
852 * @ctx: the user data (XML parser context)
853 * @name: The name of the entity
854 * @publicId: The public ID of the entity
855 * @systemId: The system ID of the entity
856 * @notationName: the name of the notation
857 *
858 * What to do when an unparsed entity declaration is parsed
859 */
860void
861xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
862		   const xmlChar *publicId, const xmlChar *systemId,
863		   const xmlChar *notationName)
864{
865    xmlEntityPtr ent;
866    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
867    if (ctx == NULL) return;
868#ifdef DEBUG_SAX
869    xmlGenericError(xmlGenericErrorContext,
870	    "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
871            name, publicId, systemId, notationName);
872#endif
873    if (ctxt->inSubset == 1) {
874	ent = xmlAddDocEntity(ctxt->myDoc, name,
875			XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
876			publicId, systemId, notationName);
877	if ((ent == NULL) && (ctxt->pedantic) &&
878	    (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
879	    ctxt->sax->warning(ctxt->userData,
880	     "Entity(%s) already defined in the internal subset\n", name);
881	if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
882	    xmlChar *URI;
883	    const char *base = NULL;
884
885	    if (ctxt->input != NULL)
886		base = ctxt->input->filename;
887	    if (base == NULL)
888		base = ctxt->directory;
889
890	    URI = xmlBuildURI(systemId, (const xmlChar *) base);
891	    ent->URI = URI;
892	}
893    } else if (ctxt->inSubset == 2) {
894	ent = xmlAddDtdEntity(ctxt->myDoc, name,
895			XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
896			publicId, systemId, notationName);
897	if ((ent == NULL) && (ctxt->pedantic) &&
898	    (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
899	    ctxt->sax->warning(ctxt->userData,
900	     "Entity(%s) already defined in the external subset\n", name);
901	if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
902	    xmlChar *URI;
903	    const char *base = NULL;
904
905	    if (ctxt->input != NULL)
906		base = ctxt->input->filename;
907	    if (base == NULL)
908		base = ctxt->directory;
909
910	    URI = xmlBuildURI(systemId, (const xmlChar *) base);
911	    ent->URI = URI;
912	}
913    } else {
914        xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
915	     "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
916	               name, NULL);
917    }
918}
919
920/**
921 * xmlSAX2SetDocumentLocator:
922 * @ctx: the user data (XML parser context)
923 * @loc: A SAX Locator
924 *
925 * Receive the document locator at startup, actually xmlDefaultSAXLocator
926 * Everything is available on the context, so this is useless in our case.
927 */
928void
929xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
930{
931    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
932#ifdef DEBUG_SAX
933    xmlGenericError(xmlGenericErrorContext,
934	    "SAX.xmlSAX2SetDocumentLocator()\n");
935#endif
936}
937
938/**
939 * xmlSAX2StartDocument:
940 * @ctx: the user data (XML parser context)
941 *
942 * called when the document start being processed.
943 */
944void
945xmlSAX2StartDocument(void *ctx)
946{
947    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
948    xmlDocPtr doc;
949
950    if (ctx == NULL) return;
951
952#ifdef DEBUG_SAX
953    xmlGenericError(xmlGenericErrorContext,
954	    "SAX.xmlSAX2StartDocument()\n");
955#endif
956    if (ctxt->html) {
957#ifdef LIBXML_HTML_ENABLED
958	if (ctxt->myDoc == NULL)
959	    ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
960	if (ctxt->myDoc == NULL) {
961	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
962	    return;
963	}
964#else
965        xmlGenericError(xmlGenericErrorContext,
966		"libxml2 built without HTML support\n");
967	ctxt->errNo = XML_ERR_INTERNAL_ERROR;
968	ctxt->instate = XML_PARSER_EOF;
969	ctxt->disableSAX = 1;
970	return;
971#endif
972    } else {
973	doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
974	if (doc != NULL) {
975	    if (ctxt->encoding != NULL)
976		doc->encoding = xmlStrdup(ctxt->encoding);
977	    else
978		doc->encoding = NULL;
979	    doc->standalone = ctxt->standalone;
980	} else {
981	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
982	    return;
983	}
984	if ((ctxt->dictNames) && (doc != NULL)) {
985	    doc->dict = ctxt->dict;
986	    xmlDictReference(doc->dict);
987	}
988    }
989    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
990	(ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
991	ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename);
992	if (ctxt->myDoc->URL == NULL)
993	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
994    }
995}
996
997/**
998 * xmlSAX2EndDocument:
999 * @ctx: the user data (XML parser context)
1000 *
1001 * called when the document end has been detected.
1002 */
1003void
1004xmlSAX2EndDocument(void *ctx)
1005{
1006    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1007#ifdef DEBUG_SAX
1008    xmlGenericError(xmlGenericErrorContext,
1009	    "SAX.xmlSAX2EndDocument()\n");
1010#endif
1011    if (ctx == NULL) return;
1012#ifdef LIBXML_VALID_ENABLED
1013    if (ctxt->validate && ctxt->wellFormed &&
1014        ctxt->myDoc && ctxt->myDoc->intSubset)
1015	ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
1016#endif /* LIBXML_VALID_ENABLED */
1017
1018    /*
1019     * Grab the encoding if it was added on-the-fly
1020     */
1021    if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
1022	(ctxt->myDoc->encoding == NULL)) {
1023	ctxt->myDoc->encoding = ctxt->encoding;
1024	ctxt->encoding = NULL;
1025    }
1026    if ((ctxt->inputTab != NULL) &&
1027        (ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) &&
1028        (ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
1029	(ctxt->myDoc->encoding == NULL)) {
1030	ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
1031    }
1032    if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
1033	(ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
1034	ctxt->myDoc->charset = ctxt->charset;
1035    }
1036}
1037
1038#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
1039/**
1040 * xmlSAX2AttributeInternal:
1041 * @ctx: the user data (XML parser context)
1042 * @fullname:  The attribute name, including namespace prefix
1043 * @value:  The attribute value
1044 * @prefix: the prefix on the element node
1045 *
1046 * Handle an attribute that has been read by the parser.
1047 * The default handling is to convert the attribute into an
1048 * DOM subtree and past it in a new xmlAttr element added to
1049 * the element.
1050 */
1051static void
1052xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
1053             const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED)
1054{
1055    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1056    xmlAttrPtr ret;
1057    xmlChar *name;
1058    xmlChar *ns;
1059    xmlChar *nval;
1060    xmlNsPtr namespace;
1061
1062    /*
1063     * Split the full name into a namespace prefix and the tag name
1064     */
1065    name = xmlSplitQName(ctxt, fullname, &ns);
1066    if ((name != NULL) && (name[0] == 0)) {
1067        if (xmlStrEqual(ns, BAD_CAST "xmlns")) {
1068	    xmlNsErrMsg(ctxt, XML_ERR_NS_DECL_ERROR,
1069			"invalid namespace declaration '%s'\n",
1070		        fullname, NULL);
1071	} else {
1072	    xmlNsWarnMsg(ctxt, XML_WAR_NS_COLUMN,
1073		         "Avoid attribute ending with ':' like '%s'\n",
1074			 fullname, NULL);
1075	}
1076	if (ns != NULL)
1077	    xmlFree(ns);
1078	ns = NULL;
1079	xmlFree(name);
1080	name = xmlStrdup(fullname);
1081    }
1082    if (name == NULL) {
1083        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1084	if (ns != NULL)
1085	    xmlFree(ns);
1086	return;
1087    }
1088
1089#ifdef LIBXML_VALID_ENABLED
1090    /*
1091     * Do the last stage of the attribute normalization
1092     * Needed for HTML too:
1093     *   http://www.w3.org/TR/html4/types.html#h-6.2
1094     */
1095    ctxt->vctxt.valid = 1;
1096    nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
1097	                                   ctxt->myDoc, ctxt->node,
1098					   fullname, value);
1099    if (ctxt->vctxt.valid != 1) {
1100	ctxt->valid = 0;
1101    }
1102    if (nval != NULL)
1103	value = nval;
1104#else
1105    nval = NULL;
1106#endif /* LIBXML_VALID_ENABLED */
1107
1108    /*
1109     * Check whether it's a namespace definition
1110     */
1111    if ((!ctxt->html) && (ns == NULL) &&
1112        (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
1113        (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
1114	xmlNsPtr nsret;
1115	xmlChar *val;
1116
1117        if (!ctxt->replaceEntities) {
1118	    ctxt->depth++;
1119	    val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1120		                          0,0,0);
1121	    ctxt->depth--;
1122	} else {
1123	    val = (xmlChar *) value;
1124	}
1125
1126	if (val[0] != 0) {
1127	    xmlURIPtr uri;
1128
1129	    uri = xmlParseURI((const char *)val);
1130	    if (uri == NULL) {
1131		if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1132		    ctxt->sax->warning(ctxt->userData,
1133			 "xmlns: %s not a valid URI\n", val);
1134	    } else {
1135		if (uri->scheme == NULL) {
1136		    if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1137			ctxt->sax->warning(ctxt->userData,
1138			     "xmlns: URI %s is not absolute\n", val);
1139		}
1140		xmlFreeURI(uri);
1141	    }
1142	}
1143
1144	/* a default namespace definition */
1145	nsret = xmlNewNs(ctxt->node, val, NULL);
1146
1147#ifdef LIBXML_VALID_ENABLED
1148	/*
1149	 * Validate also for namespace decls, they are attributes from
1150	 * an XML-1.0 perspective
1151	 */
1152        if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
1153	    ctxt->myDoc && ctxt->myDoc->intSubset)
1154	    ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1155					   ctxt->node, prefix, nsret, val);
1156#endif /* LIBXML_VALID_ENABLED */
1157	if (name != NULL)
1158	    xmlFree(name);
1159	if (nval != NULL)
1160	    xmlFree(nval);
1161	if (val != value)
1162	    xmlFree(val);
1163	return;
1164    }
1165    if ((!ctxt->html) &&
1166	(ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
1167        (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
1168	xmlNsPtr nsret;
1169	xmlChar *val;
1170
1171        if (!ctxt->replaceEntities) {
1172	    ctxt->depth++;
1173	    val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1174		                          0,0,0);
1175	    ctxt->depth--;
1176	    if (val == NULL) {
1177	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1178	        xmlFree(ns);
1179		if (name != NULL)
1180		    xmlFree(name);
1181		return;
1182	    }
1183	} else {
1184	    val = (xmlChar *) value;
1185	}
1186
1187	if (val[0] == 0) {
1188	    xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY,
1189		        "Empty namespace name for prefix %s\n", name, NULL);
1190	}
1191	if ((ctxt->pedantic != 0) && (val[0] != 0)) {
1192	    xmlURIPtr uri;
1193
1194	    uri = xmlParseURI((const char *)val);
1195	    if (uri == NULL) {
1196	        xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
1197			 "xmlns:%s: %s not a valid URI\n", name, value);
1198	    } else {
1199		if (uri->scheme == NULL) {
1200		    xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
1201			   "xmlns:%s: URI %s is not absolute\n", name, value);
1202		}
1203		xmlFreeURI(uri);
1204	    }
1205	}
1206
1207	/* a standard namespace definition */
1208	nsret = xmlNewNs(ctxt->node, val, name);
1209	xmlFree(ns);
1210#ifdef LIBXML_VALID_ENABLED
1211	/*
1212	 * Validate also for namespace decls, they are attributes from
1213	 * an XML-1.0 perspective
1214	 */
1215        if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
1216	    ctxt->myDoc && ctxt->myDoc->intSubset)
1217	    ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1218					   ctxt->node, prefix, nsret, value);
1219#endif /* LIBXML_VALID_ENABLED */
1220	if (name != NULL)
1221	    xmlFree(name);
1222	if (nval != NULL)
1223	    xmlFree(nval);
1224	if (val != value)
1225	    xmlFree(val);
1226	return;
1227    }
1228
1229    if (ns != NULL) {
1230	xmlAttrPtr prop;
1231	namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
1232	if (namespace == NULL) {
1233	    xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
1234		    "Namespace prefix %s of attribute %s is not defined\n",
1235		             ns, name);
1236	}
1237
1238	prop = ctxt->node->properties;
1239	while (prop != NULL) {
1240	    if (prop->ns != NULL) {
1241		if ((xmlStrEqual(name, prop->name)) &&
1242		    ((namespace == prop->ns) ||
1243		     (xmlStrEqual(namespace->href, prop->ns->href)))) {
1244			xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
1245			        "Attribute %s in %s redefined\n",
1246			                 name, namespace->href);
1247		    ctxt->wellFormed = 0;
1248		    if (ctxt->recovery == 0) ctxt->disableSAX = 1;
1249		    goto error;
1250		}
1251	    }
1252	    prop = prop->next;
1253	}
1254    } else {
1255	namespace = NULL;
1256    }
1257
1258    /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
1259    ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
1260
1261    if (ret != NULL) {
1262        if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
1263	    xmlNodePtr tmp;
1264
1265	    ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
1266	    tmp = ret->children;
1267	    while (tmp != NULL) {
1268		tmp->parent = (xmlNodePtr) ret;
1269		if (tmp->next == NULL)
1270		    ret->last = tmp;
1271		tmp = tmp->next;
1272	    }
1273	} else if (value != NULL) {
1274	    ret->children = xmlNewDocText(ctxt->myDoc, value);
1275	    ret->last = ret->children;
1276	    if (ret->children != NULL)
1277		ret->children->parent = (xmlNodePtr) ret;
1278	}
1279    }
1280
1281#ifdef LIBXML_VALID_ENABLED
1282    if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
1283        ctxt->myDoc && ctxt->myDoc->intSubset) {
1284
1285	/*
1286	 * If we don't substitute entities, the validation should be
1287	 * done on a value with replaced entities anyway.
1288	 */
1289        if (!ctxt->replaceEntities) {
1290	    xmlChar *val;
1291
1292	    ctxt->depth++;
1293	    val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1294		                          0,0,0);
1295	    ctxt->depth--;
1296
1297	    if (val == NULL)
1298		ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1299				ctxt->myDoc, ctxt->node, ret, value);
1300	    else {
1301		xmlChar *nvalnorm;
1302
1303		/*
1304		 * Do the last stage of the attribute normalization
1305		 * It need to be done twice ... it's an extra burden related
1306		 * to the ability to keep xmlSAX2References in attributes
1307		 */
1308		nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc,
1309					    ctxt->node, fullname, val);
1310		if (nvalnorm != NULL) {
1311		    xmlFree(val);
1312		    val = nvalnorm;
1313		}
1314
1315		ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1316			        ctxt->myDoc, ctxt->node, ret, val);
1317                xmlFree(val);
1318	    }
1319	} else {
1320	    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
1321					       ctxt->node, ret, value);
1322	}
1323    } else
1324#endif /* LIBXML_VALID_ENABLED */
1325           if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
1326	       (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
1327	        ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
1328        /*
1329	 * when validating, the ID registration is done at the attribute
1330	 * validation level. Otherwise we have to do specific handling here.
1331	 */
1332	if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
1333	    /*
1334	     * Add the xml:id value
1335	     *
1336	     * Open issue: normalization of the value.
1337	     */
1338	    if (xmlValidateNCName(value, 1) != 0) {
1339	        xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
1340		      "xml:id : attribute value %s is not an NCName\n",
1341			    (const char *) value, NULL);
1342	    }
1343	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
1344	} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
1345	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
1346	else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
1347	    xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
1348    }
1349
1350error:
1351    if (nval != NULL)
1352	xmlFree(nval);
1353    if (ns != NULL)
1354	xmlFree(ns);
1355}
1356
1357/*
1358 * xmlCheckDefaultedAttributes:
1359 *
1360 * Check defaulted attributes from the DTD
1361 */
1362static void
1363xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
1364	const xmlChar *prefix, const xmlChar **atts) {
1365    xmlElementPtr elemDecl;
1366    const xmlChar *att;
1367    int internal = 1;
1368    int i;
1369
1370    elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
1371    if (elemDecl == NULL) {
1372	elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
1373	internal = 0;
1374    }
1375
1376process_external_subset:
1377
1378    if (elemDecl != NULL) {
1379	xmlAttributePtr attr = elemDecl->attributes;
1380	/*
1381	 * Check against defaulted attributes from the external subset
1382	 * if the document is stamped as standalone
1383	 */
1384	if ((ctxt->myDoc->standalone == 1) &&
1385	    (ctxt->myDoc->extSubset != NULL) &&
1386	    (ctxt->validate)) {
1387	    while (attr != NULL) {
1388		if ((attr->defaultValue != NULL) &&
1389		    (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset,
1390					attr->elem, attr->name,
1391					attr->prefix) == attr) &&
1392		    (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1393					attr->elem, attr->name,
1394					attr->prefix) == NULL)) {
1395		    xmlChar *fulln;
1396
1397		    if (attr->prefix != NULL) {
1398			fulln = xmlStrdup(attr->prefix);
1399			fulln = xmlStrcat(fulln, BAD_CAST ":");
1400			fulln = xmlStrcat(fulln, attr->name);
1401		    } else {
1402			fulln = xmlStrdup(attr->name);
1403		    }
1404
1405		    /*
1406		     * Check that the attribute is not declared in the
1407		     * serialization
1408		     */
1409		    att = NULL;
1410		    if (atts != NULL) {
1411			i = 0;
1412			att = atts[i];
1413			while (att != NULL) {
1414			    if (xmlStrEqual(att, fulln))
1415				break;
1416			    i += 2;
1417			    att = atts[i];
1418			}
1419		    }
1420		    if (att == NULL) {
1421		        xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED,
1422      "standalone: attribute %s on %s defaulted from external subset\n",
1423				    (const char *)fulln,
1424				    (const char *)attr->elem);
1425		    }
1426		}
1427		attr = attr->nexth;
1428	    }
1429	}
1430
1431	/*
1432	 * Actually insert defaulted values when needed
1433	 */
1434	attr = elemDecl->attributes;
1435	while (attr != NULL) {
1436	    /*
1437	     * Make sure that attributes redefinition occuring in the
1438	     * internal subset are not overriden by definitions in the
1439	     * external subset.
1440	     */
1441	    if (attr->defaultValue != NULL) {
1442		/*
1443		 * the element should be instantiated in the tree if:
1444		 *  - this is a namespace prefix
1445		 *  - the user required for completion in the tree
1446		 *    like XSLT
1447		 *  - there isn't already an attribute definition
1448		 *    in the internal subset overriding it.
1449		 */
1450		if (((attr->prefix != NULL) &&
1451		     (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
1452		    ((attr->prefix == NULL) &&
1453		     (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
1454		    (ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
1455		    xmlAttributePtr tst;
1456
1457		    tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1458					     attr->elem, attr->name,
1459					     attr->prefix);
1460		    if ((tst == attr) || (tst == NULL)) {
1461		        xmlChar fn[50];
1462			xmlChar *fulln;
1463
1464                        fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
1465			if (fulln == NULL) {
1466			    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1467			    return;
1468			}
1469
1470			/*
1471			 * Check that the attribute is not declared in the
1472			 * serialization
1473			 */
1474			att = NULL;
1475			if (atts != NULL) {
1476			    i = 0;
1477			    att = atts[i];
1478			    while (att != NULL) {
1479				if (xmlStrEqual(att, fulln))
1480				    break;
1481				i += 2;
1482				att = atts[i];
1483			    }
1484			}
1485			if (att == NULL) {
1486			    xmlSAX2AttributeInternal(ctxt, fulln,
1487						 attr->defaultValue, prefix);
1488			}
1489			if ((fulln != fn) && (fulln != attr->name))
1490			    xmlFree(fulln);
1491		    }
1492		}
1493	    }
1494	    attr = attr->nexth;
1495	}
1496	if (internal == 1) {
1497	    elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
1498		                             name, prefix);
1499	    internal = 0;
1500	    goto process_external_subset;
1501	}
1502    }
1503}
1504
1505/**
1506 * xmlSAX2StartElement:
1507 * @ctx: the user data (XML parser context)
1508 * @fullname:  The element name, including namespace prefix
1509 * @atts:  An array of name/value attributes pairs, NULL terminated
1510 *
1511 * called when an opening tag has been processed.
1512 */
1513void
1514xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1515{
1516    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1517    xmlNodePtr ret;
1518    xmlNodePtr parent;
1519    xmlNsPtr ns;
1520    xmlChar *name;
1521    xmlChar *prefix;
1522    const xmlChar *att;
1523    const xmlChar *value;
1524    int i;
1525
1526    if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return;
1527    parent = ctxt->node;
1528#ifdef DEBUG_SAX
1529    xmlGenericError(xmlGenericErrorContext,
1530	    "SAX.xmlSAX2StartElement(%s)\n", fullname);
1531#endif
1532
1533    /*
1534     * First check on validity:
1535     */
1536    if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
1537        ((ctxt->myDoc->intSubset == NULL) ||
1538	 ((ctxt->myDoc->intSubset->notations == NULL) &&
1539	  (ctxt->myDoc->intSubset->elements == NULL) &&
1540	  (ctxt->myDoc->intSubset->attributes == NULL) &&
1541	  (ctxt->myDoc->intSubset->entities == NULL)))) {
1542	xmlErrValid(ctxt, XML_ERR_NO_DTD,
1543	  "Validation failed: no DTD found !", NULL, NULL);
1544	ctxt->validate = 0;
1545    }
1546
1547
1548    /*
1549     * Split the full name into a namespace prefix and the tag name
1550     */
1551    name = xmlSplitQName(ctxt, fullname, &prefix);
1552
1553
1554    /*
1555     * Note : the namespace resolution is deferred until the end of the
1556     *        attributes parsing, since local namespace can be defined as
1557     *        an attribute at this level.
1558     */
1559    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
1560    if (ret == NULL) {
1561        if (prefix != NULL)
1562	    xmlFree(prefix);
1563	xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1564        return;
1565    }
1566    if (ctxt->myDoc->children == NULL) {
1567#ifdef DEBUG_SAX_TREE
1568	xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
1569#endif
1570        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1571    } else if (parent == NULL) {
1572        parent = ctxt->myDoc->children;
1573    }
1574    ctxt->nodemem = -1;
1575    if (ctxt->linenumbers) {
1576	if (ctxt->input != NULL) {
1577	    if (ctxt->input->line < 65535)
1578		ret->line = (short) ctxt->input->line;
1579	    else
1580	        ret->line = 65535;
1581	}
1582    }
1583
1584    /*
1585     * We are parsing a new node.
1586     */
1587#ifdef DEBUG_SAX_TREE
1588    xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
1589#endif
1590    nodePush(ctxt, ret);
1591
1592    /*
1593     * Link the child element
1594     */
1595    if (parent != NULL) {
1596        if (parent->type == XML_ELEMENT_NODE) {
1597#ifdef DEBUG_SAX_TREE
1598	    xmlGenericError(xmlGenericErrorContext,
1599		    "adding child %s to %s\n", name, parent->name);
1600#endif
1601	    xmlAddChild(parent, ret);
1602	} else {
1603#ifdef DEBUG_SAX_TREE
1604	    xmlGenericError(xmlGenericErrorContext,
1605		    "adding sibling %s to ", name);
1606	    xmlDebugDumpOneNode(stderr, parent, 0);
1607#endif
1608	    xmlAddSibling(parent, ret);
1609	}
1610    }
1611
1612    /*
1613     * Insert all the defaulted attributes from the DTD especially namespaces
1614     */
1615    if ((!ctxt->html) &&
1616	((ctxt->myDoc->intSubset != NULL) ||
1617	 (ctxt->myDoc->extSubset != NULL))) {
1618	xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
1619    }
1620
1621    /*
1622     * process all the attributes whose name start with "xmlns"
1623     */
1624    if (atts != NULL) {
1625        i = 0;
1626	att = atts[i++];
1627	value = atts[i++];
1628	if (!ctxt->html) {
1629	    while ((att != NULL) && (value != NULL)) {
1630		if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
1631		    (att[3] == 'n') && (att[4] == 's'))
1632		    xmlSAX2AttributeInternal(ctxt, att, value, prefix);
1633
1634		att = atts[i++];
1635		value = atts[i++];
1636	    }
1637	}
1638    }
1639
1640    /*
1641     * Search the namespace, note that since the attributes have been
1642     * processed, the local namespaces are available.
1643     */
1644    ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
1645    if ((ns == NULL) && (parent != NULL))
1646	ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
1647    if ((prefix != NULL) && (ns == NULL)) {
1648	ns = xmlNewNs(ret, NULL, prefix);
1649	xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
1650		     "Namespace prefix %s is not defined\n",
1651		     prefix, NULL);
1652    }
1653
1654    /*
1655     * set the namespace node, making sure that if the default namspace
1656     * is unbound on a parent we simply kee it NULL
1657     */
1658    if ((ns != NULL) && (ns->href != NULL) &&
1659	((ns->href[0] != 0) || (ns->prefix != NULL)))
1660	xmlSetNs(ret, ns);
1661
1662    /*
1663     * process all the other attributes
1664     */
1665    if (atts != NULL) {
1666        i = 0;
1667	att = atts[i++];
1668	value = atts[i++];
1669	if (ctxt->html) {
1670	    while (att != NULL) {
1671		xmlSAX2AttributeInternal(ctxt, att, value, NULL);
1672		att = atts[i++];
1673		value = atts[i++];
1674	    }
1675	} else {
1676	    while ((att != NULL) && (value != NULL)) {
1677		if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
1678		    (att[3] != 'n') || (att[4] != 's'))
1679		    xmlSAX2AttributeInternal(ctxt, att, value, NULL);
1680
1681		/*
1682		 * Next ones
1683		 */
1684		att = atts[i++];
1685		value = atts[i++];
1686	    }
1687	}
1688    }
1689
1690#ifdef LIBXML_VALID_ENABLED
1691    /*
1692     * If it's the Document root, finish the DTD validation and
1693     * check the document root element for validity
1694     */
1695    if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
1696	int chk;
1697
1698	chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
1699	if (chk <= 0)
1700	    ctxt->valid = 0;
1701	if (chk < 0)
1702	    ctxt->wellFormed = 0;
1703	ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1704	ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
1705    }
1706#endif /* LIBXML_VALID_ENABLED */
1707
1708    if (prefix != NULL)
1709	xmlFree(prefix);
1710
1711}
1712
1713/**
1714 * xmlSAX2EndElement:
1715 * @ctx: the user data (XML parser context)
1716 * @name:  The element name
1717 *
1718 * called when the end of an element has been detected.
1719 */
1720void
1721xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
1722{
1723    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1724    xmlParserNodeInfo node_info;
1725    xmlNodePtr cur;
1726
1727    if (ctx == NULL) return;
1728    cur = ctxt->node;
1729#ifdef DEBUG_SAX
1730    if (name == NULL)
1731        xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n");
1732    else
1733	xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name);
1734#endif
1735
1736    /* Capture end position and add node */
1737    if (cur != NULL && ctxt->record_info) {
1738      node_info.end_pos = ctxt->input->cur - ctxt->input->base;
1739      node_info.end_line = ctxt->input->line;
1740      node_info.node = cur;
1741      xmlParserAddNodeInfo(ctxt, &node_info);
1742    }
1743    ctxt->nodemem = -1;
1744
1745#ifdef LIBXML_VALID_ENABLED
1746    if (ctxt->validate && ctxt->wellFormed &&
1747        ctxt->myDoc && ctxt->myDoc->intSubset)
1748        ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1749					     cur);
1750#endif /* LIBXML_VALID_ENABLED */
1751
1752
1753    /*
1754     * end of parsing of this node.
1755     */
1756#ifdef DEBUG_SAX_TREE
1757    xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
1758#endif
1759    nodePop(ctxt);
1760}
1761#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
1762
1763/*
1764 * xmlSAX2TextNode:
1765 * @ctxt:  the parser context
1766 * @str:  the input string
1767 * @len: the string length
1768 *
1769 * Remove the entities from an attribute value
1770 *
1771 * Returns the newly allocated string or NULL if not needed or error
1772 */
1773static xmlNodePtr
1774xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
1775    xmlNodePtr ret;
1776    const xmlChar *intern = NULL;
1777
1778    /*
1779     * Allocate
1780     */
1781    if (ctxt->freeElems != NULL) {
1782	ret = ctxt->freeElems;
1783	ctxt->freeElems = ret->next;
1784	ctxt->freeElemsNr--;
1785    } else {
1786	ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
1787    }
1788    if (ret == NULL) {
1789        xmlErrMemory(ctxt, "xmlSAX2Characters");
1790	return(NULL);
1791    }
1792    memset(ret, 0, sizeof(xmlNode));
1793    /*
1794     * intern the formatting blanks found between tags, or the
1795     * very short strings
1796     */
1797    if (ctxt->dictNames) {
1798        xmlChar cur = str[len];
1799
1800	if ((len < (int) (2 * sizeof(void *))) &&
1801	    (ctxt->options & XML_PARSE_COMPACT)) {
1802	    /* store the string in the node overrithing properties and nsDef */
1803	    xmlChar *tmp = (xmlChar *) &(ret->properties);
1804	    memcpy(tmp, str, len);
1805	    tmp[len] = 0;
1806	    intern = tmp;
1807	} else if ((len <= 3) && ((cur == '"') || (cur == '\'') ||
1808	    ((cur == '<') && (str[len + 1] != '!')))) {
1809	    intern = xmlDictLookup(ctxt->dict, str, len);
1810	} else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') &&
1811	           (str[len + 1] != '!')) {
1812	    int i;
1813
1814	    for (i = 1;i < len;i++) {
1815		if (!IS_BLANK_CH(str[i])) goto skip;
1816	    }
1817	    intern = xmlDictLookup(ctxt->dict, str, len);
1818	}
1819    }
1820skip:
1821    ret->type = XML_TEXT_NODE;
1822
1823    ret->name = xmlStringText;
1824    if (intern == NULL) {
1825	ret->content = xmlStrndup(str, len);
1826	if (ret->content == NULL) {
1827	    xmlSAX2ErrMemory(ctxt, "xmlSAX2TextNode");
1828	    xmlFree(ret);
1829	    return(NULL);
1830	}
1831    } else
1832	ret->content = (xmlChar *) intern;
1833
1834    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
1835	xmlRegisterNodeDefaultValue(ret);
1836    return(ret);
1837}
1838
1839#ifdef LIBXML_VALID_ENABLED
1840/*
1841 * xmlSAX2DecodeAttrEntities:
1842 * @ctxt:  the parser context
1843 * @str:  the input string
1844 * @len: the string length
1845 *
1846 * Remove the entities from an attribute value
1847 *
1848 * Returns the newly allocated string or NULL if not needed or error
1849 */
1850static xmlChar *
1851xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
1852                          const xmlChar *end) {
1853    const xmlChar *in;
1854    xmlChar *ret;
1855
1856    in = str;
1857    while (in < end)
1858        if (*in++ == '&')
1859	    goto decode;
1860    return(NULL);
1861decode:
1862    ctxt->depth++;
1863    ret = xmlStringLenDecodeEntities(ctxt, str, end - str,
1864				     XML_SUBSTITUTE_REF, 0,0,0);
1865    ctxt->depth--;
1866    return(ret);
1867}
1868#endif /* LIBXML_VALID_ENABLED */
1869
1870/**
1871 * xmlSAX2AttributeNs:
1872 * @ctx: the user data (XML parser context)
1873 * @localname:  the local name of the attribute
1874 * @prefix:  the attribute namespace prefix if available
1875 * @URI:  the attribute namespace name if available
1876 * @value:  Start of the attribute value
1877 * @valueend: end of the attribute value
1878 *
1879 * Handle an attribute that has been read by the parser.
1880 * The default handling is to convert the attribute into an
1881 * DOM subtree and past it in a new xmlAttr element added to
1882 * the element.
1883 */
1884static void
1885xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
1886                   const xmlChar * localname,
1887                   const xmlChar * prefix,
1888		   const xmlChar * value,
1889		   const xmlChar * valueend)
1890{
1891    xmlAttrPtr ret;
1892    xmlNsPtr namespace = NULL;
1893    xmlChar *dup = NULL;
1894
1895    /*
1896     * Note: if prefix == NULL, the attribute is not in the default namespace
1897     */
1898    if (prefix != NULL)
1899	namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
1900
1901    /*
1902     * allocate the node
1903     */
1904    if (ctxt->freeAttrs != NULL) {
1905        ret = ctxt->freeAttrs;
1906	ctxt->freeAttrs = ret->next;
1907	ctxt->freeAttrsNr--;
1908	memset(ret, 0, sizeof(xmlAttr));
1909	ret->type = XML_ATTRIBUTE_NODE;
1910
1911	ret->parent = ctxt->node;
1912	ret->doc = ctxt->myDoc;
1913	ret->ns = namespace;
1914
1915	if (ctxt->dictNames)
1916	    ret->name = localname;
1917	else
1918	    ret->name = xmlStrdup(localname);
1919
1920        /* link at the end to preserv order, TODO speed up with a last */
1921	if (ctxt->node->properties == NULL) {
1922	    ctxt->node->properties = ret;
1923	} else {
1924	    xmlAttrPtr prev = ctxt->node->properties;
1925
1926	    while (prev->next != NULL) prev = prev->next;
1927	    prev->next = ret;
1928	    ret->prev = prev;
1929	}
1930
1931	if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
1932	    xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
1933    } else {
1934	if (ctxt->dictNames)
1935	    ret = xmlNewNsPropEatName(ctxt->node, namespace,
1936	                              (xmlChar *) localname, NULL);
1937	else
1938	    ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL);
1939	if (ret == NULL) {
1940	    xmlErrMemory(ctxt, "xmlSAX2AttributeNs");
1941	    return;
1942	}
1943    }
1944
1945    if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
1946	xmlNodePtr tmp;
1947
1948	/*
1949	 * We know that if there is an entity reference, then
1950	 * the string has been dup'ed and terminates with 0
1951	 * otherwise with ' or "
1952	 */
1953	if (*valueend != 0) {
1954	    tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
1955	    ret->children = tmp;
1956	    ret->last = tmp;
1957	    if (tmp != NULL) {
1958		tmp->doc = ret->doc;
1959		tmp->parent = (xmlNodePtr) ret;
1960	    }
1961	} else {
1962	    ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
1963						    valueend - value);
1964	    tmp = ret->children;
1965	    while (tmp != NULL) {
1966	        tmp->doc = ret->doc;
1967		tmp->parent = (xmlNodePtr) ret;
1968		if (tmp->next == NULL)
1969		    ret->last = tmp;
1970		tmp = tmp->next;
1971	    }
1972	}
1973    } else if (value != NULL) {
1974	xmlNodePtr tmp;
1975
1976	tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
1977	ret->children = tmp;
1978	ret->last = tmp;
1979	if (tmp != NULL) {
1980	    tmp->doc = ret->doc;
1981	    tmp->parent = (xmlNodePtr) ret;
1982	}
1983    }
1984
1985#ifdef LIBXML_VALID_ENABLED
1986    if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
1987        ctxt->myDoc && ctxt->myDoc->intSubset) {
1988	/*
1989	 * If we don't substitute entities, the validation should be
1990	 * done on a value with replaced entities anyway.
1991	 */
1992        if (!ctxt->replaceEntities) {
1993	    dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend);
1994	    if (dup == NULL) {
1995	        if (*valueend == 0) {
1996		    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1997				    ctxt->myDoc, ctxt->node, ret, value);
1998		} else {
1999		    /*
2000		     * That should already be normalized.
2001		     * cheaper to finally allocate here than duplicate
2002		     * entry points in the full validation code
2003		     */
2004		    dup = xmlStrndup(value, valueend - value);
2005
2006		    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2007				    ctxt->myDoc, ctxt->node, ret, dup);
2008		}
2009	    } else {
2010	        /*
2011		 * dup now contains a string of the flattened attribute
2012		 * content with entities substitued. Check if we need to
2013		 * apply an extra layer of normalization.
2014		 * It need to be done twice ... it's an extra burden related
2015		 * to the ability to keep references in attributes
2016		 */
2017		if (ctxt->attsSpecial != NULL) {
2018		    xmlChar *nvalnorm;
2019		    xmlChar fn[50];
2020		    xmlChar *fullname;
2021
2022		    fullname = xmlBuildQName(localname, prefix, fn, 50);
2023		    if (fullname != NULL) {
2024			ctxt->vctxt.valid = 1;
2025		        nvalnorm = xmlValidCtxtNormalizeAttributeValue(
2026			                 &ctxt->vctxt, ctxt->myDoc,
2027					 ctxt->node, fullname, dup);
2028			if (ctxt->vctxt.valid != 1)
2029			    ctxt->valid = 0;
2030
2031			if ((fullname != fn) && (fullname != localname))
2032			    xmlFree(fullname);
2033			if (nvalnorm != NULL) {
2034			    xmlFree(dup);
2035			    dup = nvalnorm;
2036			}
2037		    }
2038		}
2039
2040		ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2041			        ctxt->myDoc, ctxt->node, ret, dup);
2042	    }
2043	} else {
2044	    /*
2045	     * if entities already have been substitued, then
2046	     * the attribute as passed is already normalized
2047	     */
2048	    dup = xmlStrndup(value, valueend - value);
2049
2050	    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2051	                             ctxt->myDoc, ctxt->node, ret, dup);
2052	}
2053    } else
2054#endif /* LIBXML_VALID_ENABLED */
2055           if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
2056	       (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
2057	        ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
2058        /*
2059	 * when validating, the ID registration is done at the attribute
2060	 * validation level. Otherwise we have to do specific handling here.
2061	 */
2062        if ((prefix == ctxt->str_xml) &&
2063	           (localname[0] == 'i') && (localname[1] == 'd') &&
2064		   (localname[2] == 0)) {
2065	    /*
2066	     * Add the xml:id value
2067	     *
2068	     * Open issue: normalization of the value.
2069	     */
2070	    if (dup == NULL)
2071	        dup = xmlStrndup(value, valueend - value);
2072#ifdef LIBXML_VALID_ENABLED
2073	    if (xmlValidateNCName(dup, 1) != 0) {
2074	        xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
2075		      "xml:id : attribute value %s is not an NCName\n",
2076			    (const char *) dup, NULL);
2077	    }
2078#endif
2079	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
2080	} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
2081	    /* might be worth duplicate entry points and not copy */
2082	    if (dup == NULL)
2083	        dup = xmlStrndup(value, valueend - value);
2084	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
2085	} else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
2086	    if (dup == NULL)
2087	        dup = xmlStrndup(value, valueend - value);
2088	    xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret);
2089	}
2090    }
2091    if (dup != NULL)
2092	xmlFree(dup);
2093}
2094
2095/**
2096 * xmlSAX2StartElementNs:
2097 * @ctx:  the user data (XML parser context)
2098 * @localname:  the local name of the element
2099 * @prefix:  the element namespace prefix if available
2100 * @URI:  the element namespace name if available
2101 * @nb_namespaces:  number of namespace definitions on that node
2102 * @namespaces:  pointer to the array of prefix/URI pairs namespace definitions
2103 * @nb_attributes:  the number of attributes on that node
2104 * @nb_defaulted:  the number of defaulted attributes.
2105 * @attributes:  pointer to the array of (localname/prefix/URI/value/end)
2106 *               attribute values.
2107 *
2108 * SAX2 callback when an element start has been detected by the parser.
2109 * It provides the namespace informations for the element, as well as
2110 * the new namespace declarations on the element.
2111 */
2112void
2113xmlSAX2StartElementNs(void *ctx,
2114                      const xmlChar *localname,
2115		      const xmlChar *prefix,
2116		      const xmlChar *URI,
2117		      int nb_namespaces,
2118		      const xmlChar **namespaces,
2119		      int nb_attributes,
2120		      int nb_defaulted,
2121		      const xmlChar **attributes)
2122{
2123    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2124    xmlNodePtr ret;
2125    xmlNodePtr parent;
2126    xmlNsPtr last = NULL, ns;
2127    const xmlChar *uri, *pref;
2128    int i, j;
2129
2130    if (ctx == NULL) return;
2131    parent = ctxt->node;
2132    /*
2133     * First check on validity:
2134     */
2135    if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
2136        ((ctxt->myDoc->intSubset == NULL) ||
2137	 ((ctxt->myDoc->intSubset->notations == NULL) &&
2138	  (ctxt->myDoc->intSubset->elements == NULL) &&
2139	  (ctxt->myDoc->intSubset->attributes == NULL) &&
2140	  (ctxt->myDoc->intSubset->entities == NULL)))) {
2141	xmlErrValid(ctxt, XML_ERR_NO_DTD,
2142	  "Validation failed: no DTD found !", NULL, NULL);
2143	ctxt->validate = 0;
2144    }
2145
2146    /*
2147     * allocate the node
2148     */
2149    if (ctxt->freeElems != NULL) {
2150        ret = ctxt->freeElems;
2151	ctxt->freeElems = ret->next;
2152	ctxt->freeElemsNr--;
2153	memset(ret, 0, sizeof(xmlNode));
2154	ret->type = XML_ELEMENT_NODE;
2155
2156	if (ctxt->dictNames)
2157	    ret->name = localname;
2158	else {
2159	    ret->name = xmlStrdup(localname);
2160	    if (ret->name == NULL) {
2161	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2162		return;
2163	    }
2164	}
2165	if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
2166	    xmlRegisterNodeDefaultValue(ret);
2167    } else {
2168	if (ctxt->dictNames)
2169	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
2170	                               (xmlChar *) localname, NULL);
2171	else
2172	    ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
2173	if (ret == NULL) {
2174	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2175	    return;
2176	}
2177    }
2178    if (ctxt->linenumbers) {
2179	if (ctxt->input != NULL) {
2180	    if (ctxt->input->line < 65535)
2181		ret->line = (short) ctxt->input->line;
2182	    else
2183	        ret->line = 65535;
2184	}
2185    }
2186
2187    if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
2188        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2189    }
2190    /*
2191     * Build the namespace list
2192     */
2193    for (i = 0,j = 0;j < nb_namespaces;j++) {
2194        pref = namespaces[i++];
2195	uri = namespaces[i++];
2196	ns = xmlNewNs(NULL, uri, pref);
2197	if (ns != NULL) {
2198	    if (last == NULL) {
2199	        ret->nsDef = last = ns;
2200	    } else {
2201	        last->next = ns;
2202		last = ns;
2203	    }
2204	    if ((URI != NULL) && (prefix == pref))
2205		ret->ns = ns;
2206	} else {
2207	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2208	    return;
2209	}
2210#ifdef LIBXML_VALID_ENABLED
2211	if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
2212	    ctxt->myDoc && ctxt->myDoc->intSubset) {
2213	    ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
2214	                                           ret, prefix, ns, uri);
2215	}
2216#endif /* LIBXML_VALID_ENABLED */
2217    }
2218    ctxt->nodemem = -1;
2219
2220    /*
2221     * We are parsing a new node.
2222     */
2223    nodePush(ctxt, ret);
2224
2225    /*
2226     * Link the child element
2227     */
2228    if (parent != NULL) {
2229        if (parent->type == XML_ELEMENT_NODE) {
2230	    xmlAddChild(parent, ret);
2231	} else {
2232	    xmlAddSibling(parent, ret);
2233	}
2234    }
2235
2236    /*
2237     * Insert the defaulted attributes from the DTD only if requested:
2238     */
2239    if ((nb_defaulted != 0) &&
2240        ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0))
2241	nb_attributes -= nb_defaulted;
2242
2243    /*
2244     * Search the namespace if it wasn't already found
2245     * Note that, if prefix is NULL, this searches for the default Ns
2246     */
2247    if ((URI != NULL) && (ret->ns == NULL)) {
2248        ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
2249	if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
2250	    ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
2251	}
2252	if (ret->ns == NULL) {
2253	    ns = xmlNewNs(ret, NULL, prefix);
2254	    if (ns == NULL) {
2255
2256	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2257		return;
2258	    }
2259	    xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
2260			"Namespace prefix %s was not found\n",
2261			prefix, NULL);
2262	}
2263    }
2264
2265    /*
2266     * process all the other attributes
2267     */
2268    if (nb_attributes > 0) {
2269        for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
2270	    xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
2271	                       attributes[j+3], attributes[j+4]);
2272	}
2273    }
2274
2275#ifdef LIBXML_VALID_ENABLED
2276    /*
2277     * If it's the Document root, finish the DTD validation and
2278     * check the document root element for validity
2279     */
2280    if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
2281	int chk;
2282
2283	chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
2284	if (chk <= 0)
2285	    ctxt->valid = 0;
2286	if (chk < 0)
2287	    ctxt->wellFormed = 0;
2288	ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
2289	ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
2290    }
2291#endif /* LIBXML_VALID_ENABLED */
2292}
2293
2294/**
2295 * xmlSAX2EndElementNs:
2296 * @ctx:  the user data (XML parser context)
2297 * @localname:  the local name of the element
2298 * @prefix:  the element namespace prefix if available
2299 * @URI:  the element namespace name if available
2300 *
2301 * SAX2 callback when an element end has been detected by the parser.
2302 * It provides the namespace informations for the element.
2303 */
2304void
2305xmlSAX2EndElementNs(void *ctx,
2306                    const xmlChar * localname ATTRIBUTE_UNUSED,
2307                    const xmlChar * prefix ATTRIBUTE_UNUSED,
2308		    const xmlChar * URI ATTRIBUTE_UNUSED)
2309{
2310    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2311    xmlParserNodeInfo node_info;
2312    xmlNodePtr cur;
2313
2314    if (ctx == NULL) return;
2315    cur = ctxt->node;
2316    /* Capture end position and add node */
2317    if ((ctxt->record_info) && (cur != NULL)) {
2318        node_info.end_pos = ctxt->input->cur - ctxt->input->base;
2319        node_info.end_line = ctxt->input->line;
2320        node_info.node = cur;
2321        xmlParserAddNodeInfo(ctxt, &node_info);
2322    }
2323    ctxt->nodemem = -1;
2324
2325#ifdef LIBXML_VALID_ENABLED
2326    if (ctxt->validate && ctxt->wellFormed &&
2327        ctxt->myDoc && ctxt->myDoc->intSubset)
2328        ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur);
2329#endif /* LIBXML_VALID_ENABLED */
2330
2331    /*
2332     * end of parsing of this node.
2333     */
2334    nodePop(ctxt);
2335}
2336
2337/**
2338 * xmlSAX2Reference:
2339 * @ctx: the user data (XML parser context)
2340 * @name:  The entity name
2341 *
2342 * called when an entity xmlSAX2Reference is detected.
2343 */
2344void
2345xmlSAX2Reference(void *ctx, const xmlChar *name)
2346{
2347    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2348    xmlNodePtr ret;
2349
2350    if (ctx == NULL) return;
2351#ifdef DEBUG_SAX
2352    xmlGenericError(xmlGenericErrorContext,
2353	    "SAX.xmlSAX2Reference(%s)\n", name);
2354#endif
2355    if (name[0] == '#')
2356	ret = xmlNewCharRef(ctxt->myDoc, name);
2357    else
2358	ret = xmlNewReference(ctxt->myDoc, name);
2359#ifdef DEBUG_SAX_TREE
2360    xmlGenericError(xmlGenericErrorContext,
2361	    "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name);
2362#endif
2363    xmlAddChild(ctxt->node, ret);
2364}
2365
2366/**
2367 * xmlSAX2Characters:
2368 * @ctx: the user data (XML parser context)
2369 * @ch:  a xmlChar string
2370 * @len: the number of xmlChar
2371 *
2372 * receiving some chars from the parser.
2373 */
2374void
2375xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
2376{
2377    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2378    xmlNodePtr lastChild;
2379
2380    if (ctx == NULL) return;
2381#ifdef DEBUG_SAX
2382    xmlGenericError(xmlGenericErrorContext,
2383	    "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len);
2384#endif
2385    /*
2386     * Handle the data if any. If there is no child
2387     * add it as content, otherwise if the last child is text,
2388     * concatenate it, else create a new node of type text.
2389     */
2390
2391    if (ctxt->node == NULL) {
2392#ifdef DEBUG_SAX_TREE
2393	xmlGenericError(xmlGenericErrorContext,
2394		"add chars: ctxt->node == NULL !\n");
2395#endif
2396        return;
2397    }
2398    lastChild = ctxt->node->last;
2399#ifdef DEBUG_SAX_TREE
2400    xmlGenericError(xmlGenericErrorContext,
2401	    "add chars to %s \n", ctxt->node->name);
2402#endif
2403
2404    /*
2405     * Here we needed an accelerator mechanism in case of very large
2406     * elements. Use an attribute in the structure !!!
2407     */
2408    if (lastChild == NULL) {
2409        lastChild = xmlSAX2TextNode(ctxt, ch, len);
2410	if (lastChild != NULL) {
2411	    ctxt->node->children = lastChild;
2412	    ctxt->node->last = lastChild;
2413	    lastChild->parent = ctxt->node;
2414	    lastChild->doc = ctxt->node->doc;
2415	    ctxt->nodelen = len;
2416	    ctxt->nodemem = len + 1;
2417	} else {
2418	    xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2419	    return;
2420	}
2421    } else {
2422	int coalesceText = (lastChild != NULL) &&
2423	    (lastChild->type == XML_TEXT_NODE) &&
2424	    (lastChild->name == xmlStringText);
2425	if ((coalesceText) && (ctxt->nodemem != 0)) {
2426	    /*
2427	     * The whole point of maintaining nodelen and nodemem,
2428	     * xmlTextConcat is too costly, i.e. compute length,
2429	     * reallocate a new buffer, move data, append ch. Here
2430	     * We try to minimaze realloc() uses and avoid copying
2431	     * and recomputing length over and over.
2432	     */
2433	    if (lastChild->content == (xmlChar *)&(lastChild->properties)) {
2434		lastChild->content = xmlStrdup(lastChild->content);
2435		lastChild->properties = NULL;
2436	    } else if ((ctxt->nodemem == ctxt->nodelen + 1) &&
2437	               (xmlDictOwns(ctxt->dict, lastChild->content))) {
2438		lastChild->content = xmlStrdup(lastChild->content);
2439	    }
2440	    if (ctxt->nodelen + len >= ctxt->nodemem) {
2441		xmlChar *newbuf;
2442		int size;
2443
2444		size = ctxt->nodemem + len;
2445		size *= 2;
2446                newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
2447		if (newbuf == NULL) {
2448		    xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2449		    return;
2450		}
2451		ctxt->nodemem = size;
2452		lastChild->content = newbuf;
2453	    }
2454	    memcpy(&lastChild->content[ctxt->nodelen], ch, len);
2455	    ctxt->nodelen += len;
2456	    lastChild->content[ctxt->nodelen] = 0;
2457	} else if (coalesceText) {
2458	    if (xmlTextConcat(lastChild, ch, len)) {
2459		xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2460	    }
2461	    if (ctxt->node->children != NULL) {
2462		ctxt->nodelen = xmlStrlen(lastChild->content);
2463		ctxt->nodemem = ctxt->nodelen + 1;
2464	    }
2465	} else {
2466	    /* Mixed content, first time */
2467	    lastChild = xmlSAX2TextNode(ctxt, ch, len);
2468	    if (lastChild != NULL) {
2469		xmlAddChild(ctxt->node, lastChild);
2470		if (ctxt->node->children != NULL) {
2471		    ctxt->nodelen = len;
2472		    ctxt->nodemem = len + 1;
2473		}
2474	    }
2475	}
2476    }
2477}
2478
2479/**
2480 * xmlSAX2IgnorableWhitespace:
2481 * @ctx: the user data (XML parser context)
2482 * @ch:  a xmlChar string
2483 * @len: the number of xmlChar
2484 *
2485 * receiving some ignorable whitespaces from the parser.
2486 * UNUSED: by default the DOM building will use xmlSAX2Characters
2487 */
2488void
2489xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
2490{
2491    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
2492#ifdef DEBUG_SAX
2493    xmlGenericError(xmlGenericErrorContext,
2494	    "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len);
2495#endif
2496}
2497
2498/**
2499 * xmlSAX2ProcessingInstruction:
2500 * @ctx: the user data (XML parser context)
2501 * @target:  the target name
2502 * @data: the PI data's
2503 *
2504 * A processing instruction has been parsed.
2505 */
2506void
2507xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
2508                      const xmlChar *data)
2509{
2510    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2511    xmlNodePtr ret;
2512    xmlNodePtr parent;
2513
2514    if (ctx == NULL) return;
2515    parent = ctxt->node;
2516#ifdef DEBUG_SAX
2517    xmlGenericError(xmlGenericErrorContext,
2518	    "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data);
2519#endif
2520
2521    ret = xmlNewDocPI(ctxt->myDoc, target, data);
2522    if (ret == NULL) return;
2523    parent = ctxt->node;
2524
2525    if (ctxt->linenumbers) {
2526	if (ctxt->input != NULL) {
2527	    if (ctxt->input->line < 65535)
2528		ret->line = (short) ctxt->input->line;
2529	    else
2530	        ret->line = 65535;
2531	}
2532    }
2533    if (ctxt->inSubset == 1) {
2534	xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
2535	return;
2536    } else if (ctxt->inSubset == 2) {
2537	xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
2538	return;
2539    }
2540    if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
2541#ifdef DEBUG_SAX_TREE
2542	    xmlGenericError(xmlGenericErrorContext,
2543		    "Setting PI %s as root\n", target);
2544#endif
2545        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2546	return;
2547    }
2548    if (parent->type == XML_ELEMENT_NODE) {
2549#ifdef DEBUG_SAX_TREE
2550	xmlGenericError(xmlGenericErrorContext,
2551		"adding PI %s child to %s\n", target, parent->name);
2552#endif
2553	xmlAddChild(parent, ret);
2554    } else {
2555#ifdef DEBUG_SAX_TREE
2556	xmlGenericError(xmlGenericErrorContext,
2557		"adding PI %s sibling to ", target);
2558	xmlDebugDumpOneNode(stderr, parent, 0);
2559#endif
2560	xmlAddSibling(parent, ret);
2561    }
2562}
2563
2564/**
2565 * xmlSAX2Comment:
2566 * @ctx: the user data (XML parser context)
2567 * @value:  the xmlSAX2Comment content
2568 *
2569 * A xmlSAX2Comment has been parsed.
2570 */
2571void
2572xmlSAX2Comment(void *ctx, const xmlChar *value)
2573{
2574    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2575    xmlNodePtr ret;
2576    xmlNodePtr parent;
2577
2578    if (ctx == NULL) return;
2579    parent = ctxt->node;
2580#ifdef DEBUG_SAX
2581    xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value);
2582#endif
2583    ret = xmlNewDocComment(ctxt->myDoc, value);
2584    if (ret == NULL) return;
2585    if (ctxt->linenumbers) {
2586	if (ctxt->input != NULL) {
2587	    if (ctxt->input->line < 65535)
2588		ret->line = (short) ctxt->input->line;
2589	    else
2590	        ret->line = 65535;
2591	}
2592    }
2593
2594    if (ctxt->inSubset == 1) {
2595	xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
2596	return;
2597    } else if (ctxt->inSubset == 2) {
2598	xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
2599	return;
2600    }
2601    if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
2602#ifdef DEBUG_SAX_TREE
2603	    xmlGenericError(xmlGenericErrorContext,
2604		    "Setting xmlSAX2Comment as root\n");
2605#endif
2606        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2607	return;
2608    }
2609    if (parent->type == XML_ELEMENT_NODE) {
2610#ifdef DEBUG_SAX_TREE
2611	xmlGenericError(xmlGenericErrorContext,
2612		"adding xmlSAX2Comment child to %s\n", parent->name);
2613#endif
2614	xmlAddChild(parent, ret);
2615    } else {
2616#ifdef DEBUG_SAX_TREE
2617	xmlGenericError(xmlGenericErrorContext,
2618		"adding xmlSAX2Comment sibling to ");
2619	xmlDebugDumpOneNode(stderr, parent, 0);
2620#endif
2621	xmlAddSibling(parent, ret);
2622    }
2623}
2624
2625/**
2626 * xmlSAX2CDataBlock:
2627 * @ctx: the user data (XML parser context)
2628 * @value:  The pcdata content
2629 * @len:  the block length
2630 *
2631 * called when a pcdata block has been parsed
2632 */
2633void
2634xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
2635{
2636    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2637    xmlNodePtr ret, lastChild;
2638
2639    if (ctx == NULL) return;
2640#ifdef DEBUG_SAX
2641    xmlGenericError(xmlGenericErrorContext,
2642	    "SAX.pcdata(%.10s, %d)\n", value, len);
2643#endif
2644    lastChild = xmlGetLastChild(ctxt->node);
2645#ifdef DEBUG_SAX_TREE
2646    xmlGenericError(xmlGenericErrorContext,
2647	    "add chars to %s \n", ctxt->node->name);
2648#endif
2649    if ((lastChild != NULL) &&
2650        (lastChild->type == XML_CDATA_SECTION_NODE)) {
2651	xmlTextConcat(lastChild, value, len);
2652    } else {
2653	ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
2654	xmlAddChild(ctxt->node, ret);
2655    }
2656}
2657
2658static int xmlSAX2DefaultVersionValue = 2;
2659
2660#ifdef LIBXML_SAX1_ENABLED
2661/**
2662 * xmlSAXDefaultVersion:
2663 * @version:  the version, 1 or 2
2664 *
2665 * Set the default version of SAX used globally by the library.
2666 * By default, during initialization the default is set to 2.
2667 * Note that it is generally a better coding style to use
2668 * xmlSAXVersion() to set up the version explicitly for a given
2669 * parsing context.
2670 *
2671 * Returns the previous value in case of success and -1 in case of error.
2672 */
2673int
2674xmlSAXDefaultVersion(int version)
2675{
2676    int ret = xmlSAX2DefaultVersionValue;
2677
2678    if ((version != 1) && (version != 2))
2679        return(-1);
2680    xmlSAX2DefaultVersionValue = version;
2681    return(ret);
2682}
2683#endif /* LIBXML_SAX1_ENABLED */
2684
2685/**
2686 * xmlSAXVersion:
2687 * @hdlr:  the SAX handler
2688 * @version:  the version, 1 or 2
2689 *
2690 * Initialize the default XML SAX handler according to the version
2691 *
2692 * Returns 0 in case of success and -1 in case of error.
2693 */
2694int
2695xmlSAXVersion(xmlSAXHandler *hdlr, int version)
2696{
2697    if (hdlr == NULL) return(-1);
2698    if (version == 2) {
2699	hdlr->startElement = NULL;
2700	hdlr->endElement = NULL;
2701	hdlr->startElementNs = xmlSAX2StartElementNs;
2702	hdlr->endElementNs = xmlSAX2EndElementNs;
2703	hdlr->serror = NULL;
2704	hdlr->initialized = XML_SAX2_MAGIC;
2705#ifdef LIBXML_SAX1_ENABLED
2706    } else if (version == 1) {
2707	hdlr->startElement = xmlSAX2StartElement;
2708	hdlr->endElement = xmlSAX2EndElement;
2709	hdlr->initialized = 1;
2710#endif /* LIBXML_SAX1_ENABLED */
2711    } else
2712        return(-1);
2713    hdlr->internalSubset = xmlSAX2InternalSubset;
2714    hdlr->externalSubset = xmlSAX2ExternalSubset;
2715    hdlr->isStandalone = xmlSAX2IsStandalone;
2716    hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
2717    hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
2718    hdlr->resolveEntity = xmlSAX2ResolveEntity;
2719    hdlr->getEntity = xmlSAX2GetEntity;
2720    hdlr->getParameterEntity = xmlSAX2GetParameterEntity;
2721    hdlr->entityDecl = xmlSAX2EntityDecl;
2722    hdlr->attributeDecl = xmlSAX2AttributeDecl;
2723    hdlr->elementDecl = xmlSAX2ElementDecl;
2724    hdlr->notationDecl = xmlSAX2NotationDecl;
2725    hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl;
2726    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2727    hdlr->startDocument = xmlSAX2StartDocument;
2728    hdlr->endDocument = xmlSAX2EndDocument;
2729    hdlr->reference = xmlSAX2Reference;
2730    hdlr->characters = xmlSAX2Characters;
2731    hdlr->cdataBlock = xmlSAX2CDataBlock;
2732    hdlr->ignorableWhitespace = xmlSAX2Characters;
2733    hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
2734    hdlr->comment = xmlSAX2Comment;
2735    hdlr->warning = xmlParserWarning;
2736    hdlr->error = xmlParserError;
2737    hdlr->fatalError = xmlParserError;
2738
2739    return(0);
2740}
2741
2742/**
2743 * xmlSAX2InitDefaultSAXHandler:
2744 * @hdlr:  the SAX handler
2745 * @warning:  flag if non-zero sets the handler warning procedure
2746 *
2747 * Initialize the default XML SAX2 handler
2748 */
2749void
2750xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning)
2751{
2752    if ((hdlr == NULL) || (hdlr->initialized != 0))
2753	return;
2754
2755    xmlSAXVersion(hdlr, xmlSAX2DefaultVersionValue);
2756    if (warning == 0)
2757	hdlr->warning = NULL;
2758    else
2759	hdlr->warning = xmlParserWarning;
2760}
2761
2762/**
2763 * xmlDefaultSAXHandlerInit:
2764 *
2765 * Initialize the default SAX2 handler
2766 */
2767void
2768xmlDefaultSAXHandlerInit(void)
2769{
2770#ifdef LIBXML_SAX1_ENABLED
2771    xmlSAXVersion((xmlSAXHandlerPtr) &xmlDefaultSAXHandler, 1);
2772#endif /* LIBXML_SAX1_ENABLED */
2773}
2774
2775#ifdef LIBXML_HTML_ENABLED
2776
2777/**
2778 * xmlSAX2InitHtmlDefaultSAXHandler:
2779 * @hdlr:  the SAX handler
2780 *
2781 * Initialize the default HTML SAX2 handler
2782 */
2783void
2784xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr)
2785{
2786    if ((hdlr == NULL) || (hdlr->initialized != 0))
2787	return;
2788
2789    hdlr->internalSubset = xmlSAX2InternalSubset;
2790    hdlr->externalSubset = NULL;
2791    hdlr->isStandalone = NULL;
2792    hdlr->hasInternalSubset = NULL;
2793    hdlr->hasExternalSubset = NULL;
2794    hdlr->resolveEntity = NULL;
2795    hdlr->getEntity = xmlSAX2GetEntity;
2796    hdlr->getParameterEntity = NULL;
2797    hdlr->entityDecl = NULL;
2798    hdlr->attributeDecl = NULL;
2799    hdlr->elementDecl = NULL;
2800    hdlr->notationDecl = NULL;
2801    hdlr->unparsedEntityDecl = NULL;
2802    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2803    hdlr->startDocument = xmlSAX2StartDocument;
2804    hdlr->endDocument = xmlSAX2EndDocument;
2805    hdlr->startElement = xmlSAX2StartElement;
2806    hdlr->endElement = xmlSAX2EndElement;
2807    hdlr->reference = NULL;
2808    hdlr->characters = xmlSAX2Characters;
2809    hdlr->cdataBlock = xmlSAX2CDataBlock;
2810    hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
2811    hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
2812    hdlr->comment = xmlSAX2Comment;
2813    hdlr->warning = xmlParserWarning;
2814    hdlr->error = xmlParserError;
2815    hdlr->fatalError = xmlParserError;
2816
2817    hdlr->initialized = 1;
2818}
2819
2820/**
2821 * htmlDefaultSAXHandlerInit:
2822 *
2823 * Initialize the default SAX handler
2824 */
2825void
2826htmlDefaultSAXHandlerInit(void)
2827{
2828    xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr) &htmlDefaultSAXHandler);
2829}
2830
2831#endif /* LIBXML_HTML_ENABLED */
2832
2833#ifdef LIBXML_DOCB_ENABLED
2834
2835/**
2836 * xmlSAX2InitDocbDefaultSAXHandler:
2837 * @hdlr:  the SAX handler
2838 *
2839 * Initialize the default DocBook SAX2 handler
2840 */
2841void
2842xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr)
2843{
2844    if ((hdlr == NULL) || (hdlr->initialized != 0))
2845	return;
2846
2847    hdlr->internalSubset = xmlSAX2InternalSubset;
2848    hdlr->externalSubset = NULL;
2849    hdlr->isStandalone = xmlSAX2IsStandalone;
2850    hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
2851    hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
2852    hdlr->resolveEntity = xmlSAX2ResolveEntity;
2853    hdlr->getEntity = xmlSAX2GetEntity;
2854    hdlr->getParameterEntity = NULL;
2855    hdlr->entityDecl = xmlSAX2EntityDecl;
2856    hdlr->attributeDecl = NULL;
2857    hdlr->elementDecl = NULL;
2858    hdlr->notationDecl = NULL;
2859    hdlr->unparsedEntityDecl = NULL;
2860    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2861    hdlr->startDocument = xmlSAX2StartDocument;
2862    hdlr->endDocument = xmlSAX2EndDocument;
2863    hdlr->startElement = xmlSAX2StartElement;
2864    hdlr->endElement = xmlSAX2EndElement;
2865    hdlr->reference = xmlSAX2Reference;
2866    hdlr->characters = xmlSAX2Characters;
2867    hdlr->cdataBlock = NULL;
2868    hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
2869    hdlr->processingInstruction = NULL;
2870    hdlr->comment = xmlSAX2Comment;
2871    hdlr->warning = xmlParserWarning;
2872    hdlr->error = xmlParserError;
2873    hdlr->fatalError = xmlParserError;
2874
2875    hdlr->initialized = 1;
2876}
2877
2878/**
2879 * docbDefaultSAXHandlerInit:
2880 *
2881 * Initialize the default SAX handler
2882 */
2883void
2884docbDefaultSAXHandlerInit(void)
2885{
2886    xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr) &docbDefaultSAXHandler);
2887}
2888
2889#endif /* LIBXML_DOCB_ENABLED */
2890#define bottom_SAX2
2891#include "elfgcchack.h"
2892