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