Annotation of embedaddon/libxml2/SAX2.c, revision 1.1.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>