Annotation of embedaddon/libxml2/SAX2.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>