File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / SAX2.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 19:53:28 2014 UTC (9 years, 11 months ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_9_1p0, v2_9_1, HEAD
libxml2 2.9.1

    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:  */
   48: #define TODO								\
   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) {
   60:     xmlStructuredErrorFunc schannel = NULL;
   61:     const char *str1 = "out of memory\n";
   62: 
   63:     if (ctxt != NULL) {
   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);
   73: 	ctxt->errNo = XML_ERR_NO_MEMORY;
   74: 	ctxt->instate = XML_PARSER_EOF;
   75: 	ctxt->disableSAX = 1;
   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);
   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,
  146:                     XML_ERR_FATAL, NULL, 0,
  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,
  177:                     XML_ERR_WARNING, NULL, 0,
  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,
  202:                     XML_ERR_ERROR, NULL, 0,
  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,
  226:                     XML_ERR_WARNING, NULL, 0,
  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);
  260:     return((const xmlChar *) ctxt->input->filename);
  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:     }
  375:     ctxt->myDoc->intSubset =
  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;
  414: 	const xmlChar *oldencoding;
  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;
  436: 	oldencoding = ctxt->encoding;
  437: 	ctxt->encoding = NULL;
  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;
  448: 	    ctxt->encoding = oldencoding;
  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;
  494: 	if ((ctxt->encoding != NULL) &&
  495: 	    ((ctxt->dict == NULL) ||
  496: 	     (!xmlDictOwns(ctxt->dict, ctxt->encoding))))
  497: 	    xmlFree((xmlChar *) ctxt->encoding);
  498: 	ctxt->encoding = oldencoding;
  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;
  603: 	unsigned long oldnbent = ctxt->nbentities;
  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;
  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: 	}
  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)
  654:  * @name:  the entity name
  655:  * @type:  the entity type
  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;
  690: 
  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))
  699: 	    ctxt->sax->warning(ctxt->userData,
  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;
  709: 
  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
  724:  * @fullname:  the attribute name
  725:  * @type:  the attribute type
  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,
  768: 	   name, prefix, (xmlAttributeType) type,
  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)
  794:  * @name:  the element name
  795:  * @type:  the element type
  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))
  916: 	    ctxt->sax->warning(ctxt->userData,
  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;
  926: 
  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))
  936: 	    ctxt->sax->warning(ctxt->userData,
  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;
  946: 
  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))
 1190: 		    ctxt->sax->warning(ctxt->userData,
 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))
 1195: 			ctxt->sax->warning(ctxt->userData,
 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 */
 1215: 	if (name != NULL)
 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);
 1237: 		if (name != NULL)
 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 */
 1278: 	if (name != NULL)
 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) {
 1344: 
 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--;
 1356: 
 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);
 1413:     if (ns != NULL)
 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
 1512: 		 *  - there isn't already an attribute definition
 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:      */
 1601:     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
 1602:         ((ctxt->myDoc->intSubset == NULL) ||
 1603: 	 ((ctxt->myDoc->intSubset->notations == NULL) &&
 1604: 	  (ctxt->myDoc->intSubset->elements == NULL) &&
 1605: 	  (ctxt->myDoc->intSubset->attributes == NULL) &&
 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:     }
 1611: 
 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
 1799: 
 1800:     /* Capture end position and add node */
 1801:     if (cur != NULL && ctxt->record_info) {
 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);
 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: 
 1816: 
 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
 1832:  *
 1833:  * Callback for a text node
 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)) {
 1866: 	    /* store the string in the node overriding properties and nsDef */
 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: 
 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:     }
 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
 1921:  *
 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: 
 1987: 	ret->parent = ctxt->node;
 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)
 2011: 	    ret = xmlNewNsPropEatName(ctxt->node, namespace,
 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;
 2097: 
 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;
 2204:     xmlChar *lname = NULL;
 2205:     int i, j;
 2206: 
 2207:     if (ctx == NULL) return;
 2208:     parent = ctxt->node;
 2209:     /*
 2210:      * First check on validity:
 2211:      */
 2212:     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
 2213:         ((ctxt->myDoc->intSubset == NULL) ||
 2214: 	 ((ctxt->myDoc->intSubset->notations == NULL) &&
 2215: 	  (ctxt->myDoc->intSubset->elements == NULL) &&
 2216: 	  (ctxt->myDoc->intSubset->attributes == NULL) &&
 2217: 	  (ctxt->myDoc->intSubset->entities == NULL)))) {
 2218: 	xmlErrValid(ctxt, XML_DTD_NO_DTD,
 2219: 	  "Validation failed: no DTD found !", NULL, NULL);
 2220: 	ctxt->validate = 0;
 2221:     }
 2222: 
 2223:     /*
 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:     /*
 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 {
 2250: 	    if (lname == NULL)
 2251: 		ret->name = xmlStrdup(localname);
 2252: 	    else
 2253: 	        ret->name = lname;
 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)
 2263: 	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
 2264: 	                               (xmlChar *) localname, NULL);
 2265: 	else if (lname == NULL)
 2266: 	    ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
 2267: 	else
 2268: 	    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
 2269: 	                               (xmlChar *) lname, NULL);
 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: 
 2284:     if (parent == NULL) {
 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) {
 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: 	    }
 2401: 	    xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
 2402: 			       attributes[j+3], attributes[j+4]);
 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:  *
 2473:  * called when an entity xmlSAX2Reference is detected.
 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:             }
 2578: 	    if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len ||
 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:     }
 2682:     if (parent == NULL) {
 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:     }
 2743:     if (parent == NULL) {
 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>