Annotation of embedaddon/libxml2/parser.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
                      3:  *            implemented on top of the SAX interfaces
                      4:  *
                      5:  * References:
                      6:  *   The XML specification:
                      7:  *     http://www.w3.org/TR/REC-xml
                      8:  *   Original 1.0 version:
                      9:  *     http://www.w3.org/TR/1998/REC-xml-19980210
                     10:  *   XML second edition working draft
                     11:  *     http://www.w3.org/TR/2000/WD-xml-2e-20000814
                     12:  *
                     13:  * Okay this is a big file, the parser core is around 7000 lines, then it
                     14:  * is followed by the progressive parser top routines, then the various
                     15:  * high level APIs to call the parser and a few miscellaneous functions.
                     16:  * A number of helper functions and deprecated ones have been moved to
                     17:  * parserInternals.c to reduce this file size.
                     18:  * As much as possible the functions are associated with their relative
                     19:  * production in the XML specification. A few productions defining the
                     20:  * different ranges of character are actually implanted either in 
                     21:  * parserInternals.h or parserInternals.c
                     22:  * The DOM tree build is realized from the default SAX callbacks in
                     23:  * the module SAX.c.
                     24:  * The routines doing the validation checks are in valid.c and called either
                     25:  * from the SAX callbacks or as standalone functions using a preparsed
                     26:  * document.
                     27:  *
                     28:  * See Copyright for the status of this software.
                     29:  *
                     30:  * daniel@veillard.com
                     31:  */
                     32: 
                     33: #define IN_LIBXML
                     34: #include "libxml.h"
                     35: 
                     36: #if defined(WIN32) && !defined (__CYGWIN__)
                     37: #define XML_DIR_SEP '\\'
                     38: #else
                     39: #define XML_DIR_SEP '/'
                     40: #endif
                     41: 
                     42: #include <stdlib.h>
                     43: #include <string.h>
                     44: #include <stdarg.h>
                     45: #include <libxml/xmlmemory.h>
                     46: #include <libxml/threads.h>
                     47: #include <libxml/globals.h>
                     48: #include <libxml/tree.h>
                     49: #include <libxml/parser.h>
                     50: #include <libxml/parserInternals.h>
                     51: #include <libxml/valid.h>
                     52: #include <libxml/entities.h>
                     53: #include <libxml/xmlerror.h>
                     54: #include <libxml/encoding.h>
                     55: #include <libxml/xmlIO.h>
                     56: #include <libxml/uri.h>
                     57: #ifdef LIBXML_CATALOG_ENABLED
                     58: #include <libxml/catalog.h>
                     59: #endif
                     60: #ifdef LIBXML_SCHEMAS_ENABLED
                     61: #include <libxml/xmlschemastypes.h>
                     62: #include <libxml/relaxng.h>
                     63: #endif
                     64: #ifdef HAVE_CTYPE_H
                     65: #include <ctype.h>
                     66: #endif
                     67: #ifdef HAVE_STDLIB_H
                     68: #include <stdlib.h>
                     69: #endif
                     70: #ifdef HAVE_SYS_STAT_H
                     71: #include <sys/stat.h>
                     72: #endif
                     73: #ifdef HAVE_FCNTL_H
                     74: #include <fcntl.h>
                     75: #endif
                     76: #ifdef HAVE_UNISTD_H
                     77: #include <unistd.h>
                     78: #endif
                     79: #ifdef HAVE_ZLIB_H
                     80: #include <zlib.h>
                     81: #endif
1.1.1.2 ! misho      82: #ifdef HAVE_LZMA_H
        !            83: #include <lzma.h>
        !            84: #endif
1.1       misho      85: 
                     86: static void
                     87: xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
                     88: 
                     89: static xmlParserCtxtPtr
                     90: xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
                     91:                          const xmlChar *base, xmlParserCtxtPtr pctx);
                     92: 
                     93: /************************************************************************
                     94:  *                                                                     *
                     95:  *     Arbitrary limits set in the parser. See XML_PARSE_HUGE          *
                     96:  *                                                                     *
                     97:  ************************************************************************/
                     98: 
                     99: #define XML_PARSER_BIG_ENTITY 1000
                    100: #define XML_PARSER_LOT_ENTITY 5000
                    101: 
                    102: /*
                    103:  * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
                    104:  *    replacement over the size in byte of the input indicates that you have
                    105:  *    and eponential behaviour. A value of 10 correspond to at least 3 entity
                    106:  *    replacement per byte of input.
                    107:  */
                    108: #define XML_PARSER_NON_LINEAR 10
                    109: 
                    110: /*
                    111:  * xmlParserEntityCheck
                    112:  *
                    113:  * Function to check non-linear entity expansion behaviour
                    114:  * This is here to detect and stop exponential linear entity expansion
                    115:  * This is not a limitation of the parser but a safety
                    116:  * boundary feature. It can be disabled with the XML_PARSE_HUGE
                    117:  * parser option.
                    118:  */
                    119: static int
                    120: xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long size,
                    121:                      xmlEntityPtr ent)
                    122: {
                    123:     unsigned long consumed = 0;
                    124: 
                    125:     if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
                    126:         return (0);
                    127:     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
                    128:         return (1);
                    129:     if (size != 0) {
                    130:         /*
                    131:          * Do the check based on the replacement size of the entity
                    132:          */
                    133:         if (size < XML_PARSER_BIG_ENTITY)
                    134:            return(0);
                    135: 
                    136:         /*
                    137:          * A limit on the amount of text data reasonably used
                    138:          */
                    139:         if (ctxt->input != NULL) {
                    140:             consumed = ctxt->input->consumed +
                    141:                 (ctxt->input->cur - ctxt->input->base);
                    142:         }
                    143:         consumed += ctxt->sizeentities;
                    144: 
                    145:         if ((size < XML_PARSER_NON_LINEAR * consumed) &&
                    146:            (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
                    147:             return (0);
                    148:     } else if (ent != NULL) {
                    149:         /*
                    150:          * use the number of parsed entities in the replacement
                    151:          */
                    152:         size = ent->checked;
                    153: 
                    154:         /*
                    155:          * The amount of data parsed counting entities size only once
                    156:          */
                    157:         if (ctxt->input != NULL) {
                    158:             consumed = ctxt->input->consumed +
                    159:                 (ctxt->input->cur - ctxt->input->base);
                    160:         }
                    161:         consumed += ctxt->sizeentities;
                    162: 
                    163:         /*
                    164:          * Check the density of entities for the amount of data
                    165:         * knowing an entity reference will take at least 3 bytes
                    166:          */
                    167:         if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
                    168:             return (0);
                    169:     } else {
                    170:         /*
                    171:          * strange we got no data for checking just return
                    172:          */
                    173:         return (0);
                    174:     }
                    175: 
                    176:     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
                    177:     return (1);
                    178: }
                    179: 
                    180: /**
                    181:  * xmlParserMaxDepth:
                    182:  *
                    183:  * arbitrary depth limit for the XML documents that we allow to
                    184:  * process. This is not a limitation of the parser but a safety
                    185:  * boundary feature. It can be disabled with the XML_PARSE_HUGE
                    186:  * parser option.
                    187:  */
                    188: unsigned int xmlParserMaxDepth = 256;
                    189: 
                    190: 
                    191: 
                    192: #define SAX2 1
                    193: #define XML_PARSER_BIG_BUFFER_SIZE 300
                    194: #define XML_PARSER_BUFFER_SIZE 100
                    195: #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
                    196: 
                    197: /*
                    198:  * List of XML prefixed PI allowed by W3C specs
                    199:  */
                    200: 
                    201: static const char *xmlW3CPIs[] = {
                    202:     "xml-stylesheet",
1.1.1.2 ! misho     203:     "xml-model",
1.1       misho     204:     NULL
                    205: };
                    206: 
                    207: 
                    208: /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
                    209: static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
                    210:                                               const xmlChar **str);
                    211: 
                    212: static xmlParserErrors
                    213: xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
                    214:                      xmlSAXHandlerPtr sax,
                    215:                      void *user_data, int depth, const xmlChar *URL,
                    216:                      const xmlChar *ID, xmlNodePtr *list);
                    217: 
                    218: static int
                    219: xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
                    220:                           const char *encoding);
                    221: #ifdef LIBXML_LEGACY_ENABLED
                    222: static void
                    223: xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
                    224:                       xmlNodePtr lastNode);
                    225: #endif /* LIBXML_LEGACY_ENABLED */
                    226: 
                    227: static xmlParserErrors
                    228: xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
                    229:                      const xmlChar *string, void *user_data, xmlNodePtr *lst);
                    230: 
                    231: static int
                    232: xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
                    233: 
                    234: /************************************************************************
                    235:  *                                                                     *
                    236:  *             Some factorized error routines                          *
                    237:  *                                                                     *
                    238:  ************************************************************************/
                    239: 
                    240: /**
                    241:  * xmlErrAttributeDup:
                    242:  * @ctxt:  an XML parser context
                    243:  * @prefix:  the attribute prefix
                    244:  * @localname:  the attribute localname
                    245:  *
                    246:  * Handle a redefinition of attribute error
                    247:  */
                    248: static void
                    249: xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
                    250:                    const xmlChar * localname)
                    251: {
                    252:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    253:         (ctxt->instate == XML_PARSER_EOF))
                    254:        return;
                    255:     if (ctxt != NULL)
                    256:        ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
                    257: 
                    258:     if (prefix == NULL)
                    259:         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                    260:                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
                    261:                         (const char *) localname, NULL, NULL, 0, 0,
                    262:                         "Attribute %s redefined\n", localname);
                    263:     else
                    264:         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                    265:                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
                    266:                         (const char *) prefix, (const char *) localname,
                    267:                         NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
                    268:                         localname);
                    269:     if (ctxt != NULL) {
                    270:        ctxt->wellFormed = 0;
                    271:        if (ctxt->recovery == 0)
                    272:            ctxt->disableSAX = 1;
                    273:     }
                    274: }
                    275: 
                    276: /**
                    277:  * xmlFatalErr:
                    278:  * @ctxt:  an XML parser context
                    279:  * @error:  the error number
                    280:  * @extra:  extra information string
                    281:  *
                    282:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    283:  */
                    284: static void
                    285: xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
                    286: {
                    287:     const char *errmsg;
                    288: 
                    289:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    290:         (ctxt->instate == XML_PARSER_EOF))
                    291:        return;
                    292:     switch (error) {
                    293:         case XML_ERR_INVALID_HEX_CHARREF:
                    294:             errmsg = "CharRef: invalid hexadecimal value\n";
                    295:             break;
                    296:         case XML_ERR_INVALID_DEC_CHARREF:
                    297:             errmsg = "CharRef: invalid decimal value\n";
                    298:             break;
                    299:         case XML_ERR_INVALID_CHARREF:
                    300:             errmsg = "CharRef: invalid value\n";
                    301:             break;
                    302:         case XML_ERR_INTERNAL_ERROR:
                    303:             errmsg = "internal error";
                    304:             break;
                    305:         case XML_ERR_PEREF_AT_EOF:
                    306:             errmsg = "PEReference at end of document\n";
                    307:             break;
                    308:         case XML_ERR_PEREF_IN_PROLOG:
                    309:             errmsg = "PEReference in prolog\n";
                    310:             break;
                    311:         case XML_ERR_PEREF_IN_EPILOG:
                    312:             errmsg = "PEReference in epilog\n";
                    313:             break;
                    314:         case XML_ERR_PEREF_NO_NAME:
                    315:             errmsg = "PEReference: no name\n";
                    316:             break;
                    317:         case XML_ERR_PEREF_SEMICOL_MISSING:
                    318:             errmsg = "PEReference: expecting ';'\n";
                    319:             break;
                    320:         case XML_ERR_ENTITY_LOOP:
                    321:             errmsg = "Detected an entity reference loop\n";
                    322:             break;
                    323:         case XML_ERR_ENTITY_NOT_STARTED:
                    324:             errmsg = "EntityValue: \" or ' expected\n";
                    325:             break;
                    326:         case XML_ERR_ENTITY_PE_INTERNAL:
                    327:             errmsg = "PEReferences forbidden in internal subset\n";
                    328:             break;
                    329:         case XML_ERR_ENTITY_NOT_FINISHED:
                    330:             errmsg = "EntityValue: \" or ' expected\n";
                    331:             break;
                    332:         case XML_ERR_ATTRIBUTE_NOT_STARTED:
                    333:             errmsg = "AttValue: \" or ' expected\n";
                    334:             break;
                    335:         case XML_ERR_LT_IN_ATTRIBUTE:
                    336:             errmsg = "Unescaped '<' not allowed in attributes values\n";
                    337:             break;
                    338:         case XML_ERR_LITERAL_NOT_STARTED:
                    339:             errmsg = "SystemLiteral \" or ' expected\n";
                    340:             break;
                    341:         case XML_ERR_LITERAL_NOT_FINISHED:
                    342:             errmsg = "Unfinished System or Public ID \" or ' expected\n";
                    343:             break;
                    344:         case XML_ERR_MISPLACED_CDATA_END:
                    345:             errmsg = "Sequence ']]>' not allowed in content\n";
                    346:             break;
                    347:         case XML_ERR_URI_REQUIRED:
                    348:             errmsg = "SYSTEM or PUBLIC, the URI is missing\n";
                    349:             break;
                    350:         case XML_ERR_PUBID_REQUIRED:
                    351:             errmsg = "PUBLIC, the Public Identifier is missing\n";
                    352:             break;
                    353:         case XML_ERR_HYPHEN_IN_COMMENT:
                    354:             errmsg = "Comment must not contain '--' (double-hyphen)\n";
                    355:             break;
                    356:         case XML_ERR_PI_NOT_STARTED:
                    357:             errmsg = "xmlParsePI : no target name\n";
                    358:             break;
                    359:         case XML_ERR_RESERVED_XML_NAME:
                    360:             errmsg = "Invalid PI name\n";
                    361:             break;
                    362:         case XML_ERR_NOTATION_NOT_STARTED:
                    363:             errmsg = "NOTATION: Name expected here\n";
                    364:             break;
                    365:         case XML_ERR_NOTATION_NOT_FINISHED:
                    366:             errmsg = "'>' required to close NOTATION declaration\n";
                    367:             break;
                    368:         case XML_ERR_VALUE_REQUIRED:
                    369:             errmsg = "Entity value required\n";
                    370:             break;
                    371:         case XML_ERR_URI_FRAGMENT:
                    372:             errmsg = "Fragment not allowed";
                    373:             break;
                    374:         case XML_ERR_ATTLIST_NOT_STARTED:
                    375:             errmsg = "'(' required to start ATTLIST enumeration\n";
                    376:             break;
                    377:         case XML_ERR_NMTOKEN_REQUIRED:
                    378:             errmsg = "NmToken expected in ATTLIST enumeration\n";
                    379:             break;
                    380:         case XML_ERR_ATTLIST_NOT_FINISHED:
                    381:             errmsg = "')' required to finish ATTLIST enumeration\n";
                    382:             break;
                    383:         case XML_ERR_MIXED_NOT_STARTED:
                    384:             errmsg = "MixedContentDecl : '|' or ')*' expected\n";
                    385:             break;
                    386:         case XML_ERR_PCDATA_REQUIRED:
                    387:             errmsg = "MixedContentDecl : '#PCDATA' expected\n";
                    388:             break;
                    389:         case XML_ERR_ELEMCONTENT_NOT_STARTED:
                    390:             errmsg = "ContentDecl : Name or '(' expected\n";
                    391:             break;
                    392:         case XML_ERR_ELEMCONTENT_NOT_FINISHED:
                    393:             errmsg = "ContentDecl : ',' '|' or ')' expected\n";
                    394:             break;
                    395:         case XML_ERR_PEREF_IN_INT_SUBSET:
                    396:             errmsg =
                    397:                 "PEReference: forbidden within markup decl in internal subset\n";
                    398:             break;
                    399:         case XML_ERR_GT_REQUIRED:
                    400:             errmsg = "expected '>'\n";
                    401:             break;
                    402:         case XML_ERR_CONDSEC_INVALID:
                    403:             errmsg = "XML conditional section '[' expected\n";
                    404:             break;
                    405:         case XML_ERR_EXT_SUBSET_NOT_FINISHED:
                    406:             errmsg = "Content error in the external subset\n";
                    407:             break;
                    408:         case XML_ERR_CONDSEC_INVALID_KEYWORD:
                    409:             errmsg =
                    410:                 "conditional section INCLUDE or IGNORE keyword expected\n";
                    411:             break;
                    412:         case XML_ERR_CONDSEC_NOT_FINISHED:
                    413:             errmsg = "XML conditional section not closed\n";
                    414:             break;
                    415:         case XML_ERR_XMLDECL_NOT_STARTED:
                    416:             errmsg = "Text declaration '<?xml' required\n";
                    417:             break;
                    418:         case XML_ERR_XMLDECL_NOT_FINISHED:
                    419:             errmsg = "parsing XML declaration: '?>' expected\n";
                    420:             break;
                    421:         case XML_ERR_EXT_ENTITY_STANDALONE:
                    422:             errmsg = "external parsed entities cannot be standalone\n";
                    423:             break;
                    424:         case XML_ERR_ENTITYREF_SEMICOL_MISSING:
                    425:             errmsg = "EntityRef: expecting ';'\n";
                    426:             break;
                    427:         case XML_ERR_DOCTYPE_NOT_FINISHED:
                    428:             errmsg = "DOCTYPE improperly terminated\n";
                    429:             break;
                    430:         case XML_ERR_LTSLASH_REQUIRED:
                    431:             errmsg = "EndTag: '</' not found\n";
                    432:             break;
                    433:         case XML_ERR_EQUAL_REQUIRED:
                    434:             errmsg = "expected '='\n";
                    435:             break;
                    436:         case XML_ERR_STRING_NOT_CLOSED:
                    437:             errmsg = "String not closed expecting \" or '\n";
                    438:             break;
                    439:         case XML_ERR_STRING_NOT_STARTED:
                    440:             errmsg = "String not started expecting ' or \"\n";
                    441:             break;
                    442:         case XML_ERR_ENCODING_NAME:
                    443:             errmsg = "Invalid XML encoding name\n";
                    444:             break;
                    445:         case XML_ERR_STANDALONE_VALUE:
                    446:             errmsg = "standalone accepts only 'yes' or 'no'\n";
                    447:             break;
                    448:         case XML_ERR_DOCUMENT_EMPTY:
                    449:             errmsg = "Document is empty\n";
                    450:             break;
                    451:         case XML_ERR_DOCUMENT_END:
                    452:             errmsg = "Extra content at the end of the document\n";
                    453:             break;
                    454:         case XML_ERR_NOT_WELL_BALANCED:
                    455:             errmsg = "chunk is not well balanced\n";
                    456:             break;
                    457:         case XML_ERR_EXTRA_CONTENT:
                    458:             errmsg = "extra content at the end of well balanced chunk\n";
                    459:             break;
                    460:         case XML_ERR_VERSION_MISSING:
                    461:             errmsg = "Malformed declaration expecting version\n";
                    462:             break;
                    463: #if 0
                    464:         case:
                    465:             errmsg = "\n";
                    466:             break;
                    467: #endif
                    468:         default:
                    469:             errmsg = "Unregistered error message\n";
                    470:     }
                    471:     if (ctxt != NULL)
                    472:        ctxt->errNo = error;
                    473:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
                    474:                     XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, errmsg,
                    475:                     info);
                    476:     if (ctxt != NULL) {
                    477:        ctxt->wellFormed = 0;
                    478:        if (ctxt->recovery == 0)
                    479:            ctxt->disableSAX = 1;
                    480:     }
                    481: }
                    482: 
                    483: /**
                    484:  * xmlFatalErrMsg:
                    485:  * @ctxt:  an XML parser context
                    486:  * @error:  the error number
                    487:  * @msg:  the error message
                    488:  *
                    489:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    490:  */
                    491: static void
                    492: xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    493:                const char *msg)
                    494: {
                    495:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    496:         (ctxt->instate == XML_PARSER_EOF))
                    497:        return;
                    498:     if (ctxt != NULL)
                    499:        ctxt->errNo = error;
                    500:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
                    501:                     XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
                    502:     if (ctxt != NULL) {
                    503:        ctxt->wellFormed = 0;
                    504:        if (ctxt->recovery == 0)
                    505:            ctxt->disableSAX = 1;
                    506:     }
                    507: }
                    508: 
                    509: /**
                    510:  * xmlWarningMsg:
                    511:  * @ctxt:  an XML parser context
                    512:  * @error:  the error number
                    513:  * @msg:  the error message
                    514:  * @str1:  extra data
                    515:  * @str2:  extra data
                    516:  *
                    517:  * Handle a warning.
                    518:  */
                    519: static void
                    520: xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    521:               const char *msg, const xmlChar *str1, const xmlChar *str2)
                    522: {
                    523:     xmlStructuredErrorFunc schannel = NULL;
                    524: 
                    525:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    526:         (ctxt->instate == XML_PARSER_EOF))
                    527:        return;
                    528:     if ((ctxt != NULL) && (ctxt->sax != NULL) &&
                    529:         (ctxt->sax->initialized == XML_SAX2_MAGIC))
                    530:         schannel = ctxt->sax->serror;
                    531:     if (ctxt != NULL) {
                    532:         __xmlRaiseError(schannel,
                    533:                     (ctxt->sax) ? ctxt->sax->warning : NULL,
                    534:                     ctxt->userData,
                    535:                     ctxt, NULL, XML_FROM_PARSER, error,
                    536:                     XML_ERR_WARNING, NULL, 0,
                    537:                    (const char *) str1, (const char *) str2, NULL, 0, 0,
                    538:                    msg, (const char *) str1, (const char *) str2);
                    539:     } else {
                    540:         __xmlRaiseError(schannel, NULL, NULL,
                    541:                     ctxt, NULL, XML_FROM_PARSER, error,
                    542:                     XML_ERR_WARNING, NULL, 0,
                    543:                    (const char *) str1, (const char *) str2, NULL, 0, 0,
                    544:                    msg, (const char *) str1, (const char *) str2);
                    545:     }
                    546: }
                    547: 
                    548: /**
                    549:  * xmlValidityError:
                    550:  * @ctxt:  an XML parser context
                    551:  * @error:  the error number
                    552:  * @msg:  the error message
                    553:  * @str1:  extra data
                    554:  *
                    555:  * Handle a validity error.
                    556:  */
                    557: static void
                    558: xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    559:               const char *msg, const xmlChar *str1, const xmlChar *str2)
                    560: {
                    561:     xmlStructuredErrorFunc schannel = NULL;
                    562: 
                    563:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    564:         (ctxt->instate == XML_PARSER_EOF))
                    565:        return;
                    566:     if (ctxt != NULL) {
                    567:        ctxt->errNo = error;
                    568:        if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
                    569:            schannel = ctxt->sax->serror;
                    570:     }
                    571:     if (ctxt != NULL) {
                    572:         __xmlRaiseError(schannel,
                    573:                     ctxt->vctxt.error, ctxt->vctxt.userData,
                    574:                     ctxt, NULL, XML_FROM_DTD, error,
                    575:                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
                    576:                    (const char *) str2, NULL, 0, 0,
                    577:                    msg, (const char *) str1, (const char *) str2);
                    578:        ctxt->valid = 0;
                    579:     } else {
                    580:         __xmlRaiseError(schannel, NULL, NULL,
                    581:                     ctxt, NULL, XML_FROM_DTD, error,
                    582:                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
                    583:                    (const char *) str2, NULL, 0, 0,
                    584:                    msg, (const char *) str1, (const char *) str2);
                    585:     }
                    586: }
                    587: 
                    588: /**
                    589:  * xmlFatalErrMsgInt:
                    590:  * @ctxt:  an XML parser context
                    591:  * @error:  the error number
                    592:  * @msg:  the error message
                    593:  * @val:  an integer value
                    594:  *
                    595:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    596:  */
                    597: static void
                    598: xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    599:                   const char *msg, int val)
                    600: {
                    601:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    602:         (ctxt->instate == XML_PARSER_EOF))
                    603:        return;
                    604:     if (ctxt != NULL)
                    605:        ctxt->errNo = error;
                    606:     __xmlRaiseError(NULL, NULL, NULL,
                    607:                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                    608:                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
                    609:     if (ctxt != NULL) {
                    610:        ctxt->wellFormed = 0;
                    611:        if (ctxt->recovery == 0)
                    612:            ctxt->disableSAX = 1;
                    613:     }
                    614: }
                    615: 
                    616: /**
                    617:  * xmlFatalErrMsgStrIntStr:
                    618:  * @ctxt:  an XML parser context
                    619:  * @error:  the error number
                    620:  * @msg:  the error message
                    621:  * @str1:  an string info
                    622:  * @val:  an integer value
                    623:  * @str2:  an string info
                    624:  *
                    625:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    626:  */
                    627: static void
                    628: xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    629:                   const char *msg, const xmlChar *str1, int val, 
                    630:                  const xmlChar *str2)
                    631: {
                    632:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    633:         (ctxt->instate == XML_PARSER_EOF))
                    634:        return;
                    635:     if (ctxt != NULL)
                    636:        ctxt->errNo = error;
                    637:     __xmlRaiseError(NULL, NULL, NULL,
                    638:                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                    639:                     NULL, 0, (const char *) str1, (const char *) str2,
                    640:                    NULL, val, 0, msg, str1, val, str2);
                    641:     if (ctxt != NULL) {
                    642:        ctxt->wellFormed = 0;
                    643:        if (ctxt->recovery == 0)
                    644:            ctxt->disableSAX = 1;
                    645:     }
                    646: }
                    647: 
                    648: /**
                    649:  * xmlFatalErrMsgStr:
                    650:  * @ctxt:  an XML parser context
                    651:  * @error:  the error number
                    652:  * @msg:  the error message
                    653:  * @val:  a string value
                    654:  *
                    655:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    656:  */
                    657: static void
                    658: xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    659:                   const char *msg, const xmlChar * val)
                    660: {
                    661:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    662:         (ctxt->instate == XML_PARSER_EOF))
                    663:        return;
                    664:     if (ctxt != NULL)
                    665:        ctxt->errNo = error;
                    666:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
                    667:                     XML_FROM_PARSER, error, XML_ERR_FATAL,
                    668:                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
                    669:                     val);
                    670:     if (ctxt != NULL) {
                    671:        ctxt->wellFormed = 0;
                    672:        if (ctxt->recovery == 0)
                    673:            ctxt->disableSAX = 1;
                    674:     }
                    675: }
                    676: 
                    677: /**
                    678:  * xmlErrMsgStr:
                    679:  * @ctxt:  an XML parser context
                    680:  * @error:  the error number
                    681:  * @msg:  the error message
                    682:  * @val:  a string value
                    683:  *
                    684:  * Handle a non fatal parser error
                    685:  */
                    686: static void
                    687: xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    688:                   const char *msg, const xmlChar * val)
                    689: {
                    690:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    691:         (ctxt->instate == XML_PARSER_EOF))
                    692:        return;
                    693:     if (ctxt != NULL)
                    694:        ctxt->errNo = error;
                    695:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
                    696:                     XML_FROM_PARSER, error, XML_ERR_ERROR,
                    697:                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
                    698:                     val);
                    699: }
                    700: 
                    701: /**
                    702:  * xmlNsErr:
                    703:  * @ctxt:  an XML parser context
                    704:  * @error:  the error number
                    705:  * @msg:  the message
                    706:  * @info1:  extra information string
                    707:  * @info2:  extra information string
                    708:  *
                    709:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    710:  */
                    711: static void
                    712: xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    713:          const char *msg,
                    714:          const xmlChar * info1, const xmlChar * info2,
                    715:          const xmlChar * info3)
                    716: {
                    717:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    718:         (ctxt->instate == XML_PARSER_EOF))
                    719:        return;
                    720:     if (ctxt != NULL)
                    721:        ctxt->errNo = error;
                    722:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
                    723:                     XML_ERR_ERROR, NULL, 0, (const char *) info1,
                    724:                     (const char *) info2, (const char *) info3, 0, 0, msg,
                    725:                     info1, info2, info3);
                    726:     if (ctxt != NULL)
                    727:        ctxt->nsWellFormed = 0;
                    728: }
                    729: 
                    730: /**
                    731:  * xmlNsWarn
                    732:  * @ctxt:  an XML parser context
                    733:  * @error:  the error number
                    734:  * @msg:  the message
                    735:  * @info1:  extra information string
                    736:  * @info2:  extra information string
                    737:  *
1.1.1.2 ! misho     738:  * Handle a namespace warning error
1.1       misho     739:  */
                    740: static void
                    741: xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    742:          const char *msg,
                    743:          const xmlChar * info1, const xmlChar * info2,
                    744:          const xmlChar * info3)
                    745: {
                    746:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    747:         (ctxt->instate == XML_PARSER_EOF))
                    748:        return;
                    749:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
                    750:                     XML_ERR_WARNING, NULL, 0, (const char *) info1,
                    751:                     (const char *) info2, (const char *) info3, 0, 0, msg,
                    752:                     info1, info2, info3);
                    753: }
                    754: 
                    755: /************************************************************************
                    756:  *                                                                     *
                    757:  *             Library wide options                                    *
                    758:  *                                                                     *
                    759:  ************************************************************************/
                    760: 
                    761: /**
                    762:   * xmlHasFeature:
                    763:   * @feature: the feature to be examined
                    764:   *
                    765:   * Examines if the library has been compiled with a given feature.
                    766:   *
                    767:   * Returns a non-zero value if the feature exist, otherwise zero.
                    768:   * Returns zero (0) if the feature does not exist or an unknown
                    769:   * unknown feature is requested, non-zero otherwise.
                    770:   */
                    771: int
                    772: xmlHasFeature(xmlFeature feature)
                    773: {
                    774:     switch (feature) {
                    775:        case XML_WITH_THREAD:
                    776: #ifdef LIBXML_THREAD_ENABLED
                    777:            return(1);
                    778: #else
                    779:            return(0);
                    780: #endif
                    781:         case XML_WITH_TREE:
                    782: #ifdef LIBXML_TREE_ENABLED
                    783:             return(1);
                    784: #else
                    785:             return(0);
                    786: #endif
                    787:         case XML_WITH_OUTPUT:
                    788: #ifdef LIBXML_OUTPUT_ENABLED
                    789:             return(1);
                    790: #else
                    791:             return(0);
                    792: #endif
                    793:         case XML_WITH_PUSH:
                    794: #ifdef LIBXML_PUSH_ENABLED
                    795:             return(1);
                    796: #else
                    797:             return(0);
                    798: #endif
                    799:         case XML_WITH_READER:
                    800: #ifdef LIBXML_READER_ENABLED
                    801:             return(1);
                    802: #else
                    803:             return(0);
                    804: #endif
                    805:         case XML_WITH_PATTERN:
                    806: #ifdef LIBXML_PATTERN_ENABLED
                    807:             return(1);
                    808: #else
                    809:             return(0);
                    810: #endif
                    811:         case XML_WITH_WRITER:
                    812: #ifdef LIBXML_WRITER_ENABLED
                    813:             return(1);
                    814: #else
                    815:             return(0);
                    816: #endif
                    817:         case XML_WITH_SAX1:
                    818: #ifdef LIBXML_SAX1_ENABLED
                    819:             return(1);
                    820: #else
                    821:             return(0);
                    822: #endif
                    823:         case XML_WITH_FTP:
                    824: #ifdef LIBXML_FTP_ENABLED
                    825:             return(1);
                    826: #else
                    827:             return(0);
                    828: #endif
                    829:         case XML_WITH_HTTP:
                    830: #ifdef LIBXML_HTTP_ENABLED
                    831:             return(1);
                    832: #else
                    833:             return(0);
                    834: #endif
                    835:         case XML_WITH_VALID:
                    836: #ifdef LIBXML_VALID_ENABLED
                    837:             return(1);
                    838: #else
                    839:             return(0);
                    840: #endif
                    841:         case XML_WITH_HTML:
                    842: #ifdef LIBXML_HTML_ENABLED
                    843:             return(1);
                    844: #else
                    845:             return(0);
                    846: #endif
                    847:         case XML_WITH_LEGACY:
                    848: #ifdef LIBXML_LEGACY_ENABLED
                    849:             return(1);
                    850: #else
                    851:             return(0);
                    852: #endif
                    853:         case XML_WITH_C14N:
                    854: #ifdef LIBXML_C14N_ENABLED
                    855:             return(1);
                    856: #else
                    857:             return(0);
                    858: #endif
                    859:         case XML_WITH_CATALOG:
                    860: #ifdef LIBXML_CATALOG_ENABLED
                    861:             return(1);
                    862: #else
                    863:             return(0);
                    864: #endif
                    865:         case XML_WITH_XPATH:
                    866: #ifdef LIBXML_XPATH_ENABLED
                    867:             return(1);
                    868: #else
                    869:             return(0);
                    870: #endif
                    871:         case XML_WITH_XPTR:
                    872: #ifdef LIBXML_XPTR_ENABLED
                    873:             return(1);
                    874: #else
                    875:             return(0);
                    876: #endif
                    877:         case XML_WITH_XINCLUDE:
                    878: #ifdef LIBXML_XINCLUDE_ENABLED
                    879:             return(1);
                    880: #else
                    881:             return(0);
                    882: #endif
                    883:         case XML_WITH_ICONV:
                    884: #ifdef LIBXML_ICONV_ENABLED
                    885:             return(1);
                    886: #else
                    887:             return(0);
                    888: #endif
                    889:         case XML_WITH_ISO8859X:
                    890: #ifdef LIBXML_ISO8859X_ENABLED
                    891:             return(1);
                    892: #else
                    893:             return(0);
                    894: #endif
                    895:         case XML_WITH_UNICODE:
                    896: #ifdef LIBXML_UNICODE_ENABLED
                    897:             return(1);
                    898: #else
                    899:             return(0);
                    900: #endif
                    901:         case XML_WITH_REGEXP:
                    902: #ifdef LIBXML_REGEXP_ENABLED
                    903:             return(1);
                    904: #else
                    905:             return(0);
                    906: #endif
                    907:         case XML_WITH_AUTOMATA:
                    908: #ifdef LIBXML_AUTOMATA_ENABLED
                    909:             return(1);
                    910: #else
                    911:             return(0);
                    912: #endif
                    913:         case XML_WITH_EXPR:
                    914: #ifdef LIBXML_EXPR_ENABLED
                    915:             return(1);
                    916: #else
                    917:             return(0);
                    918: #endif
                    919:         case XML_WITH_SCHEMAS:
                    920: #ifdef LIBXML_SCHEMAS_ENABLED
                    921:             return(1);
                    922: #else
                    923:             return(0);
                    924: #endif
                    925:         case XML_WITH_SCHEMATRON:
                    926: #ifdef LIBXML_SCHEMATRON_ENABLED
                    927:             return(1);
                    928: #else
                    929:             return(0);
                    930: #endif
                    931:         case XML_WITH_MODULES:
                    932: #ifdef LIBXML_MODULES_ENABLED
                    933:             return(1);
                    934: #else
                    935:             return(0);
                    936: #endif
                    937:         case XML_WITH_DEBUG:
                    938: #ifdef LIBXML_DEBUG_ENABLED
                    939:             return(1);
                    940: #else
                    941:             return(0);
                    942: #endif
                    943:         case XML_WITH_DEBUG_MEM:
                    944: #ifdef DEBUG_MEMORY_LOCATION
                    945:             return(1);
                    946: #else
                    947:             return(0);
                    948: #endif
                    949:         case XML_WITH_DEBUG_RUN:
                    950: #ifdef LIBXML_DEBUG_RUNTIME
                    951:             return(1);
                    952: #else
                    953:             return(0);
                    954: #endif
                    955:         case XML_WITH_ZLIB:
                    956: #ifdef LIBXML_ZLIB_ENABLED
                    957:             return(1);
                    958: #else
                    959:             return(0);
                    960: #endif
1.1.1.2 ! misho     961:         case XML_WITH_LZMA:
        !           962: #ifdef LIBXML_LZMA_ENABLED
        !           963:             return(1);
        !           964: #else
        !           965:             return(0);
        !           966: #endif
1.1       misho     967:         case XML_WITH_ICU:
                    968: #ifdef LIBXML_ICU_ENABLED
                    969:             return(1);
                    970: #else
                    971:             return(0);
                    972: #endif
                    973:         default:
                    974:            break;
                    975:      }
                    976:      return(0);
                    977: }
                    978: 
                    979: /************************************************************************
                    980:  *                                                                     *
                    981:  *             SAX2 defaulted attributes handling                      *
                    982:  *                                                                     *
                    983:  ************************************************************************/
                    984: 
                    985: /**
                    986:  * xmlDetectSAX2:
                    987:  * @ctxt:  an XML parser context
                    988:  *
                    989:  * Do the SAX2 detection and specific intialization
                    990:  */
                    991: static void
                    992: xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
                    993:     if (ctxt == NULL) return;
                    994: #ifdef LIBXML_SAX1_ENABLED
                    995:     if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
                    996:         ((ctxt->sax->startElementNs != NULL) ||
                    997:          (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
                    998: #else
                    999:     ctxt->sax2 = 1;
                   1000: #endif /* LIBXML_SAX1_ENABLED */
                   1001: 
                   1002:     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
                   1003:     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
                   1004:     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
                   1005:     if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) || 
                   1006:                (ctxt->str_xml_ns == NULL)) {
                   1007:         xmlErrMemory(ctxt, NULL);
                   1008:     }
                   1009: }
                   1010: 
                   1011: typedef struct _xmlDefAttrs xmlDefAttrs;
                   1012: typedef xmlDefAttrs *xmlDefAttrsPtr;
                   1013: struct _xmlDefAttrs {
                   1014:     int nbAttrs;       /* number of defaulted attributes on that element */
                   1015:     int maxAttrs;       /* the size of the array */
                   1016:     const xmlChar *values[5]; /* array of localname/prefix/values/external */
                   1017: };
                   1018: 
                   1019: /**
                   1020:  * xmlAttrNormalizeSpace:
                   1021:  * @src: the source string
                   1022:  * @dst: the target string
                   1023:  *
                   1024:  * Normalize the space in non CDATA attribute values:
                   1025:  * If the attribute type is not CDATA, then the XML processor MUST further
                   1026:  * process the normalized attribute value by discarding any leading and
                   1027:  * trailing space (#x20) characters, and by replacing sequences of space
                   1028:  * (#x20) characters by a single space (#x20) character.
                   1029:  * Note that the size of dst need to be at least src, and if one doesn't need
                   1030:  * to preserve dst (and it doesn't come from a dictionary or read-only) then
                   1031:  * passing src as dst is just fine.
                   1032:  *
                   1033:  * Returns a pointer to the normalized value (dst) or NULL if no conversion
                   1034:  *         is needed.
                   1035:  */
                   1036: static xmlChar *
                   1037: xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
                   1038: {
                   1039:     if ((src == NULL) || (dst == NULL))
                   1040:         return(NULL);
                   1041: 
                   1042:     while (*src == 0x20) src++;
                   1043:     while (*src != 0) {
                   1044:        if (*src == 0x20) {
                   1045:            while (*src == 0x20) src++;
                   1046:            if (*src != 0)
                   1047:                *dst++ = 0x20;
                   1048:        } else {
                   1049:            *dst++ = *src++;
                   1050:        }
                   1051:     }
                   1052:     *dst = 0;
                   1053:     if (dst == src)
                   1054:        return(NULL);
                   1055:     return(dst);
                   1056: }
                   1057: 
                   1058: /**
                   1059:  * xmlAttrNormalizeSpace2:
                   1060:  * @src: the source string
                   1061:  *
                   1062:  * Normalize the space in non CDATA attribute values, a slightly more complex
                   1063:  * front end to avoid allocation problems when running on attribute values
                   1064:  * coming from the input.
                   1065:  *
                   1066:  * Returns a pointer to the normalized value (dst) or NULL if no conversion
                   1067:  *         is needed.
                   1068:  */
                   1069: static const xmlChar *
                   1070: xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
                   1071: {
                   1072:     int i;
                   1073:     int remove_head = 0;
                   1074:     int need_realloc = 0;
                   1075:     const xmlChar *cur;
                   1076: 
                   1077:     if ((ctxt == NULL) || (src == NULL) || (len == NULL))
                   1078:         return(NULL);
                   1079:     i = *len;
                   1080:     if (i <= 0)
                   1081:         return(NULL);
                   1082: 
                   1083:     cur = src;
                   1084:     while (*cur == 0x20) {
                   1085:         cur++;
                   1086:        remove_head++;
                   1087:     }
                   1088:     while (*cur != 0) {
                   1089:        if (*cur == 0x20) {
                   1090:            cur++;
                   1091:            if ((*cur == 0x20) || (*cur == 0)) {
                   1092:                need_realloc = 1;
                   1093:                break;
                   1094:            }
                   1095:        } else
                   1096:            cur++;
                   1097:     }
                   1098:     if (need_realloc) {
                   1099:         xmlChar *ret;
                   1100: 
                   1101:        ret = xmlStrndup(src + remove_head, i - remove_head + 1);
                   1102:        if (ret == NULL) {
                   1103:            xmlErrMemory(ctxt, NULL);
                   1104:            return(NULL);
                   1105:        }
                   1106:        xmlAttrNormalizeSpace(ret, ret);
                   1107:        *len = (int) strlen((const char *)ret);
                   1108:         return(ret);
                   1109:     } else if (remove_head) {
                   1110:         *len -= remove_head;
                   1111:         memmove(src, src + remove_head, 1 + *len);
                   1112:        return(src);
                   1113:     }
                   1114:     return(NULL);
                   1115: }
                   1116: 
                   1117: /**
                   1118:  * xmlAddDefAttrs:
                   1119:  * @ctxt:  an XML parser context
                   1120:  * @fullname:  the element fullname
                   1121:  * @fullattr:  the attribute fullname
                   1122:  * @value:  the attribute value
                   1123:  *
                   1124:  * Add a defaulted attribute for an element
                   1125:  */
                   1126: static void
                   1127: xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
                   1128:                const xmlChar *fullname,
                   1129:                const xmlChar *fullattr,
                   1130:                const xmlChar *value) {
                   1131:     xmlDefAttrsPtr defaults;
                   1132:     int len;
                   1133:     const xmlChar *name;
                   1134:     const xmlChar *prefix;
                   1135: 
                   1136:     /*
                   1137:      * Allows to detect attribute redefinitions
                   1138:      */
                   1139:     if (ctxt->attsSpecial != NULL) {
                   1140:         if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
                   1141:            return;
                   1142:     }
                   1143: 
                   1144:     if (ctxt->attsDefault == NULL) {
                   1145:         ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
                   1146:        if (ctxt->attsDefault == NULL)
                   1147:            goto mem_error;
                   1148:     }
                   1149: 
                   1150:     /*
                   1151:      * split the element name into prefix:localname , the string found
                   1152:      * are within the DTD and then not associated to namespace names.
                   1153:      */
                   1154:     name = xmlSplitQName3(fullname, &len);
                   1155:     if (name == NULL) {
                   1156:         name = xmlDictLookup(ctxt->dict, fullname, -1);
                   1157:        prefix = NULL;
                   1158:     } else {
                   1159:         name = xmlDictLookup(ctxt->dict, name, -1);
                   1160:        prefix = xmlDictLookup(ctxt->dict, fullname, len);
                   1161:     }
                   1162: 
                   1163:     /*
                   1164:      * make sure there is some storage
                   1165:      */
                   1166:     defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
                   1167:     if (defaults == NULL) {
                   1168:         defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
                   1169:                           (4 * 5) * sizeof(const xmlChar *));
                   1170:        if (defaults == NULL)
                   1171:            goto mem_error;
                   1172:        defaults->nbAttrs = 0;
                   1173:        defaults->maxAttrs = 4;
                   1174:        if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
                   1175:                                defaults, NULL) < 0) {
                   1176:            xmlFree(defaults);
                   1177:            goto mem_error;
                   1178:        }
                   1179:     } else if (defaults->nbAttrs >= defaults->maxAttrs) {
                   1180:         xmlDefAttrsPtr temp;
                   1181: 
                   1182:         temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
                   1183:                       (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
                   1184:        if (temp == NULL)
                   1185:            goto mem_error;
                   1186:        defaults = temp;
                   1187:        defaults->maxAttrs *= 2;
                   1188:        if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
                   1189:                                defaults, NULL) < 0) {
                   1190:            xmlFree(defaults);
                   1191:            goto mem_error;
                   1192:        }
                   1193:     }
                   1194: 
                   1195:     /*
                   1196:      * Split the element name into prefix:localname , the string found
                   1197:      * are within the DTD and hen not associated to namespace names.
                   1198:      */
                   1199:     name = xmlSplitQName3(fullattr, &len);
                   1200:     if (name == NULL) {
                   1201:         name = xmlDictLookup(ctxt->dict, fullattr, -1);
                   1202:        prefix = NULL;
                   1203:     } else {
                   1204:         name = xmlDictLookup(ctxt->dict, name, -1);
                   1205:        prefix = xmlDictLookup(ctxt->dict, fullattr, len);
                   1206:     }
                   1207: 
                   1208:     defaults->values[5 * defaults->nbAttrs] = name;
                   1209:     defaults->values[5 * defaults->nbAttrs + 1] = prefix;
                   1210:     /* intern the string and precompute the end */
                   1211:     len = xmlStrlen(value);
                   1212:     value = xmlDictLookup(ctxt->dict, value, len);
                   1213:     defaults->values[5 * defaults->nbAttrs + 2] = value;
                   1214:     defaults->values[5 * defaults->nbAttrs + 3] = value + len;
                   1215:     if (ctxt->external)
                   1216:         defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
                   1217:     else
                   1218:         defaults->values[5 * defaults->nbAttrs + 4] = NULL;
                   1219:     defaults->nbAttrs++;
                   1220: 
                   1221:     return;
                   1222: 
                   1223: mem_error:
                   1224:     xmlErrMemory(ctxt, NULL);
                   1225:     return;
                   1226: }
                   1227: 
                   1228: /**
                   1229:  * xmlAddSpecialAttr:
                   1230:  * @ctxt:  an XML parser context
                   1231:  * @fullname:  the element fullname
                   1232:  * @fullattr:  the attribute fullname
                   1233:  * @type:  the attribute type
                   1234:  *
                   1235:  * Register this attribute type
                   1236:  */
                   1237: static void
                   1238: xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
                   1239:                  const xmlChar *fullname,
                   1240:                  const xmlChar *fullattr,
                   1241:                  int type)
                   1242: {
                   1243:     if (ctxt->attsSpecial == NULL) {
                   1244:         ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
                   1245:        if (ctxt->attsSpecial == NULL)
                   1246:            goto mem_error;
                   1247:     }
                   1248: 
                   1249:     if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
                   1250:         return;
                   1251: 
                   1252:     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
                   1253:                      (void *) (long) type);
                   1254:     return;
                   1255: 
                   1256: mem_error:
                   1257:     xmlErrMemory(ctxt, NULL);
                   1258:     return;
                   1259: }
                   1260: 
                   1261: /**
                   1262:  * xmlCleanSpecialAttrCallback:
                   1263:  *
                   1264:  * Removes CDATA attributes from the special attribute table
                   1265:  */
                   1266: static void
                   1267: xmlCleanSpecialAttrCallback(void *payload, void *data,
                   1268:                             const xmlChar *fullname, const xmlChar *fullattr,
                   1269:                             const xmlChar *unused ATTRIBUTE_UNUSED) {
                   1270:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
                   1271: 
                   1272:     if (((long) payload) == XML_ATTRIBUTE_CDATA) {
                   1273:         xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
                   1274:     }
                   1275: }
                   1276: 
                   1277: /**
                   1278:  * xmlCleanSpecialAttr:
                   1279:  * @ctxt:  an XML parser context
                   1280:  *
                   1281:  * Trim the list of attributes defined to remove all those of type
                   1282:  * CDATA as they are not special. This call should be done when finishing
                   1283:  * to parse the DTD and before starting to parse the document root.
                   1284:  */
                   1285: static void
                   1286: xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
                   1287: {
                   1288:     if (ctxt->attsSpecial == NULL)
                   1289:         return;
                   1290: 
                   1291:     xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
                   1292: 
                   1293:     if (xmlHashSize(ctxt->attsSpecial) == 0) {
                   1294:         xmlHashFree(ctxt->attsSpecial, NULL);
                   1295:         ctxt->attsSpecial = NULL;
                   1296:     }
                   1297:     return;
                   1298: }
                   1299: 
                   1300: /**
                   1301:  * xmlCheckLanguageID:
                   1302:  * @lang:  pointer to the string value
                   1303:  *
                   1304:  * Checks that the value conforms to the LanguageID production:
                   1305:  *
                   1306:  * NOTE: this is somewhat deprecated, those productions were removed from
                   1307:  *       the XML Second edition.
                   1308:  *
                   1309:  * [33] LanguageID ::= Langcode ('-' Subcode)*
                   1310:  * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
                   1311:  * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
                   1312:  * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
                   1313:  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
                   1314:  * [38] Subcode ::= ([a-z] | [A-Z])+
                   1315:  *
                   1316:  * The current REC reference the sucessors of RFC 1766, currently 5646
                   1317:  *
                   1318:  * http://www.rfc-editor.org/rfc/rfc5646.txt
                   1319:  * langtag       = language
                   1320:  *                 ["-" script]
                   1321:  *                 ["-" region]
                   1322:  *                 *("-" variant)
                   1323:  *                 *("-" extension)
                   1324:  *                 ["-" privateuse]
                   1325:  * language      = 2*3ALPHA            ; shortest ISO 639 code
                   1326:  *                 ["-" extlang]       ; sometimes followed by
                   1327:  *                                     ; extended language subtags
                   1328:  *               / 4ALPHA              ; or reserved for future use
                   1329:  *               / 5*8ALPHA            ; or registered language subtag
                   1330:  *
                   1331:  * extlang       = 3ALPHA              ; selected ISO 639 codes
                   1332:  *                 *2("-" 3ALPHA)      ; permanently reserved
                   1333:  *
                   1334:  * script        = 4ALPHA              ; ISO 15924 code
                   1335:  *
                   1336:  * region        = 2ALPHA              ; ISO 3166-1 code
                   1337:  *               / 3DIGIT              ; UN M.49 code
                   1338:  *
                   1339:  * variant       = 5*8alphanum         ; registered variants
                   1340:  *               / (DIGIT 3alphanum)
                   1341:  *
                   1342:  * extension     = singleton 1*("-" (2*8alphanum))
                   1343:  *
                   1344:  *                                     ; Single alphanumerics
                   1345:  *                                     ; "x" reserved for private use
                   1346:  * singleton     = DIGIT               ; 0 - 9
                   1347:  *               / %x41-57             ; A - W
                   1348:  *               / %x59-5A             ; Y - Z
                   1349:  *               / %x61-77             ; a - w
                   1350:  *               / %x79-7A             ; y - z
                   1351:  *
                   1352:  * it sounds right to still allow Irregular i-xxx IANA and user codes too
                   1353:  * The parser below doesn't try to cope with extension or privateuse
                   1354:  * that could be added but that's not interoperable anyway
                   1355:  *
                   1356:  * Returns 1 if correct 0 otherwise
                   1357:  **/
                   1358: int
                   1359: xmlCheckLanguageID(const xmlChar * lang)
                   1360: {
                   1361:     const xmlChar *cur = lang, *nxt;
                   1362: 
                   1363:     if (cur == NULL)
                   1364:         return (0);
                   1365:     if (((cur[0] == 'i') && (cur[1] == '-')) ||
                   1366:         ((cur[0] == 'I') && (cur[1] == '-')) ||
                   1367:         ((cur[0] == 'x') && (cur[1] == '-')) ||
                   1368:         ((cur[0] == 'X') && (cur[1] == '-'))) {
                   1369:         /*
                   1370:          * Still allow IANA code and user code which were coming
                   1371:          * from the previous version of the XML-1.0 specification
                   1372:          * it's deprecated but we should not fail
                   1373:          */
                   1374:         cur += 2;
                   1375:         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
                   1376:                ((cur[0] >= 'a') && (cur[0] <= 'z')))
                   1377:             cur++;
                   1378:         return(cur[0] == 0);
                   1379:     }
                   1380:     nxt = cur;
                   1381:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
                   1382:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
                   1383:            nxt++;
                   1384:     if (nxt - cur >= 4) {
                   1385:         /*
                   1386:          * Reserved
                   1387:          */
                   1388:         if ((nxt - cur > 8) || (nxt[0] != 0))
                   1389:             return(0);
                   1390:         return(1);
                   1391:     }
                   1392:     if (nxt - cur < 2)
                   1393:         return(0);
                   1394:     /* we got an ISO 639 code */
                   1395:     if (nxt[0] == 0)
                   1396:         return(1);
                   1397:     if (nxt[0] != '-')
                   1398:         return(0);
                   1399: 
                   1400:     nxt++;
                   1401:     cur = nxt;
                   1402:     /* now we can have extlang or script or region or variant */
                   1403:     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
                   1404:         goto region_m49;
                   1405: 
                   1406:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
                   1407:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
                   1408:            nxt++;
                   1409:     if (nxt - cur == 4)
                   1410:         goto script;
                   1411:     if (nxt - cur == 2)
                   1412:         goto region;
                   1413:     if ((nxt - cur >= 5) && (nxt - cur <= 8))
                   1414:         goto variant;
                   1415:     if (nxt - cur != 3)
                   1416:         return(0);
                   1417:     /* we parsed an extlang */
                   1418:     if (nxt[0] == 0)
                   1419:         return(1);
                   1420:     if (nxt[0] != '-')
                   1421:         return(0);
                   1422: 
                   1423:     nxt++;
                   1424:     cur = nxt;
                   1425:     /* now we can have script or region or variant */
                   1426:     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
                   1427:         goto region_m49;
                   1428: 
                   1429:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
                   1430:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
                   1431:            nxt++;
                   1432:     if (nxt - cur == 2)
                   1433:         goto region;
                   1434:     if ((nxt - cur >= 5) && (nxt - cur <= 8))
                   1435:         goto variant;
                   1436:     if (nxt - cur != 4)
                   1437:         return(0);
                   1438:     /* we parsed a script */
                   1439: script:
                   1440:     if (nxt[0] == 0)
                   1441:         return(1);
                   1442:     if (nxt[0] != '-')
                   1443:         return(0);
                   1444: 
                   1445:     nxt++;
                   1446:     cur = nxt;
                   1447:     /* now we can have region or variant */
                   1448:     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
                   1449:         goto region_m49;
                   1450: 
                   1451:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
                   1452:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
                   1453:            nxt++;
                   1454: 
                   1455:     if ((nxt - cur >= 5) && (nxt - cur <= 8))
                   1456:         goto variant;
                   1457:     if (nxt - cur != 2)
                   1458:         return(0);
                   1459:     /* we parsed a region */
                   1460: region:
                   1461:     if (nxt[0] == 0)
                   1462:         return(1);
                   1463:     if (nxt[0] != '-')
                   1464:         return(0);
                   1465: 
                   1466:     nxt++;
                   1467:     cur = nxt;
                   1468:     /* now we can just have a variant */
                   1469:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
                   1470:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
                   1471:            nxt++;
                   1472: 
                   1473:     if ((nxt - cur < 5) || (nxt - cur > 8))
                   1474:         return(0);
                   1475: 
                   1476:     /* we parsed a variant */
                   1477: variant:
                   1478:     if (nxt[0] == 0)
                   1479:         return(1);
                   1480:     if (nxt[0] != '-')
                   1481:         return(0);
                   1482:     /* extensions and private use subtags not checked */
                   1483:     return (1);
                   1484: 
                   1485: region_m49:
                   1486:     if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
                   1487:         ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
                   1488:         nxt += 3;
                   1489:         goto region;
                   1490:     }
                   1491:     return(0);
                   1492: }
                   1493: 
                   1494: /************************************************************************
                   1495:  *                                                                     *
                   1496:  *             Parser stacks related functions and macros              *
                   1497:  *                                                                     *
                   1498:  ************************************************************************/
                   1499: 
                   1500: static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
                   1501:                                             const xmlChar ** str);
                   1502: 
                   1503: #ifdef SAX2
                   1504: /**
                   1505:  * nsPush:
                   1506:  * @ctxt:  an XML parser context
                   1507:  * @prefix:  the namespace prefix or NULL
                   1508:  * @URL:  the namespace name
                   1509:  *
                   1510:  * Pushes a new parser namespace on top of the ns stack
                   1511:  *
                   1512:  * Returns -1 in case of error, -2 if the namespace should be discarded
                   1513:  *        and the index in the stack otherwise.
                   1514:  */
                   1515: static int
                   1516: nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
                   1517: {
                   1518:     if (ctxt->options & XML_PARSE_NSCLEAN) {
                   1519:         int i;
                   1520:        for (i = 0;i < ctxt->nsNr;i += 2) {
                   1521:            if (ctxt->nsTab[i] == prefix) {
                   1522:                /* in scope */
                   1523:                if (ctxt->nsTab[i + 1] == URL)
                   1524:                    return(-2);
                   1525:                /* out of scope keep it */
                   1526:                break;
                   1527:            }
                   1528:        }
                   1529:     }
                   1530:     if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
                   1531:        ctxt->nsMax = 10;
                   1532:        ctxt->nsNr = 0;
                   1533:        ctxt->nsTab = (const xmlChar **)
                   1534:                      xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
                   1535:        if (ctxt->nsTab == NULL) {
                   1536:            xmlErrMemory(ctxt, NULL);
                   1537:            ctxt->nsMax = 0;
                   1538:             return (-1);
                   1539:        }
                   1540:     } else if (ctxt->nsNr >= ctxt->nsMax) {
                   1541:         const xmlChar ** tmp;
                   1542:         ctxt->nsMax *= 2;
                   1543:         tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
                   1544:                                    ctxt->nsMax * sizeof(ctxt->nsTab[0]));
                   1545:         if (tmp == NULL) {
                   1546:             xmlErrMemory(ctxt, NULL);
                   1547:            ctxt->nsMax /= 2;
                   1548:             return (-1);
                   1549:         }
                   1550:        ctxt->nsTab = tmp;
                   1551:     }
                   1552:     ctxt->nsTab[ctxt->nsNr++] = prefix;
                   1553:     ctxt->nsTab[ctxt->nsNr++] = URL;
                   1554:     return (ctxt->nsNr);
                   1555: }
                   1556: /**
                   1557:  * nsPop:
                   1558:  * @ctxt: an XML parser context
                   1559:  * @nr:  the number to pop
                   1560:  *
                   1561:  * Pops the top @nr parser prefix/namespace from the ns stack
                   1562:  *
                   1563:  * Returns the number of namespaces removed
                   1564:  */
                   1565: static int
                   1566: nsPop(xmlParserCtxtPtr ctxt, int nr)
                   1567: {
                   1568:     int i;
                   1569: 
                   1570:     if (ctxt->nsTab == NULL) return(0);
                   1571:     if (ctxt->nsNr < nr) {
                   1572:         xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
                   1573:         nr = ctxt->nsNr;
                   1574:     }
                   1575:     if (ctxt->nsNr <= 0)
                   1576:         return (0);
                   1577: 
                   1578:     for (i = 0;i < nr;i++) {
                   1579:          ctxt->nsNr--;
                   1580:         ctxt->nsTab[ctxt->nsNr] = NULL;
                   1581:     }
                   1582:     return(nr);
                   1583: }
                   1584: #endif
                   1585: 
                   1586: static int
                   1587: xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
                   1588:     const xmlChar **atts;
                   1589:     int *attallocs;
                   1590:     int maxatts;
                   1591: 
                   1592:     if (ctxt->atts == NULL) {
                   1593:        maxatts = 55; /* allow for 10 attrs by default */
                   1594:        atts = (const xmlChar **)
                   1595:               xmlMalloc(maxatts * sizeof(xmlChar *));
                   1596:        if (atts == NULL) goto mem_error;
                   1597:        ctxt->atts = atts;
                   1598:        attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
                   1599:        if (attallocs == NULL) goto mem_error;
                   1600:        ctxt->attallocs = attallocs;
                   1601:        ctxt->maxatts = maxatts;
                   1602:     } else if (nr + 5 > ctxt->maxatts) {
                   1603:        maxatts = (nr + 5) * 2;
                   1604:        atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
                   1605:                                     maxatts * sizeof(const xmlChar *));
                   1606:        if (atts == NULL) goto mem_error;
                   1607:        ctxt->atts = atts;
                   1608:        attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
                   1609:                                     (maxatts / 5) * sizeof(int));
                   1610:        if (attallocs == NULL) goto mem_error;
                   1611:        ctxt->attallocs = attallocs;
                   1612:        ctxt->maxatts = maxatts;
                   1613:     }
                   1614:     return(ctxt->maxatts);
                   1615: mem_error:
                   1616:     xmlErrMemory(ctxt, NULL);
                   1617:     return(-1);
                   1618: }
                   1619: 
                   1620: /**
                   1621:  * inputPush:
                   1622:  * @ctxt:  an XML parser context
                   1623:  * @value:  the parser input
                   1624:  *
                   1625:  * Pushes a new parser input on top of the input stack
                   1626:  *
                   1627:  * Returns -1 in case of error, the index in the stack otherwise
                   1628:  */
                   1629: int
                   1630: inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
                   1631: {
                   1632:     if ((ctxt == NULL) || (value == NULL))
                   1633:         return(-1);
                   1634:     if (ctxt->inputNr >= ctxt->inputMax) {
                   1635:         ctxt->inputMax *= 2;
                   1636:         ctxt->inputTab =
                   1637:             (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
                   1638:                                              ctxt->inputMax *
                   1639:                                              sizeof(ctxt->inputTab[0]));
                   1640:         if (ctxt->inputTab == NULL) {
                   1641:             xmlErrMemory(ctxt, NULL);
                   1642:            xmlFreeInputStream(value);
                   1643:            ctxt->inputMax /= 2;
                   1644:            value = NULL;
                   1645:             return (-1);
                   1646:         }
                   1647:     }
                   1648:     ctxt->inputTab[ctxt->inputNr] = value;
                   1649:     ctxt->input = value;
                   1650:     return (ctxt->inputNr++);
                   1651: }
                   1652: /**
                   1653:  * inputPop:
                   1654:  * @ctxt: an XML parser context
                   1655:  *
                   1656:  * Pops the top parser input from the input stack
                   1657:  *
                   1658:  * Returns the input just removed
                   1659:  */
                   1660: xmlParserInputPtr
                   1661: inputPop(xmlParserCtxtPtr ctxt)
                   1662: {
                   1663:     xmlParserInputPtr ret;
                   1664: 
                   1665:     if (ctxt == NULL)
                   1666:         return(NULL);
                   1667:     if (ctxt->inputNr <= 0)
                   1668:         return (NULL);
                   1669:     ctxt->inputNr--;
                   1670:     if (ctxt->inputNr > 0)
                   1671:         ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
                   1672:     else
                   1673:         ctxt->input = NULL;
                   1674:     ret = ctxt->inputTab[ctxt->inputNr];
                   1675:     ctxt->inputTab[ctxt->inputNr] = NULL;
                   1676:     return (ret);
                   1677: }
                   1678: /**
                   1679:  * nodePush:
                   1680:  * @ctxt:  an XML parser context
                   1681:  * @value:  the element node
                   1682:  *
                   1683:  * Pushes a new element node on top of the node stack
                   1684:  *
                   1685:  * Returns -1 in case of error, the index in the stack otherwise
                   1686:  */
                   1687: int
                   1688: nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
                   1689: {
                   1690:     if (ctxt == NULL) return(0);
                   1691:     if (ctxt->nodeNr >= ctxt->nodeMax) {
                   1692:         xmlNodePtr *tmp;
                   1693: 
                   1694:        tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
                   1695:                                       ctxt->nodeMax * 2 *
                   1696:                                       sizeof(ctxt->nodeTab[0]));
                   1697:         if (tmp == NULL) {
                   1698:             xmlErrMemory(ctxt, NULL);
                   1699:             return (-1);
                   1700:         }
                   1701:         ctxt->nodeTab = tmp;
                   1702:        ctxt->nodeMax *= 2;
                   1703:     }
                   1704:     if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
                   1705:         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                   1706:        xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
                   1707:                 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
                   1708:                          xmlParserMaxDepth);
                   1709:        ctxt->instate = XML_PARSER_EOF;
                   1710:        return(-1);
                   1711:     }
                   1712:     ctxt->nodeTab[ctxt->nodeNr] = value;
                   1713:     ctxt->node = value;
                   1714:     return (ctxt->nodeNr++);
                   1715: }
                   1716: 
                   1717: /**
                   1718:  * nodePop:
                   1719:  * @ctxt: an XML parser context
                   1720:  *
                   1721:  * Pops the top element node from the node stack
                   1722:  *
                   1723:  * Returns the node just removed
                   1724:  */
                   1725: xmlNodePtr
                   1726: nodePop(xmlParserCtxtPtr ctxt)
                   1727: {
                   1728:     xmlNodePtr ret;
                   1729: 
                   1730:     if (ctxt == NULL) return(NULL);
                   1731:     if (ctxt->nodeNr <= 0)
                   1732:         return (NULL);
                   1733:     ctxt->nodeNr--;
                   1734:     if (ctxt->nodeNr > 0)
                   1735:         ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
                   1736:     else
                   1737:         ctxt->node = NULL;
                   1738:     ret = ctxt->nodeTab[ctxt->nodeNr];
                   1739:     ctxt->nodeTab[ctxt->nodeNr] = NULL;
                   1740:     return (ret);
                   1741: }
                   1742: 
                   1743: #ifdef LIBXML_PUSH_ENABLED
                   1744: /**
                   1745:  * nameNsPush:
                   1746:  * @ctxt:  an XML parser context
                   1747:  * @value:  the element name
                   1748:  * @prefix:  the element prefix
                   1749:  * @URI:  the element namespace name
                   1750:  *
                   1751:  * Pushes a new element name/prefix/URL on top of the name stack
                   1752:  *
                   1753:  * Returns -1 in case of error, the index in the stack otherwise
                   1754:  */
                   1755: static int
                   1756: nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
                   1757:            const xmlChar *prefix, const xmlChar *URI, int nsNr)
                   1758: {
                   1759:     if (ctxt->nameNr >= ctxt->nameMax) {
                   1760:         const xmlChar * *tmp;
                   1761:         void **tmp2;
                   1762:         ctxt->nameMax *= 2;
                   1763:         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
                   1764:                                     ctxt->nameMax *
                   1765:                                     sizeof(ctxt->nameTab[0]));
                   1766:         if (tmp == NULL) {
                   1767:            ctxt->nameMax /= 2;
                   1768:            goto mem_error;
                   1769:         }
                   1770:        ctxt->nameTab = tmp;
                   1771:         tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
                   1772:                                     ctxt->nameMax * 3 *
                   1773:                                     sizeof(ctxt->pushTab[0]));
                   1774:         if (tmp2 == NULL) {
                   1775:            ctxt->nameMax /= 2;
                   1776:            goto mem_error;
                   1777:         }
                   1778:        ctxt->pushTab = tmp2;
                   1779:     }
                   1780:     ctxt->nameTab[ctxt->nameNr] = value;
                   1781:     ctxt->name = value;
                   1782:     ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
                   1783:     ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
                   1784:     ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
                   1785:     return (ctxt->nameNr++);
                   1786: mem_error:
                   1787:     xmlErrMemory(ctxt, NULL);
                   1788:     return (-1);
                   1789: }
                   1790: /**
                   1791:  * nameNsPop:
                   1792:  * @ctxt: an XML parser context
                   1793:  *
                   1794:  * Pops the top element/prefix/URI name from the name stack
                   1795:  *
                   1796:  * Returns the name just removed
                   1797:  */
                   1798: static const xmlChar *
                   1799: nameNsPop(xmlParserCtxtPtr ctxt)
                   1800: {
                   1801:     const xmlChar *ret;
                   1802: 
                   1803:     if (ctxt->nameNr <= 0)
                   1804:         return (NULL);
                   1805:     ctxt->nameNr--;
                   1806:     if (ctxt->nameNr > 0)
                   1807:         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
                   1808:     else
                   1809:         ctxt->name = NULL;
                   1810:     ret = ctxt->nameTab[ctxt->nameNr];
                   1811:     ctxt->nameTab[ctxt->nameNr] = NULL;
                   1812:     return (ret);
                   1813: }
                   1814: #endif /* LIBXML_PUSH_ENABLED */
                   1815: 
                   1816: /**
                   1817:  * namePush:
                   1818:  * @ctxt:  an XML parser context
                   1819:  * @value:  the element name
                   1820:  *
                   1821:  * Pushes a new element name on top of the name stack
                   1822:  *
                   1823:  * Returns -1 in case of error, the index in the stack otherwise
                   1824:  */
                   1825: int
                   1826: namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
                   1827: {
                   1828:     if (ctxt == NULL) return (-1);
                   1829: 
                   1830:     if (ctxt->nameNr >= ctxt->nameMax) {
                   1831:         const xmlChar * *tmp;
                   1832:         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1.1.1.2 ! misho    1833:                                     ctxt->nameMax * 2 *
1.1       misho    1834:                                     sizeof(ctxt->nameTab[0]));
                   1835:         if (tmp == NULL) {
                   1836:            goto mem_error;
                   1837:         }
                   1838:        ctxt->nameTab = tmp;
1.1.1.2 ! misho    1839:         ctxt->nameMax *= 2;
1.1       misho    1840:     }
                   1841:     ctxt->nameTab[ctxt->nameNr] = value;
                   1842:     ctxt->name = value;
                   1843:     return (ctxt->nameNr++);
                   1844: mem_error:
                   1845:     xmlErrMemory(ctxt, NULL);
                   1846:     return (-1);
                   1847: }
                   1848: /**
                   1849:  * namePop:
                   1850:  * @ctxt: an XML parser context
                   1851:  *
                   1852:  * Pops the top element name from the name stack
                   1853:  *
                   1854:  * Returns the name just removed
                   1855:  */
                   1856: const xmlChar *
                   1857: namePop(xmlParserCtxtPtr ctxt)
                   1858: {
                   1859:     const xmlChar *ret;
                   1860: 
                   1861:     if ((ctxt == NULL) || (ctxt->nameNr <= 0))
                   1862:         return (NULL);
                   1863:     ctxt->nameNr--;
                   1864:     if (ctxt->nameNr > 0)
                   1865:         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
                   1866:     else
                   1867:         ctxt->name = NULL;
                   1868:     ret = ctxt->nameTab[ctxt->nameNr];
                   1869:     ctxt->nameTab[ctxt->nameNr] = NULL;
                   1870:     return (ret);
                   1871: }
                   1872: 
                   1873: static int spacePush(xmlParserCtxtPtr ctxt, int val) {
                   1874:     if (ctxt->spaceNr >= ctxt->spaceMax) {
                   1875:         int *tmp;
                   1876: 
                   1877:        ctxt->spaceMax *= 2;
                   1878:         tmp = (int *) xmlRealloc(ctxt->spaceTab,
                   1879:                                 ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
                   1880:         if (tmp == NULL) {
                   1881:            xmlErrMemory(ctxt, NULL);
                   1882:            ctxt->spaceMax /=2;
                   1883:            return(-1);
                   1884:        }
                   1885:        ctxt->spaceTab = tmp;
                   1886:     }
                   1887:     ctxt->spaceTab[ctxt->spaceNr] = val;
                   1888:     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
                   1889:     return(ctxt->spaceNr++);
                   1890: }
                   1891: 
                   1892: static int spacePop(xmlParserCtxtPtr ctxt) {
                   1893:     int ret;
                   1894:     if (ctxt->spaceNr <= 0) return(0);
                   1895:     ctxt->spaceNr--;
                   1896:     if (ctxt->spaceNr > 0)
                   1897:        ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
                   1898:     else
                   1899:         ctxt->space = &ctxt->spaceTab[0];
                   1900:     ret = ctxt->spaceTab[ctxt->spaceNr];
                   1901:     ctxt->spaceTab[ctxt->spaceNr] = -1;
                   1902:     return(ret);
                   1903: }
                   1904: 
                   1905: /*
                   1906:  * Macros for accessing the content. Those should be used only by the parser,
                   1907:  * and not exported.
                   1908:  *
                   1909:  * Dirty macros, i.e. one often need to make assumption on the context to
                   1910:  * use them
                   1911:  *
                   1912:  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
                   1913:  *           To be used with extreme caution since operations consuming
                   1914:  *           characters may move the input buffer to a different location !
                   1915:  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
                   1916:  *           This should be used internally by the parser
                   1917:  *           only to compare to ASCII values otherwise it would break when
                   1918:  *           running with UTF-8 encoding.
                   1919:  *   RAW     same as CUR but in the input buffer, bypass any token
                   1920:  *           extraction that may have been done
                   1921:  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
                   1922:  *           to compare on ASCII based substring.
                   1923:  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
                   1924:  *           strings without newlines within the parser.
                   1925:  *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII 
                   1926:  *           defined char within the parser.
                   1927:  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
                   1928:  *
                   1929:  *   NEXT    Skip to the next character, this does the proper decoding
                   1930:  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
                   1931:  *   NEXTL(l) Skip the current unicode character of l xmlChars long.
                   1932:  *   CUR_CHAR(l) returns the current unicode character (int), set l
                   1933:  *           to the number of xmlChars used for the encoding [0-5].
                   1934:  *   CUR_SCHAR  same but operate on a string instead of the context
                   1935:  *   COPY_BUF  copy the current unicode char to the target buffer, increment
                   1936:  *            the index
                   1937:  *   GROW, SHRINK  handling of input buffers
                   1938:  */
                   1939: 
                   1940: #define RAW (*ctxt->input->cur)
                   1941: #define CUR (*ctxt->input->cur)
                   1942: #define NXT(val) ctxt->input->cur[(val)]
                   1943: #define CUR_PTR ctxt->input->cur
                   1944: 
                   1945: #define CMP4( s, c1, c2, c3, c4 ) \
                   1946:   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
                   1947:     ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
                   1948: #define CMP5( s, c1, c2, c3, c4, c5 ) \
                   1949:   ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
                   1950: #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
                   1951:   ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
                   1952: #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
                   1953:   ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
                   1954: #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
                   1955:   ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
                   1956: #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
                   1957:   ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
                   1958:     ((unsigned char *) s)[ 8 ] == c9 )
                   1959: #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
                   1960:   ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
                   1961:     ((unsigned char *) s)[ 9 ] == c10 )
                   1962: 
                   1963: #define SKIP(val) do {                                                 \
                   1964:     ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);                  \
                   1965:     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);    \
                   1966:     if ((*ctxt->input->cur == 0) &&                                    \
                   1967:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))           \
                   1968:            xmlPopInput(ctxt);                                          \
                   1969:   } while (0)
                   1970: 
                   1971: #define SKIPL(val) do {                                                        \
                   1972:     int skipl;                                                         \
                   1973:     for(skipl=0; skipl<val; skipl++) {                                 \
                   1974:        if (*(ctxt->input->cur) == '\n') {                              \
                   1975:        ctxt->input->line++; ctxt->input->col = 1;                      \
                   1976:        } else ctxt->input->col++;                                      \
                   1977:        ctxt->nbChars++;                                                \
                   1978:        ctxt->input->cur++;                                             \
                   1979:     }                                                                  \
                   1980:     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);    \
                   1981:     if ((*ctxt->input->cur == 0) &&                                    \
                   1982:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))           \
                   1983:            xmlPopInput(ctxt);                                          \
                   1984:   } while (0)
                   1985: 
                   1986: #define SHRINK if ((ctxt->progressive == 0) &&                         \
                   1987:                   (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
                   1988:                   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
                   1989:        xmlSHRINK (ctxt);
                   1990: 
                   1991: static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
                   1992:     xmlParserInputShrink(ctxt->input);
                   1993:     if ((*ctxt->input->cur == 0) &&
                   1994:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
                   1995:            xmlPopInput(ctxt);
                   1996:   }
                   1997: 
                   1998: #define GROW if ((ctxt->progressive == 0) &&                           \
                   1999:                 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))   \
                   2000:        xmlGROW (ctxt);
                   2001: 
                   2002: static void xmlGROW (xmlParserCtxtPtr ctxt) {
                   2003:     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
                   2004:     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
                   2005:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
                   2006:            xmlPopInput(ctxt);
                   2007: }
                   2008: 
                   2009: #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
                   2010: 
                   2011: #define NEXT xmlNextChar(ctxt)
                   2012: 
                   2013: #define NEXT1 {                                                                \
                   2014:        ctxt->input->col++;                                             \
                   2015:        ctxt->input->cur++;                                             \
                   2016:        ctxt->nbChars++;                                                \
                   2017:        if (*ctxt->input->cur == 0)                                     \
                   2018:            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);               \
                   2019:     }
                   2020: 
                   2021: #define NEXTL(l) do {                                                  \
                   2022:     if (*(ctxt->input->cur) == '\n') {                                 \
                   2023:        ctxt->input->line++; ctxt->input->col = 1;                      \
                   2024:     } else ctxt->input->col++;                                         \
                   2025:     ctxt->input->cur += l;                             \
                   2026:     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);    \
                   2027:   } while (0)
                   2028: 
                   2029: #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
                   2030: #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
                   2031: 
                   2032: #define COPY_BUF(l,b,i,v)                                              \
                   2033:     if (l == 1) b[i++] = (xmlChar) v;                                  \
                   2034:     else i += xmlCopyCharMultiByte(&b[i],v)
                   2035: 
                   2036: /**
                   2037:  * xmlSkipBlankChars:
                   2038:  * @ctxt:  the XML parser context
                   2039:  *
                   2040:  * skip all blanks character found at that point in the input streams.
                   2041:  * It pops up finished entities in the process if allowable at that point.
                   2042:  *
                   2043:  * Returns the number of space chars skipped
                   2044:  */
                   2045: 
                   2046: int
                   2047: xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
                   2048:     int res = 0;
                   2049: 
                   2050:     /*
                   2051:      * It's Okay to use CUR/NEXT here since all the blanks are on
                   2052:      * the ASCII range.
                   2053:      */
                   2054:     if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
                   2055:        const xmlChar *cur;
                   2056:        /*
                   2057:         * if we are in the document content, go really fast
                   2058:         */
                   2059:        cur = ctxt->input->cur;
                   2060:        while (IS_BLANK_CH(*cur)) {
                   2061:            if (*cur == '\n') {
                   2062:                ctxt->input->line++; ctxt->input->col = 1;
                   2063:            }
                   2064:            cur++;
                   2065:            res++;
                   2066:            if (*cur == 0) {
                   2067:                ctxt->input->cur = cur;
                   2068:                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
                   2069:                cur = ctxt->input->cur;
                   2070:            }
                   2071:        }
                   2072:        ctxt->input->cur = cur;
                   2073:     } else {
                   2074:        int cur;
                   2075:        do {
                   2076:            cur = CUR;
                   2077:            while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
                   2078:                NEXT;
                   2079:                cur = CUR;
                   2080:                res++;
                   2081:            }
                   2082:            while ((cur == 0) && (ctxt->inputNr > 1) &&
                   2083:                   (ctxt->instate != XML_PARSER_COMMENT)) {
                   2084:                xmlPopInput(ctxt);
                   2085:                cur = CUR;
                   2086:            }
                   2087:            /*
                   2088:             * Need to handle support of entities branching here
                   2089:             */
                   2090:            if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
                   2091:        } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
                   2092:     }
                   2093:     return(res);
                   2094: }
                   2095: 
                   2096: /************************************************************************
                   2097:  *                                                                     *
                   2098:  *             Commodity functions to handle entities                  *
                   2099:  *                                                                     *
                   2100:  ************************************************************************/
                   2101: 
                   2102: /**
                   2103:  * xmlPopInput:
                   2104:  * @ctxt:  an XML parser context
                   2105:  *
                   2106:  * xmlPopInput: the current input pointed by ctxt->input came to an end
                   2107:  *          pop it and return the next char.
                   2108:  *
                   2109:  * Returns the current xmlChar in the parser context
                   2110:  */
                   2111: xmlChar
                   2112: xmlPopInput(xmlParserCtxtPtr ctxt) {
                   2113:     if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
                   2114:     if (xmlParserDebugEntities)
                   2115:        xmlGenericError(xmlGenericErrorContext,
                   2116:                "Popping input %d\n", ctxt->inputNr);
                   2117:     xmlFreeInputStream(inputPop(ctxt));
                   2118:     if ((*ctxt->input->cur == 0) &&
                   2119:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
                   2120:            return(xmlPopInput(ctxt));
                   2121:     return(CUR);
                   2122: }
                   2123: 
                   2124: /**
                   2125:  * xmlPushInput:
                   2126:  * @ctxt:  an XML parser context
                   2127:  * @input:  an XML parser input fragment (entity, XML fragment ...).
                   2128:  *
                   2129:  * xmlPushInput: switch to a new input stream which is stacked on top
                   2130:  *               of the previous one(s).
                   2131:  * Returns -1 in case of error or the index in the input stack
                   2132:  */
                   2133: int
                   2134: xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
                   2135:     int ret;
                   2136:     if (input == NULL) return(-1);
                   2137: 
                   2138:     if (xmlParserDebugEntities) {
                   2139:        if ((ctxt->input != NULL) && (ctxt->input->filename))
                   2140:            xmlGenericError(xmlGenericErrorContext,
                   2141:                    "%s(%d): ", ctxt->input->filename,
                   2142:                    ctxt->input->line);
                   2143:        xmlGenericError(xmlGenericErrorContext,
                   2144:                "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
                   2145:     }
                   2146:     ret = inputPush(ctxt, input);
                   2147:     GROW;
                   2148:     return(ret);
                   2149: }
                   2150: 
                   2151: /**
                   2152:  * xmlParseCharRef:
                   2153:  * @ctxt:  an XML parser context
                   2154:  *
                   2155:  * parse Reference declarations
                   2156:  *
                   2157:  * [66] CharRef ::= '&#' [0-9]+ ';' |
                   2158:  *                  '&#x' [0-9a-fA-F]+ ';'
                   2159:  *
                   2160:  * [ WFC: Legal Character ]
                   2161:  * Characters referred to using character references must match the
                   2162:  * production for Char. 
                   2163:  *
                   2164:  * Returns the value parsed (as an int), 0 in case of error
                   2165:  */
                   2166: int
                   2167: xmlParseCharRef(xmlParserCtxtPtr ctxt) {
                   2168:     unsigned int val = 0;
                   2169:     int count = 0;
                   2170:     unsigned int outofrange = 0;
                   2171: 
                   2172:     /*
                   2173:      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
                   2174:      */
                   2175:     if ((RAW == '&') && (NXT(1) == '#') &&
                   2176:         (NXT(2) == 'x')) {
                   2177:        SKIP(3);
                   2178:        GROW;
                   2179:        while (RAW != ';') { /* loop blocked by count */
                   2180:            if (count++ > 20) {
                   2181:                count = 0;
                   2182:                GROW;
                   2183:            }
                   2184:            if ((RAW >= '0') && (RAW <= '9')) 
                   2185:                val = val * 16 + (CUR - '0');
                   2186:            else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
                   2187:                val = val * 16 + (CUR - 'a') + 10;
                   2188:            else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
                   2189:                val = val * 16 + (CUR - 'A') + 10;
                   2190:            else {
                   2191:                xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
                   2192:                val = 0;
                   2193:                break;
                   2194:            }
                   2195:            if (val > 0x10FFFF)
                   2196:                outofrange = val;
                   2197: 
                   2198:            NEXT;
                   2199:            count++;
                   2200:        }
                   2201:        if (RAW == ';') {
                   2202:            /* on purpose to avoid reentrancy problems with NEXT and SKIP */
                   2203:            ctxt->input->col++;
                   2204:            ctxt->nbChars ++;
                   2205:            ctxt->input->cur++;
                   2206:        }
                   2207:     } else if  ((RAW == '&') && (NXT(1) == '#')) {
                   2208:        SKIP(2);
                   2209:        GROW;
                   2210:        while (RAW != ';') { /* loop blocked by count */
                   2211:            if (count++ > 20) {
                   2212:                count = 0;
                   2213:                GROW;
                   2214:            }
                   2215:            if ((RAW >= '0') && (RAW <= '9')) 
                   2216:                val = val * 10 + (CUR - '0');
                   2217:            else {
                   2218:                xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
                   2219:                val = 0;
                   2220:                break;
                   2221:            }
                   2222:            if (val > 0x10FFFF)
                   2223:                outofrange = val;
                   2224: 
                   2225:            NEXT;
                   2226:            count++;
                   2227:        }
                   2228:        if (RAW == ';') {
                   2229:            /* on purpose to avoid reentrancy problems with NEXT and SKIP */
                   2230:            ctxt->input->col++;
                   2231:            ctxt->nbChars ++;
                   2232:            ctxt->input->cur++;
                   2233:        }
                   2234:     } else {
                   2235:         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
                   2236:     }
                   2237: 
                   2238:     /*
                   2239:      * [ WFC: Legal Character ]
                   2240:      * Characters referred to using character references must match the
                   2241:      * production for Char. 
                   2242:      */
                   2243:     if ((IS_CHAR(val) && (outofrange == 0))) {
                   2244:         return(val);
                   2245:     } else {
                   2246:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   2247:                           "xmlParseCharRef: invalid xmlChar value %d\n",
                   2248:                          val);
                   2249:     }
                   2250:     return(0);
                   2251: }
                   2252: 
                   2253: /**
                   2254:  * xmlParseStringCharRef:
                   2255:  * @ctxt:  an XML parser context
                   2256:  * @str:  a pointer to an index in the string
                   2257:  *
                   2258:  * parse Reference declarations, variant parsing from a string rather
                   2259:  * than an an input flow.
                   2260:  *
                   2261:  * [66] CharRef ::= '&#' [0-9]+ ';' |
                   2262:  *                  '&#x' [0-9a-fA-F]+ ';'
                   2263:  *
                   2264:  * [ WFC: Legal Character ]
                   2265:  * Characters referred to using character references must match the
                   2266:  * production for Char. 
                   2267:  *
                   2268:  * Returns the value parsed (as an int), 0 in case of error, str will be
                   2269:  *         updated to the current value of the index
                   2270:  */
                   2271: static int
                   2272: xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
                   2273:     const xmlChar *ptr;
                   2274:     xmlChar cur;
                   2275:     unsigned int val = 0;
                   2276:     unsigned int outofrange = 0;
                   2277: 
                   2278:     if ((str == NULL) || (*str == NULL)) return(0);
                   2279:     ptr = *str;
                   2280:     cur = *ptr;
                   2281:     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
                   2282:        ptr += 3;
                   2283:        cur = *ptr;
                   2284:        while (cur != ';') { /* Non input consuming loop */
                   2285:            if ((cur >= '0') && (cur <= '9')) 
                   2286:                val = val * 16 + (cur - '0');
                   2287:            else if ((cur >= 'a') && (cur <= 'f'))
                   2288:                val = val * 16 + (cur - 'a') + 10;
                   2289:            else if ((cur >= 'A') && (cur <= 'F'))
                   2290:                val = val * 16 + (cur - 'A') + 10;
                   2291:            else {
                   2292:                xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
                   2293:                val = 0;
                   2294:                break;
                   2295:            }
                   2296:            if (val > 0x10FFFF)
                   2297:                outofrange = val;
                   2298: 
                   2299:            ptr++;
                   2300:            cur = *ptr;
                   2301:        }
                   2302:        if (cur == ';')
                   2303:            ptr++;
                   2304:     } else if  ((cur == '&') && (ptr[1] == '#')){
                   2305:        ptr += 2;
                   2306:        cur = *ptr;
                   2307:        while (cur != ';') { /* Non input consuming loops */
                   2308:            if ((cur >= '0') && (cur <= '9')) 
                   2309:                val = val * 10 + (cur - '0');
                   2310:            else {
                   2311:                xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
                   2312:                val = 0;
                   2313:                break;
                   2314:            }
                   2315:            if (val > 0x10FFFF)
                   2316:                outofrange = val;
                   2317: 
                   2318:            ptr++;
                   2319:            cur = *ptr;
                   2320:        }
                   2321:        if (cur == ';')
                   2322:            ptr++;
                   2323:     } else {
                   2324:        xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
                   2325:        return(0);
                   2326:     }
                   2327:     *str = ptr;
                   2328: 
                   2329:     /*
                   2330:      * [ WFC: Legal Character ]
                   2331:      * Characters referred to using character references must match the
                   2332:      * production for Char. 
                   2333:      */
                   2334:     if ((IS_CHAR(val) && (outofrange == 0))) {
                   2335:         return(val);
                   2336:     } else {
                   2337:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   2338:                          "xmlParseStringCharRef: invalid xmlChar value %d\n",
                   2339:                          val);
                   2340:     }
                   2341:     return(0);
                   2342: }
                   2343: 
                   2344: /**
                   2345:  * xmlNewBlanksWrapperInputStream:
                   2346:  * @ctxt:  an XML parser context
                   2347:  * @entity:  an Entity pointer
                   2348:  *
                   2349:  * Create a new input stream for wrapping
                   2350:  * blanks around a PEReference
                   2351:  *
                   2352:  * Returns the new input stream or NULL
                   2353:  */
                   2354:  
                   2355: static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
                   2356:  
                   2357: static xmlParserInputPtr
                   2358: xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
                   2359:     xmlParserInputPtr input;
                   2360:     xmlChar *buffer;
                   2361:     size_t length;
                   2362:     if (entity == NULL) {
                   2363:        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   2364:                    "xmlNewBlanksWrapperInputStream entity\n");
                   2365:        return(NULL);
                   2366:     }
                   2367:     if (xmlParserDebugEntities)
                   2368:        xmlGenericError(xmlGenericErrorContext,
                   2369:                "new blanks wrapper for entity: %s\n", entity->name);
                   2370:     input = xmlNewInputStream(ctxt);
                   2371:     if (input == NULL) {
                   2372:        return(NULL);
                   2373:     }
                   2374:     length = xmlStrlen(entity->name) + 5;
                   2375:     buffer = xmlMallocAtomic(length);
                   2376:     if (buffer == NULL) {
                   2377:        xmlErrMemory(ctxt, NULL);
                   2378:         xmlFree(input);
                   2379:        return(NULL);
                   2380:     }
                   2381:     buffer [0] = ' ';
                   2382:     buffer [1] = '%';
                   2383:     buffer [length-3] = ';';
                   2384:     buffer [length-2] = ' ';
                   2385:     buffer [length-1] = 0;
                   2386:     memcpy(buffer + 2, entity->name, length - 5);
                   2387:     input->free = deallocblankswrapper;
                   2388:     input->base = buffer;
                   2389:     input->cur = buffer;
                   2390:     input->length = length;
                   2391:     input->end = &buffer[length];
                   2392:     return(input);
                   2393: }
                   2394: 
                   2395: /**
                   2396:  * xmlParserHandlePEReference:
                   2397:  * @ctxt:  the parser context
                   2398:  * 
                   2399:  * [69] PEReference ::= '%' Name ';'
                   2400:  *
                   2401:  * [ WFC: No Recursion ]
                   2402:  * A parsed entity must not contain a recursive
                   2403:  * reference to itself, either directly or indirectly. 
                   2404:  *
                   2405:  * [ WFC: Entity Declared ]
                   2406:  * In a document without any DTD, a document with only an internal DTD
                   2407:  * subset which contains no parameter entity references, or a document
                   2408:  * with "standalone='yes'", ...  ... The declaration of a parameter
                   2409:  * entity must precede any reference to it...
                   2410:  *
                   2411:  * [ VC: Entity Declared ]
                   2412:  * In a document with an external subset or external parameter entities
                   2413:  * with "standalone='no'", ...  ... The declaration of a parameter entity
                   2414:  * must precede any reference to it...
                   2415:  *
                   2416:  * [ WFC: In DTD ]
                   2417:  * Parameter-entity references may only appear in the DTD.
                   2418:  * NOTE: misleading but this is handled.
                   2419:  *
                   2420:  * A PEReference may have been detected in the current input stream
                   2421:  * the handling is done accordingly to 
                   2422:  *      http://www.w3.org/TR/REC-xml#entproc
                   2423:  * i.e. 
                   2424:  *   - Included in literal in entity values
                   2425:  *   - Included as Parameter Entity reference within DTDs
                   2426:  */
                   2427: void
                   2428: xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
                   2429:     const xmlChar *name;
                   2430:     xmlEntityPtr entity = NULL;
                   2431:     xmlParserInputPtr input;
                   2432: 
                   2433:     if (RAW != '%') return;
                   2434:     switch(ctxt->instate) {
                   2435:        case XML_PARSER_CDATA_SECTION:
                   2436:            return;
                   2437:         case XML_PARSER_COMMENT:
                   2438:            return;
                   2439:        case XML_PARSER_START_TAG:
                   2440:            return;
                   2441:        case XML_PARSER_END_TAG:
                   2442:            return;
                   2443:         case XML_PARSER_EOF:
                   2444:            xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
                   2445:            return;
                   2446:         case XML_PARSER_PROLOG:
                   2447:        case XML_PARSER_START:
                   2448:        case XML_PARSER_MISC:
                   2449:            xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
                   2450:            return;
                   2451:        case XML_PARSER_ENTITY_DECL:
                   2452:         case XML_PARSER_CONTENT:
                   2453:         case XML_PARSER_ATTRIBUTE_VALUE:
                   2454:         case XML_PARSER_PI:
                   2455:        case XML_PARSER_SYSTEM_LITERAL:
                   2456:        case XML_PARSER_PUBLIC_LITERAL:
                   2457:            /* we just ignore it there */
                   2458:            return;
                   2459:         case XML_PARSER_EPILOG:
                   2460:            xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
                   2461:            return;
                   2462:        case XML_PARSER_ENTITY_VALUE:
                   2463:            /*
                   2464:             * NOTE: in the case of entity values, we don't do the
                   2465:             *       substitution here since we need the literal
                   2466:             *       entity value to be able to save the internal
                   2467:             *       subset of the document.
                   2468:             *       This will be handled by xmlStringDecodeEntities
                   2469:             */
                   2470:            return;
                   2471:         case XML_PARSER_DTD:
                   2472:            /*
                   2473:             * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
                   2474:             * In the internal DTD subset, parameter-entity references
                   2475:             * can occur only where markup declarations can occur, not
                   2476:             * within markup declarations.
                   2477:             * In that case this is handled in xmlParseMarkupDecl
                   2478:             */
                   2479:            if ((ctxt->external == 0) && (ctxt->inputNr == 1))
                   2480:                return;
                   2481:            if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
                   2482:                return;
                   2483:             break;
                   2484:         case XML_PARSER_IGNORE:
                   2485:             return;
                   2486:     }
                   2487: 
                   2488:     NEXT;
                   2489:     name = xmlParseName(ctxt);
                   2490:     if (xmlParserDebugEntities)
                   2491:        xmlGenericError(xmlGenericErrorContext,
                   2492:                "PEReference: %s\n", name);
                   2493:     if (name == NULL) {
                   2494:        xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
                   2495:     } else {
                   2496:        if (RAW == ';') {
                   2497:            NEXT;
                   2498:            if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
                   2499:                entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
                   2500:            if (entity == NULL) {
                   2501:                
                   2502:                /*
                   2503:                 * [ WFC: Entity Declared ]
                   2504:                 * In a document without any DTD, a document with only an
                   2505:                 * internal DTD subset which contains no parameter entity
                   2506:                 * references, or a document with "standalone='yes'", ...
                   2507:                 * ... The declaration of a parameter entity must precede
                   2508:                 * any reference to it...
                   2509:                 */
                   2510:                if ((ctxt->standalone == 1) ||
                   2511:                    ((ctxt->hasExternalSubset == 0) &&
                   2512:                     (ctxt->hasPErefs == 0))) {
                   2513:                    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   2514:                         "PEReference: %%%s; not found\n", name);
                   2515:                } else {
                   2516:                    /*
                   2517:                     * [ VC: Entity Declared ]
                   2518:                     * In a document with an external subset or external
                   2519:                     * parameter entities with "standalone='no'", ...
                   2520:                     * ... The declaration of a parameter entity must precede
                   2521:                     * any reference to it...
                   2522:                     */
                   2523:                    if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
                   2524:                        xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   2525:                                         "PEReference: %%%s; not found\n",
                   2526:                                         name, NULL);
                   2527:                    } else 
                   2528:                        xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   2529:                                      "PEReference: %%%s; not found\n",
                   2530:                                      name, NULL);
                   2531:                    ctxt->valid = 0;
                   2532:                }
                   2533:            } else if (ctxt->input->free != deallocblankswrapper) {
                   2534:                    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
                   2535:                    if (xmlPushInput(ctxt, input) < 0)
                   2536:                        return;
                   2537:            } else {
                   2538:                if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
                   2539:                    (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
                   2540:                    xmlChar start[4];
                   2541:                    xmlCharEncoding enc;
                   2542: 
                   2543:                    /*
                   2544:                     * handle the extra spaces added before and after
                   2545:                     * c.f. http://www.w3.org/TR/REC-xml#as-PE
                   2546:                     * this is done independently.
                   2547:                     */
                   2548:                    input = xmlNewEntityInputStream(ctxt, entity);
                   2549:                    if (xmlPushInput(ctxt, input) < 0)
                   2550:                        return;
                   2551: 
                   2552:                    /* 
                   2553:                     * Get the 4 first bytes and decode the charset
                   2554:                     * if enc != XML_CHAR_ENCODING_NONE
                   2555:                     * plug some encoding conversion routines.
                   2556:                     * Note that, since we may have some non-UTF8
                   2557:                     * encoding (like UTF16, bug 135229), the 'length'
                   2558:                     * is not known, but we can calculate based upon
                   2559:                     * the amount of data in the buffer.
                   2560:                     */
                   2561:                    GROW
                   2562:                    if ((ctxt->input->end - ctxt->input->cur)>=4) {
                   2563:                        start[0] = RAW;
                   2564:                        start[1] = NXT(1);
                   2565:                        start[2] = NXT(2);
                   2566:                        start[3] = NXT(3);
                   2567:                        enc = xmlDetectCharEncoding(start, 4);
                   2568:                        if (enc != XML_CHAR_ENCODING_NONE) {
                   2569:                            xmlSwitchEncoding(ctxt, enc);
                   2570:                        }
                   2571:                    }
                   2572: 
                   2573:                    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
                   2574:                        (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
                   2575:                        (IS_BLANK_CH(NXT(5)))) {
                   2576:                        xmlParseTextDecl(ctxt);
                   2577:                    }
                   2578:                } else {
                   2579:                    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
                   2580:                             "PEReference: %s is not a parameter entity\n",
                   2581:                                      name);
                   2582:                }
                   2583:            }
                   2584:        } else {
                   2585:            xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
                   2586:        }
                   2587:     }
                   2588: }
                   2589: 
                   2590: /*
                   2591:  * Macro used to grow the current buffer.
                   2592:  */
                   2593: #define growBuffer(buffer, n) {                                                \
                   2594:     xmlChar *tmp;                                                      \
                   2595:     buffer##_size *= 2;                                                        \
                   2596:     buffer##_size += n;                                                        \
                   2597:     tmp = (xmlChar *)                                                  \
                   2598:                xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));    \
                   2599:     if (tmp == NULL) goto mem_error;                                   \
                   2600:     buffer = tmp;                                                      \
                   2601: }
                   2602: 
                   2603: /**
                   2604:  * xmlStringLenDecodeEntities:
                   2605:  * @ctxt:  the parser context
                   2606:  * @str:  the input string
                   2607:  * @len: the string length
                   2608:  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
                   2609:  * @end:  an end marker xmlChar, 0 if none
                   2610:  * @end2:  an end marker xmlChar, 0 if none
                   2611:  * @end3:  an end marker xmlChar, 0 if none
                   2612:  * 
                   2613:  * Takes a entity string content and process to do the adequate substitutions.
                   2614:  *
                   2615:  * [67] Reference ::= EntityRef | CharRef
                   2616:  *
                   2617:  * [69] PEReference ::= '%' Name ';'
                   2618:  *
                   2619:  * Returns A newly allocated string with the substitution done. The caller
                   2620:  *      must deallocate it !
                   2621:  */
                   2622: xmlChar *
                   2623: xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                   2624:                      int what, xmlChar end, xmlChar  end2, xmlChar end3) {
                   2625:     xmlChar *buffer = NULL;
                   2626:     int buffer_size = 0;
                   2627: 
                   2628:     xmlChar *current = NULL;
                   2629:     xmlChar *rep = NULL;
                   2630:     const xmlChar *last;
                   2631:     xmlEntityPtr ent;
                   2632:     int c,l;
                   2633:     int nbchars = 0;
                   2634: 
                   2635:     if ((ctxt == NULL) || (str == NULL) || (len < 0))
                   2636:        return(NULL);
                   2637:     last = str + len;
                   2638: 
                   2639:     if (((ctxt->depth > 40) &&
                   2640:          ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
                   2641:        (ctxt->depth > 1024)) {
                   2642:        xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
                   2643:        return(NULL);
                   2644:     }
                   2645: 
                   2646:     /*
                   2647:      * allocate a translation buffer.
                   2648:      */
                   2649:     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
                   2650:     buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
                   2651:     if (buffer == NULL) goto mem_error;
                   2652: 
                   2653:     /*
                   2654:      * OK loop until we reach one of the ending char or a size limit.
                   2655:      * we are operating on already parsed values.
                   2656:      */
                   2657:     if (str < last)
                   2658:        c = CUR_SCHAR(str, l);
                   2659:     else
                   2660:         c = 0;
                   2661:     while ((c != 0) && (c != end) && /* non input consuming loop */
                   2662:           (c != end2) && (c != end3)) {
                   2663: 
                   2664:        if (c == 0) break;
                   2665:         if ((c == '&') && (str[1] == '#')) {
                   2666:            int val = xmlParseStringCharRef(ctxt, &str);
                   2667:            if (val != 0) {
                   2668:                COPY_BUF(0,buffer,nbchars,val);
                   2669:            }
                   2670:            if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
                   2671:                growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2672:            }
                   2673:        } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
                   2674:            if (xmlParserDebugEntities)
                   2675:                xmlGenericError(xmlGenericErrorContext,
                   2676:                        "String decoding Entity Reference: %.30s\n",
                   2677:                        str);
                   2678:            ent = xmlParseStringEntityRef(ctxt, &str);
                   2679:            if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
                   2680:                (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
                   2681:                goto int_error;
                   2682:            if (ent != NULL)
                   2683:                ctxt->nbentities += ent->checked;
                   2684:            if ((ent != NULL) &&
                   2685:                (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
                   2686:                if (ent->content != NULL) {
                   2687:                    COPY_BUF(0,buffer,nbchars,ent->content[0]);
                   2688:                    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
                   2689:                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2690:                    }
                   2691:                } else {
                   2692:                    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
                   2693:                            "predefined entity has no content\n");
                   2694:                }
                   2695:            } else if ((ent != NULL) && (ent->content != NULL)) {
                   2696:                ctxt->depth++;
                   2697:                rep = xmlStringDecodeEntities(ctxt, ent->content, what,
                   2698:                                              0, 0, 0);
                   2699:                ctxt->depth--;
                   2700: 
                   2701:                if (rep != NULL) {
                   2702:                    current = rep;
                   2703:                    while (*current != 0) { /* non input consuming loop */
                   2704:                        buffer[nbchars++] = *current++;
                   2705:                        if (nbchars >
                   2706:                            buffer_size - XML_PARSER_BUFFER_SIZE) {
                   2707:                            if (xmlParserEntityCheck(ctxt, nbchars, ent))
                   2708:                                goto int_error;
                   2709:                            growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2710:                        }
                   2711:                    }
                   2712:                    xmlFree(rep);
                   2713:                    rep = NULL;
                   2714:                }
                   2715:            } else if (ent != NULL) {
                   2716:                int i = xmlStrlen(ent->name);
                   2717:                const xmlChar *cur = ent->name;
                   2718: 
                   2719:                buffer[nbchars++] = '&';
                   2720:                if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
1.1.1.2 ! misho    2721:                    growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
1.1       misho    2722:                }
                   2723:                for (;i > 0;i--)
                   2724:                    buffer[nbchars++] = *cur++;
                   2725:                buffer[nbchars++] = ';';
                   2726:            }
                   2727:        } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
                   2728:            if (xmlParserDebugEntities)
                   2729:                xmlGenericError(xmlGenericErrorContext,
                   2730:                        "String decoding PE Reference: %.30s\n", str);
                   2731:            ent = xmlParseStringPEReference(ctxt, &str);
                   2732:            if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
                   2733:                goto int_error;
                   2734:            if (ent != NULL)
                   2735:                ctxt->nbentities += ent->checked;
                   2736:            if (ent != NULL) {
                   2737:                 if (ent->content == NULL) {
                   2738:                    xmlLoadEntityContent(ctxt, ent);
                   2739:                }
                   2740:                ctxt->depth++;
                   2741:                rep = xmlStringDecodeEntities(ctxt, ent->content, what,
                   2742:                                              0, 0, 0);
                   2743:                ctxt->depth--;
                   2744:                if (rep != NULL) {
                   2745:                    current = rep;
                   2746:                    while (*current != 0) { /* non input consuming loop */
                   2747:                        buffer[nbchars++] = *current++;
                   2748:                        if (nbchars >
                   2749:                            buffer_size - XML_PARSER_BUFFER_SIZE) {
                   2750:                            if (xmlParserEntityCheck(ctxt, nbchars, ent))
                   2751:                                goto int_error;
                   2752:                            growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2753:                        }
                   2754:                    }
                   2755:                    xmlFree(rep);
                   2756:                    rep = NULL;
                   2757:                }
                   2758:            }
                   2759:        } else {
                   2760:            COPY_BUF(l,buffer,nbchars,c);
                   2761:            str += l;
                   2762:            if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
                   2763:              growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2764:            }
                   2765:        }
                   2766:        if (str < last)
                   2767:            c = CUR_SCHAR(str, l);
                   2768:        else
                   2769:            c = 0;
                   2770:     }
                   2771:     buffer[nbchars] = 0;
                   2772:     return(buffer);
                   2773: 
                   2774: mem_error:
                   2775:     xmlErrMemory(ctxt, NULL);
                   2776: int_error:
                   2777:     if (rep != NULL)
                   2778:         xmlFree(rep);
                   2779:     if (buffer != NULL)
                   2780:         xmlFree(buffer);
                   2781:     return(NULL);
                   2782: }
                   2783: 
                   2784: /**
                   2785:  * xmlStringDecodeEntities:
                   2786:  * @ctxt:  the parser context
                   2787:  * @str:  the input string
                   2788:  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
                   2789:  * @end:  an end marker xmlChar, 0 if none
                   2790:  * @end2:  an end marker xmlChar, 0 if none
                   2791:  * @end3:  an end marker xmlChar, 0 if none
                   2792:  * 
                   2793:  * Takes a entity string content and process to do the adequate substitutions.
                   2794:  *
                   2795:  * [67] Reference ::= EntityRef | CharRef
                   2796:  *
                   2797:  * [69] PEReference ::= '%' Name ';'
                   2798:  *
                   2799:  * Returns A newly allocated string with the substitution done. The caller
                   2800:  *      must deallocate it !
                   2801:  */
                   2802: xmlChar *
                   2803: xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
                   2804:                        xmlChar end, xmlChar  end2, xmlChar end3) {
                   2805:     if ((ctxt == NULL) || (str == NULL)) return(NULL);
                   2806:     return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
                   2807:            end, end2, end3));
                   2808: }
                   2809: 
                   2810: /************************************************************************
                   2811:  *                                                                     *
                   2812:  *             Commodity functions, cleanup needed ?                   *
                   2813:  *                                                                     *
                   2814:  ************************************************************************/
                   2815: 
                   2816: /**
                   2817:  * areBlanks:
                   2818:  * @ctxt:  an XML parser context
                   2819:  * @str:  a xmlChar *
                   2820:  * @len:  the size of @str
                   2821:  * @blank_chars: we know the chars are blanks
                   2822:  *
                   2823:  * Is this a sequence of blank chars that one can ignore ?
                   2824:  *
                   2825:  * Returns 1 if ignorable 0 otherwise.
                   2826:  */
                   2827: 
                   2828: static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                   2829:                      int blank_chars) {
                   2830:     int i, ret;
                   2831:     xmlNodePtr lastChild;
                   2832: 
                   2833:     /*
                   2834:      * Don't spend time trying to differentiate them, the same callback is
                   2835:      * used !
                   2836:      */
                   2837:     if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
                   2838:        return(0);
                   2839: 
                   2840:     /*
                   2841:      * Check for xml:space value.
                   2842:      */
                   2843:     if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
                   2844:         (*(ctxt->space) == -2))
                   2845:        return(0);
                   2846: 
                   2847:     /*
                   2848:      * Check that the string is made of blanks
                   2849:      */
                   2850:     if (blank_chars == 0) {
                   2851:        for (i = 0;i < len;i++)
                   2852:            if (!(IS_BLANK_CH(str[i]))) return(0);
                   2853:     }
                   2854: 
                   2855:     /*
                   2856:      * Look if the element is mixed content in the DTD if available
                   2857:      */
                   2858:     if (ctxt->node == NULL) return(0);
                   2859:     if (ctxt->myDoc != NULL) {
                   2860:        ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
                   2861:         if (ret == 0) return(1);
                   2862:         if (ret == 1) return(0);
                   2863:     }
                   2864: 
                   2865:     /*
                   2866:      * Otherwise, heuristic :-\
                   2867:      */
                   2868:     if ((RAW != '<') && (RAW != 0xD)) return(0);
                   2869:     if ((ctxt->node->children == NULL) &&
                   2870:        (RAW == '<') && (NXT(1) == '/')) return(0);
                   2871: 
                   2872:     lastChild = xmlGetLastChild(ctxt->node);
                   2873:     if (lastChild == NULL) {
                   2874:         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
                   2875:             (ctxt->node->content != NULL)) return(0);
                   2876:     } else if (xmlNodeIsText(lastChild))
                   2877:         return(0);
                   2878:     else if ((ctxt->node->children != NULL) &&
                   2879:              (xmlNodeIsText(ctxt->node->children)))
                   2880:         return(0);
                   2881:     return(1);
                   2882: }
                   2883: 
                   2884: /************************************************************************
                   2885:  *                                                                     *
                   2886:  *             Extra stuff for namespace support                       *
                   2887:  *     Relates to http://www.w3.org/TR/WD-xml-names                    *
                   2888:  *                                                                     *
                   2889:  ************************************************************************/
                   2890: 
                   2891: /**
                   2892:  * xmlSplitQName:
                   2893:  * @ctxt:  an XML parser context
                   2894:  * @name:  an XML parser context
                   2895:  * @prefix:  a xmlChar **
                   2896:  *
                   2897:  * parse an UTF8 encoded XML qualified name string
                   2898:  *
                   2899:  * [NS 5] QName ::= (Prefix ':')? LocalPart
                   2900:  *
                   2901:  * [NS 6] Prefix ::= NCName
                   2902:  *
                   2903:  * [NS 7] LocalPart ::= NCName
                   2904:  *
                   2905:  * Returns the local part, and prefix is updated
                   2906:  *   to get the Prefix if any.
                   2907:  */
                   2908: 
                   2909: xmlChar *
                   2910: xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
                   2911:     xmlChar buf[XML_MAX_NAMELEN + 5];
                   2912:     xmlChar *buffer = NULL;
                   2913:     int len = 0;
                   2914:     int max = XML_MAX_NAMELEN;
                   2915:     xmlChar *ret = NULL;
                   2916:     const xmlChar *cur = name;
                   2917:     int c;
                   2918: 
                   2919:     if (prefix == NULL) return(NULL);
                   2920:     *prefix = NULL;
                   2921: 
                   2922:     if (cur == NULL) return(NULL);
                   2923: 
                   2924: #ifndef XML_XML_NAMESPACE
                   2925:     /* xml: prefix is not really a namespace */
                   2926:     if ((cur[0] == 'x') && (cur[1] == 'm') &&
                   2927:         (cur[2] == 'l') && (cur[3] == ':'))
                   2928:        return(xmlStrdup(name));
                   2929: #endif
                   2930: 
                   2931:     /* nasty but well=formed */
                   2932:     if (cur[0] == ':')
                   2933:        return(xmlStrdup(name));
                   2934: 
                   2935:     c = *cur++;
                   2936:     while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
                   2937:        buf[len++] = c;
                   2938:        c = *cur++;
                   2939:     }
                   2940:     if (len >= max) {
                   2941:        /*
                   2942:         * Okay someone managed to make a huge name, so he's ready to pay
                   2943:         * for the processing speed.
                   2944:         */
                   2945:        max = len * 2;
                   2946: 
                   2947:        buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
                   2948:        if (buffer == NULL) {
                   2949:            xmlErrMemory(ctxt, NULL);
                   2950:            return(NULL);
                   2951:        }
                   2952:        memcpy(buffer, buf, len);
                   2953:        while ((c != 0) && (c != ':')) { /* tested bigname.xml */
                   2954:            if (len + 10 > max) {
                   2955:                xmlChar *tmp;
                   2956: 
                   2957:                max *= 2;
                   2958:                tmp = (xmlChar *) xmlRealloc(buffer,
                   2959:                                                max * sizeof(xmlChar));
                   2960:                if (tmp == NULL) {
                   2961:                    xmlFree(buffer);
                   2962:                    xmlErrMemory(ctxt, NULL);
                   2963:                    return(NULL);
                   2964:                }
                   2965:                buffer = tmp;
                   2966:            }
                   2967:            buffer[len++] = c;
                   2968:            c = *cur++;
                   2969:        }
                   2970:        buffer[len] = 0;
                   2971:     }
                   2972: 
                   2973:     if ((c == ':') && (*cur == 0)) {
                   2974:         if (buffer != NULL)
                   2975:            xmlFree(buffer);
                   2976:        *prefix = NULL;
                   2977:        return(xmlStrdup(name));
                   2978:     }
                   2979: 
                   2980:     if (buffer == NULL)
                   2981:        ret = xmlStrndup(buf, len);
                   2982:     else {
                   2983:        ret = buffer;
                   2984:        buffer = NULL;
                   2985:        max = XML_MAX_NAMELEN;
                   2986:     }
                   2987: 
                   2988: 
                   2989:     if (c == ':') {
                   2990:        c = *cur;
                   2991:         *prefix = ret;
                   2992:        if (c == 0) {
                   2993:            return(xmlStrndup(BAD_CAST "", 0));
                   2994:        }
                   2995:        len = 0;
                   2996: 
                   2997:        /*
                   2998:         * Check that the first character is proper to start
                   2999:         * a new name
                   3000:         */
                   3001:        if (!(((c >= 0x61) && (c <= 0x7A)) ||
                   3002:              ((c >= 0x41) && (c <= 0x5A)) ||
                   3003:              (c == '_') || (c == ':'))) {
                   3004:            int l;
                   3005:            int first = CUR_SCHAR(cur, l);
                   3006: 
                   3007:            if (!IS_LETTER(first) && (first != '_')) {
                   3008:                xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
                   3009:                            "Name %s is not XML Namespace compliant\n",
                   3010:                                  name);
                   3011:            }
                   3012:        }
                   3013:        cur++;
                   3014: 
                   3015:        while ((c != 0) && (len < max)) { /* tested bigname2.xml */
                   3016:            buf[len++] = c;
                   3017:            c = *cur++;
                   3018:        }
                   3019:        if (len >= max) {
                   3020:            /*
                   3021:             * Okay someone managed to make a huge name, so he's ready to pay
                   3022:             * for the processing speed.
                   3023:             */
                   3024:            max = len * 2;
                   3025: 
                   3026:            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
                   3027:            if (buffer == NULL) {
                   3028:                xmlErrMemory(ctxt, NULL);
                   3029:                return(NULL);
                   3030:            }
                   3031:            memcpy(buffer, buf, len);
                   3032:            while (c != 0) { /* tested bigname2.xml */
                   3033:                if (len + 10 > max) {
                   3034:                    xmlChar *tmp;
                   3035: 
                   3036:                    max *= 2;
                   3037:                    tmp = (xmlChar *) xmlRealloc(buffer,
                   3038:                                                    max * sizeof(xmlChar));
                   3039:                    if (tmp == NULL) {
                   3040:                        xmlErrMemory(ctxt, NULL);
                   3041:                        xmlFree(buffer);
                   3042:                        return(NULL);
                   3043:                    }
                   3044:                    buffer = tmp;
                   3045:                }
                   3046:                buffer[len++] = c;
                   3047:                c = *cur++;
                   3048:            }
                   3049:            buffer[len] = 0;
                   3050:        }
                   3051: 
                   3052:        if (buffer == NULL)
                   3053:            ret = xmlStrndup(buf, len);
                   3054:        else {
                   3055:            ret = buffer;
                   3056:        }
                   3057:     }
                   3058: 
                   3059:     return(ret);
                   3060: }
                   3061: 
                   3062: /************************************************************************
                   3063:  *                                                                     *
                   3064:  *                     The parser itself                               *
                   3065:  *     Relates to http://www.w3.org/TR/REC-xml                         *
                   3066:  *                                                                     *
                   3067:  ************************************************************************/
                   3068: 
                   3069: /************************************************************************
                   3070:  *                                                                     *
                   3071:  *     Routines to parse Name, NCName and NmToken                      *
                   3072:  *                                                                     *
                   3073:  ************************************************************************/
                   3074: #ifdef DEBUG
                   3075: static unsigned long nbParseName = 0;
                   3076: static unsigned long nbParseNmToken = 0;
                   3077: static unsigned long nbParseNCName = 0;
                   3078: static unsigned long nbParseNCNameComplex = 0;
                   3079: static unsigned long nbParseNameComplex = 0;
                   3080: static unsigned long nbParseStringName = 0;
                   3081: #endif
                   3082: 
                   3083: /*
                   3084:  * The two following functions are related to the change of accepted
                   3085:  * characters for Name and NmToken in the Revision 5 of XML-1.0
                   3086:  * They correspond to the modified production [4] and the new production [4a]
                   3087:  * changes in that revision. Also note that the macros used for the
                   3088:  * productions Letter, Digit, CombiningChar and Extender are not needed
                   3089:  * anymore.
                   3090:  * We still keep compatibility to pre-revision5 parsing semantic if the
                   3091:  * new XML_PARSE_OLD10 option is given to the parser.
                   3092:  */
                   3093: static int
                   3094: xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
                   3095:     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
                   3096:         /*
                   3097:         * Use the new checks of production [4] [4a] amd [5] of the
                   3098:         * Update 5 of XML-1.0
                   3099:         */
                   3100:        if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
                   3101:            (((c >= 'a') && (c <= 'z')) ||
                   3102:             ((c >= 'A') && (c <= 'Z')) ||
                   3103:             (c == '_') || (c == ':') ||
                   3104:             ((c >= 0xC0) && (c <= 0xD6)) ||
                   3105:             ((c >= 0xD8) && (c <= 0xF6)) ||
                   3106:             ((c >= 0xF8) && (c <= 0x2FF)) ||
                   3107:             ((c >= 0x370) && (c <= 0x37D)) ||
                   3108:             ((c >= 0x37F) && (c <= 0x1FFF)) ||
                   3109:             ((c >= 0x200C) && (c <= 0x200D)) ||
                   3110:             ((c >= 0x2070) && (c <= 0x218F)) ||
                   3111:             ((c >= 0x2C00) && (c <= 0x2FEF)) ||
                   3112:             ((c >= 0x3001) && (c <= 0xD7FF)) ||
                   3113:             ((c >= 0xF900) && (c <= 0xFDCF)) ||
                   3114:             ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
                   3115:             ((c >= 0x10000) && (c <= 0xEFFFF))))
                   3116:            return(1);
                   3117:     } else {
                   3118:         if (IS_LETTER(c) || (c == '_') || (c == ':'))
                   3119:            return(1);
                   3120:     }
                   3121:     return(0);
                   3122: }
                   3123: 
                   3124: static int
                   3125: xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
                   3126:     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
                   3127:         /*
                   3128:         * Use the new checks of production [4] [4a] amd [5] of the
                   3129:         * Update 5 of XML-1.0
                   3130:         */
                   3131:        if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
                   3132:            (((c >= 'a') && (c <= 'z')) ||
                   3133:             ((c >= 'A') && (c <= 'Z')) ||
                   3134:             ((c >= '0') && (c <= '9')) || /* !start */
                   3135:             (c == '_') || (c == ':') ||
                   3136:             (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
                   3137:             ((c >= 0xC0) && (c <= 0xD6)) ||
                   3138:             ((c >= 0xD8) && (c <= 0xF6)) ||
                   3139:             ((c >= 0xF8) && (c <= 0x2FF)) ||
                   3140:             ((c >= 0x300) && (c <= 0x36F)) || /* !start */
                   3141:             ((c >= 0x370) && (c <= 0x37D)) ||
                   3142:             ((c >= 0x37F) && (c <= 0x1FFF)) ||
                   3143:             ((c >= 0x200C) && (c <= 0x200D)) ||
                   3144:             ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
                   3145:             ((c >= 0x2070) && (c <= 0x218F)) ||
                   3146:             ((c >= 0x2C00) && (c <= 0x2FEF)) ||
                   3147:             ((c >= 0x3001) && (c <= 0xD7FF)) ||
                   3148:             ((c >= 0xF900) && (c <= 0xFDCF)) ||
                   3149:             ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
                   3150:             ((c >= 0x10000) && (c <= 0xEFFFF))))
                   3151:             return(1);
                   3152:     } else {
                   3153:         if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
                   3154:             (c == '.') || (c == '-') ||
                   3155:            (c == '_') || (c == ':') || 
                   3156:            (IS_COMBINING(c)) ||
                   3157:            (IS_EXTENDER(c)))
                   3158:            return(1);
                   3159:     }
                   3160:     return(0);
                   3161: }
                   3162: 
                   3163: static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
                   3164:                                           int *len, int *alloc, int normalize);
                   3165: 
                   3166: static const xmlChar *
                   3167: xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
                   3168:     int len = 0, l;
                   3169:     int c;
                   3170:     int count = 0;
                   3171: 
                   3172: #ifdef DEBUG
                   3173:     nbParseNameComplex++;
                   3174: #endif
                   3175: 
                   3176:     /*
                   3177:      * Handler for more complex cases
                   3178:      */
                   3179:     GROW;
                   3180:     c = CUR_CHAR(l);
                   3181:     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
                   3182:         /*
                   3183:         * Use the new checks of production [4] [4a] amd [5] of the
                   3184:         * Update 5 of XML-1.0
                   3185:         */
                   3186:        if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
                   3187:            (!(((c >= 'a') && (c <= 'z')) ||
                   3188:               ((c >= 'A') && (c <= 'Z')) ||
                   3189:               (c == '_') || (c == ':') ||
                   3190:               ((c >= 0xC0) && (c <= 0xD6)) ||
                   3191:               ((c >= 0xD8) && (c <= 0xF6)) ||
                   3192:               ((c >= 0xF8) && (c <= 0x2FF)) ||
                   3193:               ((c >= 0x370) && (c <= 0x37D)) ||
                   3194:               ((c >= 0x37F) && (c <= 0x1FFF)) ||
                   3195:               ((c >= 0x200C) && (c <= 0x200D)) ||
                   3196:               ((c >= 0x2070) && (c <= 0x218F)) ||
                   3197:               ((c >= 0x2C00) && (c <= 0x2FEF)) ||
                   3198:               ((c >= 0x3001) && (c <= 0xD7FF)) ||
                   3199:               ((c >= 0xF900) && (c <= 0xFDCF)) ||
                   3200:               ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
                   3201:               ((c >= 0x10000) && (c <= 0xEFFFF))))) {
                   3202:            return(NULL);
                   3203:        }
                   3204:        len += l;
                   3205:        NEXTL(l);
                   3206:        c = CUR_CHAR(l);
                   3207:        while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
                   3208:               (((c >= 'a') && (c <= 'z')) ||
                   3209:                ((c >= 'A') && (c <= 'Z')) ||
                   3210:                ((c >= '0') && (c <= '9')) || /* !start */
                   3211:                (c == '_') || (c == ':') ||
                   3212:                (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
                   3213:                ((c >= 0xC0) && (c <= 0xD6)) ||
                   3214:                ((c >= 0xD8) && (c <= 0xF6)) ||
                   3215:                ((c >= 0xF8) && (c <= 0x2FF)) ||
                   3216:                ((c >= 0x300) && (c <= 0x36F)) || /* !start */
                   3217:                ((c >= 0x370) && (c <= 0x37D)) ||
                   3218:                ((c >= 0x37F) && (c <= 0x1FFF)) ||
                   3219:                ((c >= 0x200C) && (c <= 0x200D)) ||
                   3220:                ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
                   3221:                ((c >= 0x2070) && (c <= 0x218F)) ||
                   3222:                ((c >= 0x2C00) && (c <= 0x2FEF)) ||
                   3223:                ((c >= 0x3001) && (c <= 0xD7FF)) ||
                   3224:                ((c >= 0xF900) && (c <= 0xFDCF)) ||
                   3225:                ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
                   3226:                ((c >= 0x10000) && (c <= 0xEFFFF))
                   3227:                )) {
                   3228:            if (count++ > 100) {
                   3229:                count = 0;
                   3230:                GROW;
                   3231:            }
                   3232:            len += l;
                   3233:            NEXTL(l);
                   3234:            c = CUR_CHAR(l);
                   3235:        }
                   3236:     } else {
                   3237:        if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
                   3238:            (!IS_LETTER(c) && (c != '_') &&
                   3239:             (c != ':'))) {
                   3240:            return(NULL);
                   3241:        }
                   3242:        len += l;
                   3243:        NEXTL(l);
                   3244:        c = CUR_CHAR(l);
                   3245: 
                   3246:        while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
                   3247:               ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
                   3248:                (c == '.') || (c == '-') ||
                   3249:                (c == '_') || (c == ':') || 
                   3250:                (IS_COMBINING(c)) ||
                   3251:                (IS_EXTENDER(c)))) {
                   3252:            if (count++ > 100) {
                   3253:                count = 0;
                   3254:                GROW;
                   3255:            }
                   3256:            len += l;
                   3257:            NEXTL(l);
                   3258:            c = CUR_CHAR(l);
                   3259:        }
                   3260:     }
                   3261:     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
                   3262:         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
                   3263:     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
                   3264: }
                   3265: 
                   3266: /**
                   3267:  * xmlParseName:
                   3268:  * @ctxt:  an XML parser context
                   3269:  *
                   3270:  * parse an XML name.
                   3271:  *
                   3272:  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
                   3273:  *                  CombiningChar | Extender
                   3274:  *
                   3275:  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
                   3276:  *
                   3277:  * [6] Names ::= Name (#x20 Name)*
                   3278:  *
                   3279:  * Returns the Name parsed or NULL
                   3280:  */
                   3281: 
                   3282: const xmlChar *
                   3283: xmlParseName(xmlParserCtxtPtr ctxt) {
                   3284:     const xmlChar *in;
                   3285:     const xmlChar *ret;
                   3286:     int count = 0;
                   3287: 
                   3288:     GROW;
                   3289: 
                   3290: #ifdef DEBUG
                   3291:     nbParseName++;
                   3292: #endif
                   3293: 
                   3294:     /*
                   3295:      * Accelerator for simple ASCII names
                   3296:      */
                   3297:     in = ctxt->input->cur;
                   3298:     if (((*in >= 0x61) && (*in <= 0x7A)) ||
                   3299:        ((*in >= 0x41) && (*in <= 0x5A)) ||
                   3300:        (*in == '_') || (*in == ':')) {
                   3301:        in++;
                   3302:        while (((*in >= 0x61) && (*in <= 0x7A)) ||
                   3303:               ((*in >= 0x41) && (*in <= 0x5A)) ||
                   3304:               ((*in >= 0x30) && (*in <= 0x39)) ||
                   3305:               (*in == '_') || (*in == '-') ||
                   3306:               (*in == ':') || (*in == '.'))
                   3307:            in++;
                   3308:        if ((*in > 0) && (*in < 0x80)) {
                   3309:            count = in - ctxt->input->cur;
                   3310:            ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
                   3311:            ctxt->input->cur = in;
                   3312:            ctxt->nbChars += count;
                   3313:            ctxt->input->col += count;
                   3314:            if (ret == NULL)
                   3315:                xmlErrMemory(ctxt, NULL);
                   3316:            return(ret);
                   3317:        }
                   3318:     }
                   3319:     /* accelerator for special cases */
                   3320:     return(xmlParseNameComplex(ctxt));
                   3321: }
                   3322: 
                   3323: static const xmlChar *
                   3324: xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
                   3325:     int len = 0, l;
                   3326:     int c;
                   3327:     int count = 0;
                   3328: 
                   3329: #ifdef DEBUG
                   3330:     nbParseNCNameComplex++;
                   3331: #endif
                   3332: 
                   3333:     /*
                   3334:      * Handler for more complex cases
                   3335:      */
                   3336:     GROW;
                   3337:     c = CUR_CHAR(l);
                   3338:     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
                   3339:        (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
                   3340:        return(NULL);
                   3341:     }
                   3342: 
                   3343:     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
                   3344:           (xmlIsNameChar(ctxt, c) && (c != ':'))) {
                   3345:        if (count++ > 100) {
                   3346:            count = 0;
                   3347:            GROW;
                   3348:        }
                   3349:        len += l;
                   3350:        NEXTL(l);
                   3351:        c = CUR_CHAR(l);
                   3352:     }
                   3353:     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
                   3354: }
                   3355: 
                   3356: /**
                   3357:  * xmlParseNCName:
                   3358:  * @ctxt:  an XML parser context
                   3359:  * @len:  lenght of the string parsed
                   3360:  *
                   3361:  * parse an XML name.
                   3362:  *
                   3363:  * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
                   3364:  *                      CombiningChar | Extender
                   3365:  *
                   3366:  * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
                   3367:  *
                   3368:  * Returns the Name parsed or NULL
                   3369:  */
                   3370: 
                   3371: static const xmlChar *
                   3372: xmlParseNCName(xmlParserCtxtPtr ctxt) {
                   3373:     const xmlChar *in;
                   3374:     const xmlChar *ret;
                   3375:     int count = 0;
                   3376: 
                   3377: #ifdef DEBUG
                   3378:     nbParseNCName++;
                   3379: #endif
                   3380: 
                   3381:     /*
                   3382:      * Accelerator for simple ASCII names
                   3383:      */
                   3384:     in = ctxt->input->cur;
                   3385:     if (((*in >= 0x61) && (*in <= 0x7A)) ||
                   3386:        ((*in >= 0x41) && (*in <= 0x5A)) ||
                   3387:        (*in == '_')) {
                   3388:        in++;
                   3389:        while (((*in >= 0x61) && (*in <= 0x7A)) ||
                   3390:               ((*in >= 0x41) && (*in <= 0x5A)) ||
                   3391:               ((*in >= 0x30) && (*in <= 0x39)) ||
                   3392:               (*in == '_') || (*in == '-') ||
                   3393:               (*in == '.'))
                   3394:            in++;
                   3395:        if ((*in > 0) && (*in < 0x80)) {
                   3396:            count = in - ctxt->input->cur;
                   3397:            ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
                   3398:            ctxt->input->cur = in;
                   3399:            ctxt->nbChars += count;
                   3400:            ctxt->input->col += count;
                   3401:            if (ret == NULL) {
                   3402:                xmlErrMemory(ctxt, NULL);
                   3403:            }
                   3404:            return(ret);
                   3405:        }
                   3406:     }
                   3407:     return(xmlParseNCNameComplex(ctxt));
                   3408: }
                   3409: 
                   3410: /**
                   3411:  * xmlParseNameAndCompare:
                   3412:  * @ctxt:  an XML parser context
                   3413:  *
                   3414:  * parse an XML name and compares for match
                   3415:  * (specialized for endtag parsing)
                   3416:  *
                   3417:  * Returns NULL for an illegal name, (xmlChar*) 1 for success
                   3418:  * and the name for mismatch
                   3419:  */
                   3420: 
                   3421: static const xmlChar *
                   3422: xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
                   3423:     register const xmlChar *cmp = other;
                   3424:     register const xmlChar *in;
                   3425:     const xmlChar *ret;
                   3426: 
                   3427:     GROW;
                   3428: 
                   3429:     in = ctxt->input->cur;
                   3430:     while (*in != 0 && *in == *cmp) {
                   3431:        ++in;
                   3432:        ++cmp;
                   3433:        ctxt->input->col++;
                   3434:     }
                   3435:     if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
                   3436:        /* success */
                   3437:        ctxt->input->cur = in;
                   3438:        return (const xmlChar*) 1;
                   3439:     }
                   3440:     /* failure (or end of input buffer), check with full function */
                   3441:     ret = xmlParseName (ctxt);
                   3442:     /* strings coming from the dictionnary direct compare possible */
                   3443:     if (ret == other) {
                   3444:        return (const xmlChar*) 1;
                   3445:     }
                   3446:     return ret;
                   3447: }
                   3448: 
                   3449: /**
                   3450:  * xmlParseStringName:
                   3451:  * @ctxt:  an XML parser context
                   3452:  * @str:  a pointer to the string pointer (IN/OUT)
                   3453:  *
                   3454:  * parse an XML name.
                   3455:  *
                   3456:  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
                   3457:  *                  CombiningChar | Extender
                   3458:  *
                   3459:  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
                   3460:  *
                   3461:  * [6] Names ::= Name (#x20 Name)*
                   3462:  *
                   3463:  * Returns the Name parsed or NULL. The @str pointer 
                   3464:  * is updated to the current location in the string.
                   3465:  */
                   3466: 
                   3467: static xmlChar *
                   3468: xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
                   3469:     xmlChar buf[XML_MAX_NAMELEN + 5];
                   3470:     const xmlChar *cur = *str;
                   3471:     int len = 0, l;
                   3472:     int c;
                   3473: 
                   3474: #ifdef DEBUG
                   3475:     nbParseStringName++;
                   3476: #endif
                   3477: 
                   3478:     c = CUR_SCHAR(cur, l);
                   3479:     if (!xmlIsNameStartChar(ctxt, c)) {
                   3480:        return(NULL);
                   3481:     }
                   3482: 
                   3483:     COPY_BUF(l,buf,len,c);
                   3484:     cur += l;
                   3485:     c = CUR_SCHAR(cur, l);
                   3486:     while (xmlIsNameChar(ctxt, c)) {
                   3487:        COPY_BUF(l,buf,len,c);
                   3488:        cur += l;
                   3489:        c = CUR_SCHAR(cur, l);
                   3490:        if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
                   3491:            /*
                   3492:             * Okay someone managed to make a huge name, so he's ready to pay
                   3493:             * for the processing speed.
                   3494:             */
                   3495:            xmlChar *buffer;
                   3496:            int max = len * 2;
                   3497: 
                   3498:            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
                   3499:            if (buffer == NULL) {
                   3500:                xmlErrMemory(ctxt, NULL);
                   3501:                return(NULL);
                   3502:            }
                   3503:            memcpy(buffer, buf, len);
                   3504:            while (xmlIsNameChar(ctxt, c)) {
                   3505:                if (len + 10 > max) {
                   3506:                    xmlChar *tmp;
                   3507:                    max *= 2;
                   3508:                    tmp = (xmlChar *) xmlRealloc(buffer,
                   3509:                                                    max * sizeof(xmlChar));
                   3510:                    if (tmp == NULL) {
                   3511:                        xmlErrMemory(ctxt, NULL);
                   3512:                        xmlFree(buffer);
                   3513:                        return(NULL);
                   3514:                    }
                   3515:                    buffer = tmp;
                   3516:                }
                   3517:                COPY_BUF(l,buffer,len,c);
                   3518:                cur += l;
                   3519:                c = CUR_SCHAR(cur, l);
                   3520:            }
                   3521:            buffer[len] = 0;
                   3522:            *str = cur;
                   3523:            return(buffer);
                   3524:        }
                   3525:     }
                   3526:     *str = cur;
                   3527:     return(xmlStrndup(buf, len));
                   3528: }
                   3529: 
                   3530: /**
                   3531:  * xmlParseNmtoken:
                   3532:  * @ctxt:  an XML parser context
                   3533:  *
                   3534:  * parse an XML Nmtoken.
                   3535:  *
                   3536:  * [7] Nmtoken ::= (NameChar)+
                   3537:  *
                   3538:  * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
                   3539:  *
                   3540:  * Returns the Nmtoken parsed or NULL
                   3541:  */
                   3542: 
                   3543: xmlChar *
                   3544: xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
                   3545:     xmlChar buf[XML_MAX_NAMELEN + 5];
                   3546:     int len = 0, l;
                   3547:     int c;
                   3548:     int count = 0;
                   3549: 
                   3550: #ifdef DEBUG
                   3551:     nbParseNmToken++;
                   3552: #endif
                   3553: 
                   3554:     GROW;
                   3555:     c = CUR_CHAR(l);
                   3556: 
                   3557:     while (xmlIsNameChar(ctxt, c)) {
                   3558:        if (count++ > 100) {
                   3559:            count = 0;
                   3560:            GROW;
                   3561:        }
                   3562:        COPY_BUF(l,buf,len,c);
                   3563:        NEXTL(l);
                   3564:        c = CUR_CHAR(l);
                   3565:        if (len >= XML_MAX_NAMELEN) {
                   3566:            /*
                   3567:             * Okay someone managed to make a huge token, so he's ready to pay
                   3568:             * for the processing speed.
                   3569:             */
                   3570:            xmlChar *buffer;
                   3571:            int max = len * 2;
                   3572: 
                   3573:            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
                   3574:            if (buffer == NULL) {
                   3575:                xmlErrMemory(ctxt, NULL);
                   3576:                return(NULL);
                   3577:            }
                   3578:            memcpy(buffer, buf, len);
                   3579:            while (xmlIsNameChar(ctxt, c)) {
                   3580:                if (count++ > 100) {
                   3581:                    count = 0;
                   3582:                    GROW;
                   3583:                }
                   3584:                if (len + 10 > max) {
                   3585:                    xmlChar *tmp;
                   3586: 
                   3587:                    max *= 2;
                   3588:                    tmp = (xmlChar *) xmlRealloc(buffer,
                   3589:                                                    max * sizeof(xmlChar));
                   3590:                    if (tmp == NULL) {
                   3591:                        xmlErrMemory(ctxt, NULL);
                   3592:                        xmlFree(buffer);
                   3593:                        return(NULL);
                   3594:                    }
                   3595:                    buffer = tmp;
                   3596:                }
                   3597:                COPY_BUF(l,buffer,len,c);
                   3598:                NEXTL(l);
                   3599:                c = CUR_CHAR(l);
                   3600:            }
                   3601:            buffer[len] = 0;
                   3602:            return(buffer);
                   3603:        }
                   3604:     }
                   3605:     if (len == 0)
                   3606:         return(NULL);
                   3607:     return(xmlStrndup(buf, len));
                   3608: }
                   3609: 
                   3610: /**
                   3611:  * xmlParseEntityValue:
                   3612:  * @ctxt:  an XML parser context
                   3613:  * @orig:  if non-NULL store a copy of the original entity value
                   3614:  *
                   3615:  * parse a value for ENTITY declarations
                   3616:  *
                   3617:  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
                   3618:  *                    "'" ([^%&'] | PEReference | Reference)* "'"
                   3619:  *
                   3620:  * Returns the EntityValue parsed with reference substituted or NULL
                   3621:  */
                   3622: 
                   3623: xmlChar *
                   3624: xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
                   3625:     xmlChar *buf = NULL;
                   3626:     int len = 0;
                   3627:     int size = XML_PARSER_BUFFER_SIZE;
                   3628:     int c, l;
                   3629:     xmlChar stop;
                   3630:     xmlChar *ret = NULL;
                   3631:     const xmlChar *cur = NULL;
                   3632:     xmlParserInputPtr input;
                   3633: 
                   3634:     if (RAW == '"') stop = '"';
                   3635:     else if (RAW == '\'') stop = '\'';
                   3636:     else {
                   3637:        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
                   3638:        return(NULL);
                   3639:     }
                   3640:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   3641:     if (buf == NULL) {
                   3642:        xmlErrMemory(ctxt, NULL);
                   3643:        return(NULL);
                   3644:     }
                   3645: 
                   3646:     /*
                   3647:      * The content of the entity definition is copied in a buffer.
                   3648:      */
                   3649: 
                   3650:     ctxt->instate = XML_PARSER_ENTITY_VALUE;
                   3651:     input = ctxt->input;
                   3652:     GROW;
                   3653:     NEXT;
                   3654:     c = CUR_CHAR(l);
                   3655:     /*
                   3656:      * NOTE: 4.4.5 Included in Literal
                   3657:      * When a parameter entity reference appears in a literal entity
                   3658:      * value, ... a single or double quote character in the replacement
                   3659:      * text is always treated as a normal data character and will not
                   3660:      * terminate the literal. 
                   3661:      * In practice it means we stop the loop only when back at parsing
                   3662:      * the initial entity and the quote is found
                   3663:      */
                   3664:     while ((IS_CHAR(c)) && ((c != stop) || /* checked */
                   3665:           (ctxt->input != input))) {
                   3666:        if (len + 5 >= size) {
                   3667:            xmlChar *tmp;
                   3668: 
                   3669:            size *= 2;
                   3670:            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   3671:            if (tmp == NULL) {
                   3672:                xmlErrMemory(ctxt, NULL);
                   3673:                xmlFree(buf);
                   3674:                return(NULL);
                   3675:            }
                   3676:            buf = tmp;
                   3677:        }
                   3678:        COPY_BUF(l,buf,len,c);
                   3679:        NEXTL(l);
                   3680:        /*
                   3681:         * Pop-up of finished entities.
                   3682:         */
                   3683:        while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
                   3684:            xmlPopInput(ctxt);
                   3685: 
                   3686:        GROW;
                   3687:        c = CUR_CHAR(l);
                   3688:        if (c == 0) {
                   3689:            GROW;
                   3690:            c = CUR_CHAR(l);
                   3691:        }
                   3692:     }
                   3693:     buf[len] = 0;
                   3694: 
                   3695:     /*
                   3696:      * Raise problem w.r.t. '&' and '%' being used in non-entities
                   3697:      * reference constructs. Note Charref will be handled in
                   3698:      * xmlStringDecodeEntities()
                   3699:      */
                   3700:     cur = buf;
                   3701:     while (*cur != 0) { /* non input consuming */
                   3702:        if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
                   3703:            xmlChar *name;
                   3704:            xmlChar tmp = *cur;
                   3705: 
                   3706:            cur++;
                   3707:            name = xmlParseStringName(ctxt, &cur);
                   3708:             if ((name == NULL) || (*cur != ';')) {
                   3709:                xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
                   3710:            "EntityValue: '%c' forbidden except for entities references\n",
                   3711:                                  tmp);
                   3712:            }
                   3713:            if ((tmp == '%') && (ctxt->inSubset == 1) &&
                   3714:                (ctxt->inputNr == 1)) {
                   3715:                xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
                   3716:            }
                   3717:            if (name != NULL)
                   3718:                xmlFree(name);
                   3719:            if (*cur == 0)
                   3720:                break;
                   3721:        }
                   3722:        cur++;
                   3723:     }
                   3724: 
                   3725:     /*
                   3726:      * Then PEReference entities are substituted.
                   3727:      */
                   3728:     if (c != stop) {
                   3729:        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
                   3730:        xmlFree(buf);
                   3731:     } else {
                   3732:        NEXT;
                   3733:        /*
                   3734:         * NOTE: 4.4.7 Bypassed
                   3735:         * When a general entity reference appears in the EntityValue in
                   3736:         * an entity declaration, it is bypassed and left as is.
                   3737:         * so XML_SUBSTITUTE_REF is not set here.
                   3738:         */
                   3739:        ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
                   3740:                                      0, 0, 0);
                   3741:        if (orig != NULL) 
                   3742:            *orig = buf;
                   3743:        else
                   3744:            xmlFree(buf);
                   3745:     }
                   3746:     
                   3747:     return(ret);
                   3748: }
                   3749: 
                   3750: /**
                   3751:  * xmlParseAttValueComplex:
                   3752:  * @ctxt:  an XML parser context
                   3753:  * @len:   the resulting attribute len
                   3754:  * @normalize:  wether to apply the inner normalization
                   3755:  *
                   3756:  * parse a value for an attribute, this is the fallback function
                   3757:  * of xmlParseAttValue() when the attribute parsing requires handling
                   3758:  * of non-ASCII characters, or normalization compaction.
                   3759:  *
                   3760:  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
                   3761:  */
                   3762: static xmlChar *
                   3763: xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
                   3764:     xmlChar limit = 0;
                   3765:     xmlChar *buf = NULL;
                   3766:     xmlChar *rep = NULL;
                   3767:     int len = 0;
                   3768:     int buf_size = 0;
                   3769:     int c, l, in_space = 0;
                   3770:     xmlChar *current = NULL;
                   3771:     xmlEntityPtr ent;
                   3772: 
                   3773:     if (NXT(0) == '"') {
                   3774:        ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
                   3775:        limit = '"';
                   3776:         NEXT;
                   3777:     } else if (NXT(0) == '\'') {
                   3778:        limit = '\'';
                   3779:        ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
                   3780:         NEXT;
                   3781:     } else {
                   3782:        xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
                   3783:        return(NULL);
                   3784:     }
                   3785: 
                   3786:     /*
                   3787:      * allocate a translation buffer.
                   3788:      */
                   3789:     buf_size = XML_PARSER_BUFFER_SIZE;
                   3790:     buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
                   3791:     if (buf == NULL) goto mem_error;
                   3792: 
                   3793:     /*
                   3794:      * OK loop until we reach one of the ending char or a size limit.
                   3795:      */
                   3796:     c = CUR_CHAR(l);
                   3797:     while ((NXT(0) != limit) && /* checked */
                   3798:            (IS_CHAR(c)) && (c != '<')) {
                   3799:        if (c == 0) break;
                   3800:        if (c == '&') {
                   3801:            in_space = 0;
                   3802:            if (NXT(1) == '#') {
                   3803:                int val = xmlParseCharRef(ctxt);
                   3804: 
                   3805:                if (val == '&') {
                   3806:                    if (ctxt->replaceEntities) {
                   3807:                        if (len > buf_size - 10) {
                   3808:                            growBuffer(buf, 10);
                   3809:                        }
                   3810:                        buf[len++] = '&';
                   3811:                    } else {
                   3812:                        /*
                   3813:                         * The reparsing will be done in xmlStringGetNodeList()
                   3814:                         * called by the attribute() function in SAX.c
                   3815:                         */
                   3816:                        if (len > buf_size - 10) {
                   3817:                            growBuffer(buf, 10);
                   3818:                        }
                   3819:                        buf[len++] = '&';
                   3820:                        buf[len++] = '#';
                   3821:                        buf[len++] = '3';
                   3822:                        buf[len++] = '8';
                   3823:                        buf[len++] = ';';
                   3824:                    }
                   3825:                } else if (val != 0) {
                   3826:                    if (len > buf_size - 10) {
                   3827:                        growBuffer(buf, 10);
                   3828:                    }
                   3829:                    len += xmlCopyChar(0, &buf[len], val);
                   3830:                }
                   3831:            } else {
                   3832:                ent = xmlParseEntityRef(ctxt);
                   3833:                ctxt->nbentities++;
                   3834:                if (ent != NULL)
                   3835:                    ctxt->nbentities += ent->owner;
                   3836:                if ((ent != NULL) &&
                   3837:                    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
                   3838:                    if (len > buf_size - 10) {
                   3839:                        growBuffer(buf, 10);
                   3840:                    }
                   3841:                    if ((ctxt->replaceEntities == 0) &&
                   3842:                        (ent->content[0] == '&')) {
                   3843:                        buf[len++] = '&';
                   3844:                        buf[len++] = '#';
                   3845:                        buf[len++] = '3';
                   3846:                        buf[len++] = '8';
                   3847:                        buf[len++] = ';';
                   3848:                    } else {
                   3849:                        buf[len++] = ent->content[0];
                   3850:                    }
                   3851:                } else if ((ent != NULL) && 
                   3852:                           (ctxt->replaceEntities != 0)) {
                   3853:                    if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
                   3854:                        rep = xmlStringDecodeEntities(ctxt, ent->content,
                   3855:                                                      XML_SUBSTITUTE_REF,
                   3856:                                                      0, 0, 0);
                   3857:                        if (rep != NULL) {
                   3858:                            current = rep;
                   3859:                            while (*current != 0) { /* non input consuming */
                   3860:                                 if ((*current == 0xD) || (*current == 0xA) ||
                   3861:                                     (*current == 0x9)) {
                   3862:                                     buf[len++] = 0x20;
                   3863:                                     current++;
                   3864:                                 } else
                   3865:                                     buf[len++] = *current++;
                   3866:                                if (len > buf_size - 10) {
                   3867:                                    growBuffer(buf, 10);
                   3868:                                }
                   3869:                            }
                   3870:                            xmlFree(rep);
                   3871:                            rep = NULL;
                   3872:                        }
                   3873:                    } else {
                   3874:                        if (len > buf_size - 10) {
                   3875:                            growBuffer(buf, 10);
                   3876:                        }
                   3877:                        if (ent->content != NULL)
                   3878:                            buf[len++] = ent->content[0];
                   3879:                    }
                   3880:                } else if (ent != NULL) {
                   3881:                    int i = xmlStrlen(ent->name);
                   3882:                    const xmlChar *cur = ent->name;
                   3883: 
                   3884:                    /*
                   3885:                     * This may look absurd but is needed to detect
                   3886:                     * entities problems
                   3887:                     */
                   3888:                    if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
                   3889:                        (ent->content != NULL)) {
                   3890:                        rep = xmlStringDecodeEntities(ctxt, ent->content,
                   3891:                                                  XML_SUBSTITUTE_REF, 0, 0, 0);
                   3892:                        if (rep != NULL) {
                   3893:                            xmlFree(rep);
                   3894:                            rep = NULL;
                   3895:                        }
                   3896:                    }
                   3897: 
                   3898:                    /*
                   3899:                     * Just output the reference
                   3900:                     */
                   3901:                    buf[len++] = '&';
                   3902:                    while (len > buf_size - i - 10) {
                   3903:                        growBuffer(buf, i + 10);
                   3904:                    }
                   3905:                    for (;i > 0;i--)
                   3906:                        buf[len++] = *cur++;
                   3907:                    buf[len++] = ';';
                   3908:                }
                   3909:            }
                   3910:        } else {
                   3911:            if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
                   3912:                if ((len != 0) || (!normalize)) {
                   3913:                    if ((!normalize) || (!in_space)) {
                   3914:                        COPY_BUF(l,buf,len,0x20);
                   3915:                        while (len > buf_size - 10) {
                   3916:                            growBuffer(buf, 10);
                   3917:                        }
                   3918:                    }
                   3919:                    in_space = 1;
                   3920:                }
                   3921:            } else {
                   3922:                in_space = 0;
                   3923:                COPY_BUF(l,buf,len,c);
                   3924:                if (len > buf_size - 10) {
                   3925:                    growBuffer(buf, 10);
                   3926:                }
                   3927:            }
                   3928:            NEXTL(l);
                   3929:        }
                   3930:        GROW;
                   3931:        c = CUR_CHAR(l);
                   3932:     }
                   3933:     if ((in_space) && (normalize)) {
                   3934:         while (buf[len - 1] == 0x20) len--;
                   3935:     }
                   3936:     buf[len] = 0;
                   3937:     if (RAW == '<') {
                   3938:        xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
                   3939:     } else if (RAW != limit) {
                   3940:        if ((c != 0) && (!IS_CHAR(c))) {
                   3941:            xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
                   3942:                           "invalid character in attribute value\n");
                   3943:        } else {
                   3944:            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
                   3945:                           "AttValue: ' expected\n");
                   3946:         }
                   3947:     } else
                   3948:        NEXT;
                   3949:     if (attlen != NULL) *attlen = len;
                   3950:     return(buf);
                   3951: 
                   3952: mem_error:
                   3953:     xmlErrMemory(ctxt, NULL);
                   3954:     if (buf != NULL)
                   3955:         xmlFree(buf);
                   3956:     if (rep != NULL)
                   3957:         xmlFree(rep);
                   3958:     return(NULL);
                   3959: }
                   3960: 
                   3961: /**
                   3962:  * xmlParseAttValue:
                   3963:  * @ctxt:  an XML parser context
                   3964:  *
                   3965:  * parse a value for an attribute
                   3966:  * Note: the parser won't do substitution of entities here, this
                   3967:  * will be handled later in xmlStringGetNodeList
                   3968:  *
                   3969:  * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
                   3970:  *                   "'" ([^<&'] | Reference)* "'"
                   3971:  *
                   3972:  * 3.3.3 Attribute-Value Normalization:
                   3973:  * Before the value of an attribute is passed to the application or
                   3974:  * checked for validity, the XML processor must normalize it as follows: 
                   3975:  * - a character reference is processed by appending the referenced
                   3976:  *   character to the attribute value
                   3977:  * - an entity reference is processed by recursively processing the
                   3978:  *   replacement text of the entity 
                   3979:  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
                   3980:  *   appending #x20 to the normalized value, except that only a single
                   3981:  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
                   3982:  *   parsed entity or the literal entity value of an internal parsed entity 
                   3983:  * - other characters are processed by appending them to the normalized value 
                   3984:  * If the declared value is not CDATA, then the XML processor must further
                   3985:  * process the normalized attribute value by discarding any leading and
                   3986:  * trailing space (#x20) characters, and by replacing sequences of space
                   3987:  * (#x20) characters by a single space (#x20) character.  
                   3988:  * All attributes for which no declaration has been read should be treated
                   3989:  * by a non-validating parser as if declared CDATA.
                   3990:  *
                   3991:  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
                   3992:  */
                   3993: 
                   3994: 
                   3995: xmlChar *
                   3996: xmlParseAttValue(xmlParserCtxtPtr ctxt) {
                   3997:     if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
                   3998:     return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
                   3999: }
                   4000: 
                   4001: /**
                   4002:  * xmlParseSystemLiteral:
                   4003:  * @ctxt:  an XML parser context
                   4004:  * 
                   4005:  * parse an XML Literal
                   4006:  *
                   4007:  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
                   4008:  *
                   4009:  * Returns the SystemLiteral parsed or NULL
                   4010:  */
                   4011: 
                   4012: xmlChar *
                   4013: xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
                   4014:     xmlChar *buf = NULL;
                   4015:     int len = 0;
                   4016:     int size = XML_PARSER_BUFFER_SIZE;
                   4017:     int cur, l;
                   4018:     xmlChar stop;
                   4019:     int state = ctxt->instate;
                   4020:     int count = 0;
                   4021: 
                   4022:     SHRINK;
                   4023:     if (RAW == '"') {
                   4024:         NEXT;
                   4025:        stop = '"';
                   4026:     } else if (RAW == '\'') {
                   4027:         NEXT;
                   4028:        stop = '\'';
                   4029:     } else {
                   4030:        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
                   4031:        return(NULL);
                   4032:     }
                   4033:     
                   4034:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   4035:     if (buf == NULL) {
                   4036:         xmlErrMemory(ctxt, NULL);
                   4037:        return(NULL);
                   4038:     }
                   4039:     ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
                   4040:     cur = CUR_CHAR(l);
                   4041:     while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
                   4042:        if (len + 5 >= size) {
                   4043:            xmlChar *tmp;
                   4044: 
                   4045:            size *= 2;
                   4046:            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   4047:            if (tmp == NULL) {
                   4048:                xmlFree(buf);
                   4049:                xmlErrMemory(ctxt, NULL);
                   4050:                ctxt->instate = (xmlParserInputState) state;
                   4051:                return(NULL);
                   4052:            }
                   4053:            buf = tmp;
                   4054:        }
                   4055:        count++;
                   4056:        if (count > 50) {
                   4057:            GROW;
                   4058:            count = 0;
                   4059:        }
                   4060:        COPY_BUF(l,buf,len,cur);
                   4061:        NEXTL(l);
                   4062:        cur = CUR_CHAR(l);
                   4063:        if (cur == 0) {
                   4064:            GROW;
                   4065:            SHRINK;
                   4066:            cur = CUR_CHAR(l);
                   4067:        }
                   4068:     }
                   4069:     buf[len] = 0;
                   4070:     ctxt->instate = (xmlParserInputState) state;
                   4071:     if (!IS_CHAR(cur)) {
                   4072:        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
                   4073:     } else {
                   4074:        NEXT;
                   4075:     }
                   4076:     return(buf);
                   4077: }
                   4078: 
                   4079: /**
                   4080:  * xmlParsePubidLiteral:
                   4081:  * @ctxt:  an XML parser context
                   4082:  *
                   4083:  * parse an XML public literal
                   4084:  *
                   4085:  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
                   4086:  *
                   4087:  * Returns the PubidLiteral parsed or NULL.
                   4088:  */
                   4089: 
                   4090: xmlChar *
                   4091: xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
                   4092:     xmlChar *buf = NULL;
                   4093:     int len = 0;
                   4094:     int size = XML_PARSER_BUFFER_SIZE;
                   4095:     xmlChar cur;
                   4096:     xmlChar stop;
                   4097:     int count = 0;
                   4098:     xmlParserInputState oldstate = ctxt->instate;
                   4099: 
                   4100:     SHRINK;
                   4101:     if (RAW == '"') {
                   4102:         NEXT;
                   4103:        stop = '"';
                   4104:     } else if (RAW == '\'') {
                   4105:         NEXT;
                   4106:        stop = '\'';
                   4107:     } else {
                   4108:        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
                   4109:        return(NULL);
                   4110:     }
                   4111:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   4112:     if (buf == NULL) {
                   4113:        xmlErrMemory(ctxt, NULL);
                   4114:        return(NULL);
                   4115:     }
                   4116:     ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
                   4117:     cur = CUR;
                   4118:     while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
                   4119:        if (len + 1 >= size) {
                   4120:            xmlChar *tmp;
                   4121: 
                   4122:            size *= 2;
                   4123:            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   4124:            if (tmp == NULL) {
                   4125:                xmlErrMemory(ctxt, NULL);
                   4126:                xmlFree(buf);
                   4127:                return(NULL);
                   4128:            }
                   4129:            buf = tmp;
                   4130:        }
                   4131:        buf[len++] = cur;
                   4132:        count++;
                   4133:        if (count > 50) {
                   4134:            GROW;
                   4135:            count = 0;
                   4136:        }
                   4137:        NEXT;
                   4138:        cur = CUR;
                   4139:        if (cur == 0) {
                   4140:            GROW;
                   4141:            SHRINK;
                   4142:            cur = CUR;
                   4143:        }
                   4144:     }
                   4145:     buf[len] = 0;
                   4146:     if (cur != stop) {
                   4147:        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
                   4148:     } else {
                   4149:        NEXT;
                   4150:     }
                   4151:     ctxt->instate = oldstate;
                   4152:     return(buf);
                   4153: }
                   4154: 
                   4155: static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
                   4156: 
                   4157: /*
                   4158:  * used for the test in the inner loop of the char data testing
                   4159:  */
                   4160: static const unsigned char test_char_data[256] = {
                   4161:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4162:     0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
                   4163:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4164:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4165:     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
                   4166:     0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
                   4167:     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
                   4168:     0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
                   4169:     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
                   4170:     0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
                   4171:     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
                   4172:     0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
                   4173:     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
                   4174:     0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
                   4175:     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
                   4176:     0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
                   4177:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
                   4178:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4179:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4180:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4181:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4182:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4183:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4184:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4185:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4186:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4187:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4188:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4189:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4190:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4191:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4192:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                   4193: };
                   4194: 
                   4195: /**
                   4196:  * xmlParseCharData:
                   4197:  * @ctxt:  an XML parser context
                   4198:  * @cdata:  int indicating whether we are within a CDATA section
                   4199:  *
                   4200:  * parse a CharData section.
                   4201:  * if we are within a CDATA section ']]>' marks an end of section.
                   4202:  *
                   4203:  * The right angle bracket (>) may be represented using the string "&gt;",
                   4204:  * and must, for compatibility, be escaped using "&gt;" or a character
                   4205:  * reference when it appears in the string "]]>" in content, when that
                   4206:  * string is not marking the end of a CDATA section. 
                   4207:  *
                   4208:  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
                   4209:  */
                   4210: 
                   4211: void
                   4212: xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
                   4213:     const xmlChar *in;
                   4214:     int nbchar = 0;
                   4215:     int line = ctxt->input->line;
                   4216:     int col = ctxt->input->col;
                   4217:     int ccol;
                   4218: 
                   4219:     SHRINK;
                   4220:     GROW;
                   4221:     /*
                   4222:      * Accelerated common case where input don't need to be
                   4223:      * modified before passing it to the handler.
                   4224:      */
                   4225:     if (!cdata) {
                   4226:        in = ctxt->input->cur;
                   4227:        do {
                   4228: get_more_space:
                   4229:            while (*in == 0x20) { in++; ctxt->input->col++; }
                   4230:            if (*in == 0xA) {
                   4231:                do {
                   4232:                    ctxt->input->line++; ctxt->input->col = 1;
                   4233:                    in++;
                   4234:                } while (*in == 0xA);
                   4235:                goto get_more_space;
                   4236:            }
                   4237:            if (*in == '<') {
                   4238:                nbchar = in - ctxt->input->cur;
                   4239:                if (nbchar > 0) {
                   4240:                    const xmlChar *tmp = ctxt->input->cur;
                   4241:                    ctxt->input->cur = in;
                   4242: 
                   4243:                    if ((ctxt->sax != NULL) &&
                   4244:                        (ctxt->sax->ignorableWhitespace !=
                   4245:                         ctxt->sax->characters)) {
                   4246:                        if (areBlanks(ctxt, tmp, nbchar, 1)) {
                   4247:                            if (ctxt->sax->ignorableWhitespace != NULL)
                   4248:                                ctxt->sax->ignorableWhitespace(ctxt->userData,
                   4249:                                                       tmp, nbchar);
                   4250:                        } else {
                   4251:                            if (ctxt->sax->characters != NULL)
                   4252:                                ctxt->sax->characters(ctxt->userData,
                   4253:                                                      tmp, nbchar);
                   4254:                            if (*ctxt->space == -1)
                   4255:                                *ctxt->space = -2;
                   4256:                        }
                   4257:                    } else if ((ctxt->sax != NULL) &&
                   4258:                               (ctxt->sax->characters != NULL)) {
                   4259:                        ctxt->sax->characters(ctxt->userData,
                   4260:                                              tmp, nbchar);
                   4261:                    }
                   4262:                }
                   4263:                return;
                   4264:            }
                   4265: 
                   4266: get_more:
                   4267:             ccol = ctxt->input->col;
                   4268:            while (test_char_data[*in]) {
                   4269:                in++;
                   4270:                ccol++;
                   4271:            }
                   4272:            ctxt->input->col = ccol;
                   4273:            if (*in == 0xA) {
                   4274:                do {
                   4275:                    ctxt->input->line++; ctxt->input->col = 1;
                   4276:                    in++;
                   4277:                } while (*in == 0xA);
                   4278:                goto get_more;
                   4279:            }
                   4280:            if (*in == ']') {
                   4281:                if ((in[1] == ']') && (in[2] == '>')) {
                   4282:                    xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
                   4283:                    ctxt->input->cur = in;
                   4284:                    return;
                   4285:                }
                   4286:                in++;
                   4287:                ctxt->input->col++;
                   4288:                goto get_more;
                   4289:            }
                   4290:            nbchar = in - ctxt->input->cur;
                   4291:            if (nbchar > 0) {
                   4292:                if ((ctxt->sax != NULL) &&
                   4293:                    (ctxt->sax->ignorableWhitespace !=
                   4294:                     ctxt->sax->characters) &&
                   4295:                    (IS_BLANK_CH(*ctxt->input->cur))) {
                   4296:                    const xmlChar *tmp = ctxt->input->cur;
                   4297:                    ctxt->input->cur = in;
                   4298: 
                   4299:                    if (areBlanks(ctxt, tmp, nbchar, 0)) {
                   4300:                        if (ctxt->sax->ignorableWhitespace != NULL)
                   4301:                            ctxt->sax->ignorableWhitespace(ctxt->userData,
                   4302:                                                           tmp, nbchar);
                   4303:                    } else {
                   4304:                        if (ctxt->sax->characters != NULL)
                   4305:                            ctxt->sax->characters(ctxt->userData,
                   4306:                                                  tmp, nbchar);
                   4307:                        if (*ctxt->space == -1)
                   4308:                            *ctxt->space = -2;
                   4309:                    }
                   4310:                     line = ctxt->input->line;
                   4311:                     col = ctxt->input->col;
                   4312:                } else if (ctxt->sax != NULL) {
                   4313:                    if (ctxt->sax->characters != NULL)
                   4314:                        ctxt->sax->characters(ctxt->userData,
                   4315:                                              ctxt->input->cur, nbchar);
                   4316:                     line = ctxt->input->line;
                   4317:                     col = ctxt->input->col;
                   4318:                }
                   4319:                 /* something really bad happened in the SAX callback */
                   4320:                 if (ctxt->instate != XML_PARSER_CONTENT)
                   4321:                     return;
                   4322:            }
                   4323:            ctxt->input->cur = in;
                   4324:            if (*in == 0xD) {
                   4325:                in++;
                   4326:                if (*in == 0xA) {
                   4327:                    ctxt->input->cur = in;
                   4328:                    in++;
                   4329:                    ctxt->input->line++; ctxt->input->col = 1;
                   4330:                    continue; /* while */
                   4331:                }
                   4332:                in--;
                   4333:            }
                   4334:            if (*in == '<') {
                   4335:                return;
                   4336:            }
                   4337:            if (*in == '&') {
                   4338:                return;
                   4339:            }
                   4340:            SHRINK;
                   4341:            GROW;
                   4342:            in = ctxt->input->cur;
                   4343:        } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
                   4344:        nbchar = 0;
                   4345:     }
                   4346:     ctxt->input->line = line;
                   4347:     ctxt->input->col = col;
                   4348:     xmlParseCharDataComplex(ctxt, cdata);
                   4349: }
                   4350: 
                   4351: /**
                   4352:  * xmlParseCharDataComplex:
                   4353:  * @ctxt:  an XML parser context
                   4354:  * @cdata:  int indicating whether we are within a CDATA section
                   4355:  *
                   4356:  * parse a CharData section.this is the fallback function
                   4357:  * of xmlParseCharData() when the parsing requires handling
                   4358:  * of non-ASCII characters.
                   4359:  */
                   4360: static void
                   4361: xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
                   4362:     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
                   4363:     int nbchar = 0;
                   4364:     int cur, l;
                   4365:     int count = 0;
                   4366: 
                   4367:     SHRINK;
                   4368:     GROW;
                   4369:     cur = CUR_CHAR(l);
                   4370:     while ((cur != '<') && /* checked */
                   4371:            (cur != '&') && 
                   4372:           (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
                   4373:        if ((cur == ']') && (NXT(1) == ']') &&
                   4374:            (NXT(2) == '>')) {
                   4375:            if (cdata) break;
                   4376:            else {
                   4377:                xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
                   4378:            }
                   4379:        }
                   4380:        COPY_BUF(l,buf,nbchar,cur);
                   4381:        if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
                   4382:            buf[nbchar] = 0;
                   4383: 
                   4384:            /*
                   4385:             * OK the segment is to be consumed as chars.
                   4386:             */
                   4387:            if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
                   4388:                if (areBlanks(ctxt, buf, nbchar, 0)) {
                   4389:                    if (ctxt->sax->ignorableWhitespace != NULL)
                   4390:                        ctxt->sax->ignorableWhitespace(ctxt->userData,
                   4391:                                                       buf, nbchar);
                   4392:                } else {
                   4393:                    if (ctxt->sax->characters != NULL)
                   4394:                        ctxt->sax->characters(ctxt->userData, buf, nbchar);
                   4395:                    if ((ctxt->sax->characters !=
                   4396:                         ctxt->sax->ignorableWhitespace) &&
                   4397:                        (*ctxt->space == -1))
                   4398:                        *ctxt->space = -2;
                   4399:                }
                   4400:            }
                   4401:            nbchar = 0;
                   4402:             /* something really bad happened in the SAX callback */
                   4403:             if (ctxt->instate != XML_PARSER_CONTENT)
                   4404:                 return;
                   4405:        }
                   4406:        count++;
                   4407:        if (count > 50) {
                   4408:            GROW;
                   4409:            count = 0;
                   4410:        }
                   4411:        NEXTL(l);
                   4412:        cur = CUR_CHAR(l);
                   4413:     }
                   4414:     if (nbchar != 0) {
                   4415:         buf[nbchar] = 0;
                   4416:        /*
                   4417:         * OK the segment is to be consumed as chars.
                   4418:         */
                   4419:        if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
                   4420:            if (areBlanks(ctxt, buf, nbchar, 0)) {
                   4421:                if (ctxt->sax->ignorableWhitespace != NULL)
                   4422:                    ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
                   4423:            } else {
                   4424:                if (ctxt->sax->characters != NULL)
                   4425:                    ctxt->sax->characters(ctxt->userData, buf, nbchar);
                   4426:                if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
                   4427:                    (*ctxt->space == -1))
                   4428:                    *ctxt->space = -2;
                   4429:            }
                   4430:        }
                   4431:     }
                   4432:     if ((cur != 0) && (!IS_CHAR(cur))) {
                   4433:        /* Generate the error and skip the offending character */
                   4434:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   4435:                           "PCDATA invalid Char value %d\n",
                   4436:                          cur);
                   4437:        NEXTL(l);
                   4438:     }
                   4439: }
                   4440: 
                   4441: /**
                   4442:  * xmlParseExternalID:
                   4443:  * @ctxt:  an XML parser context
                   4444:  * @publicID:  a xmlChar** receiving PubidLiteral
                   4445:  * @strict: indicate whether we should restrict parsing to only
                   4446:  *          production [75], see NOTE below
                   4447:  *
                   4448:  * Parse an External ID or a Public ID
                   4449:  *
                   4450:  * NOTE: Productions [75] and [83] interact badly since [75] can generate
                   4451:  *       'PUBLIC' S PubidLiteral S SystemLiteral
                   4452:  *
                   4453:  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
                   4454:  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
                   4455:  *
                   4456:  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
                   4457:  *
                   4458:  * Returns the function returns SystemLiteral and in the second
                   4459:  *                case publicID receives PubidLiteral, is strict is off
                   4460:  *                it is possible to return NULL and have publicID set.
                   4461:  */
                   4462: 
                   4463: xmlChar *
                   4464: xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
                   4465:     xmlChar *URI = NULL;
                   4466: 
                   4467:     SHRINK;
                   4468: 
                   4469:     *publicID = NULL;
                   4470:     if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
                   4471:         SKIP(6);
                   4472:        if (!IS_BLANK_CH(CUR)) {
                   4473:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   4474:                           "Space required after 'SYSTEM'\n");
                   4475:        }
                   4476:         SKIP_BLANKS;
                   4477:        URI = xmlParseSystemLiteral(ctxt);
                   4478:        if (URI == NULL) {
                   4479:            xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
                   4480:         }
                   4481:     } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
                   4482:         SKIP(6);
                   4483:        if (!IS_BLANK_CH(CUR)) {
                   4484:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   4485:                    "Space required after 'PUBLIC'\n");
                   4486:        }
                   4487:         SKIP_BLANKS;
                   4488:        *publicID = xmlParsePubidLiteral(ctxt);
                   4489:        if (*publicID == NULL) {
                   4490:            xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
                   4491:        }
                   4492:        if (strict) {
                   4493:            /*
                   4494:             * We don't handle [83] so "S SystemLiteral" is required.
                   4495:             */
                   4496:            if (!IS_BLANK_CH(CUR)) {
                   4497:                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   4498:                        "Space required after the Public Identifier\n");
                   4499:            }
                   4500:        } else {
                   4501:            /*
                   4502:             * We handle [83] so we return immediately, if 
                   4503:             * "S SystemLiteral" is not detected. From a purely parsing
                   4504:             * point of view that's a nice mess.
                   4505:             */
                   4506:            const xmlChar *ptr;
                   4507:            GROW;
                   4508: 
                   4509:            ptr = CUR_PTR;
                   4510:            if (!IS_BLANK_CH(*ptr)) return(NULL);
                   4511:            
                   4512:            while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
                   4513:            if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
                   4514:        }
                   4515:         SKIP_BLANKS;
                   4516:        URI = xmlParseSystemLiteral(ctxt);
                   4517:        if (URI == NULL) {
                   4518:            xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
                   4519:         }
                   4520:     }
                   4521:     return(URI);
                   4522: }
                   4523: 
                   4524: /**
                   4525:  * xmlParseCommentComplex:
                   4526:  * @ctxt:  an XML parser context
                   4527:  * @buf:  the already parsed part of the buffer
                   4528:  * @len:  number of bytes filles in the buffer
                   4529:  * @size:  allocated size of the buffer
                   4530:  *
                   4531:  * Skip an XML (SGML) comment <!-- .... -->
                   4532:  *  The spec says that "For compatibility, the string "--" (double-hyphen)
                   4533:  *  must not occur within comments. "
                   4534:  * This is the slow routine in case the accelerator for ascii didn't work
                   4535:  *
                   4536:  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
                   4537:  */
                   4538: static void
                   4539: xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, int len, int size) {
                   4540:     int q, ql;
                   4541:     int r, rl;
                   4542:     int cur, l;
                   4543:     int count = 0;
                   4544:     int inputid;
                   4545: 
                   4546:     inputid = ctxt->input->id;
                   4547: 
                   4548:     if (buf == NULL) {
                   4549:         len = 0;
                   4550:        size = XML_PARSER_BUFFER_SIZE;
                   4551:        buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   4552:        if (buf == NULL) {
                   4553:            xmlErrMemory(ctxt, NULL);
                   4554:            return;
                   4555:        }
                   4556:     }
                   4557:     GROW;      /* Assure there's enough input data */
                   4558:     q = CUR_CHAR(ql);
                   4559:     if (q == 0)
                   4560:         goto not_terminated;
                   4561:     if (!IS_CHAR(q)) {
                   4562:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   4563:                           "xmlParseComment: invalid xmlChar value %d\n",
                   4564:                          q);
                   4565:        xmlFree (buf);
                   4566:        return;
                   4567:     }
                   4568:     NEXTL(ql);
                   4569:     r = CUR_CHAR(rl);
                   4570:     if (r == 0)
                   4571:         goto not_terminated;
                   4572:     if (!IS_CHAR(r)) {
                   4573:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   4574:                           "xmlParseComment: invalid xmlChar value %d\n",
                   4575:                          q);
                   4576:        xmlFree (buf);
                   4577:        return;
                   4578:     }
                   4579:     NEXTL(rl);
                   4580:     cur = CUR_CHAR(l);
                   4581:     if (cur == 0)
                   4582:         goto not_terminated;
                   4583:     while (IS_CHAR(cur) && /* checked */
                   4584:            ((cur != '>') ||
                   4585:            (r != '-') || (q != '-'))) {
                   4586:        if ((r == '-') && (q == '-')) {
                   4587:            xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
                   4588:        }
                   4589:        if (len + 5 >= size) {
                   4590:            xmlChar *new_buf;
                   4591:            size *= 2;
                   4592:            new_buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   4593:            if (new_buf == NULL) {
                   4594:                xmlFree (buf);
                   4595:                xmlErrMemory(ctxt, NULL);
                   4596:                return;
                   4597:            }
                   4598:            buf = new_buf;
                   4599:        }
                   4600:        COPY_BUF(ql,buf,len,q);
                   4601:        q = r;
                   4602:        ql = rl;
                   4603:        r = cur;
                   4604:        rl = l;
                   4605: 
                   4606:        count++;
                   4607:        if (count > 50) {
                   4608:            GROW;
                   4609:            count = 0;
                   4610:        }
                   4611:        NEXTL(l);
                   4612:        cur = CUR_CHAR(l);
                   4613:        if (cur == 0) {
                   4614:            SHRINK;
                   4615:            GROW;
                   4616:            cur = CUR_CHAR(l);
                   4617:        }
                   4618:     }
                   4619:     buf[len] = 0;
                   4620:     if (cur == 0) {
                   4621:        xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
                   4622:                             "Comment not terminated \n<!--%.50s\n", buf);
                   4623:     } else if (!IS_CHAR(cur)) {
                   4624:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   4625:                           "xmlParseComment: invalid xmlChar value %d\n",
                   4626:                          cur);
                   4627:     } else {
                   4628:        if (inputid != ctxt->input->id) {
                   4629:            xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   4630:                "Comment doesn't start and stop in the same entity\n");
                   4631:        }
                   4632:         NEXT;
                   4633:        if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
                   4634:            (!ctxt->disableSAX))
                   4635:            ctxt->sax->comment(ctxt->userData, buf);
                   4636:     }
                   4637:     xmlFree(buf);
                   4638:     return;
                   4639: not_terminated:
                   4640:     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
                   4641:                         "Comment not terminated\n", NULL);
                   4642:     xmlFree(buf);
                   4643:     return;
                   4644: }
                   4645: 
                   4646: /**
                   4647:  * xmlParseComment:
                   4648:  * @ctxt:  an XML parser context
                   4649:  *
                   4650:  * Skip an XML (SGML) comment <!-- .... -->
                   4651:  *  The spec says that "For compatibility, the string "--" (double-hyphen)
                   4652:  *  must not occur within comments. "
                   4653:  *
                   4654:  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
                   4655:  */
                   4656: void
                   4657: xmlParseComment(xmlParserCtxtPtr ctxt) {
                   4658:     xmlChar *buf = NULL;
                   4659:     int size = XML_PARSER_BUFFER_SIZE;
                   4660:     int len = 0;
                   4661:     xmlParserInputState state;
                   4662:     const xmlChar *in;
                   4663:     int nbchar = 0, ccol;
                   4664:     int inputid;
                   4665: 
                   4666:     /*
                   4667:      * Check that there is a comment right here.
                   4668:      */
                   4669:     if ((RAW != '<') || (NXT(1) != '!') ||
                   4670:         (NXT(2) != '-') || (NXT(3) != '-')) return;
                   4671:     state = ctxt->instate;
                   4672:     ctxt->instate = XML_PARSER_COMMENT;
                   4673:     inputid = ctxt->input->id;
                   4674:     SKIP(4);
                   4675:     SHRINK;
                   4676:     GROW;
                   4677: 
                   4678:     /*
                   4679:      * Accelerated common case where input don't need to be
                   4680:      * modified before passing it to the handler.
                   4681:      */
                   4682:     in = ctxt->input->cur;
                   4683:     do {
                   4684:        if (*in == 0xA) {
                   4685:            do {
                   4686:                ctxt->input->line++; ctxt->input->col = 1;
                   4687:                in++;
                   4688:            } while (*in == 0xA);
                   4689:        }
                   4690: get_more:
                   4691:         ccol = ctxt->input->col;
                   4692:        while (((*in > '-') && (*in <= 0x7F)) ||
                   4693:               ((*in >= 0x20) && (*in < '-')) ||
                   4694:               (*in == 0x09)) {
                   4695:                    in++;
                   4696:                    ccol++;
                   4697:        }
                   4698:        ctxt->input->col = ccol;
                   4699:        if (*in == 0xA) {
                   4700:            do {
                   4701:                ctxt->input->line++; ctxt->input->col = 1;
                   4702:                in++;
                   4703:            } while (*in == 0xA);
                   4704:            goto get_more;
                   4705:        }
                   4706:        nbchar = in - ctxt->input->cur;
                   4707:        /*
                   4708:         * save current set of data
                   4709:         */
                   4710:        if (nbchar > 0) {
                   4711:            if ((ctxt->sax != NULL) &&
                   4712:                (ctxt->sax->comment != NULL)) {
                   4713:                if (buf == NULL) {
                   4714:                    if ((*in == '-') && (in[1] == '-'))
                   4715:                        size = nbchar + 1;
                   4716:                    else
                   4717:                        size = XML_PARSER_BUFFER_SIZE + nbchar;
                   4718:                    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   4719:                    if (buf == NULL) {
                   4720:                        xmlErrMemory(ctxt, NULL);
                   4721:                        ctxt->instate = state;
                   4722:                        return;
                   4723:                    }
                   4724:                    len = 0;
                   4725:                } else if (len + nbchar + 1 >= size) {
                   4726:                    xmlChar *new_buf;
                   4727:                    size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
                   4728:                    new_buf = (xmlChar *) xmlRealloc(buf,
                   4729:                                                     size * sizeof(xmlChar));
                   4730:                    if (new_buf == NULL) {
                   4731:                        xmlFree (buf);
                   4732:                        xmlErrMemory(ctxt, NULL);
                   4733:                        ctxt->instate = state;
                   4734:                        return;
                   4735:                    }
                   4736:                    buf = new_buf;
                   4737:                }
                   4738:                memcpy(&buf[len], ctxt->input->cur, nbchar);
                   4739:                len += nbchar;
                   4740:                buf[len] = 0;
                   4741:            }
                   4742:        }
                   4743:        ctxt->input->cur = in;
                   4744:        if (*in == 0xA) {
                   4745:            in++;
                   4746:            ctxt->input->line++; ctxt->input->col = 1;
                   4747:        }
                   4748:        if (*in == 0xD) {
                   4749:            in++;
                   4750:            if (*in == 0xA) {
                   4751:                ctxt->input->cur = in;
                   4752:                in++;
                   4753:                ctxt->input->line++; ctxt->input->col = 1;
                   4754:                continue; /* while */
                   4755:            }
                   4756:            in--;
                   4757:        }
                   4758:        SHRINK;
                   4759:        GROW;
                   4760:        in = ctxt->input->cur;
                   4761:        if (*in == '-') {
                   4762:            if (in[1] == '-') {
                   4763:                if (in[2] == '>') {
                   4764:                    if (ctxt->input->id != inputid) {
                   4765:                        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   4766:                        "comment doesn't start and stop in the same entity\n");
                   4767:                    }
                   4768:                    SKIP(3);
                   4769:                    if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
                   4770:                        (!ctxt->disableSAX)) {
                   4771:                        if (buf != NULL)
                   4772:                            ctxt->sax->comment(ctxt->userData, buf);
                   4773:                        else
                   4774:                            ctxt->sax->comment(ctxt->userData, BAD_CAST "");
                   4775:                    }
                   4776:                    if (buf != NULL)
                   4777:                        xmlFree(buf);
                   4778:                    ctxt->instate = state;
                   4779:                    return;
                   4780:                }
1.1.1.2 ! misho    4781:                if (buf != NULL) {
        !          4782:                    xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
        !          4783:                                      "Double hyphen within comment: "
        !          4784:                                       "<!--%.50s\n",
1.1       misho    4785:                                      buf);
1.1.1.2 ! misho    4786:                } else
        !          4787:                    xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
        !          4788:                                      "Double hyphen within comment\n", NULL);
1.1       misho    4789:                in++;
                   4790:                ctxt->input->col++;
                   4791:            }
                   4792:            in++;
                   4793:            ctxt->input->col++;
                   4794:            goto get_more;
                   4795:        }
                   4796:     } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
                   4797:     xmlParseCommentComplex(ctxt, buf, len, size);
                   4798:     ctxt->instate = state;
                   4799:     return;
                   4800: }
                   4801: 
                   4802: 
                   4803: /**
                   4804:  * xmlParsePITarget:
                   4805:  * @ctxt:  an XML parser context
                   4806:  * 
                   4807:  * parse the name of a PI
                   4808:  *
                   4809:  * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
                   4810:  *
                   4811:  * Returns the PITarget name or NULL
                   4812:  */
                   4813: 
                   4814: const xmlChar *
                   4815: xmlParsePITarget(xmlParserCtxtPtr ctxt) {
                   4816:     const xmlChar *name;
                   4817: 
                   4818:     name = xmlParseName(ctxt);
                   4819:     if ((name != NULL) &&
                   4820:         ((name[0] == 'x') || (name[0] == 'X')) &&
                   4821:         ((name[1] == 'm') || (name[1] == 'M')) &&
                   4822:         ((name[2] == 'l') || (name[2] == 'L'))) {
                   4823:        int i;
                   4824:        if ((name[0] == 'x') && (name[1] == 'm') &&
                   4825:            (name[2] == 'l') && (name[3] == 0)) {
                   4826:            xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
                   4827:                 "XML declaration allowed only at the start of the document\n");
                   4828:            return(name);
                   4829:        } else if (name[3] == 0) {
                   4830:            xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
                   4831:            return(name);
                   4832:        }
                   4833:        for (i = 0;;i++) {
                   4834:            if (xmlW3CPIs[i] == NULL) break;
                   4835:            if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
                   4836:                return(name);
                   4837:        }
                   4838:        xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
                   4839:                      "xmlParsePITarget: invalid name prefix 'xml'\n",
                   4840:                      NULL, NULL);
                   4841:     }
                   4842:     if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
                   4843:        xmlNsErr(ctxt, XML_NS_ERR_COLON, 
                   4844:                 "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
                   4845:     }
                   4846:     return(name);
                   4847: }
                   4848: 
                   4849: #ifdef LIBXML_CATALOG_ENABLED
                   4850: /**
                   4851:  * xmlParseCatalogPI:
                   4852:  * @ctxt:  an XML parser context
                   4853:  * @catalog:  the PI value string
                   4854:  * 
                   4855:  * parse an XML Catalog Processing Instruction.
                   4856:  *
                   4857:  * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
                   4858:  *
                   4859:  * Occurs only if allowed by the user and if happening in the Misc
                   4860:  * part of the document before any doctype informations
                   4861:  * This will add the given catalog to the parsing context in order
                   4862:  * to be used if there is a resolution need further down in the document
                   4863:  */
                   4864: 
                   4865: static void
                   4866: xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
                   4867:     xmlChar *URL = NULL;
                   4868:     const xmlChar *tmp, *base;
                   4869:     xmlChar marker;
                   4870: 
                   4871:     tmp = catalog;
                   4872:     while (IS_BLANK_CH(*tmp)) tmp++;
                   4873:     if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
                   4874:        goto error;
                   4875:     tmp += 7;
                   4876:     while (IS_BLANK_CH(*tmp)) tmp++;
                   4877:     if (*tmp != '=') {
                   4878:        return;
                   4879:     }
                   4880:     tmp++;
                   4881:     while (IS_BLANK_CH(*tmp)) tmp++;
                   4882:     marker = *tmp;
                   4883:     if ((marker != '\'') && (marker != '"'))
                   4884:        goto error;
                   4885:     tmp++;
                   4886:     base = tmp;
                   4887:     while ((*tmp != 0) && (*tmp != marker)) tmp++;
                   4888:     if (*tmp == 0)
                   4889:        goto error;
                   4890:     URL = xmlStrndup(base, tmp - base);
                   4891:     tmp++;
                   4892:     while (IS_BLANK_CH(*tmp)) tmp++;
                   4893:     if (*tmp != 0)
                   4894:        goto error;
                   4895: 
                   4896:     if (URL != NULL) {
                   4897:        ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
                   4898:        xmlFree(URL);
                   4899:     }
                   4900:     return;
                   4901: 
                   4902: error:
                   4903:     xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
                   4904:                  "Catalog PI syntax error: %s\n",
                   4905:                  catalog, NULL);
                   4906:     if (URL != NULL)
                   4907:        xmlFree(URL);
                   4908: }
                   4909: #endif
                   4910: 
                   4911: /**
                   4912:  * xmlParsePI:
                   4913:  * @ctxt:  an XML parser context
                   4914:  * 
                   4915:  * parse an XML Processing Instruction.
                   4916:  *
                   4917:  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
                   4918:  *
                   4919:  * The processing is transfered to SAX once parsed.
                   4920:  */
                   4921: 
                   4922: void
                   4923: xmlParsePI(xmlParserCtxtPtr ctxt) {
                   4924:     xmlChar *buf = NULL;
                   4925:     int len = 0;
                   4926:     int size = XML_PARSER_BUFFER_SIZE;
                   4927:     int cur, l;
                   4928:     const xmlChar *target;
                   4929:     xmlParserInputState state;
                   4930:     int count = 0;
                   4931: 
                   4932:     if ((RAW == '<') && (NXT(1) == '?')) {
                   4933:        xmlParserInputPtr input = ctxt->input;
                   4934:        state = ctxt->instate;
                   4935:         ctxt->instate = XML_PARSER_PI;
                   4936:        /*
                   4937:         * this is a Processing Instruction.
                   4938:         */
                   4939:        SKIP(2);
                   4940:        SHRINK;
                   4941: 
                   4942:        /*
                   4943:         * Parse the target name and check for special support like
                   4944:         * namespace.
                   4945:         */
                   4946:         target = xmlParsePITarget(ctxt);
                   4947:        if (target != NULL) {
                   4948:            if ((RAW == '?') && (NXT(1) == '>')) {
                   4949:                if (input != ctxt->input) {
                   4950:                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   4951:            "PI declaration doesn't start and stop in the same entity\n");
                   4952:                }
                   4953:                SKIP(2);
                   4954: 
                   4955:                /*
                   4956:                 * SAX: PI detected.
                   4957:                 */
                   4958:                if ((ctxt->sax) && (!ctxt->disableSAX) &&
                   4959:                    (ctxt->sax->processingInstruction != NULL))
                   4960:                    ctxt->sax->processingInstruction(ctxt->userData,
                   4961:                                                     target, NULL);
1.1.1.2 ! misho    4962:                if (ctxt->instate != XML_PARSER_EOF)
        !          4963:                    ctxt->instate = state;
1.1       misho    4964:                return;
                   4965:            }
                   4966:            buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   4967:            if (buf == NULL) {
                   4968:                xmlErrMemory(ctxt, NULL);
                   4969:                ctxt->instate = state;
                   4970:                return;
                   4971:            }
                   4972:            cur = CUR;
                   4973:            if (!IS_BLANK(cur)) {
                   4974:                xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
                   4975:                          "ParsePI: PI %s space expected\n", target);
                   4976:            }
                   4977:             SKIP_BLANKS;
                   4978:            cur = CUR_CHAR(l);
                   4979:            while (IS_CHAR(cur) && /* checked */
                   4980:                   ((cur != '?') || (NXT(1) != '>'))) {
                   4981:                if (len + 5 >= size) {
                   4982:                    xmlChar *tmp;
                   4983: 
                   4984:                    size *= 2;
                   4985:                    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   4986:                    if (tmp == NULL) {
                   4987:                        xmlErrMemory(ctxt, NULL);
                   4988:                        xmlFree(buf);
                   4989:                        ctxt->instate = state;
                   4990:                        return;
                   4991:                    }
                   4992:                    buf = tmp;
                   4993:                }
                   4994:                count++;
                   4995:                if (count > 50) {
                   4996:                    GROW;
                   4997:                    count = 0;
                   4998:                }
                   4999:                COPY_BUF(l,buf,len,cur);
                   5000:                NEXTL(l);
                   5001:                cur = CUR_CHAR(l);
                   5002:                if (cur == 0) {
                   5003:                    SHRINK;
                   5004:                    GROW;
                   5005:                    cur = CUR_CHAR(l);
                   5006:                }
                   5007:            }
                   5008:            buf[len] = 0;
                   5009:            if (cur != '?') {
                   5010:                xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
                   5011:                      "ParsePI: PI %s never end ...\n", target);
                   5012:            } else {
                   5013:                if (input != ctxt->input) {
                   5014:                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5015:            "PI declaration doesn't start and stop in the same entity\n");
                   5016:                }
                   5017:                SKIP(2);
                   5018: 
                   5019: #ifdef LIBXML_CATALOG_ENABLED
                   5020:                if (((state == XML_PARSER_MISC) ||
                   5021:                     (state == XML_PARSER_START)) &&
                   5022:                    (xmlStrEqual(target, XML_CATALOG_PI))) {
                   5023:                    xmlCatalogAllow allow = xmlCatalogGetDefaults();
                   5024:                    if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
                   5025:                        (allow == XML_CATA_ALLOW_ALL))
                   5026:                        xmlParseCatalogPI(ctxt, buf);
                   5027:                }
                   5028: #endif
                   5029: 
                   5030: 
                   5031:                /*
                   5032:                 * SAX: PI detected.
                   5033:                 */
                   5034:                if ((ctxt->sax) && (!ctxt->disableSAX) &&
                   5035:                    (ctxt->sax->processingInstruction != NULL))
                   5036:                    ctxt->sax->processingInstruction(ctxt->userData,
                   5037:                                                     target, buf);
                   5038:            }
                   5039:            xmlFree(buf);
                   5040:        } else {
                   5041:            xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
                   5042:        }
1.1.1.2 ! misho    5043:        if (ctxt->instate != XML_PARSER_EOF)
        !          5044:            ctxt->instate = state;
1.1       misho    5045:     }
                   5046: }
                   5047: 
                   5048: /**
                   5049:  * xmlParseNotationDecl:
                   5050:  * @ctxt:  an XML parser context
                   5051:  *
                   5052:  * parse a notation declaration
                   5053:  *
                   5054:  * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
                   5055:  *
                   5056:  * Hence there is actually 3 choices:
                   5057:  *     'PUBLIC' S PubidLiteral
                   5058:  *     'PUBLIC' S PubidLiteral S SystemLiteral
                   5059:  * and 'SYSTEM' S SystemLiteral
                   5060:  *
                   5061:  * See the NOTE on xmlParseExternalID().
                   5062:  */
                   5063: 
                   5064: void
                   5065: xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
                   5066:     const xmlChar *name;
                   5067:     xmlChar *Pubid;
                   5068:     xmlChar *Systemid;
                   5069:     
                   5070:     if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
                   5071:        xmlParserInputPtr input = ctxt->input;
                   5072:        SHRINK;
                   5073:        SKIP(10);
                   5074:        if (!IS_BLANK_CH(CUR)) {
                   5075:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5076:                           "Space required after '<!NOTATION'\n");
                   5077:            return;
                   5078:        }
                   5079:        SKIP_BLANKS;
                   5080: 
                   5081:         name = xmlParseName(ctxt);
                   5082:        if (name == NULL) {
                   5083:            xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
                   5084:            return;
                   5085:        }
                   5086:        if (!IS_BLANK_CH(CUR)) {
                   5087:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5088:                     "Space required after the NOTATION name'\n");
                   5089:            return;
                   5090:        }
                   5091:        if (xmlStrchr(name, ':') != NULL) {
                   5092:            xmlNsErr(ctxt, XML_NS_ERR_COLON, 
                   5093:                     "colon are forbidden from notation names '%s'\n",
                   5094:                     name, NULL, NULL);
                   5095:        }
                   5096:        SKIP_BLANKS;
                   5097: 
                   5098:        /*
                   5099:         * Parse the IDs.
                   5100:         */
                   5101:        Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
                   5102:        SKIP_BLANKS;
                   5103: 
                   5104:        if (RAW == '>') {
                   5105:            if (input != ctxt->input) {
                   5106:                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5107:        "Notation declaration doesn't start and stop in the same entity\n");
                   5108:            }
                   5109:            NEXT;
                   5110:            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   5111:                (ctxt->sax->notationDecl != NULL))
                   5112:                ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
                   5113:        } else {
                   5114:            xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
                   5115:        }
                   5116:        if (Systemid != NULL) xmlFree(Systemid);
                   5117:        if (Pubid != NULL) xmlFree(Pubid);
                   5118:     }
                   5119: }
                   5120: 
                   5121: /**
                   5122:  * xmlParseEntityDecl:
                   5123:  * @ctxt:  an XML parser context
                   5124:  *
                   5125:  * parse <!ENTITY declarations
                   5126:  *
                   5127:  * [70] EntityDecl ::= GEDecl | PEDecl
                   5128:  *
                   5129:  * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
                   5130:  *
                   5131:  * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
                   5132:  *
                   5133:  * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
                   5134:  *
                   5135:  * [74] PEDef ::= EntityValue | ExternalID
                   5136:  *
                   5137:  * [76] NDataDecl ::= S 'NDATA' S Name
                   5138:  *
                   5139:  * [ VC: Notation Declared ]
                   5140:  * The Name must match the declared name of a notation.
                   5141:  */
                   5142: 
                   5143: void
                   5144: xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
                   5145:     const xmlChar *name = NULL;
                   5146:     xmlChar *value = NULL;
                   5147:     xmlChar *URI = NULL, *literal = NULL;
                   5148:     const xmlChar *ndata = NULL;
                   5149:     int isParameter = 0;
                   5150:     xmlChar *orig = NULL;
                   5151:     int skipped;
                   5152:     
                   5153:     /* GROW; done in the caller */
                   5154:     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
                   5155:        xmlParserInputPtr input = ctxt->input;
                   5156:        SHRINK;
                   5157:        SKIP(8);
                   5158:        skipped = SKIP_BLANKS;
                   5159:        if (skipped == 0) {
                   5160:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5161:                           "Space required after '<!ENTITY'\n");
                   5162:        }
                   5163: 
                   5164:        if (RAW == '%') {
                   5165:            NEXT;
                   5166:            skipped = SKIP_BLANKS;
                   5167:            if (skipped == 0) {
                   5168:                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5169:                               "Space required after '%'\n");
                   5170:            }
                   5171:            isParameter = 1;
                   5172:        }
                   5173: 
                   5174:         name = xmlParseName(ctxt);
                   5175:        if (name == NULL) {
                   5176:            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   5177:                           "xmlParseEntityDecl: no name\n");
                   5178:             return;
                   5179:        }
                   5180:        if (xmlStrchr(name, ':') != NULL) {
                   5181:            xmlNsErr(ctxt, XML_NS_ERR_COLON, 
                   5182:                     "colon are forbidden from entities names '%s'\n",
                   5183:                     name, NULL, NULL);
                   5184:        }
                   5185:         skipped = SKIP_BLANKS;
                   5186:        if (skipped == 0) {
                   5187:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5188:                           "Space required after the entity name\n");
                   5189:        }
                   5190: 
                   5191:        ctxt->instate = XML_PARSER_ENTITY_DECL;
                   5192:        /*
                   5193:         * handle the various case of definitions...
                   5194:         */
                   5195:        if (isParameter) {
                   5196:            if ((RAW == '"') || (RAW == '\'')) {
                   5197:                value = xmlParseEntityValue(ctxt, &orig);
                   5198:                if (value) {
                   5199:                    if ((ctxt->sax != NULL) &&
                   5200:                        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
                   5201:                        ctxt->sax->entityDecl(ctxt->userData, name,
                   5202:                                    XML_INTERNAL_PARAMETER_ENTITY,
                   5203:                                    NULL, NULL, value);
                   5204:                }
                   5205:            } else {
                   5206:                URI = xmlParseExternalID(ctxt, &literal, 1);
                   5207:                if ((URI == NULL) && (literal == NULL)) {
                   5208:                    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
                   5209:                }
                   5210:                if (URI) {
                   5211:                    xmlURIPtr uri;
                   5212: 
                   5213:                    uri = xmlParseURI((const char *) URI);
                   5214:                    if (uri == NULL) {
                   5215:                        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
                   5216:                                     "Invalid URI: %s\n", URI);
                   5217:                        /*
                   5218:                         * This really ought to be a well formedness error
                   5219:                         * but the XML Core WG decided otherwise c.f. issue
                   5220:                         * E26 of the XML erratas.
                   5221:                         */
                   5222:                    } else {
                   5223:                        if (uri->fragment != NULL) {
                   5224:                            /*
                   5225:                             * Okay this is foolish to block those but not
                   5226:                             * invalid URIs.
                   5227:                             */
                   5228:                            xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
                   5229:                        } else {
                   5230:                            if ((ctxt->sax != NULL) &&
                   5231:                                (!ctxt->disableSAX) &&
                   5232:                                (ctxt->sax->entityDecl != NULL))
                   5233:                                ctxt->sax->entityDecl(ctxt->userData, name,
                   5234:                                            XML_EXTERNAL_PARAMETER_ENTITY,
                   5235:                                            literal, URI, NULL);
                   5236:                        }
                   5237:                        xmlFreeURI(uri);
                   5238:                    }
                   5239:                }
                   5240:            }
                   5241:        } else {
                   5242:            if ((RAW == '"') || (RAW == '\'')) {
                   5243:                value = xmlParseEntityValue(ctxt, &orig);
                   5244:                if ((ctxt->sax != NULL) &&
                   5245:                    (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
                   5246:                    ctxt->sax->entityDecl(ctxt->userData, name,
                   5247:                                XML_INTERNAL_GENERAL_ENTITY,
                   5248:                                NULL, NULL, value);
                   5249:                /*
                   5250:                 * For expat compatibility in SAX mode.
                   5251:                 */
                   5252:                if ((ctxt->myDoc == NULL) ||
                   5253:                    (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
                   5254:                    if (ctxt->myDoc == NULL) {
                   5255:                        ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
                   5256:                        if (ctxt->myDoc == NULL) {
                   5257:                            xmlErrMemory(ctxt, "New Doc failed");
                   5258:                            return;
                   5259:                        }
                   5260:                        ctxt->myDoc->properties = XML_DOC_INTERNAL;
                   5261:                    }
                   5262:                    if (ctxt->myDoc->intSubset == NULL)
                   5263:                        ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
                   5264:                                            BAD_CAST "fake", NULL, NULL);
                   5265: 
                   5266:                    xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
                   5267:                                      NULL, NULL, value);
                   5268:                }
                   5269:            } else {
                   5270:                URI = xmlParseExternalID(ctxt, &literal, 1);
                   5271:                if ((URI == NULL) && (literal == NULL)) {
                   5272:                    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
                   5273:                }
                   5274:                if (URI) {
                   5275:                    xmlURIPtr uri;
                   5276: 
                   5277:                    uri = xmlParseURI((const char *)URI);
                   5278:                    if (uri == NULL) {
                   5279:                        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
                   5280:                                     "Invalid URI: %s\n", URI);
                   5281:                        /*
                   5282:                         * This really ought to be a well formedness error
                   5283:                         * but the XML Core WG decided otherwise c.f. issue
                   5284:                         * E26 of the XML erratas.
                   5285:                         */
                   5286:                    } else {
                   5287:                        if (uri->fragment != NULL) {
                   5288:                            /*
                   5289:                             * Okay this is foolish to block those but not
                   5290:                             * invalid URIs.
                   5291:                             */
                   5292:                            xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
                   5293:                        }
                   5294:                        xmlFreeURI(uri);
                   5295:                    }
                   5296:                }
                   5297:                if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
                   5298:                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5299:                                   "Space required before 'NDATA'\n");
                   5300:                }
                   5301:                SKIP_BLANKS;
                   5302:                if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
                   5303:                    SKIP(5);
                   5304:                    if (!IS_BLANK_CH(CUR)) {
                   5305:                        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5306:                                       "Space required after 'NDATA'\n");
                   5307:                    }
                   5308:                    SKIP_BLANKS;
                   5309:                    ndata = xmlParseName(ctxt);
                   5310:                    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   5311:                        (ctxt->sax->unparsedEntityDecl != NULL))
                   5312:                        ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
                   5313:                                    literal, URI, ndata);
                   5314:                } else {
                   5315:                    if ((ctxt->sax != NULL) &&
                   5316:                        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
                   5317:                        ctxt->sax->entityDecl(ctxt->userData, name,
                   5318:                                    XML_EXTERNAL_GENERAL_PARSED_ENTITY,
                   5319:                                    literal, URI, NULL);
                   5320:                    /*
                   5321:                     * For expat compatibility in SAX mode.
                   5322:                     * assuming the entity repalcement was asked for
                   5323:                     */
                   5324:                    if ((ctxt->replaceEntities != 0) &&
                   5325:                        ((ctxt->myDoc == NULL) ||
                   5326:                        (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
                   5327:                        if (ctxt->myDoc == NULL) {
                   5328:                            ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
                   5329:                            if (ctxt->myDoc == NULL) {
                   5330:                                xmlErrMemory(ctxt, "New Doc failed");
                   5331:                                return;
                   5332:                            }
                   5333:                            ctxt->myDoc->properties = XML_DOC_INTERNAL;
                   5334:                        }
                   5335: 
                   5336:                        if (ctxt->myDoc->intSubset == NULL)
                   5337:                            ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
                   5338:                                                BAD_CAST "fake", NULL, NULL);
                   5339:                        xmlSAX2EntityDecl(ctxt, name,
                   5340:                                          XML_EXTERNAL_GENERAL_PARSED_ENTITY,
                   5341:                                          literal, URI, NULL);
                   5342:                    }
                   5343:                }
                   5344:            }
                   5345:        }
                   5346:        SKIP_BLANKS;
                   5347:        if (RAW != '>') {
                   5348:            xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
                   5349:                    "xmlParseEntityDecl: entity %s not terminated\n", name);
                   5350:        } else {
                   5351:            if (input != ctxt->input) {
                   5352:                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   5353:        "Entity declaration doesn't start and stop in the same entity\n");
                   5354:            }
                   5355:            NEXT;
                   5356:        }
                   5357:        if (orig != NULL) {
                   5358:            /*
                   5359:             * Ugly mechanism to save the raw entity value.
                   5360:             */
                   5361:            xmlEntityPtr cur = NULL;
                   5362: 
                   5363:            if (isParameter) {
                   5364:                if ((ctxt->sax != NULL) &&
                   5365:                    (ctxt->sax->getParameterEntity != NULL))
                   5366:                    cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
                   5367:            } else {
                   5368:                if ((ctxt->sax != NULL) &&
                   5369:                    (ctxt->sax->getEntity != NULL))
                   5370:                    cur = ctxt->sax->getEntity(ctxt->userData, name);
                   5371:                if ((cur == NULL) && (ctxt->userData==ctxt)) {
                   5372:                    cur = xmlSAX2GetEntity(ctxt, name);
                   5373:                }
                   5374:            }
                   5375:             if (cur != NULL) {
                   5376:                if (cur->orig != NULL)
                   5377:                    xmlFree(orig);
                   5378:                else
                   5379:                    cur->orig = orig;
                   5380:            } else
                   5381:                xmlFree(orig);
                   5382:        }
                   5383:        if (value != NULL) xmlFree(value);
                   5384:        if (URI != NULL) xmlFree(URI);
                   5385:        if (literal != NULL) xmlFree(literal);
                   5386:     }
                   5387: }
                   5388: 
                   5389: /**
                   5390:  * xmlParseDefaultDecl:
                   5391:  * @ctxt:  an XML parser context
                   5392:  * @value:  Receive a possible fixed default value for the attribute
                   5393:  *
                   5394:  * Parse an attribute default declaration
                   5395:  *
                   5396:  * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
                   5397:  *
                   5398:  * [ VC: Required Attribute ]
                   5399:  * if the default declaration is the keyword #REQUIRED, then the
                   5400:  * attribute must be specified for all elements of the type in the
                   5401:  * attribute-list declaration.
                   5402:  *
                   5403:  * [ VC: Attribute Default Legal ]
                   5404:  * The declared default value must meet the lexical constraints of
                   5405:  * the declared attribute type c.f. xmlValidateAttributeDecl()
                   5406:  *
                   5407:  * [ VC: Fixed Attribute Default ]
                   5408:  * if an attribute has a default value declared with the #FIXED
                   5409:  * keyword, instances of that attribute must match the default value. 
                   5410:  *
                   5411:  * [ WFC: No < in Attribute Values ]
                   5412:  * handled in xmlParseAttValue()
                   5413:  *
                   5414:  * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
                   5415:  *          or XML_ATTRIBUTE_FIXED. 
                   5416:  */
                   5417: 
                   5418: int
                   5419: xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
                   5420:     int val;
                   5421:     xmlChar *ret;
                   5422: 
                   5423:     *value = NULL;
                   5424:     if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
                   5425:        SKIP(9);
                   5426:        return(XML_ATTRIBUTE_REQUIRED);
                   5427:     }
                   5428:     if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
                   5429:        SKIP(8);
                   5430:        return(XML_ATTRIBUTE_IMPLIED);
                   5431:     }
                   5432:     val = XML_ATTRIBUTE_NONE;
                   5433:     if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
                   5434:        SKIP(6);
                   5435:        val = XML_ATTRIBUTE_FIXED;
                   5436:        if (!IS_BLANK_CH(CUR)) {
                   5437:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5438:                           "Space required after '#FIXED'\n");
                   5439:        }
                   5440:        SKIP_BLANKS;
                   5441:     }
                   5442:     ret = xmlParseAttValue(ctxt);
                   5443:     ctxt->instate = XML_PARSER_DTD;
                   5444:     if (ret == NULL) {
                   5445:        xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
                   5446:                       "Attribute default value declaration error\n");
                   5447:     } else
                   5448:         *value = ret;
                   5449:     return(val);
                   5450: }
                   5451: 
                   5452: /**
                   5453:  * xmlParseNotationType:
                   5454:  * @ctxt:  an XML parser context
                   5455:  *
                   5456:  * parse an Notation attribute type.
                   5457:  *
                   5458:  * Note: the leading 'NOTATION' S part has already being parsed...
                   5459:  *
                   5460:  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
                   5461:  *
                   5462:  * [ VC: Notation Attributes ]
                   5463:  * Values of this type must match one of the notation names included
                   5464:  * in the declaration; all notation names in the declaration must be declared. 
                   5465:  *
                   5466:  * Returns: the notation attribute tree built while parsing
                   5467:  */
                   5468: 
                   5469: xmlEnumerationPtr
                   5470: xmlParseNotationType(xmlParserCtxtPtr ctxt) {
                   5471:     const xmlChar *name;
                   5472:     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
                   5473: 
                   5474:     if (RAW != '(') {
                   5475:        xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
                   5476:        return(NULL);
                   5477:     }
                   5478:     SHRINK;
                   5479:     do {
                   5480:         NEXT;
                   5481:        SKIP_BLANKS;
                   5482:         name = xmlParseName(ctxt);
                   5483:        if (name == NULL) {
                   5484:            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   5485:                           "Name expected in NOTATION declaration\n");
                   5486:             xmlFreeEnumeration(ret);
                   5487:            return(NULL);
                   5488:        }
                   5489:        tmp = ret;
                   5490:        while (tmp != NULL) {
                   5491:            if (xmlStrEqual(name, tmp->name)) {
                   5492:                xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
                   5493:          "standalone: attribute notation value token %s duplicated\n",
                   5494:                                 name, NULL);
                   5495:                if (!xmlDictOwns(ctxt->dict, name))
                   5496:                    xmlFree((xmlChar *) name);
                   5497:                break;
                   5498:            }
                   5499:            tmp = tmp->next;
                   5500:        }
                   5501:        if (tmp == NULL) {
                   5502:            cur = xmlCreateEnumeration(name);
                   5503:            if (cur == NULL) {
                   5504:                 xmlFreeEnumeration(ret);
                   5505:                 return(NULL);
                   5506:             }
                   5507:            if (last == NULL) ret = last = cur;
                   5508:            else {
                   5509:                last->next = cur;
                   5510:                last = cur;
                   5511:            }
                   5512:        }
                   5513:        SKIP_BLANKS;
                   5514:     } while (RAW == '|');
                   5515:     if (RAW != ')') {
                   5516:        xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
                   5517:         xmlFreeEnumeration(ret);
                   5518:        return(NULL);
                   5519:     }
                   5520:     NEXT;
                   5521:     return(ret);
                   5522: }
                   5523: 
                   5524: /**
                   5525:  * xmlParseEnumerationType:
                   5526:  * @ctxt:  an XML parser context
                   5527:  *
                   5528:  * parse an Enumeration attribute type.
                   5529:  *
                   5530:  * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
                   5531:  *
                   5532:  * [ VC: Enumeration ]
                   5533:  * Values of this type must match one of the Nmtoken tokens in
                   5534:  * the declaration
                   5535:  *
                   5536:  * Returns: the enumeration attribute tree built while parsing
                   5537:  */
                   5538: 
                   5539: xmlEnumerationPtr
                   5540: xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
                   5541:     xmlChar *name;
                   5542:     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
                   5543: 
                   5544:     if (RAW != '(') {
                   5545:        xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
                   5546:        return(NULL);
                   5547:     }
                   5548:     SHRINK;
                   5549:     do {
                   5550:         NEXT;
                   5551:        SKIP_BLANKS;
                   5552:         name = xmlParseNmtoken(ctxt);
                   5553:        if (name == NULL) {
                   5554:            xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
                   5555:            return(ret);
                   5556:        }
                   5557:        tmp = ret;
                   5558:        while (tmp != NULL) {
                   5559:            if (xmlStrEqual(name, tmp->name)) {
                   5560:                xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
                   5561:          "standalone: attribute enumeration value token %s duplicated\n",
                   5562:                                 name, NULL);
                   5563:                if (!xmlDictOwns(ctxt->dict, name))
                   5564:                    xmlFree(name);
                   5565:                break;
                   5566:            }
                   5567:            tmp = tmp->next;
                   5568:        }
                   5569:        if (tmp == NULL) {
                   5570:            cur = xmlCreateEnumeration(name);
                   5571:            if (!xmlDictOwns(ctxt->dict, name))
                   5572:                xmlFree(name);
                   5573:            if (cur == NULL) {
                   5574:                 xmlFreeEnumeration(ret);
                   5575:                 return(NULL);
                   5576:             }
                   5577:            if (last == NULL) ret = last = cur;
                   5578:            else {
                   5579:                last->next = cur;
                   5580:                last = cur;
                   5581:            }
                   5582:        }
                   5583:        SKIP_BLANKS;
                   5584:     } while (RAW == '|');
                   5585:     if (RAW != ')') {
                   5586:        xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
                   5587:        return(ret);
                   5588:     }
                   5589:     NEXT;
                   5590:     return(ret);
                   5591: }
                   5592: 
                   5593: /**
                   5594:  * xmlParseEnumeratedType:
                   5595:  * @ctxt:  an XML parser context
                   5596:  * @tree:  the enumeration tree built while parsing
                   5597:  *
                   5598:  * parse an Enumerated attribute type.
                   5599:  *
                   5600:  * [57] EnumeratedType ::= NotationType | Enumeration
                   5601:  *
                   5602:  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
                   5603:  *
                   5604:  *
                   5605:  * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
                   5606:  */
                   5607: 
                   5608: int
                   5609: xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
                   5610:     if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
                   5611:        SKIP(8);
                   5612:        if (!IS_BLANK_CH(CUR)) {
                   5613:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5614:                           "Space required after 'NOTATION'\n");
                   5615:            return(0);
                   5616:        }
                   5617:         SKIP_BLANKS;
                   5618:        *tree = xmlParseNotationType(ctxt);
                   5619:        if (*tree == NULL) return(0);
                   5620:        return(XML_ATTRIBUTE_NOTATION);
                   5621:     }
                   5622:     *tree = xmlParseEnumerationType(ctxt);
                   5623:     if (*tree == NULL) return(0);
                   5624:     return(XML_ATTRIBUTE_ENUMERATION);
                   5625: }
                   5626: 
                   5627: /**
                   5628:  * xmlParseAttributeType:
                   5629:  * @ctxt:  an XML parser context
                   5630:  * @tree:  the enumeration tree built while parsing
                   5631:  *
                   5632:  * parse the Attribute list def for an element
                   5633:  *
                   5634:  * [54] AttType ::= StringType | TokenizedType | EnumeratedType
                   5635:  *
                   5636:  * [55] StringType ::= 'CDATA'
                   5637:  *
                   5638:  * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
                   5639:  *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
                   5640:  *
                   5641:  * Validity constraints for attribute values syntax are checked in
                   5642:  * xmlValidateAttributeValue()
                   5643:  *
                   5644:  * [ VC: ID ]
                   5645:  * Values of type ID must match the Name production. A name must not
                   5646:  * appear more than once in an XML document as a value of this type;
                   5647:  * i.e., ID values must uniquely identify the elements which bear them.
                   5648:  *
                   5649:  * [ VC: One ID per Element Type ]
                   5650:  * No element type may have more than one ID attribute specified.
                   5651:  *
                   5652:  * [ VC: ID Attribute Default ]
                   5653:  * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
                   5654:  *
                   5655:  * [ VC: IDREF ]
                   5656:  * Values of type IDREF must match the Name production, and values
                   5657:  * of type IDREFS must match Names; each IDREF Name must match the value
                   5658:  * of an ID attribute on some element in the XML document; i.e. IDREF
                   5659:  * values must match the value of some ID attribute.
                   5660:  *
                   5661:  * [ VC: Entity Name ]
                   5662:  * Values of type ENTITY must match the Name production, values
                   5663:  * of type ENTITIES must match Names; each Entity Name must match the
                   5664:  * name of an unparsed entity declared in the DTD.  
                   5665:  *
                   5666:  * [ VC: Name Token ]
                   5667:  * Values of type NMTOKEN must match the Nmtoken production; values
                   5668:  * of type NMTOKENS must match Nmtokens. 
                   5669:  *
                   5670:  * Returns the attribute type
                   5671:  */
                   5672: int 
                   5673: xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
                   5674:     SHRINK;
                   5675:     if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
                   5676:        SKIP(5);
                   5677:        return(XML_ATTRIBUTE_CDATA);
                   5678:      } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
                   5679:        SKIP(6);
                   5680:        return(XML_ATTRIBUTE_IDREFS);
                   5681:      } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
                   5682:        SKIP(5);
                   5683:        return(XML_ATTRIBUTE_IDREF);
                   5684:      } else if ((RAW == 'I') && (NXT(1) == 'D')) {
                   5685:         SKIP(2);
                   5686:        return(XML_ATTRIBUTE_ID);
                   5687:      } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
                   5688:        SKIP(6);
                   5689:        return(XML_ATTRIBUTE_ENTITY);
                   5690:      } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
                   5691:        SKIP(8);
                   5692:        return(XML_ATTRIBUTE_ENTITIES);
                   5693:      } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
                   5694:        SKIP(8);
                   5695:        return(XML_ATTRIBUTE_NMTOKENS);
                   5696:      } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
                   5697:        SKIP(7);
                   5698:        return(XML_ATTRIBUTE_NMTOKEN);
                   5699:      }
                   5700:      return(xmlParseEnumeratedType(ctxt, tree));
                   5701: }
                   5702: 
                   5703: /**
                   5704:  * xmlParseAttributeListDecl:
                   5705:  * @ctxt:  an XML parser context
                   5706:  *
                   5707:  * : parse the Attribute list def for an element
                   5708:  *
                   5709:  * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
                   5710:  *
                   5711:  * [53] AttDef ::= S Name S AttType S DefaultDecl
                   5712:  *
                   5713:  */
                   5714: void
                   5715: xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
                   5716:     const xmlChar *elemName;
                   5717:     const xmlChar *attrName;
                   5718:     xmlEnumerationPtr tree;
                   5719: 
                   5720:     if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
                   5721:        xmlParserInputPtr input = ctxt->input;
                   5722: 
                   5723:        SKIP(9);
                   5724:        if (!IS_BLANK_CH(CUR)) {
                   5725:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5726:                                 "Space required after '<!ATTLIST'\n");
                   5727:        }
                   5728:         SKIP_BLANKS;
                   5729:         elemName = xmlParseName(ctxt);
                   5730:        if (elemName == NULL) {
                   5731:            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   5732:                           "ATTLIST: no name for Element\n");
                   5733:            return;
                   5734:        }
                   5735:        SKIP_BLANKS;
                   5736:        GROW;
                   5737:        while (RAW != '>') {
                   5738:            const xmlChar *check = CUR_PTR;
                   5739:            int type;
                   5740:            int def;
                   5741:            xmlChar *defaultValue = NULL;
                   5742: 
                   5743:            GROW;
                   5744:             tree = NULL;
                   5745:            attrName = xmlParseName(ctxt);
                   5746:            if (attrName == NULL) {
                   5747:                xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   5748:                               "ATTLIST: no name for Attribute\n");
                   5749:                break;
                   5750:            }
                   5751:            GROW;
                   5752:            if (!IS_BLANK_CH(CUR)) {
                   5753:                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5754:                        "Space required after the attribute name\n");
                   5755:                break;
                   5756:            }
                   5757:            SKIP_BLANKS;
                   5758: 
                   5759:            type = xmlParseAttributeType(ctxt, &tree);
                   5760:            if (type <= 0) {
                   5761:                break;
                   5762:            }
                   5763: 
                   5764:            GROW;
                   5765:            if (!IS_BLANK_CH(CUR)) {
                   5766:                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5767:                               "Space required after the attribute type\n");
                   5768:                if (tree != NULL)
                   5769:                    xmlFreeEnumeration(tree);
                   5770:                break;
                   5771:            }
                   5772:            SKIP_BLANKS;
                   5773: 
                   5774:            def = xmlParseDefaultDecl(ctxt, &defaultValue);
                   5775:            if (def <= 0) {
                   5776:                 if (defaultValue != NULL)
                   5777:                    xmlFree(defaultValue);
                   5778:                if (tree != NULL)
                   5779:                    xmlFreeEnumeration(tree);
                   5780:                break;
                   5781:            }
                   5782:            if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
                   5783:                xmlAttrNormalizeSpace(defaultValue, defaultValue);
                   5784: 
                   5785:            GROW;
                   5786:             if (RAW != '>') {
                   5787:                if (!IS_BLANK_CH(CUR)) {
                   5788:                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5789:                        "Space required after the attribute default value\n");
                   5790:                    if (defaultValue != NULL)
                   5791:                        xmlFree(defaultValue);
                   5792:                    if (tree != NULL)
                   5793:                        xmlFreeEnumeration(tree);
                   5794:                    break;
                   5795:                }
                   5796:                SKIP_BLANKS;
                   5797:            }
                   5798:            if (check == CUR_PTR) {
                   5799:                xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   5800:                            "in xmlParseAttributeListDecl\n");
                   5801:                if (defaultValue != NULL)
                   5802:                    xmlFree(defaultValue);
                   5803:                if (tree != NULL)
                   5804:                    xmlFreeEnumeration(tree);
                   5805:                break;
                   5806:            }
                   5807:            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   5808:                (ctxt->sax->attributeDecl != NULL))
                   5809:                ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
                   5810:                                type, def, defaultValue, tree);
                   5811:            else if (tree != NULL)
                   5812:                xmlFreeEnumeration(tree);
                   5813: 
                   5814:            if ((ctxt->sax2) && (defaultValue != NULL) &&
                   5815:                (def != XML_ATTRIBUTE_IMPLIED) && 
                   5816:                (def != XML_ATTRIBUTE_REQUIRED)) {
                   5817:                xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
                   5818:            }
                   5819:            if (ctxt->sax2) {
                   5820:                xmlAddSpecialAttr(ctxt, elemName, attrName, type);
                   5821:            }
                   5822:            if (defaultValue != NULL)
                   5823:                xmlFree(defaultValue);
                   5824:            GROW;
                   5825:        }
                   5826:        if (RAW == '>') {
                   5827:            if (input != ctxt->input) {
                   5828:                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   5829:     "Attribute list declaration doesn't start and stop in the same entity\n",
                   5830:                                  NULL, NULL);
                   5831:            }
                   5832:            NEXT;
                   5833:        }
                   5834:     }
                   5835: }
                   5836: 
                   5837: /**
                   5838:  * xmlParseElementMixedContentDecl:
                   5839:  * @ctxt:  an XML parser context
                   5840:  * @inputchk:  the input used for the current entity, needed for boundary checks
                   5841:  *
                   5842:  * parse the declaration for a Mixed Element content
                   5843:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
                   5844:  * 
                   5845:  * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
                   5846:  *                '(' S? '#PCDATA' S? ')'
                   5847:  *
                   5848:  * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
                   5849:  *
                   5850:  * [ VC: No Duplicate Types ]
                   5851:  * The same name must not appear more than once in a single
                   5852:  * mixed-content declaration. 
                   5853:  *
                   5854:  * returns: the list of the xmlElementContentPtr describing the element choices
                   5855:  */
                   5856: xmlElementContentPtr
                   5857: xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
                   5858:     xmlElementContentPtr ret = NULL, cur = NULL, n;
                   5859:     const xmlChar *elem = NULL;
                   5860: 
                   5861:     GROW;
                   5862:     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
                   5863:        SKIP(7);
                   5864:        SKIP_BLANKS;
                   5865:        SHRINK;
                   5866:        if (RAW == ')') {
                   5867:            if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
                   5868:                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   5869: "Element content declaration doesn't start and stop in the same entity\n",
                   5870:                                  NULL, NULL);
                   5871:            }
                   5872:            NEXT;
                   5873:            ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
                   5874:            if (ret == NULL)
                   5875:                return(NULL);
                   5876:            if (RAW == '*') {
                   5877:                ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   5878:                NEXT;
                   5879:            }
                   5880:            return(ret);
                   5881:        }
                   5882:        if ((RAW == '(') || (RAW == '|')) {
                   5883:            ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
                   5884:            if (ret == NULL) return(NULL);
                   5885:        }
                   5886:        while (RAW == '|') {
                   5887:            NEXT;
                   5888:            if (elem == NULL) {
                   5889:                ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
                   5890:                if (ret == NULL) return(NULL);
                   5891:                ret->c1 = cur;
                   5892:                if (cur != NULL)
                   5893:                    cur->parent = ret;
                   5894:                cur = ret;
                   5895:            } else {
                   5896:                n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
                   5897:                if (n == NULL) return(NULL);
                   5898:                n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
                   5899:                if (n->c1 != NULL)
                   5900:                    n->c1->parent = n;
                   5901:                cur->c2 = n;
                   5902:                if (n != NULL)
                   5903:                    n->parent = cur;
                   5904:                cur = n;
                   5905:            }
                   5906:            SKIP_BLANKS;
                   5907:            elem = xmlParseName(ctxt);
                   5908:            if (elem == NULL) {
                   5909:                xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   5910:                        "xmlParseElementMixedContentDecl : Name expected\n");
                   5911:                xmlFreeDocElementContent(ctxt->myDoc, cur);
                   5912:                return(NULL);
                   5913:            }
                   5914:            SKIP_BLANKS;
                   5915:            GROW;
                   5916:        }
                   5917:        if ((RAW == ')') && (NXT(1) == '*')) {
                   5918:            if (elem != NULL) {
                   5919:                cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
                   5920:                                               XML_ELEMENT_CONTENT_ELEMENT);
                   5921:                if (cur->c2 != NULL)
                   5922:                    cur->c2->parent = cur;
                   5923:             }
                   5924:             if (ret != NULL)
                   5925:                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   5926:            if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
                   5927:                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   5928: "Element content declaration doesn't start and stop in the same entity\n",
                   5929:                                 NULL, NULL);
                   5930:            }
                   5931:            SKIP(2);
                   5932:        } else {
                   5933:            xmlFreeDocElementContent(ctxt->myDoc, ret);
                   5934:            xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
                   5935:            return(NULL);
                   5936:        }
                   5937: 
                   5938:     } else {
                   5939:        xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
                   5940:     }
                   5941:     return(ret);
                   5942: }
                   5943: 
                   5944: /**
                   5945:  * xmlParseElementChildrenContentDeclPriv:
                   5946:  * @ctxt:  an XML parser context
                   5947:  * @inputchk:  the input used for the current entity, needed for boundary checks
                   5948:  * @depth: the level of recursion
                   5949:  *
                   5950:  * parse the declaration for a Mixed Element content
                   5951:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
                   5952:  * 
                   5953:  *
                   5954:  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
                   5955:  *
                   5956:  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
                   5957:  *
                   5958:  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
                   5959:  *
                   5960:  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
                   5961:  *
                   5962:  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
                   5963:  * TODO Parameter-entity replacement text must be properly nested
                   5964:  *     with parenthesized groups. That is to say, if either of the
                   5965:  *     opening or closing parentheses in a choice, seq, or Mixed
                   5966:  *     construct is contained in the replacement text for a parameter
                   5967:  *     entity, both must be contained in the same replacement text. For
                   5968:  *     interoperability, if a parameter-entity reference appears in a
                   5969:  *     choice, seq, or Mixed construct, its replacement text should not
                   5970:  *     be empty, and neither the first nor last non-blank character of
                   5971:  *     the replacement text should be a connector (| or ,).
                   5972:  *
                   5973:  * Returns the tree of xmlElementContentPtr describing the element 
                   5974:  *          hierarchy.
                   5975:  */
                   5976: static xmlElementContentPtr
                   5977: xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
                   5978:                                        int depth) {
                   5979:     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
                   5980:     const xmlChar *elem;
                   5981:     xmlChar type = 0;
                   5982: 
                   5983:     if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
                   5984:         (depth >  2048)) {
                   5985:         xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
                   5986: "xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
                   5987:                           depth);
                   5988:        return(NULL);
                   5989:     }
                   5990:     SKIP_BLANKS;
                   5991:     GROW;
                   5992:     if (RAW == '(') {
                   5993:        int inputid = ctxt->input->id;
                   5994: 
                   5995:         /* Recurse on first child */
                   5996:        NEXT;
                   5997:        SKIP_BLANKS;
                   5998:         cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
                   5999:                                                            depth + 1);
                   6000:        SKIP_BLANKS;
                   6001:        GROW;
                   6002:     } else {
                   6003:        elem = xmlParseName(ctxt);
                   6004:        if (elem == NULL) {
                   6005:            xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
                   6006:            return(NULL);
                   6007:        }
                   6008:         cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
                   6009:        if (cur == NULL) {
                   6010:            xmlErrMemory(ctxt, NULL);
                   6011:            return(NULL);
                   6012:        }
                   6013:        GROW;
                   6014:        if (RAW == '?') {
                   6015:            cur->ocur = XML_ELEMENT_CONTENT_OPT;
                   6016:            NEXT;
                   6017:        } else if (RAW == '*') {
                   6018:            cur->ocur = XML_ELEMENT_CONTENT_MULT;
                   6019:            NEXT;
                   6020:        } else if (RAW == '+') {
                   6021:            cur->ocur = XML_ELEMENT_CONTENT_PLUS;
                   6022:            NEXT;
                   6023:        } else {
                   6024:            cur->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6025:        }
                   6026:        GROW;
                   6027:     }
                   6028:     SKIP_BLANKS;
                   6029:     SHRINK;
                   6030:     while (RAW != ')') {
                   6031:         /*
                   6032:         * Each loop we parse one separator and one element.
                   6033:         */
                   6034:         if (RAW == ',') {
                   6035:            if (type == 0) type = CUR;
                   6036: 
                   6037:            /*
                   6038:             * Detect "Name | Name , Name" error
                   6039:             */
                   6040:            else if (type != CUR) {
                   6041:                xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
                   6042:                    "xmlParseElementChildrenContentDecl : '%c' expected\n",
                   6043:                                  type);
                   6044:                if ((last != NULL) && (last != ret))
                   6045:                    xmlFreeDocElementContent(ctxt->myDoc, last);
                   6046:                if (ret != NULL)
                   6047:                    xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6048:                return(NULL);
                   6049:            }
                   6050:            NEXT;
                   6051: 
                   6052:            op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
                   6053:            if (op == NULL) {
                   6054:                if ((last != NULL) && (last != ret))
                   6055:                    xmlFreeDocElementContent(ctxt->myDoc, last);
                   6056:                xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6057:                return(NULL);
                   6058:            }
                   6059:            if (last == NULL) {
                   6060:                op->c1 = ret;
                   6061:                if (ret != NULL)
                   6062:                    ret->parent = op;
                   6063:                ret = cur = op;
                   6064:            } else {
                   6065:                cur->c2 = op;
                   6066:                if (op != NULL)
                   6067:                    op->parent = cur;
                   6068:                op->c1 = last;
                   6069:                if (last != NULL)
                   6070:                    last->parent = op;
                   6071:                cur =op;
                   6072:                last = NULL;
                   6073:            }
                   6074:        } else if (RAW == '|') {
                   6075:            if (type == 0) type = CUR;
                   6076: 
                   6077:            /*
                   6078:             * Detect "Name , Name | Name" error
                   6079:             */
                   6080:            else if (type != CUR) {
                   6081:                xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
                   6082:                    "xmlParseElementChildrenContentDecl : '%c' expected\n",
                   6083:                                  type);
                   6084:                if ((last != NULL) && (last != ret))
                   6085:                    xmlFreeDocElementContent(ctxt->myDoc, last);
                   6086:                if (ret != NULL)
                   6087:                    xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6088:                return(NULL);
                   6089:            }
                   6090:            NEXT;
                   6091: 
                   6092:            op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
                   6093:            if (op == NULL) {
                   6094:                if ((last != NULL) && (last != ret))
                   6095:                    xmlFreeDocElementContent(ctxt->myDoc, last);
                   6096:                if (ret != NULL)
                   6097:                    xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6098:                return(NULL);
                   6099:            }
                   6100:            if (last == NULL) {
                   6101:                op->c1 = ret;
                   6102:                if (ret != NULL)
                   6103:                    ret->parent = op;
                   6104:                ret = cur = op;
                   6105:            } else {
                   6106:                cur->c2 = op;
                   6107:                if (op != NULL)
                   6108:                    op->parent = cur;
                   6109:                op->c1 = last;
                   6110:                if (last != NULL)
                   6111:                    last->parent = op;
                   6112:                cur =op;
                   6113:                last = NULL;
                   6114:            }
                   6115:        } else {
                   6116:            xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
                   6117:            if ((last != NULL) && (last != ret))
                   6118:                xmlFreeDocElementContent(ctxt->myDoc, last);
                   6119:            if (ret != NULL)
                   6120:                xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6121:            return(NULL);
                   6122:        }
                   6123:        GROW;
                   6124:        SKIP_BLANKS;
                   6125:        GROW;
                   6126:        if (RAW == '(') {
                   6127:            int inputid = ctxt->input->id;
                   6128:            /* Recurse on second child */
                   6129:            NEXT;
                   6130:            SKIP_BLANKS;
                   6131:            last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
                   6132:                                                           depth + 1);
                   6133:            SKIP_BLANKS;
                   6134:        } else {
                   6135:            elem = xmlParseName(ctxt);
                   6136:            if (elem == NULL) {
                   6137:                xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
                   6138:                if (ret != NULL)
                   6139:                    xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6140:                return(NULL);
                   6141:            }
                   6142:            last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
                   6143:            if (last == NULL) {
                   6144:                if (ret != NULL)
                   6145:                    xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6146:                return(NULL);
                   6147:            }
                   6148:            if (RAW == '?') {
                   6149:                last->ocur = XML_ELEMENT_CONTENT_OPT;
                   6150:                NEXT;
                   6151:            } else if (RAW == '*') {
                   6152:                last->ocur = XML_ELEMENT_CONTENT_MULT;
                   6153:                NEXT;
                   6154:            } else if (RAW == '+') {
                   6155:                last->ocur = XML_ELEMENT_CONTENT_PLUS;
                   6156:                NEXT;
                   6157:            } else {
                   6158:                last->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6159:            }
                   6160:        }
                   6161:        SKIP_BLANKS;
                   6162:        GROW;
                   6163:     }
                   6164:     if ((cur != NULL) && (last != NULL)) {
                   6165:         cur->c2 = last;
                   6166:        if (last != NULL)
                   6167:            last->parent = cur;
                   6168:     }
                   6169:     if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
                   6170:        xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   6171: "Element content declaration doesn't start and stop in the same entity\n",
                   6172:                         NULL, NULL);
                   6173:     }
                   6174:     NEXT;
                   6175:     if (RAW == '?') {
                   6176:        if (ret != NULL) {
                   6177:            if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
                   6178:                (ret->ocur == XML_ELEMENT_CONTENT_MULT))
                   6179:                ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   6180:            else
                   6181:                ret->ocur = XML_ELEMENT_CONTENT_OPT;
                   6182:        }
                   6183:        NEXT;
                   6184:     } else if (RAW == '*') {
                   6185:        if (ret != NULL) {
                   6186:            ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   6187:            cur = ret;
                   6188:            /*
                   6189:             * Some normalization:
                   6190:             * (a | b* | c?)* == (a | b | c)*
                   6191:             */
                   6192:            while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
                   6193:                if ((cur->c1 != NULL) &&
                   6194:                    ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
                   6195:                     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
                   6196:                    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6197:                if ((cur->c2 != NULL) &&
                   6198:                    ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
                   6199:                     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
                   6200:                    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6201:                cur = cur->c2;
                   6202:            }
                   6203:        }
                   6204:        NEXT;
                   6205:     } else if (RAW == '+') {
                   6206:        if (ret != NULL) {
                   6207:            int found = 0;
                   6208: 
                   6209:            if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
                   6210:                (ret->ocur == XML_ELEMENT_CONTENT_MULT))
                   6211:                ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   6212:            else
                   6213:                ret->ocur = XML_ELEMENT_CONTENT_PLUS;
                   6214:            /*
                   6215:             * Some normalization:
                   6216:             * (a | b*)+ == (a | b)*
                   6217:             * (a | b?)+ == (a | b)*
                   6218:             */
                   6219:            while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
                   6220:                if ((cur->c1 != NULL) &&
                   6221:                    ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
                   6222:                     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
                   6223:                    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6224:                    found = 1;
                   6225:                }
                   6226:                if ((cur->c2 != NULL) &&
                   6227:                    ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
                   6228:                     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
                   6229:                    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6230:                    found = 1;
                   6231:                }
                   6232:                cur = cur->c2;
                   6233:            }
                   6234:            if (found)
                   6235:                ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   6236:        }
                   6237:        NEXT;
                   6238:     }
                   6239:     return(ret);
                   6240: }
                   6241: 
                   6242: /**
                   6243:  * xmlParseElementChildrenContentDecl:
                   6244:  * @ctxt:  an XML parser context
                   6245:  * @inputchk:  the input used for the current entity, needed for boundary checks
                   6246:  *
                   6247:  * parse the declaration for a Mixed Element content
                   6248:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
                   6249:  *
                   6250:  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
                   6251:  *
                   6252:  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
                   6253:  *
                   6254:  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
                   6255:  *
                   6256:  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
                   6257:  *
                   6258:  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
                   6259:  * TODO Parameter-entity replacement text must be properly nested
                   6260:  *     with parenthesized groups. That is to say, if either of the
                   6261:  *     opening or closing parentheses in a choice, seq, or Mixed
                   6262:  *     construct is contained in the replacement text for a parameter
                   6263:  *     entity, both must be contained in the same replacement text. For
                   6264:  *     interoperability, if a parameter-entity reference appears in a
                   6265:  *     choice, seq, or Mixed construct, its replacement text should not
                   6266:  *     be empty, and neither the first nor last non-blank character of
                   6267:  *     the replacement text should be a connector (| or ,).
                   6268:  *
                   6269:  * Returns the tree of xmlElementContentPtr describing the element
                   6270:  *          hierarchy.
                   6271:  */
                   6272: xmlElementContentPtr
                   6273: xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
                   6274:     /* stub left for API/ABI compat */
                   6275:     return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
                   6276: }
                   6277: 
                   6278: /**
                   6279:  * xmlParseElementContentDecl:
                   6280:  * @ctxt:  an XML parser context
                   6281:  * @name:  the name of the element being defined.
                   6282:  * @result:  the Element Content pointer will be stored here if any
                   6283:  *
                   6284:  * parse the declaration for an Element content either Mixed or Children,
                   6285:  * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
                   6286:  * 
                   6287:  * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
                   6288:  *
                   6289:  * returns: the type of element content XML_ELEMENT_TYPE_xxx
                   6290:  */
                   6291: 
                   6292: int
                   6293: xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
                   6294:                            xmlElementContentPtr *result) {
                   6295: 
                   6296:     xmlElementContentPtr tree = NULL;
                   6297:     int inputid = ctxt->input->id;
                   6298:     int res;
                   6299: 
                   6300:     *result = NULL;
                   6301: 
                   6302:     if (RAW != '(') {
                   6303:        xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
                   6304:                "xmlParseElementContentDecl : %s '(' expected\n", name);
                   6305:        return(-1);
                   6306:     }
                   6307:     NEXT;
                   6308:     GROW;
                   6309:     SKIP_BLANKS;
                   6310:     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
                   6311:         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
                   6312:        res = XML_ELEMENT_TYPE_MIXED;
                   6313:     } else {
                   6314:         tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
                   6315:        res = XML_ELEMENT_TYPE_ELEMENT;
                   6316:     }
                   6317:     SKIP_BLANKS;
                   6318:     *result = tree;
                   6319:     return(res);
                   6320: }
                   6321: 
                   6322: /**
                   6323:  * xmlParseElementDecl:
                   6324:  * @ctxt:  an XML parser context
                   6325:  *
                   6326:  * parse an Element declaration.
                   6327:  *
                   6328:  * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
                   6329:  *
                   6330:  * [ VC: Unique Element Type Declaration ]
                   6331:  * No element type may be declared more than once
                   6332:  *
                   6333:  * Returns the type of the element, or -1 in case of error
                   6334:  */
                   6335: int
                   6336: xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
                   6337:     const xmlChar *name;
                   6338:     int ret = -1;
                   6339:     xmlElementContentPtr content  = NULL;
                   6340: 
                   6341:     /* GROW; done in the caller */
                   6342:     if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
                   6343:        xmlParserInputPtr input = ctxt->input;
                   6344: 
                   6345:        SKIP(9);
                   6346:        if (!IS_BLANK_CH(CUR)) {
                   6347:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   6348:                           "Space required after 'ELEMENT'\n");
                   6349:        }
                   6350:         SKIP_BLANKS;
                   6351:         name = xmlParseName(ctxt);
                   6352:        if (name == NULL) {
                   6353:            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   6354:                           "xmlParseElementDecl: no name for Element\n");
                   6355:            return(-1);
                   6356:        }
                   6357:        while ((RAW == 0) && (ctxt->inputNr > 1))
                   6358:            xmlPopInput(ctxt);
                   6359:        if (!IS_BLANK_CH(CUR)) {
                   6360:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   6361:                           "Space required after the element name\n");
                   6362:        }
                   6363:         SKIP_BLANKS;
                   6364:        if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
                   6365:            SKIP(5);
                   6366:            /*
                   6367:             * Element must always be empty.
                   6368:             */
                   6369:            ret = XML_ELEMENT_TYPE_EMPTY;
                   6370:        } else if ((RAW == 'A') && (NXT(1) == 'N') &&
                   6371:                   (NXT(2) == 'Y')) {
                   6372:            SKIP(3);
                   6373:            /*
                   6374:             * Element is a generic container.
                   6375:             */
                   6376:            ret = XML_ELEMENT_TYPE_ANY;
                   6377:        } else if (RAW == '(') {
                   6378:            ret = xmlParseElementContentDecl(ctxt, name, &content);
                   6379:        } else {
                   6380:            /*
                   6381:             * [ WFC: PEs in Internal Subset ] error handling.
                   6382:             */
                   6383:            if ((RAW == '%') && (ctxt->external == 0) &&
                   6384:                (ctxt->inputNr == 1)) {
                   6385:                xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
                   6386:          "PEReference: forbidden within markup decl in internal subset\n");
                   6387:            } else {
                   6388:                xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
                   6389:                      "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
                   6390:             }
                   6391:            return(-1);
                   6392:        }
                   6393: 
                   6394:        SKIP_BLANKS;
                   6395:        /*
                   6396:         * Pop-up of finished entities.
                   6397:         */
                   6398:        while ((RAW == 0) && (ctxt->inputNr > 1))
                   6399:            xmlPopInput(ctxt);
                   6400:        SKIP_BLANKS;
                   6401: 
                   6402:        if (RAW != '>') {
                   6403:            xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
                   6404:            if (content != NULL) {
                   6405:                xmlFreeDocElementContent(ctxt->myDoc, content);
                   6406:            }
                   6407:        } else {
                   6408:            if (input != ctxt->input) {
                   6409:                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   6410:     "Element declaration doesn't start and stop in the same entity\n");
                   6411:            }
                   6412:                
                   6413:            NEXT;
                   6414:            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   6415:                (ctxt->sax->elementDecl != NULL)) {
                   6416:                if (content != NULL)
                   6417:                    content->parent = NULL;
                   6418:                ctxt->sax->elementDecl(ctxt->userData, name, ret,
                   6419:                                       content);
                   6420:                if ((content != NULL) && (content->parent == NULL)) {
                   6421:                    /*
                   6422:                     * this is a trick: if xmlAddElementDecl is called,
                   6423:                     * instead of copying the full tree it is plugged directly
                   6424:                     * if called from the parser. Avoid duplicating the 
                   6425:                     * interfaces or change the API/ABI
                   6426:                     */
                   6427:                    xmlFreeDocElementContent(ctxt->myDoc, content);
                   6428:                }
                   6429:            } else if (content != NULL) {
                   6430:                xmlFreeDocElementContent(ctxt->myDoc, content);
                   6431:            }
                   6432:        }
                   6433:     }
                   6434:     return(ret);
                   6435: }
                   6436: 
                   6437: /**
                   6438:  * xmlParseConditionalSections
                   6439:  * @ctxt:  an XML parser context
                   6440:  *
                   6441:  * [61] conditionalSect ::= includeSect | ignoreSect 
                   6442:  * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>' 
                   6443:  * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
                   6444:  * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
                   6445:  * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
                   6446:  */
                   6447: 
                   6448: static void
                   6449: xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
                   6450:     int id = ctxt->input->id;
                   6451: 
                   6452:     SKIP(3);
                   6453:     SKIP_BLANKS;
                   6454:     if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
                   6455:        SKIP(7);
                   6456:        SKIP_BLANKS;
                   6457:        if (RAW != '[') {
                   6458:            xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
                   6459:        } else {
                   6460:            if (ctxt->input->id != id) {
                   6461:                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   6462:            "All markup of the conditional section is not in the same entity\n",
                   6463:                                     NULL, NULL);
                   6464:            }
                   6465:            NEXT;
                   6466:        }
                   6467:        if (xmlParserDebugEntities) {
                   6468:            if ((ctxt->input != NULL) && (ctxt->input->filename))
                   6469:                xmlGenericError(xmlGenericErrorContext,
                   6470:                        "%s(%d): ", ctxt->input->filename,
                   6471:                        ctxt->input->line);
                   6472:            xmlGenericError(xmlGenericErrorContext,
                   6473:                    "Entering INCLUDE Conditional Section\n");
                   6474:        }
                   6475: 
                   6476:        while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
                   6477:               (NXT(2) != '>'))) {
                   6478:            const xmlChar *check = CUR_PTR;
                   6479:            unsigned int cons = ctxt->input->consumed;
                   6480: 
                   6481:            if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
                   6482:                xmlParseConditionalSections(ctxt);
                   6483:            } else if (IS_BLANK_CH(CUR)) {
                   6484:                NEXT;
                   6485:            } else if (RAW == '%') {
                   6486:                xmlParsePEReference(ctxt);
                   6487:            } else
                   6488:                xmlParseMarkupDecl(ctxt);
                   6489: 
                   6490:            /*
                   6491:             * Pop-up of finished entities.
                   6492:             */
                   6493:            while ((RAW == 0) && (ctxt->inputNr > 1))
                   6494:                xmlPopInput(ctxt);
                   6495: 
                   6496:            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
                   6497:                xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
                   6498:                break;
                   6499:            }
                   6500:        }
                   6501:        if (xmlParserDebugEntities) {
                   6502:            if ((ctxt->input != NULL) && (ctxt->input->filename))
                   6503:                xmlGenericError(xmlGenericErrorContext,
                   6504:                        "%s(%d): ", ctxt->input->filename,
                   6505:                        ctxt->input->line);
                   6506:            xmlGenericError(xmlGenericErrorContext,
                   6507:                    "Leaving INCLUDE Conditional Section\n");
                   6508:        }
                   6509: 
                   6510:     } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
                   6511:        int state;
                   6512:        xmlParserInputState instate;
                   6513:        int depth = 0;
                   6514: 
                   6515:        SKIP(6);
                   6516:        SKIP_BLANKS;
                   6517:        if (RAW != '[') {
                   6518:            xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
                   6519:        } else {
                   6520:            if (ctxt->input->id != id) {
                   6521:                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   6522:            "All markup of the conditional section is not in the same entity\n",
                   6523:                                     NULL, NULL);
                   6524:            }
                   6525:            NEXT;
                   6526:        }
                   6527:        if (xmlParserDebugEntities) {
                   6528:            if ((ctxt->input != NULL) && (ctxt->input->filename))
                   6529:                xmlGenericError(xmlGenericErrorContext,
                   6530:                        "%s(%d): ", ctxt->input->filename,
                   6531:                        ctxt->input->line);
                   6532:            xmlGenericError(xmlGenericErrorContext,
                   6533:                    "Entering IGNORE Conditional Section\n");
                   6534:        }
                   6535: 
                   6536:        /*
                   6537:         * Parse up to the end of the conditional section
                   6538:         * But disable SAX event generating DTD building in the meantime
                   6539:         */
                   6540:        state = ctxt->disableSAX;
                   6541:        instate = ctxt->instate;
                   6542:        if (ctxt->recovery == 0) ctxt->disableSAX = 1;
                   6543:        ctxt->instate = XML_PARSER_IGNORE;
                   6544: 
                   6545:        while ((depth >= 0) && (RAW != 0)) {
                   6546:          if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
                   6547:            depth++;
                   6548:            SKIP(3);
                   6549:            continue;
                   6550:          }
                   6551:          if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
                   6552:            if (--depth >= 0) SKIP(3);
                   6553:            continue;
                   6554:          }
                   6555:          NEXT;
                   6556:          continue;
                   6557:        }
                   6558: 
                   6559:        ctxt->disableSAX = state;
                   6560:        ctxt->instate = instate;
                   6561: 
                   6562:        if (xmlParserDebugEntities) {
                   6563:            if ((ctxt->input != NULL) && (ctxt->input->filename))
                   6564:                xmlGenericError(xmlGenericErrorContext,
                   6565:                        "%s(%d): ", ctxt->input->filename,
                   6566:                        ctxt->input->line);
                   6567:            xmlGenericError(xmlGenericErrorContext,
                   6568:                    "Leaving IGNORE Conditional Section\n");
                   6569:        }
                   6570: 
                   6571:     } else {
                   6572:        xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
                   6573:     }
                   6574: 
                   6575:     if (RAW == 0)
                   6576:         SHRINK;
                   6577: 
                   6578:     if (RAW == 0) {
                   6579:        xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
                   6580:     } else {
                   6581:        if (ctxt->input->id != id) {
                   6582:            xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   6583:        "All markup of the conditional section is not in the same entity\n",
                   6584:                                 NULL, NULL);
                   6585:        }
                   6586:         SKIP(3);
                   6587:     }
                   6588: }
                   6589: 
                   6590: /**
                   6591:  * xmlParseMarkupDecl:
                   6592:  * @ctxt:  an XML parser context
                   6593:  * 
                   6594:  * parse Markup declarations
                   6595:  *
                   6596:  * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
                   6597:  *                     NotationDecl | PI | Comment
                   6598:  *
                   6599:  * [ VC: Proper Declaration/PE Nesting ]
                   6600:  * Parameter-entity replacement text must be properly nested with
                   6601:  * markup declarations. That is to say, if either the first character
                   6602:  * or the last character of a markup declaration (markupdecl above) is
                   6603:  * contained in the replacement text for a parameter-entity reference,
                   6604:  * both must be contained in the same replacement text.
                   6605:  *
                   6606:  * [ WFC: PEs in Internal Subset ]
                   6607:  * In the internal DTD subset, parameter-entity references can occur
                   6608:  * only where markup declarations can occur, not within markup declarations.
                   6609:  * (This does not apply to references that occur in external parameter
                   6610:  * entities or to the external subset.) 
                   6611:  */
                   6612: void
                   6613: xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
                   6614:     GROW;
                   6615:     if (CUR == '<') {
                   6616:         if (NXT(1) == '!') {
                   6617:            switch (NXT(2)) {
                   6618:                case 'E':
                   6619:                    if (NXT(3) == 'L')
                   6620:                        xmlParseElementDecl(ctxt);
                   6621:                    else if (NXT(3) == 'N')
                   6622:                        xmlParseEntityDecl(ctxt);
                   6623:                    break;
                   6624:                case 'A':
                   6625:                    xmlParseAttributeListDecl(ctxt);
                   6626:                    break;
                   6627:                case 'N':
                   6628:                    xmlParseNotationDecl(ctxt);
                   6629:                    break;
                   6630:                case '-':
                   6631:                    xmlParseComment(ctxt);
                   6632:                    break;
                   6633:                default:
                   6634:                    /* there is an error but it will be detected later */
                   6635:                    break;
                   6636:            }
                   6637:        } else if (NXT(1) == '?') {
                   6638:            xmlParsePI(ctxt);
                   6639:        }
                   6640:     }
                   6641:     /*
                   6642:      * This is only for internal subset. On external entities,
                   6643:      * the replacement is done before parsing stage
                   6644:      */
                   6645:     if ((ctxt->external == 0) && (ctxt->inputNr == 1))
                   6646:        xmlParsePEReference(ctxt);
                   6647: 
                   6648:     /*
                   6649:      * Conditional sections are allowed from entities included
                   6650:      * by PE References in the internal subset.
                   6651:      */
                   6652:     if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
                   6653:         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
                   6654:            xmlParseConditionalSections(ctxt);
                   6655:        }
                   6656:     }
                   6657: 
                   6658:     ctxt->instate = XML_PARSER_DTD;
                   6659: }
                   6660: 
                   6661: /**
                   6662:  * xmlParseTextDecl:
                   6663:  * @ctxt:  an XML parser context
                   6664:  *
                   6665:  * parse an XML declaration header for external entities
                   6666:  *
                   6667:  * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
                   6668:  */
                   6669: 
                   6670: void
                   6671: xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
                   6672:     xmlChar *version;
                   6673:     const xmlChar *encoding;
                   6674: 
                   6675:     /*
                   6676:      * We know that '<?xml' is here.
                   6677:      */
                   6678:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
                   6679:        SKIP(5);
                   6680:     } else {
                   6681:        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
                   6682:        return;
                   6683:     }
                   6684: 
                   6685:     if (!IS_BLANK_CH(CUR)) {
                   6686:        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   6687:                       "Space needed after '<?xml'\n");
                   6688:     }
                   6689:     SKIP_BLANKS;
                   6690: 
                   6691:     /*
                   6692:      * We may have the VersionInfo here.
                   6693:      */
                   6694:     version = xmlParseVersionInfo(ctxt);
                   6695:     if (version == NULL)
                   6696:        version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   6697:     else {
                   6698:        if (!IS_BLANK_CH(CUR)) {
                   6699:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   6700:                           "Space needed here\n");
                   6701:        }
                   6702:     }
                   6703:     ctxt->input->version = version;
                   6704: 
                   6705:     /*
                   6706:      * We must have the encoding declaration
                   6707:      */
                   6708:     encoding = xmlParseEncodingDecl(ctxt);
                   6709:     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   6710:        /*
                   6711:         * The XML REC instructs us to stop parsing right here
                   6712:         */
                   6713:         return;
                   6714:     }
                   6715:     if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
                   6716:        xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
                   6717:                       "Missing encoding in text declaration\n");
                   6718:     }
                   6719: 
                   6720:     SKIP_BLANKS;
                   6721:     if ((RAW == '?') && (NXT(1) == '>')) {
                   6722:         SKIP(2);
                   6723:     } else if (RAW == '>') {
                   6724:         /* Deprecated old WD ... */
                   6725:        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
                   6726:        NEXT;
                   6727:     } else {
                   6728:        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
                   6729:        MOVETO_ENDTAG(CUR_PTR);
                   6730:        NEXT;
                   6731:     }
                   6732: }
                   6733: 
                   6734: /**
                   6735:  * xmlParseExternalSubset:
                   6736:  * @ctxt:  an XML parser context
                   6737:  * @ExternalID: the external identifier
                   6738:  * @SystemID: the system identifier (or URL)
                   6739:  * 
                   6740:  * parse Markup declarations from an external subset
                   6741:  *
                   6742:  * [30] extSubset ::= textDecl? extSubsetDecl
                   6743:  *
                   6744:  * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
                   6745:  */
                   6746: void
                   6747: xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
                   6748:                        const xmlChar *SystemID) {
                   6749:     xmlDetectSAX2(ctxt);
                   6750:     GROW;
                   6751: 
                   6752:     if ((ctxt->encoding == NULL) &&
                   6753:         (ctxt->input->end - ctxt->input->cur >= 4)) {
                   6754:         xmlChar start[4];
                   6755:        xmlCharEncoding enc;
                   6756: 
                   6757:        start[0] = RAW;
                   6758:        start[1] = NXT(1);
                   6759:        start[2] = NXT(2);
                   6760:        start[3] = NXT(3);
                   6761:        enc = xmlDetectCharEncoding(start, 4);
                   6762:        if (enc != XML_CHAR_ENCODING_NONE)
                   6763:            xmlSwitchEncoding(ctxt, enc);
                   6764:     }
                   6765: 
                   6766:     if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
                   6767:        xmlParseTextDecl(ctxt);
                   6768:        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   6769:            /*
                   6770:             * The XML REC instructs us to stop parsing right here
                   6771:             */
                   6772:            ctxt->instate = XML_PARSER_EOF;
                   6773:            return;
                   6774:        }
                   6775:     }
                   6776:     if (ctxt->myDoc == NULL) {
                   6777:         ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
                   6778:        if (ctxt->myDoc == NULL) {
                   6779:            xmlErrMemory(ctxt, "New Doc failed");
                   6780:            return;
                   6781:        }
                   6782:        ctxt->myDoc->properties = XML_DOC_INTERNAL;
                   6783:     }
                   6784:     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
                   6785:         xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
                   6786: 
                   6787:     ctxt->instate = XML_PARSER_DTD;
                   6788:     ctxt->external = 1;
                   6789:     while (((RAW == '<') && (NXT(1) == '?')) ||
                   6790:            ((RAW == '<') && (NXT(1) == '!')) ||
                   6791:           (RAW == '%') || IS_BLANK_CH(CUR)) {
                   6792:        const xmlChar *check = CUR_PTR;
                   6793:        unsigned int cons = ctxt->input->consumed;
                   6794: 
                   6795:        GROW;
                   6796:         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
                   6797:            xmlParseConditionalSections(ctxt);
                   6798:        } else if (IS_BLANK_CH(CUR)) {
                   6799:            NEXT;
                   6800:        } else if (RAW == '%') {
                   6801:             xmlParsePEReference(ctxt);
                   6802:        } else
                   6803:            xmlParseMarkupDecl(ctxt);
                   6804: 
                   6805:        /*
                   6806:         * Pop-up of finished entities.
                   6807:         */
                   6808:        while ((RAW == 0) && (ctxt->inputNr > 1))
                   6809:            xmlPopInput(ctxt);
                   6810: 
                   6811:        if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
                   6812:            xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
                   6813:            break;
                   6814:        }
                   6815:     }
                   6816:     
                   6817:     if (RAW != 0) {
                   6818:        xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
                   6819:     }
                   6820: 
                   6821: }
                   6822: 
                   6823: /**
                   6824:  * xmlParseReference:
                   6825:  * @ctxt:  an XML parser context
                   6826:  *
                   6827:  * parse and handle entity references in content, depending on the SAX
                   6828:  * interface, this may end-up in a call to character() if this is a
                   6829:  * CharRef, a predefined entity, if there is no reference() callback.
                   6830:  * or if the parser was asked to switch to that mode.
                   6831:  *
                   6832:  * [67] Reference ::= EntityRef | CharRef
                   6833:  */
                   6834: void
                   6835: xmlParseReference(xmlParserCtxtPtr ctxt) {
                   6836:     xmlEntityPtr ent;
                   6837:     xmlChar *val;
                   6838:     int was_checked;
                   6839:     xmlNodePtr list = NULL;
                   6840:     xmlParserErrors ret = XML_ERR_OK;
                   6841: 
                   6842: 
                   6843:     if (RAW != '&')
                   6844:         return;
                   6845: 
                   6846:     /*
                   6847:      * Simple case of a CharRef
                   6848:      */
                   6849:     if (NXT(1) == '#') {
                   6850:        int i = 0;
                   6851:        xmlChar out[10];
                   6852:        int hex = NXT(2);
                   6853:        int value = xmlParseCharRef(ctxt);
                   6854: 
                   6855:        if (value == 0)
                   6856:            return;
                   6857:        if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
                   6858:            /*
                   6859:             * So we are using non-UTF-8 buffers
                   6860:             * Check that the char fit on 8bits, if not
                   6861:             * generate a CharRef.
                   6862:             */
                   6863:            if (value <= 0xFF) {
                   6864:                out[0] = value;
                   6865:                out[1] = 0;
                   6866:                if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
                   6867:                    (!ctxt->disableSAX))
                   6868:                    ctxt->sax->characters(ctxt->userData, out, 1);
                   6869:            } else {
                   6870:                if ((hex == 'x') || (hex == 'X'))
                   6871:                    snprintf((char *)out, sizeof(out), "#x%X", value);
                   6872:                else
                   6873:                    snprintf((char *)out, sizeof(out), "#%d", value);
                   6874:                if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
                   6875:                    (!ctxt->disableSAX))
                   6876:                    ctxt->sax->reference(ctxt->userData, out);
                   6877:            }
                   6878:        } else {
                   6879:            /*
                   6880:             * Just encode the value in UTF-8
                   6881:             */
                   6882:            COPY_BUF(0 ,out, i, value);
                   6883:            out[i] = 0;
                   6884:            if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
                   6885:                (!ctxt->disableSAX))
                   6886:                ctxt->sax->characters(ctxt->userData, out, i);
                   6887:        }
                   6888:        return;
                   6889:     }
                   6890: 
                   6891:     /*
                   6892:      * We are seeing an entity reference
                   6893:      */
                   6894:     ent = xmlParseEntityRef(ctxt);
                   6895:     if (ent == NULL) return;
                   6896:     if (!ctxt->wellFormed)
                   6897:        return;
                   6898:     was_checked = ent->checked;
                   6899: 
                   6900:     /* special case of predefined entities */
                   6901:     if ((ent->name == NULL) ||
                   6902:         (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
                   6903:        val = ent->content;
                   6904:        if (val == NULL) return;
                   6905:        /*
                   6906:         * inline the entity.
                   6907:         */
                   6908:        if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
                   6909:            (!ctxt->disableSAX))
                   6910:            ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
                   6911:        return;
                   6912:     }
                   6913: 
                   6914:     /*
                   6915:      * The first reference to the entity trigger a parsing phase
                   6916:      * where the ent->children is filled with the result from
                   6917:      * the parsing.
                   6918:      */
                   6919:     if (ent->checked == 0) {
                   6920:        unsigned long oldnbent = ctxt->nbentities;
                   6921: 
                   6922:        /*
                   6923:         * This is a bit hackish but this seems the best
                   6924:         * way to make sure both SAX and DOM entity support
                   6925:         * behaves okay.
                   6926:         */
                   6927:        void *user_data;
                   6928:        if (ctxt->userData == ctxt)
                   6929:            user_data = NULL;
                   6930:        else
                   6931:            user_data = ctxt->userData;
                   6932: 
                   6933:        /*
                   6934:         * Check that this entity is well formed
                   6935:         * 4.3.2: An internal general parsed entity is well-formed
                   6936:         * if its replacement text matches the production labeled
                   6937:         * content.
                   6938:         */
                   6939:        if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
                   6940:            ctxt->depth++;
                   6941:            ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
                   6942:                                                      user_data, &list);
                   6943:            ctxt->depth--;
                   6944: 
                   6945:        } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
                   6946:            ctxt->depth++;
                   6947:            ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
                   6948:                                           user_data, ctxt->depth, ent->URI,
                   6949:                                           ent->ExternalID, &list);
                   6950:            ctxt->depth--;
                   6951:        } else {
                   6952:            ret = XML_ERR_ENTITY_PE_INTERNAL;
                   6953:            xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
                   6954:                         "invalid entity type found\n", NULL);
                   6955:        }
                   6956: 
                   6957:        /*
                   6958:         * Store the number of entities needing parsing for this entity
                   6959:         * content and do checkings
                   6960:         */
                   6961:        ent->checked = ctxt->nbentities - oldnbent;
                   6962:        if (ret == XML_ERR_ENTITY_LOOP) {
                   6963:            xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
                   6964:            xmlFreeNodeList(list);
                   6965:            return;
                   6966:        }
                   6967:        if (xmlParserEntityCheck(ctxt, 0, ent)) {
                   6968:            xmlFreeNodeList(list);
                   6969:            return;
                   6970:        }
                   6971: 
                   6972:        if ((ret == XML_ERR_OK) && (list != NULL)) {
                   6973:            if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
                   6974:             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
                   6975:                (ent->children == NULL)) {
                   6976:                ent->children = list;
                   6977:                if (ctxt->replaceEntities) {
                   6978:                    /*
                   6979:                     * Prune it directly in the generated document
                   6980:                     * except for single text nodes.
                   6981:                     */
                   6982:                    if (((list->type == XML_TEXT_NODE) &&
                   6983:                         (list->next == NULL)) ||
                   6984:                        (ctxt->parseMode == XML_PARSE_READER)) {
                   6985:                        list->parent = (xmlNodePtr) ent;
                   6986:                        list = NULL;
                   6987:                        ent->owner = 1;
                   6988:                    } else {
                   6989:                        ent->owner = 0;
                   6990:                        while (list != NULL) {
                   6991:                            list->parent = (xmlNodePtr) ctxt->node;
                   6992:                            list->doc = ctxt->myDoc;
                   6993:                            if (list->next == NULL)
                   6994:                                ent->last = list;
                   6995:                            list = list->next;
                   6996:                        }
                   6997:                        list = ent->children;
                   6998: #ifdef LIBXML_LEGACY_ENABLED
                   6999:                        if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
                   7000:                          xmlAddEntityReference(ent, list, NULL);
                   7001: #endif /* LIBXML_LEGACY_ENABLED */
                   7002:                    }
                   7003:                } else {
                   7004:                    ent->owner = 1;
                   7005:                    while (list != NULL) {
                   7006:                        list->parent = (xmlNodePtr) ent;
1.1.1.2 ! misho    7007:                        xmlSetTreeDoc(list, ent->doc);
1.1       misho    7008:                        if (list->next == NULL)
                   7009:                            ent->last = list;
                   7010:                        list = list->next;
                   7011:                    }
                   7012:                }
                   7013:            } else {
                   7014:                xmlFreeNodeList(list);
                   7015:                list = NULL;
                   7016:            }
                   7017:        } else if ((ret != XML_ERR_OK) &&
                   7018:                   (ret != XML_WAR_UNDECLARED_ENTITY)) {
                   7019:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   7020:                     "Entity '%s' failed to parse\n", ent->name);
                   7021:        } else if (list != NULL) {
                   7022:            xmlFreeNodeList(list);
                   7023:            list = NULL;
                   7024:        }
                   7025:        if (ent->checked == 0)
                   7026:            ent->checked = 1;
                   7027:     } else if (ent->checked != 1) {
                   7028:        ctxt->nbentities += ent->checked;
                   7029:     }
                   7030: 
                   7031:     /*
                   7032:      * Now that the entity content has been gathered
                   7033:      * provide it to the application, this can take different forms based
                   7034:      * on the parsing modes.
                   7035:      */
                   7036:     if (ent->children == NULL) {
                   7037:        /*
                   7038:         * Probably running in SAX mode and the callbacks don't
                   7039:         * build the entity content. So unless we already went
                   7040:         * though parsing for first checking go though the entity
                   7041:         * content to generate callbacks associated to the entity
                   7042:         */
                   7043:        if (was_checked != 0) {
                   7044:            void *user_data;
                   7045:            /*
                   7046:             * This is a bit hackish but this seems the best
                   7047:             * way to make sure both SAX and DOM entity support
                   7048:             * behaves okay.
                   7049:             */
                   7050:            if (ctxt->userData == ctxt)
                   7051:                user_data = NULL;
                   7052:            else
                   7053:                user_data = ctxt->userData;
                   7054: 
                   7055:            if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
                   7056:                ctxt->depth++;
                   7057:                ret = xmlParseBalancedChunkMemoryInternal(ctxt,
                   7058:                                   ent->content, user_data, NULL);
                   7059:                ctxt->depth--;
                   7060:            } else if (ent->etype ==
                   7061:                       XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
                   7062:                ctxt->depth++;
                   7063:                ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
                   7064:                           ctxt->sax, user_data, ctxt->depth,
                   7065:                           ent->URI, ent->ExternalID, NULL);
                   7066:                ctxt->depth--;
                   7067:            } else {
                   7068:                ret = XML_ERR_ENTITY_PE_INTERNAL;
                   7069:                xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
                   7070:                             "invalid entity type found\n", NULL);
                   7071:            }
                   7072:            if (ret == XML_ERR_ENTITY_LOOP) {
                   7073:                xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
                   7074:                return;
                   7075:            }
                   7076:        }
                   7077:        if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
                   7078:            (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
                   7079:            /*
                   7080:             * Entity reference callback comes second, it's somewhat
                   7081:             * superfluous but a compatibility to historical behaviour
                   7082:             */
                   7083:            ctxt->sax->reference(ctxt->userData, ent->name);
                   7084:        }
                   7085:        return;
                   7086:     }
                   7087: 
                   7088:     /*
                   7089:      * If we didn't get any children for the entity being built
                   7090:      */
                   7091:     if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
                   7092:        (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
                   7093:        /*
                   7094:         * Create a node.
                   7095:         */
                   7096:        ctxt->sax->reference(ctxt->userData, ent->name);
                   7097:        return;
                   7098:     }
                   7099: 
                   7100:     if ((ctxt->replaceEntities) || (ent->children == NULL))  {
                   7101:        /*
                   7102:         * There is a problem on the handling of _private for entities
                   7103:         * (bug 155816): Should we copy the content of the field from
                   7104:         * the entity (possibly overwriting some value set by the user
                   7105:         * when a copy is created), should we leave it alone, or should
                   7106:         * we try to take care of different situations?  The problem
                   7107:         * is exacerbated by the usage of this field by the xmlReader.
                   7108:         * To fix this bug, we look at _private on the created node
                   7109:         * and, if it's NULL, we copy in whatever was in the entity.
                   7110:         * If it's not NULL we leave it alone.  This is somewhat of a
                   7111:         * hack - maybe we should have further tests to determine
                   7112:         * what to do.
                   7113:         */
                   7114:        if ((ctxt->node != NULL) && (ent->children != NULL)) {
                   7115:            /*
                   7116:             * Seems we are generating the DOM content, do
                   7117:             * a simple tree copy for all references except the first
                   7118:             * In the first occurrence list contains the replacement.
                   7119:             * progressive == 2 means we are operating on the Reader
                   7120:             * and since nodes are discarded we must copy all the time.
                   7121:             */
                   7122:            if (((list == NULL) && (ent->owner == 0)) ||
                   7123:                (ctxt->parseMode == XML_PARSE_READER)) {
                   7124:                xmlNodePtr nw = NULL, cur, firstChild = NULL;
                   7125: 
                   7126:                /*
                   7127:                 * when operating on a reader, the entities definitions
                   7128:                 * are always owning the entities subtree.
                   7129:                if (ctxt->parseMode == XML_PARSE_READER)
                   7130:                    ent->owner = 1;
                   7131:                 */
                   7132: 
                   7133:                cur = ent->children;
                   7134:                while (cur != NULL) {
                   7135:                    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
                   7136:                    if (nw != NULL) {
                   7137:                        if (nw->_private == NULL)
                   7138:                            nw->_private = cur->_private;
                   7139:                        if (firstChild == NULL){
                   7140:                            firstChild = nw;
                   7141:                        }
                   7142:                        nw = xmlAddChild(ctxt->node, nw);
                   7143:                    }
                   7144:                    if (cur == ent->last) {
                   7145:                        /*
                   7146:                         * needed to detect some strange empty
                   7147:                         * node cases in the reader tests
                   7148:                         */
                   7149:                        if ((ctxt->parseMode == XML_PARSE_READER) &&
                   7150:                            (nw != NULL) &&
                   7151:                            (nw->type == XML_ELEMENT_NODE) &&
                   7152:                            (nw->children == NULL))
                   7153:                            nw->extra = 1;
                   7154: 
                   7155:                        break;
                   7156:                    }
                   7157:                    cur = cur->next;
                   7158:                }
                   7159: #ifdef LIBXML_LEGACY_ENABLED
                   7160:                if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
                   7161:                  xmlAddEntityReference(ent, firstChild, nw);
                   7162: #endif /* LIBXML_LEGACY_ENABLED */
                   7163:            } else if (list == NULL) {
                   7164:                xmlNodePtr nw = NULL, cur, next, last,
                   7165:                           firstChild = NULL;
                   7166:                /*
                   7167:                 * Copy the entity child list and make it the new
                   7168:                 * entity child list. The goal is to make sure any
                   7169:                 * ID or REF referenced will be the one from the
                   7170:                 * document content and not the entity copy.
                   7171:                 */
                   7172:                cur = ent->children;
                   7173:                ent->children = NULL;
                   7174:                last = ent->last;
                   7175:                ent->last = NULL;
                   7176:                while (cur != NULL) {
                   7177:                    next = cur->next;
                   7178:                    cur->next = NULL;
                   7179:                    cur->parent = NULL;
                   7180:                    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
                   7181:                    if (nw != NULL) {
                   7182:                        if (nw->_private == NULL)
                   7183:                            nw->_private = cur->_private;
                   7184:                        if (firstChild == NULL){
                   7185:                            firstChild = cur;
                   7186:                        }
                   7187:                        xmlAddChild((xmlNodePtr) ent, nw);
                   7188:                        xmlAddChild(ctxt->node, cur);
                   7189:                    }
                   7190:                    if (cur == last)
                   7191:                        break;
                   7192:                    cur = next;
                   7193:                }
                   7194:                if (ent->owner == 0)
                   7195:                    ent->owner = 1;
                   7196: #ifdef LIBXML_LEGACY_ENABLED
                   7197:                if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
                   7198:                  xmlAddEntityReference(ent, firstChild, nw);
                   7199: #endif /* LIBXML_LEGACY_ENABLED */
                   7200:            } else {
                   7201:                const xmlChar *nbktext;
                   7202: 
                   7203:                /*
                   7204:                 * the name change is to avoid coalescing of the
                   7205:                 * node with a possible previous text one which
                   7206:                 * would make ent->children a dangling pointer
                   7207:                 */
                   7208:                nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
                   7209:                                        -1);
                   7210:                if (ent->children->type == XML_TEXT_NODE)
                   7211:                    ent->children->name = nbktext;
                   7212:                if ((ent->last != ent->children) &&
                   7213:                    (ent->last->type == XML_TEXT_NODE))
                   7214:                    ent->last->name = nbktext;
                   7215:                xmlAddChildList(ctxt->node, ent->children);
                   7216:            }
                   7217: 
                   7218:            /*
                   7219:             * This is to avoid a nasty side effect, see
                   7220:             * characters() in SAX.c
                   7221:             */
                   7222:            ctxt->nodemem = 0;
                   7223:            ctxt->nodelen = 0;
                   7224:            return;
                   7225:        }
                   7226:     }
                   7227: }
                   7228: 
                   7229: /**
                   7230:  * xmlParseEntityRef:
                   7231:  * @ctxt:  an XML parser context
                   7232:  *
                   7233:  * parse ENTITY references declarations
                   7234:  *
                   7235:  * [68] EntityRef ::= '&' Name ';'
                   7236:  *
                   7237:  * [ WFC: Entity Declared ]
                   7238:  * In a document without any DTD, a document with only an internal DTD
                   7239:  * subset which contains no parameter entity references, or a document
                   7240:  * with "standalone='yes'", the Name given in the entity reference
                   7241:  * must match that in an entity declaration, except that well-formed
                   7242:  * documents need not declare any of the following entities: amp, lt,
                   7243:  * gt, apos, quot.  The declaration of a parameter entity must precede
                   7244:  * any reference to it.  Similarly, the declaration of a general entity
                   7245:  * must precede any reference to it which appears in a default value in an
                   7246:  * attribute-list declaration. Note that if entities are declared in the
                   7247:  * external subset or in external parameter entities, a non-validating
                   7248:  * processor is not obligated to read and process their declarations;
                   7249:  * for such documents, the rule that an entity must be declared is a
                   7250:  * well-formedness constraint only if standalone='yes'.
                   7251:  *
                   7252:  * [ WFC: Parsed Entity ]
                   7253:  * An entity reference must not contain the name of an unparsed entity
                   7254:  *
                   7255:  * Returns the xmlEntityPtr if found, or NULL otherwise.
                   7256:  */
                   7257: xmlEntityPtr
                   7258: xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
                   7259:     const xmlChar *name;
                   7260:     xmlEntityPtr ent = NULL;
                   7261: 
                   7262:     GROW;
                   7263: 
                   7264:     if (RAW != '&')
                   7265:         return(NULL);
                   7266:     NEXT;
                   7267:     name = xmlParseName(ctxt);
                   7268:     if (name == NULL) {
                   7269:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   7270:                       "xmlParseEntityRef: no name\n");
                   7271:         return(NULL);
                   7272:     }
                   7273:     if (RAW != ';') {
                   7274:        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
                   7275:        return(NULL);
                   7276:     }
                   7277:     NEXT;
                   7278: 
                   7279:     /*
                   7280:      * Predefined entites override any extra definition
                   7281:      */
                   7282:     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
                   7283:         ent = xmlGetPredefinedEntity(name);
                   7284:         if (ent != NULL)
                   7285:             return(ent);
                   7286:     }
                   7287: 
                   7288:     /*
                   7289:      * Increate the number of entity references parsed
                   7290:      */
                   7291:     ctxt->nbentities++;
                   7292: 
                   7293:     /*
                   7294:      * Ask first SAX for entity resolution, otherwise try the
                   7295:      * entities which may have stored in the parser context.
                   7296:      */
                   7297:     if (ctxt->sax != NULL) {
                   7298:        if (ctxt->sax->getEntity != NULL)
                   7299:            ent = ctxt->sax->getEntity(ctxt->userData, name);
                   7300:        if ((ctxt->wellFormed == 1 ) && (ent == NULL) && 
                   7301:            (ctxt->options & XML_PARSE_OLDSAX))
                   7302:            ent = xmlGetPredefinedEntity(name);
                   7303:        if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
                   7304:            (ctxt->userData==ctxt)) {
                   7305:            ent = xmlSAX2GetEntity(ctxt, name);
                   7306:        }
                   7307:     }
                   7308:     /*
                   7309:      * [ WFC: Entity Declared ]
                   7310:      * In a document without any DTD, a document with only an
                   7311:      * internal DTD subset which contains no parameter entity
                   7312:      * references, or a document with "standalone='yes'", the
                   7313:      * Name given in the entity reference must match that in an
                   7314:      * entity declaration, except that well-formed documents
                   7315:      * need not declare any of the following entities: amp, lt,
                   7316:      * gt, apos, quot.
                   7317:      * The declaration of a parameter entity must precede any
                   7318:      * reference to it.
                   7319:      * Similarly, the declaration of a general entity must
                   7320:      * precede any reference to it which appears in a default
                   7321:      * value in an attribute-list declaration. Note that if
                   7322:      * entities are declared in the external subset or in
                   7323:      * external parameter entities, a non-validating processor
                   7324:      * is not obligated to read and process their declarations;
                   7325:      * for such documents, the rule that an entity must be
                   7326:      * declared is a well-formedness constraint only if
                   7327:      * standalone='yes'.
                   7328:      */
                   7329:     if (ent == NULL) {
                   7330:        if ((ctxt->standalone == 1) ||
                   7331:            ((ctxt->hasExternalSubset == 0) &&
                   7332:             (ctxt->hasPErefs == 0))) {
                   7333:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   7334:                     "Entity '%s' not defined\n", name);
                   7335:        } else {
                   7336:            xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7337:                     "Entity '%s' not defined\n", name);
                   7338:            if ((ctxt->inSubset == 0) &&
                   7339:                (ctxt->sax != NULL) &&
                   7340:                (ctxt->sax->reference != NULL)) {
                   7341:                ctxt->sax->reference(ctxt->userData, name);
                   7342:            }
                   7343:        }
                   7344:        ctxt->valid = 0;
                   7345:     }
                   7346: 
                   7347:     /*
                   7348:      * [ WFC: Parsed Entity ]
                   7349:      * An entity reference must not contain the name of an
                   7350:      * unparsed entity
                   7351:      */
                   7352:     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
                   7353:        xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
                   7354:                 "Entity reference to unparsed entity %s\n", name);
                   7355:     }
                   7356: 
                   7357:     /*
                   7358:      * [ WFC: No External Entity References ]
                   7359:      * Attribute values cannot contain direct or indirect
                   7360:      * entity references to external entities.
                   7361:      */
                   7362:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   7363:             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
                   7364:        xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
                   7365:             "Attribute references external entity '%s'\n", name);
                   7366:     }
                   7367:     /*
                   7368:      * [ WFC: No < in Attribute Values ]
                   7369:      * The replacement text of any entity referred to directly or
                   7370:      * indirectly in an attribute value (other than "&lt;") must
                   7371:      * not contain a <. 
                   7372:      */
                   7373:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   7374:             (ent != NULL) && (ent->content != NULL) &&
                   7375:             (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
                   7376:             (xmlStrchr(ent->content, '<'))) {
                   7377:        xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
                   7378:     "'<' in entity '%s' is not allowed in attributes values\n", name);
                   7379:     }
                   7380: 
                   7381:     /*
                   7382:      * Internal check, no parameter entities here ...
                   7383:      */
                   7384:     else {
                   7385:        switch (ent->etype) {
                   7386:            case XML_INTERNAL_PARAMETER_ENTITY:
                   7387:            case XML_EXTERNAL_PARAMETER_ENTITY:
                   7388:            xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
                   7389:             "Attempt to reference the parameter entity '%s'\n",
                   7390:                              name);
                   7391:            break;
                   7392:            default:
                   7393:            break;
                   7394:        }
                   7395:     }
                   7396: 
                   7397:     /*
                   7398:      * [ WFC: No Recursion ]
                   7399:      * A parsed entity must not contain a recursive reference
                   7400:      * to itself, either directly or indirectly. 
                   7401:      * Done somewhere else
                   7402:      */
                   7403:     return(ent);
                   7404: }
                   7405: 
                   7406: /**
                   7407:  * xmlParseStringEntityRef:
                   7408:  * @ctxt:  an XML parser context
                   7409:  * @str:  a pointer to an index in the string
                   7410:  *
                   7411:  * parse ENTITY references declarations, but this version parses it from
                   7412:  * a string value.
                   7413:  *
                   7414:  * [68] EntityRef ::= '&' Name ';'
                   7415:  *
                   7416:  * [ WFC: Entity Declared ]
                   7417:  * In a document without any DTD, a document with only an internal DTD
                   7418:  * subset which contains no parameter entity references, or a document
                   7419:  * with "standalone='yes'", the Name given in the entity reference
                   7420:  * must match that in an entity declaration, except that well-formed
                   7421:  * documents need not declare any of the following entities: amp, lt,
                   7422:  * gt, apos, quot.  The declaration of a parameter entity must precede
                   7423:  * any reference to it.  Similarly, the declaration of a general entity
                   7424:  * must precede any reference to it which appears in a default value in an
                   7425:  * attribute-list declaration. Note that if entities are declared in the
                   7426:  * external subset or in external parameter entities, a non-validating
                   7427:  * processor is not obligated to read and process their declarations;
                   7428:  * for such documents, the rule that an entity must be declared is a
                   7429:  * well-formedness constraint only if standalone='yes'.
                   7430:  *
                   7431:  * [ WFC: Parsed Entity ]
                   7432:  * An entity reference must not contain the name of an unparsed entity
                   7433:  *
                   7434:  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
                   7435:  * is updated to the current location in the string.
                   7436:  */
                   7437: static xmlEntityPtr
                   7438: xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
                   7439:     xmlChar *name;
                   7440:     const xmlChar *ptr;
                   7441:     xmlChar cur;
                   7442:     xmlEntityPtr ent = NULL;
                   7443: 
                   7444:     if ((str == NULL) || (*str == NULL))
                   7445:         return(NULL);
                   7446:     ptr = *str;
                   7447:     cur = *ptr;
                   7448:     if (cur != '&')
                   7449:        return(NULL);
                   7450: 
                   7451:     ptr++;
                   7452:     name = xmlParseStringName(ctxt, &ptr);
                   7453:     if (name == NULL) {
                   7454:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   7455:                       "xmlParseStringEntityRef: no name\n");
                   7456:        *str = ptr;
                   7457:        return(NULL);
                   7458:     }
                   7459:     if (*ptr != ';') {
                   7460:        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
                   7461:         xmlFree(name);
                   7462:        *str = ptr;
                   7463:        return(NULL);
                   7464:     }
                   7465:     ptr++;
                   7466: 
                   7467: 
                   7468:     /*
                   7469:      * Predefined entites override any extra definition
                   7470:      */
                   7471:     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
                   7472:         ent = xmlGetPredefinedEntity(name);
                   7473:         if (ent != NULL) {
                   7474:             xmlFree(name);
                   7475:             *str = ptr;
                   7476:             return(ent);
                   7477:         }
                   7478:     }
                   7479: 
                   7480:     /*
                   7481:      * Increate the number of entity references parsed
                   7482:      */
                   7483:     ctxt->nbentities++;
                   7484: 
                   7485:     /*
                   7486:      * Ask first SAX for entity resolution, otherwise try the
                   7487:      * entities which may have stored in the parser context.
                   7488:      */
                   7489:     if (ctxt->sax != NULL) {
                   7490:        if (ctxt->sax->getEntity != NULL)
                   7491:            ent = ctxt->sax->getEntity(ctxt->userData, name);
                   7492:        if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
                   7493:            ent = xmlGetPredefinedEntity(name);
                   7494:        if ((ent == NULL) && (ctxt->userData==ctxt)) {
                   7495:            ent = xmlSAX2GetEntity(ctxt, name);
                   7496:        }
                   7497:     }
                   7498: 
                   7499:     /*
                   7500:      * [ WFC: Entity Declared ]
                   7501:      * In a document without any DTD, a document with only an
                   7502:      * internal DTD subset which contains no parameter entity
                   7503:      * references, or a document with "standalone='yes'", the
                   7504:      * Name given in the entity reference must match that in an
                   7505:      * entity declaration, except that well-formed documents
                   7506:      * need not declare any of the following entities: amp, lt,
                   7507:      * gt, apos, quot.
                   7508:      * The declaration of a parameter entity must precede any
                   7509:      * reference to it.
                   7510:      * Similarly, the declaration of a general entity must
                   7511:      * precede any reference to it which appears in a default
                   7512:      * value in an attribute-list declaration. Note that if
                   7513:      * entities are declared in the external subset or in
                   7514:      * external parameter entities, a non-validating processor
                   7515:      * is not obligated to read and process their declarations;
                   7516:      * for such documents, the rule that an entity must be
                   7517:      * declared is a well-formedness constraint only if
                   7518:      * standalone='yes'. 
                   7519:      */
                   7520:     if (ent == NULL) {
                   7521:        if ((ctxt->standalone == 1) ||
                   7522:            ((ctxt->hasExternalSubset == 0) &&
                   7523:             (ctxt->hasPErefs == 0))) {
                   7524:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   7525:                     "Entity '%s' not defined\n", name);
                   7526:        } else {
                   7527:            xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7528:                          "Entity '%s' not defined\n",
                   7529:                          name);
                   7530:        }
                   7531:        /* TODO ? check regressions ctxt->valid = 0; */
                   7532:     }
                   7533: 
                   7534:     /*
                   7535:      * [ WFC: Parsed Entity ]
                   7536:      * An entity reference must not contain the name of an
                   7537:      * unparsed entity
                   7538:      */
                   7539:     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
                   7540:        xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
                   7541:                 "Entity reference to unparsed entity %s\n", name);
                   7542:     }
                   7543: 
                   7544:     /*
                   7545:      * [ WFC: No External Entity References ]
                   7546:      * Attribute values cannot contain direct or indirect
                   7547:      * entity references to external entities.
                   7548:      */
                   7549:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   7550:             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
                   7551:        xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
                   7552:         "Attribute references external entity '%s'\n", name);
                   7553:     }
                   7554:     /*
                   7555:      * [ WFC: No < in Attribute Values ]
                   7556:      * The replacement text of any entity referred to directly or
                   7557:      * indirectly in an attribute value (other than "&lt;") must
                   7558:      * not contain a <.
                   7559:      */
                   7560:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   7561:             (ent != NULL) && (ent->content != NULL) &&
                   7562:             (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
                   7563:             (xmlStrchr(ent->content, '<'))) {
                   7564:        xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
                   7565:      "'<' in entity '%s' is not allowed in attributes values\n",
                   7566:                          name);
                   7567:     }
                   7568: 
                   7569:     /*
                   7570:      * Internal check, no parameter entities here ...
                   7571:      */
                   7572:     else {
                   7573:        switch (ent->etype) {
                   7574:            case XML_INTERNAL_PARAMETER_ENTITY:
                   7575:            case XML_EXTERNAL_PARAMETER_ENTITY:
                   7576:                xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
                   7577:             "Attempt to reference the parameter entity '%s'\n",
                   7578:                                  name);
                   7579:            break;
                   7580:            default:
                   7581:            break;
                   7582:        }
                   7583:     }
                   7584: 
                   7585:     /*
                   7586:      * [ WFC: No Recursion ]
                   7587:      * A parsed entity must not contain a recursive reference
                   7588:      * to itself, either directly or indirectly.
                   7589:      * Done somewhere else
                   7590:      */
                   7591: 
                   7592:     xmlFree(name);
                   7593:     *str = ptr;
                   7594:     return(ent);
                   7595: }
                   7596: 
                   7597: /**
                   7598:  * xmlParsePEReference:
                   7599:  * @ctxt:  an XML parser context
                   7600:  *
                   7601:  * parse PEReference declarations
                   7602:  * The entity content is handled directly by pushing it's content as
                   7603:  * a new input stream.
                   7604:  *
                   7605:  * [69] PEReference ::= '%' Name ';'
                   7606:  *
                   7607:  * [ WFC: No Recursion ]
                   7608:  * A parsed entity must not contain a recursive
                   7609:  * reference to itself, either directly or indirectly. 
                   7610:  *
                   7611:  * [ WFC: Entity Declared ]
                   7612:  * In a document without any DTD, a document with only an internal DTD
                   7613:  * subset which contains no parameter entity references, or a document
                   7614:  * with "standalone='yes'", ...  ... The declaration of a parameter
                   7615:  * entity must precede any reference to it...
                   7616:  *
                   7617:  * [ VC: Entity Declared ]
                   7618:  * In a document with an external subset or external parameter entities
                   7619:  * with "standalone='no'", ...  ... The declaration of a parameter entity
                   7620:  * must precede any reference to it...
                   7621:  *
                   7622:  * [ WFC: In DTD ]
                   7623:  * Parameter-entity references may only appear in the DTD.
                   7624:  * NOTE: misleading but this is handled.
                   7625:  */
                   7626: void
                   7627: xmlParsePEReference(xmlParserCtxtPtr ctxt)
                   7628: {
                   7629:     const xmlChar *name;
                   7630:     xmlEntityPtr entity = NULL;
                   7631:     xmlParserInputPtr input;
                   7632: 
                   7633:     if (RAW != '%')
                   7634:         return;
                   7635:     NEXT;
                   7636:     name = xmlParseName(ctxt);
                   7637:     if (name == NULL) {
                   7638:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   7639:                       "xmlParsePEReference: no name\n");
                   7640:        return;
                   7641:     }
                   7642:     if (RAW != ';') {
                   7643:        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
                   7644:         return;
                   7645:     }
                   7646: 
                   7647:     NEXT;
                   7648: 
                   7649:     /*
                   7650:      * Increate the number of entity references parsed
                   7651:      */
                   7652:     ctxt->nbentities++;
                   7653: 
                   7654:     /*
                   7655:      * Request the entity from SAX
                   7656:      */
                   7657:     if ((ctxt->sax != NULL) &&
                   7658:        (ctxt->sax->getParameterEntity != NULL))
                   7659:        entity = ctxt->sax->getParameterEntity(ctxt->userData,
                   7660:                                               name);
                   7661:     if (entity == NULL) {
                   7662:        /*
                   7663:         * [ WFC: Entity Declared ]
                   7664:         * In a document without any DTD, a document with only an
                   7665:         * internal DTD subset which contains no parameter entity
                   7666:         * references, or a document with "standalone='yes'", ...
                   7667:         * ... The declaration of a parameter entity must precede
                   7668:         * any reference to it...
                   7669:         */
                   7670:        if ((ctxt->standalone == 1) ||
                   7671:            ((ctxt->hasExternalSubset == 0) &&
                   7672:             (ctxt->hasPErefs == 0))) {
                   7673:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   7674:                              "PEReference: %%%s; not found\n",
                   7675:                              name);
                   7676:        } else {
                   7677:            /*
                   7678:             * [ VC: Entity Declared ]
                   7679:             * In a document with an external subset or external
                   7680:             * parameter entities with "standalone='no'", ...
                   7681:             * ... The declaration of a parameter entity must
                   7682:             * precede any reference to it...
                   7683:             */
                   7684:            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7685:                          "PEReference: %%%s; not found\n",
                   7686:                          name, NULL);
                   7687:            ctxt->valid = 0;
                   7688:        }
                   7689:     } else {
                   7690:        /*
                   7691:         * Internal checking in case the entity quest barfed
                   7692:         */
                   7693:        if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
                   7694:            (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
                   7695:            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7696:                  "Internal: %%%s; is not a parameter entity\n",
                   7697:                          name, NULL);
                   7698:        } else if (ctxt->input->free != deallocblankswrapper) {
                   7699:            input = xmlNewBlanksWrapperInputStream(ctxt, entity);
                   7700:            if (xmlPushInput(ctxt, input) < 0)
                   7701:                return;
                   7702:        } else {
                   7703:            /*
                   7704:             * TODO !!!
                   7705:             * handle the extra spaces added before and after
                   7706:             * c.f. http://www.w3.org/TR/REC-xml#as-PE
                   7707:             */
                   7708:            input = xmlNewEntityInputStream(ctxt, entity);
                   7709:            if (xmlPushInput(ctxt, input) < 0)
                   7710:                return;
                   7711:            if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
                   7712:                (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
                   7713:                (IS_BLANK_CH(NXT(5)))) {
                   7714:                xmlParseTextDecl(ctxt);
                   7715:                if (ctxt->errNo ==
                   7716:                    XML_ERR_UNSUPPORTED_ENCODING) {
                   7717:                    /*
                   7718:                     * The XML REC instructs us to stop parsing
                   7719:                     * right here
                   7720:                     */
                   7721:                    ctxt->instate = XML_PARSER_EOF;
                   7722:                    return;
                   7723:                }
                   7724:            }
                   7725:        }
                   7726:     }
                   7727:     ctxt->hasPErefs = 1;
                   7728: }
                   7729: 
                   7730: /**
                   7731:  * xmlLoadEntityContent:
                   7732:  * @ctxt:  an XML parser context
                   7733:  * @entity: an unloaded system entity
                   7734:  *
                   7735:  * Load the original content of the given system entity from the
                   7736:  * ExternalID/SystemID given. This is to be used for Included in Literal
                   7737:  * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
                   7738:  *
                   7739:  * Returns 0 in case of success and -1 in case of failure
                   7740:  */
                   7741: static int
                   7742: xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
                   7743:     xmlParserInputPtr input;
                   7744:     xmlBufferPtr buf;
                   7745:     int l, c;
                   7746:     int count = 0;
                   7747: 
                   7748:     if ((ctxt == NULL) || (entity == NULL) ||
                   7749:         ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
                   7750:         (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
                   7751:        (entity->content != NULL)) {
                   7752:        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   7753:                    "xmlLoadEntityContent parameter error");
                   7754:         return(-1);
                   7755:     }
                   7756: 
                   7757:     if (xmlParserDebugEntities)
                   7758:        xmlGenericError(xmlGenericErrorContext,
                   7759:                "Reading %s entity content input\n", entity->name);
                   7760: 
                   7761:     buf = xmlBufferCreate();
                   7762:     if (buf == NULL) {
                   7763:        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   7764:                    "xmlLoadEntityContent parameter error");
                   7765:         return(-1);
                   7766:     }
                   7767: 
                   7768:     input = xmlNewEntityInputStream(ctxt, entity);
                   7769:     if (input == NULL) {
                   7770:        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   7771:                    "xmlLoadEntityContent input error");
                   7772:        xmlBufferFree(buf);
                   7773:         return(-1);
                   7774:     }
                   7775: 
                   7776:     /*
                   7777:      * Push the entity as the current input, read char by char
                   7778:      * saving to the buffer until the end of the entity or an error
                   7779:      */
                   7780:     if (xmlPushInput(ctxt, input) < 0) {
                   7781:         xmlBufferFree(buf);
                   7782:        return(-1);
                   7783:     }
                   7784: 
                   7785:     GROW;
                   7786:     c = CUR_CHAR(l);
                   7787:     while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
                   7788:            (IS_CHAR(c))) {
                   7789:         xmlBufferAdd(buf, ctxt->input->cur, l);
                   7790:        if (count++ > 100) {
                   7791:            count = 0;
                   7792:            GROW;
                   7793:        }
                   7794:        NEXTL(l);
                   7795:        c = CUR_CHAR(l);
                   7796:     }
                   7797: 
                   7798:     if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
                   7799:         xmlPopInput(ctxt);
                   7800:     } else if (!IS_CHAR(c)) {
                   7801:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   7802:                           "xmlLoadEntityContent: invalid char value %d\n",
                   7803:                          c);
                   7804:        xmlBufferFree(buf);
                   7805:        return(-1);
                   7806:     }
                   7807:     entity->content = buf->content;
                   7808:     buf->content = NULL;
                   7809:     xmlBufferFree(buf);
                   7810: 
                   7811:     return(0);
                   7812: }
                   7813: 
                   7814: /**
                   7815:  * xmlParseStringPEReference:
                   7816:  * @ctxt:  an XML parser context
                   7817:  * @str:  a pointer to an index in the string
                   7818:  *
                   7819:  * parse PEReference declarations
                   7820:  *
                   7821:  * [69] PEReference ::= '%' Name ';'
                   7822:  *
                   7823:  * [ WFC: No Recursion ]
                   7824:  * A parsed entity must not contain a recursive
                   7825:  * reference to itself, either directly or indirectly.
                   7826:  *
                   7827:  * [ WFC: Entity Declared ]
                   7828:  * In a document without any DTD, a document with only an internal DTD
                   7829:  * subset which contains no parameter entity references, or a document
                   7830:  * with "standalone='yes'", ...  ... The declaration of a parameter
                   7831:  * entity must precede any reference to it...
                   7832:  *
                   7833:  * [ VC: Entity Declared ]
                   7834:  * In a document with an external subset or external parameter entities
                   7835:  * with "standalone='no'", ...  ... The declaration of a parameter entity
                   7836:  * must precede any reference to it...
                   7837:  *
                   7838:  * [ WFC: In DTD ]
                   7839:  * Parameter-entity references may only appear in the DTD.
                   7840:  * NOTE: misleading but this is handled.
                   7841:  *
                   7842:  * Returns the string of the entity content.
                   7843:  *         str is updated to the current value of the index
                   7844:  */
                   7845: static xmlEntityPtr
                   7846: xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
                   7847:     const xmlChar *ptr;
                   7848:     xmlChar cur;
                   7849:     xmlChar *name;
                   7850:     xmlEntityPtr entity = NULL;
                   7851: 
                   7852:     if ((str == NULL) || (*str == NULL)) return(NULL);
                   7853:     ptr = *str;
                   7854:     cur = *ptr;
                   7855:     if (cur != '%')
                   7856:         return(NULL);
                   7857:     ptr++;
                   7858:     name = xmlParseStringName(ctxt, &ptr);
                   7859:     if (name == NULL) {
                   7860:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   7861:                       "xmlParseStringPEReference: no name\n");
                   7862:        *str = ptr;
                   7863:        return(NULL);
                   7864:     }
                   7865:     cur = *ptr;
                   7866:     if (cur != ';') {
                   7867:        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
                   7868:        xmlFree(name);
                   7869:        *str = ptr;
                   7870:        return(NULL);
                   7871:     }
                   7872:     ptr++;
                   7873: 
                   7874:     /*
                   7875:      * Increate the number of entity references parsed
                   7876:      */
                   7877:     ctxt->nbentities++;
                   7878: 
                   7879:     /*
                   7880:      * Request the entity from SAX
                   7881:      */
                   7882:     if ((ctxt->sax != NULL) &&
                   7883:        (ctxt->sax->getParameterEntity != NULL))
                   7884:        entity = ctxt->sax->getParameterEntity(ctxt->userData,
                   7885:                                               name);
                   7886:     if (entity == NULL) {
                   7887:        /*
                   7888:         * [ WFC: Entity Declared ]
                   7889:         * In a document without any DTD, a document with only an
                   7890:         * internal DTD subset which contains no parameter entity
                   7891:         * references, or a document with "standalone='yes'", ...
                   7892:         * ... The declaration of a parameter entity must precede
                   7893:         * any reference to it...
                   7894:         */
                   7895:        if ((ctxt->standalone == 1) ||
                   7896:            ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
                   7897:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   7898:                 "PEReference: %%%s; not found\n", name);
                   7899:        } else {
                   7900:            /*
                   7901:             * [ VC: Entity Declared ]
                   7902:             * In a document with an external subset or external
                   7903:             * parameter entities with "standalone='no'", ...
                   7904:             * ... The declaration of a parameter entity must
                   7905:             * precede any reference to it...
                   7906:             */
                   7907:            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7908:                          "PEReference: %%%s; not found\n",
                   7909:                          name, NULL);
                   7910:            ctxt->valid = 0;
                   7911:        }
                   7912:     } else {
                   7913:        /*
                   7914:         * Internal checking in case the entity quest barfed
                   7915:         */
                   7916:        if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
                   7917:            (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
                   7918:            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7919:                          "%%%s; is not a parameter entity\n",
                   7920:                          name, NULL);
                   7921:        }
                   7922:     }
                   7923:     ctxt->hasPErefs = 1;
                   7924:     xmlFree(name);
                   7925:     *str = ptr;
                   7926:     return(entity);
                   7927: }
                   7928: 
                   7929: /**
                   7930:  * xmlParseDocTypeDecl:
                   7931:  * @ctxt:  an XML parser context
                   7932:  *
                   7933:  * parse a DOCTYPE declaration
                   7934:  *
                   7935:  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? 
                   7936:  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
                   7937:  *
                   7938:  * [ VC: Root Element Type ]
                   7939:  * The Name in the document type declaration must match the element
                   7940:  * type of the root element. 
                   7941:  */
                   7942: 
                   7943: void
                   7944: xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
                   7945:     const xmlChar *name = NULL;
                   7946:     xmlChar *ExternalID = NULL;
                   7947:     xmlChar *URI = NULL;
                   7948: 
                   7949:     /*
                   7950:      * We know that '<!DOCTYPE' has been detected.
                   7951:      */
                   7952:     SKIP(9);
                   7953: 
                   7954:     SKIP_BLANKS;
                   7955: 
                   7956:     /*
                   7957:      * Parse the DOCTYPE name.
                   7958:      */
                   7959:     name = xmlParseName(ctxt);
                   7960:     if (name == NULL) {
                   7961:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   7962:                       "xmlParseDocTypeDecl : no DOCTYPE name !\n");
                   7963:     }
                   7964:     ctxt->intSubName = name;
                   7965: 
                   7966:     SKIP_BLANKS;
                   7967: 
                   7968:     /*
                   7969:      * Check for SystemID and ExternalID
                   7970:      */
                   7971:     URI = xmlParseExternalID(ctxt, &ExternalID, 1);
                   7972: 
                   7973:     if ((URI != NULL) || (ExternalID != NULL)) {
                   7974:         ctxt->hasExternalSubset = 1;
                   7975:     }
                   7976:     ctxt->extSubURI = URI;
                   7977:     ctxt->extSubSystem = ExternalID;
                   7978: 
                   7979:     SKIP_BLANKS;
                   7980: 
                   7981:     /*
                   7982:      * Create and update the internal subset.
                   7983:      */
                   7984:     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
                   7985:        (!ctxt->disableSAX))
                   7986:        ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
                   7987: 
                   7988:     /*
                   7989:      * Is there any internal subset declarations ?
                   7990:      * they are handled separately in xmlParseInternalSubset()
                   7991:      */
                   7992:     if (RAW == '[')
                   7993:        return;
                   7994: 
                   7995:     /*
                   7996:      * We should be at the end of the DOCTYPE declaration.
                   7997:      */
                   7998:     if (RAW != '>') {
                   7999:        xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
                   8000:     }
                   8001:     NEXT;
                   8002: }
                   8003: 
                   8004: /**
                   8005:  * xmlParseInternalSubset:
                   8006:  * @ctxt:  an XML parser context
                   8007:  *
                   8008:  * parse the internal subset declaration
                   8009:  *
                   8010:  * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
                   8011:  */
                   8012: 
                   8013: static void
                   8014: xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
                   8015:     /*
                   8016:      * Is there any DTD definition ?
                   8017:      */
                   8018:     if (RAW == '[') {
                   8019:         ctxt->instate = XML_PARSER_DTD;
                   8020:         NEXT;
                   8021:        /*
                   8022:         * Parse the succession of Markup declarations and 
                   8023:         * PEReferences.
                   8024:         * Subsequence (markupdecl | PEReference | S)*
                   8025:         */
                   8026:        while (RAW != ']') {
                   8027:            const xmlChar *check = CUR_PTR;
                   8028:            unsigned int cons = ctxt->input->consumed;
                   8029: 
                   8030:            SKIP_BLANKS;
                   8031:            xmlParseMarkupDecl(ctxt);
                   8032:            xmlParsePEReference(ctxt);
                   8033: 
                   8034:            /*
                   8035:             * Pop-up of finished entities.
                   8036:             */
                   8037:            while ((RAW == 0) && (ctxt->inputNr > 1))
                   8038:                xmlPopInput(ctxt);
                   8039: 
                   8040:            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
                   8041:                xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   8042:             "xmlParseInternalSubset: error detected in Markup declaration\n");
                   8043:                break;
                   8044:            }
                   8045:        }
                   8046:        if (RAW == ']') { 
                   8047:            NEXT;
                   8048:            SKIP_BLANKS;
                   8049:        }
                   8050:     }
                   8051: 
                   8052:     /*
                   8053:      * We should be at the end of the DOCTYPE declaration.
                   8054:      */
                   8055:     if (RAW != '>') {
                   8056:        xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
                   8057:     }
                   8058:     NEXT;
                   8059: }
                   8060: 
                   8061: #ifdef LIBXML_SAX1_ENABLED
                   8062: /**
                   8063:  * xmlParseAttribute:
                   8064:  * @ctxt:  an XML parser context
                   8065:  * @value:  a xmlChar ** used to store the value of the attribute
                   8066:  *
                   8067:  * parse an attribute
                   8068:  *
                   8069:  * [41] Attribute ::= Name Eq AttValue
                   8070:  *
                   8071:  * [ WFC: No External Entity References ]
                   8072:  * Attribute values cannot contain direct or indirect entity references
                   8073:  * to external entities.
                   8074:  *
                   8075:  * [ WFC: No < in Attribute Values ]
                   8076:  * The replacement text of any entity referred to directly or indirectly in
                   8077:  * an attribute value (other than "&lt;") must not contain a <. 
                   8078:  * 
                   8079:  * [ VC: Attribute Value Type ]
                   8080:  * The attribute must have been declared; the value must be of the type
                   8081:  * declared for it.
                   8082:  *
                   8083:  * [25] Eq ::= S? '=' S?
                   8084:  *
                   8085:  * With namespace:
                   8086:  *
                   8087:  * [NS 11] Attribute ::= QName Eq AttValue
                   8088:  *
                   8089:  * Also the case QName == xmlns:??? is handled independently as a namespace
                   8090:  * definition.
                   8091:  *
                   8092:  * Returns the attribute name, and the value in *value.
                   8093:  */
                   8094: 
                   8095: const xmlChar *
                   8096: xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
                   8097:     const xmlChar *name;
                   8098:     xmlChar *val;
                   8099: 
                   8100:     *value = NULL;
                   8101:     GROW;
                   8102:     name = xmlParseName(ctxt);
                   8103:     if (name == NULL) {
                   8104:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   8105:                       "error parsing attribute name\n");
                   8106:         return(NULL);
                   8107:     }
                   8108: 
                   8109:     /*
                   8110:      * read the value
                   8111:      */
                   8112:     SKIP_BLANKS;
                   8113:     if (RAW == '=') {
                   8114:         NEXT;
                   8115:        SKIP_BLANKS;
                   8116:        val = xmlParseAttValue(ctxt);
                   8117:        ctxt->instate = XML_PARSER_CONTENT;
                   8118:     } else {
                   8119:        xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
                   8120:               "Specification mandate value for attribute %s\n", name);
                   8121:        return(NULL);
                   8122:     }
                   8123: 
                   8124:     /*
                   8125:      * Check that xml:lang conforms to the specification
                   8126:      * No more registered as an error, just generate a warning now
                   8127:      * since this was deprecated in XML second edition
                   8128:      */
                   8129:     if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
                   8130:        if (!xmlCheckLanguageID(val)) {
                   8131:            xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
                   8132:                          "Malformed value for xml:lang : %s\n",
                   8133:                          val, NULL);
                   8134:        }
                   8135:     }
                   8136: 
                   8137:     /*
                   8138:      * Check that xml:space conforms to the specification
                   8139:      */
                   8140:     if (xmlStrEqual(name, BAD_CAST "xml:space")) {
                   8141:        if (xmlStrEqual(val, BAD_CAST "default"))
                   8142:            *(ctxt->space) = 0;
                   8143:        else if (xmlStrEqual(val, BAD_CAST "preserve"))
                   8144:            *(ctxt->space) = 1;
                   8145:        else {
                   8146:                xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
                   8147: "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
                   8148:                                  val, NULL);
                   8149:        }
                   8150:     }
                   8151: 
                   8152:     *value = val;
                   8153:     return(name);
                   8154: }
                   8155: 
                   8156: /**
                   8157:  * xmlParseStartTag:
                   8158:  * @ctxt:  an XML parser context
                   8159:  * 
                   8160:  * parse a start of tag either for rule element or
                   8161:  * EmptyElement. In both case we don't parse the tag closing chars.
                   8162:  *
                   8163:  * [40] STag ::= '<' Name (S Attribute)* S? '>'
                   8164:  *
                   8165:  * [ WFC: Unique Att Spec ]
                   8166:  * No attribute name may appear more than once in the same start-tag or
                   8167:  * empty-element tag. 
                   8168:  *
                   8169:  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
                   8170:  *
                   8171:  * [ WFC: Unique Att Spec ]
                   8172:  * No attribute name may appear more than once in the same start-tag or
                   8173:  * empty-element tag. 
                   8174:  *
                   8175:  * With namespace:
                   8176:  *
                   8177:  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
                   8178:  *
                   8179:  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
                   8180:  *
                   8181:  * Returns the element name parsed
                   8182:  */
                   8183: 
                   8184: const xmlChar *
                   8185: xmlParseStartTag(xmlParserCtxtPtr ctxt) {
                   8186:     const xmlChar *name;
                   8187:     const xmlChar *attname;
                   8188:     xmlChar *attvalue;
                   8189:     const xmlChar **atts = ctxt->atts;
                   8190:     int nbatts = 0;
                   8191:     int maxatts = ctxt->maxatts;
                   8192:     int i;
                   8193: 
                   8194:     if (RAW != '<') return(NULL);
                   8195:     NEXT1;
                   8196: 
                   8197:     name = xmlParseName(ctxt);
                   8198:     if (name == NULL) {
                   8199:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   8200:             "xmlParseStartTag: invalid element name\n");
                   8201:         return(NULL);
                   8202:     }
                   8203: 
                   8204:     /*
                   8205:      * Now parse the attributes, it ends up with the ending
                   8206:      *
                   8207:      * (S Attribute)* S?
                   8208:      */
                   8209:     SKIP_BLANKS;
                   8210:     GROW;
                   8211: 
                   8212:     while ((RAW != '>') && 
                   8213:           ((RAW != '/') || (NXT(1) != '>')) &&
                   8214:           (IS_BYTE_CHAR(RAW))) {
                   8215:        const xmlChar *q = CUR_PTR;
                   8216:        unsigned int cons = ctxt->input->consumed;
                   8217: 
                   8218:        attname = xmlParseAttribute(ctxt, &attvalue);
                   8219:         if ((attname != NULL) && (attvalue != NULL)) {
                   8220:            /*
                   8221:             * [ WFC: Unique Att Spec ]
                   8222:             * No attribute name may appear more than once in the same
                   8223:             * start-tag or empty-element tag. 
                   8224:             */
                   8225:            for (i = 0; i < nbatts;i += 2) {
                   8226:                if (xmlStrEqual(atts[i], attname)) {
                   8227:                    xmlErrAttributeDup(ctxt, NULL, attname);
                   8228:                    xmlFree(attvalue);
                   8229:                    goto failed;
                   8230:                }
                   8231:            }
                   8232:            /*
                   8233:             * Add the pair to atts
                   8234:             */
                   8235:            if (atts == NULL) {
                   8236:                maxatts = 22; /* allow for 10 attrs by default */
                   8237:                atts = (const xmlChar **)
                   8238:                       xmlMalloc(maxatts * sizeof(xmlChar *));
                   8239:                if (atts == NULL) {
                   8240:                    xmlErrMemory(ctxt, NULL);
                   8241:                    if (attvalue != NULL)
                   8242:                        xmlFree(attvalue);
                   8243:                    goto failed;
                   8244:                }
                   8245:                ctxt->atts = atts;
                   8246:                ctxt->maxatts = maxatts;
                   8247:            } else if (nbatts + 4 > maxatts) {
                   8248:                const xmlChar **n;
                   8249: 
                   8250:                maxatts *= 2;
                   8251:                n = (const xmlChar **) xmlRealloc((void *) atts,
                   8252:                                             maxatts * sizeof(const xmlChar *));
                   8253:                if (n == NULL) {
                   8254:                    xmlErrMemory(ctxt, NULL);
                   8255:                    if (attvalue != NULL)
                   8256:                        xmlFree(attvalue);
                   8257:                    goto failed;
                   8258:                }
                   8259:                atts = n;
                   8260:                ctxt->atts = atts;
                   8261:                ctxt->maxatts = maxatts;
                   8262:            }
                   8263:            atts[nbatts++] = attname;
                   8264:            atts[nbatts++] = attvalue;
                   8265:            atts[nbatts] = NULL;
                   8266:            atts[nbatts + 1] = NULL;
                   8267:        } else {
                   8268:            if (attvalue != NULL)
                   8269:                xmlFree(attvalue);
                   8270:        }
                   8271: 
                   8272: failed:     
                   8273: 
                   8274:        GROW
                   8275:        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
                   8276:            break;
                   8277:        if (!IS_BLANK_CH(RAW)) {
                   8278:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   8279:                           "attributes construct error\n");
                   8280:        }
                   8281:        SKIP_BLANKS;
                   8282:         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
                   8283:             (attname == NULL) && (attvalue == NULL)) {
                   8284:            xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
                   8285:                           "xmlParseStartTag: problem parsing attributes\n");
                   8286:            break;
                   8287:        }
                   8288:        SHRINK;
                   8289:         GROW;
                   8290:     }
                   8291: 
                   8292:     /*
                   8293:      * SAX: Start of Element !
                   8294:      */
                   8295:     if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
                   8296:        (!ctxt->disableSAX)) {
                   8297:        if (nbatts > 0)
                   8298:            ctxt->sax->startElement(ctxt->userData, name, atts);
                   8299:        else
                   8300:            ctxt->sax->startElement(ctxt->userData, name, NULL);
                   8301:     }
                   8302: 
                   8303:     if (atts != NULL) {
                   8304:         /* Free only the content strings */
                   8305:         for (i = 1;i < nbatts;i+=2)
                   8306:            if (atts[i] != NULL)
                   8307:               xmlFree((xmlChar *) atts[i]);
                   8308:     }
                   8309:     return(name);
                   8310: }
                   8311: 
                   8312: /**
                   8313:  * xmlParseEndTag1:
                   8314:  * @ctxt:  an XML parser context
                   8315:  * @line:  line of the start tag
                   8316:  * @nsNr:  number of namespaces on the start tag
                   8317:  *
                   8318:  * parse an end of tag
                   8319:  *
                   8320:  * [42] ETag ::= '</' Name S? '>'
                   8321:  *
                   8322:  * With namespace
                   8323:  *
                   8324:  * [NS 9] ETag ::= '</' QName S? '>'
                   8325:  */
                   8326: 
                   8327: static void
                   8328: xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
                   8329:     const xmlChar *name;
                   8330: 
                   8331:     GROW;
                   8332:     if ((RAW != '<') || (NXT(1) != '/')) {
                   8333:        xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
                   8334:                       "xmlParseEndTag: '</' not found\n");
                   8335:        return;
                   8336:     }
                   8337:     SKIP(2);
                   8338: 
                   8339:     name = xmlParseNameAndCompare(ctxt,ctxt->name);
                   8340: 
                   8341:     /*
                   8342:      * We should definitely be at the ending "S? '>'" part
                   8343:      */
                   8344:     GROW;
                   8345:     SKIP_BLANKS;
                   8346:     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
                   8347:        xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
                   8348:     } else
                   8349:        NEXT1;
                   8350: 
                   8351:     /*
                   8352:      * [ WFC: Element Type Match ]
                   8353:      * The Name in an element's end-tag must match the element type in the
                   8354:      * start-tag. 
                   8355:      *
                   8356:      */
                   8357:     if (name != (xmlChar*)1) {
                   8358:         if (name == NULL) name = BAD_CAST "unparseable";
                   8359:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
                   8360:                     "Opening and ending tag mismatch: %s line %d and %s\n",
                   8361:                                ctxt->name, line, name);
                   8362:     }
                   8363: 
                   8364:     /*
                   8365:      * SAX: End of Tag
                   8366:      */
                   8367:     if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
                   8368:        (!ctxt->disableSAX))
                   8369:         ctxt->sax->endElement(ctxt->userData, ctxt->name);
                   8370: 
                   8371:     namePop(ctxt);
                   8372:     spacePop(ctxt);
                   8373:     return;
                   8374: }
                   8375: 
                   8376: /**
                   8377:  * xmlParseEndTag:
                   8378:  * @ctxt:  an XML parser context
                   8379:  *
                   8380:  * parse an end of tag
                   8381:  *
                   8382:  * [42] ETag ::= '</' Name S? '>'
                   8383:  *
                   8384:  * With namespace
                   8385:  *
                   8386:  * [NS 9] ETag ::= '</' QName S? '>'
                   8387:  */
                   8388: 
                   8389: void
                   8390: xmlParseEndTag(xmlParserCtxtPtr ctxt) {
                   8391:     xmlParseEndTag1(ctxt, 0);
                   8392: }
                   8393: #endif /* LIBXML_SAX1_ENABLED */
                   8394: 
                   8395: /************************************************************************
                   8396:  *                                                                     *
                   8397:  *                   SAX 2 specific operations                         *
                   8398:  *                                                                     *
                   8399:  ************************************************************************/
                   8400: 
                   8401: /*
                   8402:  * xmlGetNamespace:
                   8403:  * @ctxt:  an XML parser context
                   8404:  * @prefix:  the prefix to lookup
                   8405:  *
                   8406:  * Lookup the namespace name for the @prefix (which ca be NULL)
                   8407:  * The prefix must come from the @ctxt->dict dictionnary
                   8408:  *
                   8409:  * Returns the namespace name or NULL if not bound
                   8410:  */
                   8411: static const xmlChar *
                   8412: xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
                   8413:     int i;
                   8414: 
                   8415:     if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
                   8416:     for (i = ctxt->nsNr - 2;i >= 0;i-=2)
                   8417:         if (ctxt->nsTab[i] == prefix) {
                   8418:            if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
                   8419:                return(NULL);
                   8420:            return(ctxt->nsTab[i + 1]);
                   8421:        }
                   8422:     return(NULL);
                   8423: }
                   8424: 
                   8425: /**
                   8426:  * xmlParseQName:
                   8427:  * @ctxt:  an XML parser context
                   8428:  * @prefix:  pointer to store the prefix part
                   8429:  *
                   8430:  * parse an XML Namespace QName
                   8431:  *
                   8432:  * [6]  QName  ::= (Prefix ':')? LocalPart
                   8433:  * [7]  Prefix  ::= NCName
                   8434:  * [8]  LocalPart  ::= NCName
                   8435:  *
                   8436:  * Returns the Name parsed or NULL
                   8437:  */
                   8438: 
                   8439: static const xmlChar *
                   8440: xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
                   8441:     const xmlChar *l, *p;
                   8442: 
                   8443:     GROW;
                   8444: 
                   8445:     l = xmlParseNCName(ctxt);
                   8446:     if (l == NULL) {
                   8447:         if (CUR == ':') {
                   8448:            l = xmlParseName(ctxt);
                   8449:            if (l != NULL) {
                   8450:                xmlNsErr(ctxt, XML_NS_ERR_QNAME, 
                   8451:                         "Failed to parse QName '%s'\n", l, NULL, NULL);
                   8452:                *prefix = NULL;
                   8453:                return(l);
                   8454:            }
                   8455:        }
                   8456:         return(NULL);
                   8457:     }
                   8458:     if (CUR == ':') {
                   8459:         NEXT;
                   8460:        p = l;
                   8461:        l = xmlParseNCName(ctxt);
                   8462:        if (l == NULL) {
                   8463:            xmlChar *tmp;
                   8464: 
                   8465:             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
                   8466:                     "Failed to parse QName '%s:'\n", p, NULL, NULL);
                   8467:            l = xmlParseNmtoken(ctxt);
                   8468:            if (l == NULL)
                   8469:                tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
                   8470:            else {
                   8471:                tmp = xmlBuildQName(l, p, NULL, 0);
                   8472:                xmlFree((char *)l);
                   8473:            }
                   8474:            p = xmlDictLookup(ctxt->dict, tmp, -1);
                   8475:            if (tmp != NULL) xmlFree(tmp);
                   8476:            *prefix = NULL;
                   8477:            return(p);
                   8478:        }
                   8479:        if (CUR == ':') {
                   8480:            xmlChar *tmp;
                   8481: 
                   8482:             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
                   8483:                     "Failed to parse QName '%s:%s:'\n", p, l, NULL);
                   8484:            NEXT;
                   8485:            tmp = (xmlChar *) xmlParseName(ctxt);
                   8486:            if (tmp != NULL) {
                   8487:                tmp = xmlBuildQName(tmp, l, NULL, 0);
                   8488:                l = xmlDictLookup(ctxt->dict, tmp, -1);
                   8489:                if (tmp != NULL) xmlFree(tmp);
                   8490:                *prefix = p;
                   8491:                return(l);
                   8492:            }
                   8493:            tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
                   8494:            l = xmlDictLookup(ctxt->dict, tmp, -1);
                   8495:            if (tmp != NULL) xmlFree(tmp);
                   8496:            *prefix = p;
                   8497:            return(l);
                   8498:        }
                   8499:        *prefix = p;
                   8500:     } else
                   8501:         *prefix = NULL;
                   8502:     return(l);
                   8503: }
                   8504: 
                   8505: /**
                   8506:  * xmlParseQNameAndCompare:
                   8507:  * @ctxt:  an XML parser context
                   8508:  * @name:  the localname
                   8509:  * @prefix:  the prefix, if any.
                   8510:  *
                   8511:  * parse an XML name and compares for match
                   8512:  * (specialized for endtag parsing)
                   8513:  *
                   8514:  * Returns NULL for an illegal name, (xmlChar*) 1 for success
                   8515:  * and the name for mismatch
                   8516:  */
                   8517: 
                   8518: static const xmlChar *
                   8519: xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
                   8520:                         xmlChar const *prefix) {
                   8521:     const xmlChar *cmp;
                   8522:     const xmlChar *in;
                   8523:     const xmlChar *ret;
                   8524:     const xmlChar *prefix2;
                   8525: 
                   8526:     if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
                   8527: 
                   8528:     GROW;
                   8529:     in = ctxt->input->cur;
                   8530: 
                   8531:     cmp = prefix;
                   8532:     while (*in != 0 && *in == *cmp) {
                   8533:        ++in;
                   8534:        ++cmp;
                   8535:     }
                   8536:     if ((*cmp == 0) && (*in == ':')) {
                   8537:         in++;
                   8538:        cmp = name;
                   8539:        while (*in != 0 && *in == *cmp) {
                   8540:            ++in;
                   8541:            ++cmp;
                   8542:        }
                   8543:        if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
                   8544:            /* success */
                   8545:            ctxt->input->cur = in;
                   8546:            return((const xmlChar*) 1);
                   8547:        }
                   8548:     }
                   8549:     /*
                   8550:      * all strings coms from the dictionary, equality can be done directly
                   8551:      */
                   8552:     ret = xmlParseQName (ctxt, &prefix2);
                   8553:     if ((ret == name) && (prefix == prefix2))
                   8554:        return((const xmlChar*) 1);
                   8555:     return ret;
                   8556: }
                   8557: 
                   8558: /**
                   8559:  * xmlParseAttValueInternal:
                   8560:  * @ctxt:  an XML parser context
                   8561:  * @len:  attribute len result
                   8562:  * @alloc:  whether the attribute was reallocated as a new string
                   8563:  * @normalize:  if 1 then further non-CDATA normalization must be done
                   8564:  *
                   8565:  * parse a value for an attribute.
                   8566:  * NOTE: if no normalization is needed, the routine will return pointers
                   8567:  *       directly from the data buffer.
                   8568:  *
                   8569:  * 3.3.3 Attribute-Value Normalization:
                   8570:  * Before the value of an attribute is passed to the application or
                   8571:  * checked for validity, the XML processor must normalize it as follows: 
                   8572:  * - a character reference is processed by appending the referenced
                   8573:  *   character to the attribute value
                   8574:  * - an entity reference is processed by recursively processing the
                   8575:  *   replacement text of the entity 
                   8576:  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
                   8577:  *   appending #x20 to the normalized value, except that only a single
                   8578:  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
                   8579:  *   parsed entity or the literal entity value of an internal parsed entity 
                   8580:  * - other characters are processed by appending them to the normalized value 
                   8581:  * If the declared value is not CDATA, then the XML processor must further
                   8582:  * process the normalized attribute value by discarding any leading and
                   8583:  * trailing space (#x20) characters, and by replacing sequences of space
                   8584:  * (#x20) characters by a single space (#x20) character.  
                   8585:  * All attributes for which no declaration has been read should be treated
                   8586:  * by a non-validating parser as if declared CDATA.
                   8587:  *
                   8588:  * Returns the AttValue parsed or NULL. The value has to be freed by the
                   8589:  *     caller if it was copied, this can be detected by val[*len] == 0.
                   8590:  */
                   8591: 
                   8592: static xmlChar *
                   8593: xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
                   8594:                          int normalize)
                   8595: {
                   8596:     xmlChar limit = 0;
                   8597:     const xmlChar *in = NULL, *start, *end, *last;
                   8598:     xmlChar *ret = NULL;
                   8599: 
                   8600:     GROW;
                   8601:     in = (xmlChar *) CUR_PTR;
                   8602:     if (*in != '"' && *in != '\'') {
                   8603:         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
                   8604:         return (NULL);
                   8605:     }
                   8606:     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
                   8607: 
                   8608:     /*
                   8609:      * try to handle in this routine the most common case where no
                   8610:      * allocation of a new string is required and where content is
                   8611:      * pure ASCII.
                   8612:      */
                   8613:     limit = *in++;
                   8614:     end = ctxt->input->end;
                   8615:     start = in;
                   8616:     if (in >= end) {
                   8617:         const xmlChar *oldbase = ctxt->input->base;
                   8618:        GROW;
                   8619:        if (oldbase != ctxt->input->base) {
                   8620:            long delta = ctxt->input->base - oldbase;
                   8621:            start = start + delta;
                   8622:            in = in + delta;
                   8623:        }
                   8624:        end = ctxt->input->end;
                   8625:     }
                   8626:     if (normalize) {
                   8627:         /*
                   8628:         * Skip any leading spaces
                   8629:         */
                   8630:        while ((in < end) && (*in != limit) && 
                   8631:               ((*in == 0x20) || (*in == 0x9) ||
                   8632:                (*in == 0xA) || (*in == 0xD))) {
                   8633:            in++;
                   8634:            start = in;
                   8635:            if (in >= end) {
                   8636:                const xmlChar *oldbase = ctxt->input->base;
                   8637:                GROW;
                   8638:                if (oldbase != ctxt->input->base) {
                   8639:                    long delta = ctxt->input->base - oldbase;
                   8640:                    start = start + delta;
                   8641:                    in = in + delta;
                   8642:                }
                   8643:                end = ctxt->input->end;
                   8644:            }
                   8645:        }
                   8646:        while ((in < end) && (*in != limit) && (*in >= 0x20) &&
                   8647:               (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
                   8648:            if ((*in++ == 0x20) && (*in == 0x20)) break;
                   8649:            if (in >= end) {
                   8650:                const xmlChar *oldbase = ctxt->input->base;
                   8651:                GROW;
                   8652:                if (oldbase != ctxt->input->base) {
                   8653:                    long delta = ctxt->input->base - oldbase;
                   8654:                    start = start + delta;
                   8655:                    in = in + delta;
                   8656:                }
                   8657:                end = ctxt->input->end;
                   8658:            }
                   8659:        }
                   8660:        last = in;
                   8661:        /*
                   8662:         * skip the trailing blanks
                   8663:         */
                   8664:        while ((last[-1] == 0x20) && (last > start)) last--;
                   8665:        while ((in < end) && (*in != limit) && 
                   8666:               ((*in == 0x20) || (*in == 0x9) ||
                   8667:                (*in == 0xA) || (*in == 0xD))) {
                   8668:            in++;
                   8669:            if (in >= end) {
                   8670:                const xmlChar *oldbase = ctxt->input->base;
                   8671:                GROW;
                   8672:                if (oldbase != ctxt->input->base) {
                   8673:                    long delta = ctxt->input->base - oldbase;
                   8674:                    start = start + delta;
                   8675:                    in = in + delta;
                   8676:                    last = last + delta;
                   8677:                }
                   8678:                end = ctxt->input->end;
                   8679:            }
                   8680:        }
                   8681:        if (*in != limit) goto need_complex;
                   8682:     } else {
                   8683:        while ((in < end) && (*in != limit) && (*in >= 0x20) &&
                   8684:               (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
                   8685:            in++;
                   8686:            if (in >= end) {
                   8687:                const xmlChar *oldbase = ctxt->input->base;
                   8688:                GROW;
                   8689:                if (oldbase != ctxt->input->base) {
                   8690:                    long delta = ctxt->input->base - oldbase;
                   8691:                    start = start + delta;
                   8692:                    in = in + delta;
                   8693:                }
                   8694:                end = ctxt->input->end;
                   8695:            }
                   8696:        }
                   8697:        last = in;
                   8698:        if (*in != limit) goto need_complex;
                   8699:     }
                   8700:     in++;
                   8701:     if (len != NULL) {
                   8702:         *len = last - start;
                   8703:         ret = (xmlChar *) start;
                   8704:     } else {
                   8705:         if (alloc) *alloc = 1;
                   8706:         ret = xmlStrndup(start, last - start);
                   8707:     }
                   8708:     CUR_PTR = in;
                   8709:     if (alloc) *alloc = 0;
                   8710:     return ret;
                   8711: need_complex:
                   8712:     if (alloc) *alloc = 1;
                   8713:     return xmlParseAttValueComplex(ctxt, len, normalize);
                   8714: }
                   8715: 
                   8716: /**
                   8717:  * xmlParseAttribute2:
                   8718:  * @ctxt:  an XML parser context
                   8719:  * @pref:  the element prefix
                   8720:  * @elem:  the element name
                   8721:  * @prefix:  a xmlChar ** used to store the value of the attribute prefix
                   8722:  * @value:  a xmlChar ** used to store the value of the attribute
                   8723:  * @len:  an int * to save the length of the attribute
                   8724:  * @alloc:  an int * to indicate if the attribute was allocated
                   8725:  *
                   8726:  * parse an attribute in the new SAX2 framework.
                   8727:  *
                   8728:  * Returns the attribute name, and the value in *value, .
                   8729:  */
                   8730: 
                   8731: static const xmlChar *
                   8732: xmlParseAttribute2(xmlParserCtxtPtr ctxt,
                   8733:                    const xmlChar * pref, const xmlChar * elem,
                   8734:                    const xmlChar ** prefix, xmlChar ** value,
                   8735:                    int *len, int *alloc)
                   8736: {
                   8737:     const xmlChar *name;
                   8738:     xmlChar *val, *internal_val = NULL;
                   8739:     int normalize = 0;
                   8740: 
                   8741:     *value = NULL;
                   8742:     GROW;
                   8743:     name = xmlParseQName(ctxt, prefix);
                   8744:     if (name == NULL) {
                   8745:         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   8746:                        "error parsing attribute name\n");
                   8747:         return (NULL);
                   8748:     }
                   8749: 
                   8750:     /*
                   8751:      * get the type if needed
                   8752:      */
                   8753:     if (ctxt->attsSpecial != NULL) {
                   8754:         int type;
                   8755: 
                   8756:         type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
                   8757:                                             pref, elem, *prefix, name);
                   8758:         if (type != 0)
                   8759:             normalize = 1;
                   8760:     }
                   8761: 
                   8762:     /*
                   8763:      * read the value
                   8764:      */
                   8765:     SKIP_BLANKS;
                   8766:     if (RAW == '=') {
                   8767:         NEXT;
                   8768:         SKIP_BLANKS;
                   8769:         val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
                   8770:        if (normalize) {
                   8771:            /*
                   8772:             * Sometimes a second normalisation pass for spaces is needed
                   8773:             * but that only happens if charrefs or entities refernces
                   8774:             * have been used in the attribute value, i.e. the attribute
                   8775:             * value have been extracted in an allocated string already.
                   8776:             */
                   8777:            if (*alloc) {
                   8778:                const xmlChar *val2;
                   8779: 
                   8780:                val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
                   8781:                if ((val2 != NULL) && (val2 != val)) {
                   8782:                    xmlFree(val);
                   8783:                    val = (xmlChar *) val2;
                   8784:                }
                   8785:            }
                   8786:        }
                   8787:         ctxt->instate = XML_PARSER_CONTENT;
                   8788:     } else {
                   8789:         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
                   8790:                           "Specification mandate value for attribute %s\n",
                   8791:                           name);
                   8792:         return (NULL);
                   8793:     }
                   8794: 
                   8795:     if (*prefix == ctxt->str_xml) {
                   8796:         /*
                   8797:          * Check that xml:lang conforms to the specification
                   8798:          * No more registered as an error, just generate a warning now
                   8799:          * since this was deprecated in XML second edition
                   8800:          */
                   8801:         if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
                   8802:             internal_val = xmlStrndup(val, *len);
                   8803:             if (!xmlCheckLanguageID(internal_val)) {
                   8804:                 xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
                   8805:                               "Malformed value for xml:lang : %s\n",
                   8806:                               internal_val, NULL);
                   8807:             }
                   8808:         }
                   8809: 
                   8810:         /*
                   8811:          * Check that xml:space conforms to the specification
                   8812:          */
                   8813:         if (xmlStrEqual(name, BAD_CAST "space")) {
                   8814:             internal_val = xmlStrndup(val, *len);
                   8815:             if (xmlStrEqual(internal_val, BAD_CAST "default"))
                   8816:                 *(ctxt->space) = 0;
                   8817:             else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
                   8818:                 *(ctxt->space) = 1;
                   8819:             else {
                   8820:                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
                   8821:                               "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
                   8822:                               internal_val, NULL);
                   8823:             }
                   8824:         }
                   8825:         if (internal_val) {
                   8826:             xmlFree(internal_val);
                   8827:         }
                   8828:     }
                   8829: 
                   8830:     *value = val;
                   8831:     return (name);
                   8832: }
                   8833: /**
                   8834:  * xmlParseStartTag2:
                   8835:  * @ctxt:  an XML parser context
                   8836:  * 
                   8837:  * parse a start of tag either for rule element or
                   8838:  * EmptyElement. In both case we don't parse the tag closing chars.
                   8839:  * This routine is called when running SAX2 parsing
                   8840:  *
                   8841:  * [40] STag ::= '<' Name (S Attribute)* S? '>'
                   8842:  *
                   8843:  * [ WFC: Unique Att Spec ]
                   8844:  * No attribute name may appear more than once in the same start-tag or
                   8845:  * empty-element tag. 
                   8846:  *
                   8847:  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
                   8848:  *
                   8849:  * [ WFC: Unique Att Spec ]
                   8850:  * No attribute name may appear more than once in the same start-tag or
                   8851:  * empty-element tag. 
                   8852:  *
                   8853:  * With namespace:
                   8854:  *
                   8855:  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
                   8856:  *
                   8857:  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
                   8858:  *
                   8859:  * Returns the element name parsed
                   8860:  */
                   8861: 
                   8862: static const xmlChar *
                   8863: xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
                   8864:                   const xmlChar **URI, int *tlen) {
                   8865:     const xmlChar *localname;
                   8866:     const xmlChar *prefix;
                   8867:     const xmlChar *attname;
                   8868:     const xmlChar *aprefix;
                   8869:     const xmlChar *nsname;
                   8870:     xmlChar *attvalue;
                   8871:     const xmlChar **atts = ctxt->atts;
                   8872:     int maxatts = ctxt->maxatts;
                   8873:     int nratts, nbatts, nbdef;
                   8874:     int i, j, nbNs, attval, oldline, oldcol;
                   8875:     const xmlChar *base;
                   8876:     unsigned long cur;
                   8877:     int nsNr = ctxt->nsNr;
                   8878: 
                   8879:     if (RAW != '<') return(NULL);
                   8880:     NEXT1;
                   8881: 
                   8882:     /*
                   8883:      * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
                   8884:      *       point since the attribute values may be stored as pointers to
                   8885:      *       the buffer and calling SHRINK would destroy them !
                   8886:      *       The Shrinking is only possible once the full set of attribute
                   8887:      *       callbacks have been done.
                   8888:      */
                   8889: reparse:
                   8890:     SHRINK;
                   8891:     base = ctxt->input->base;
                   8892:     cur = ctxt->input->cur - ctxt->input->base;
                   8893:     oldline = ctxt->input->line;
                   8894:     oldcol = ctxt->input->col;
                   8895:     nbatts = 0;
                   8896:     nratts = 0;
                   8897:     nbdef = 0;
                   8898:     nbNs = 0;
                   8899:     attval = 0;
                   8900:     /* Forget any namespaces added during an earlier parse of this element. */
                   8901:     ctxt->nsNr = nsNr;
                   8902: 
                   8903:     localname = xmlParseQName(ctxt, &prefix);
                   8904:     if (localname == NULL) {
                   8905:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   8906:                       "StartTag: invalid element name\n");
                   8907:         return(NULL);
                   8908:     }
                   8909:     *tlen = ctxt->input->cur - ctxt->input->base - cur;
                   8910: 
                   8911:     /*
                   8912:      * Now parse the attributes, it ends up with the ending
                   8913:      *
                   8914:      * (S Attribute)* S?
                   8915:      */
                   8916:     SKIP_BLANKS;
                   8917:     GROW;
                   8918:     if (ctxt->input->base != base) goto base_changed;
                   8919: 
                   8920:     while ((RAW != '>') && 
                   8921:           ((RAW != '/') || (NXT(1) != '>')) &&
                   8922:           (IS_BYTE_CHAR(RAW))) {
                   8923:        const xmlChar *q = CUR_PTR;
                   8924:        unsigned int cons = ctxt->input->consumed;
                   8925:        int len = -1, alloc = 0;
                   8926: 
                   8927:        attname = xmlParseAttribute2(ctxt, prefix, localname,
                   8928:                                     &aprefix, &attvalue, &len, &alloc);
                   8929:        if (ctxt->input->base != base) {
                   8930:            if ((attvalue != NULL) && (alloc != 0))
                   8931:                xmlFree(attvalue);
                   8932:            attvalue = NULL;
                   8933:            goto base_changed;
                   8934:        }
                   8935:         if ((attname != NULL) && (attvalue != NULL)) {
                   8936:            if (len < 0) len = xmlStrlen(attvalue);
                   8937:             if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
                   8938:                const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
                   8939:                xmlURIPtr uri;
                   8940: 
                   8941:                 if (*URL != 0) {
                   8942:                    uri = xmlParseURI((const char *) URL);
                   8943:                    if (uri == NULL) {
                   8944:                        xmlNsErr(ctxt, XML_WAR_NS_URI,
                   8945:                                 "xmlns: '%s' is not a valid URI\n",
                   8946:                                           URL, NULL, NULL);
                   8947:                    } else {
                   8948:                        if (uri->scheme == NULL) {
                   8949:                            xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
                   8950:                                      "xmlns: URI %s is not absolute\n",
                   8951:                                      URL, NULL, NULL);
                   8952:                        }
                   8953:                        xmlFreeURI(uri);
                   8954:                    }
                   8955:                    if (URL == ctxt->str_xml_ns) {
                   8956:                        if (attname != ctxt->str_xml) {
                   8957:                            xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   8958:                         "xml namespace URI cannot be the default namespace\n",
                   8959:                                     NULL, NULL, NULL);
                   8960:                        }
                   8961:                        goto skip_default_ns;
                   8962:                    }
                   8963:                    if ((len == 29) &&
                   8964:                        (xmlStrEqual(URL,
                   8965:                                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
                   8966:                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   8967:                             "reuse of the xmlns namespace name is forbidden\n",
                   8968:                                 NULL, NULL, NULL);
                   8969:                        goto skip_default_ns;
                   8970:                    }
                   8971:                }
                   8972:                /*
                   8973:                 * check that it's not a defined namespace
                   8974:                 */
                   8975:                for (j = 1;j <= nbNs;j++)
                   8976:                    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
                   8977:                        break;
                   8978:                if (j <= nbNs)
                   8979:                    xmlErrAttributeDup(ctxt, NULL, attname);
                   8980:                else
                   8981:                    if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
                   8982: skip_default_ns:
                   8983:                if (alloc != 0) xmlFree(attvalue);
                   8984:                SKIP_BLANKS;
                   8985:                continue;
                   8986:            }
                   8987:             if (aprefix == ctxt->str_xmlns) {
                   8988:                const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
                   8989:                xmlURIPtr uri;
                   8990: 
                   8991:                 if (attname == ctxt->str_xml) {
                   8992:                    if (URL != ctxt->str_xml_ns) {
                   8993:                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   8994:                                 "xml namespace prefix mapped to wrong URI\n",
                   8995:                                 NULL, NULL, NULL);
                   8996:                    }
                   8997:                    /*
                   8998:                     * Do not keep a namespace definition node
                   8999:                     */
                   9000:                    goto skip_ns;
                   9001:                }
                   9002:                 if (URL == ctxt->str_xml_ns) {
                   9003:                    if (attname != ctxt->str_xml) {
                   9004:                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   9005:                                 "xml namespace URI mapped to wrong prefix\n",
                   9006:                                 NULL, NULL, NULL);
                   9007:                    }
                   9008:                    goto skip_ns;
                   9009:                }
                   9010:                 if (attname == ctxt->str_xmlns) {
                   9011:                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   9012:                             "redefinition of the xmlns prefix is forbidden\n",
                   9013:                             NULL, NULL, NULL);
                   9014:                    goto skip_ns;
                   9015:                }
                   9016:                if ((len == 29) &&
                   9017:                    (xmlStrEqual(URL,
                   9018:                                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
                   9019:                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   9020:                             "reuse of the xmlns namespace name is forbidden\n",
                   9021:                             NULL, NULL, NULL);
                   9022:                    goto skip_ns;
                   9023:                }
                   9024:                if ((URL == NULL) || (URL[0] == 0)) {
                   9025:                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   9026:                             "xmlns:%s: Empty XML namespace is not allowed\n",
                   9027:                                  attname, NULL, NULL);
                   9028:                    goto skip_ns;
                   9029:                } else {
                   9030:                    uri = xmlParseURI((const char *) URL);
                   9031:                    if (uri == NULL) {
                   9032:                        xmlNsErr(ctxt, XML_WAR_NS_URI,
                   9033:                             "xmlns:%s: '%s' is not a valid URI\n",
                   9034:                                           attname, URL, NULL);
                   9035:                    } else {
                   9036:                        if ((ctxt->pedantic) && (uri->scheme == NULL)) {
                   9037:                            xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
                   9038:                                      "xmlns:%s: URI %s is not absolute\n",
                   9039:                                      attname, URL, NULL);
                   9040:                        }
                   9041:                        xmlFreeURI(uri);
                   9042:                    }
                   9043:                }
                   9044: 
                   9045:                /*
                   9046:                 * check that it's not a defined namespace
                   9047:                 */
                   9048:                for (j = 1;j <= nbNs;j++)
                   9049:                    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
                   9050:                        break;
                   9051:                if (j <= nbNs)
                   9052:                    xmlErrAttributeDup(ctxt, aprefix, attname);
                   9053:                else
                   9054:                    if (nsPush(ctxt, attname, URL) > 0) nbNs++;
                   9055: skip_ns:
                   9056:                if (alloc != 0) xmlFree(attvalue);
                   9057:                SKIP_BLANKS;
                   9058:                if (ctxt->input->base != base) goto base_changed;
                   9059:                continue;
                   9060:            }
                   9061: 
                   9062:            /*
                   9063:             * Add the pair to atts
                   9064:             */
                   9065:            if ((atts == NULL) || (nbatts + 5 > maxatts)) {
                   9066:                if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
                   9067:                    if (attvalue[len] == 0)
                   9068:                        xmlFree(attvalue);
                   9069:                    goto failed;
                   9070:                }
                   9071:                maxatts = ctxt->maxatts;
                   9072:                atts = ctxt->atts;
                   9073:            }
                   9074:            ctxt->attallocs[nratts++] = alloc;
                   9075:            atts[nbatts++] = attname;
                   9076:            atts[nbatts++] = aprefix;
                   9077:            atts[nbatts++] = NULL; /* the URI will be fetched later */
                   9078:            atts[nbatts++] = attvalue;
                   9079:            attvalue += len;
                   9080:            atts[nbatts++] = attvalue;
                   9081:            /*
                   9082:             * tag if some deallocation is needed
                   9083:             */
                   9084:            if (alloc != 0) attval = 1;
                   9085:        } else {
                   9086:            if ((attvalue != NULL) && (attvalue[len] == 0))
                   9087:                xmlFree(attvalue);
                   9088:        }
                   9089: 
                   9090: failed:
                   9091: 
                   9092:        GROW
                   9093:        if (ctxt->input->base != base) goto base_changed;
                   9094:        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
                   9095:            break;
                   9096:        if (!IS_BLANK_CH(RAW)) {
                   9097:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   9098:                           "attributes construct error\n");
                   9099:            break;
                   9100:        }
                   9101:        SKIP_BLANKS;
                   9102:         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
                   9103:             (attname == NULL) && (attvalue == NULL)) {
                   9104:            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   9105:                 "xmlParseStartTag: problem parsing attributes\n");
                   9106:            break;
                   9107:        }
                   9108:         GROW;
                   9109:        if (ctxt->input->base != base) goto base_changed;
                   9110:     }
                   9111: 
                   9112:     /*
                   9113:      * The attributes defaulting
                   9114:      */
                   9115:     if (ctxt->attsDefault != NULL) {
                   9116:         xmlDefAttrsPtr defaults;
                   9117: 
                   9118:        defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
                   9119:        if (defaults != NULL) {
                   9120:            for (i = 0;i < defaults->nbAttrs;i++) {
                   9121:                attname = defaults->values[5 * i];
                   9122:                aprefix = defaults->values[5 * i + 1];
                   9123: 
                   9124:                 /*
                   9125:                 * special work for namespaces defaulted defs
                   9126:                 */
                   9127:                if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
                   9128:                    /*
                   9129:                     * check that it's not a defined namespace
                   9130:                     */
                   9131:                    for (j = 1;j <= nbNs;j++)
                   9132:                        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
                   9133:                            break;
                   9134:                    if (j <= nbNs) continue;
                   9135: 
                   9136:                    nsname = xmlGetNamespace(ctxt, NULL);
                   9137:                    if (nsname != defaults->values[5 * i + 2]) {
                   9138:                        if (nsPush(ctxt, NULL,
                   9139:                                   defaults->values[5 * i + 2]) > 0)
                   9140:                            nbNs++;
                   9141:                    }
                   9142:                } else if (aprefix == ctxt->str_xmlns) {
                   9143:                    /*
                   9144:                     * check that it's not a defined namespace
                   9145:                     */
                   9146:                    for (j = 1;j <= nbNs;j++)
                   9147:                        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
                   9148:                            break;
                   9149:                    if (j <= nbNs) continue;
                   9150: 
                   9151:                    nsname = xmlGetNamespace(ctxt, attname);
                   9152:                    if (nsname != defaults->values[2]) {
                   9153:                        if (nsPush(ctxt, attname,
                   9154:                                   defaults->values[5 * i + 2]) > 0)
                   9155:                            nbNs++;
                   9156:                    }
                   9157:                } else {
                   9158:                    /*
                   9159:                     * check that it's not a defined attribute
                   9160:                     */
                   9161:                    for (j = 0;j < nbatts;j+=5) {
                   9162:                        if ((attname == atts[j]) && (aprefix == atts[j+1]))
                   9163:                            break;
                   9164:                    }
                   9165:                    if (j < nbatts) continue;
                   9166: 
                   9167:                    if ((atts == NULL) || (nbatts + 5 > maxatts)) {
                   9168:                        if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
                   9169:                            return(NULL);
                   9170:                        }
                   9171:                        maxatts = ctxt->maxatts;
                   9172:                        atts = ctxt->atts;
                   9173:                    }
                   9174:                    atts[nbatts++] = attname;
                   9175:                    atts[nbatts++] = aprefix;
                   9176:                    if (aprefix == NULL)
                   9177:                        atts[nbatts++] = NULL;
                   9178:                    else
                   9179:                        atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
                   9180:                    atts[nbatts++] = defaults->values[5 * i + 2];
                   9181:                    atts[nbatts++] = defaults->values[5 * i + 3];
                   9182:                    if ((ctxt->standalone == 1) &&
                   9183:                        (defaults->values[5 * i + 4] != NULL)) {
                   9184:                        xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED, 
                   9185:          "standalone: attribute %s on %s defaulted from external subset\n",
                   9186:                                         attname, localname);
                   9187:                    }
                   9188:                    nbdef++;
                   9189:                }
                   9190:            }
                   9191:        }
                   9192:     }
                   9193: 
                   9194:     /*
                   9195:      * The attributes checkings
                   9196:      */
                   9197:     for (i = 0; i < nbatts;i += 5) {
                   9198:         /*
                   9199:        * The default namespace does not apply to attribute names.
                   9200:        */
                   9201:        if (atts[i + 1] != NULL) {
                   9202:            nsname = xmlGetNamespace(ctxt, atts[i + 1]);
                   9203:            if (nsname == NULL) {
                   9204:                xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
                   9205:                    "Namespace prefix %s for %s on %s is not defined\n",
                   9206:                    atts[i + 1], atts[i], localname);
                   9207:            }
                   9208:            atts[i + 2] = nsname;
                   9209:        } else
                   9210:            nsname = NULL;
                   9211:        /*
                   9212:         * [ WFC: Unique Att Spec ]
                   9213:         * No attribute name may appear more than once in the same
                   9214:         * start-tag or empty-element tag. 
                   9215:         * As extended by the Namespace in XML REC.
                   9216:         */
                   9217:         for (j = 0; j < i;j += 5) {
                   9218:            if (atts[i] == atts[j]) {
                   9219:                if (atts[i+1] == atts[j+1]) {
                   9220:                    xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
                   9221:                    break;
                   9222:                }
                   9223:                if ((nsname != NULL) && (atts[j + 2] == nsname)) {
                   9224:                    xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
                   9225:                             "Namespaced Attribute %s in '%s' redefined\n",
                   9226:                             atts[i], nsname, NULL);
                   9227:                    break;
                   9228:                }
                   9229:            }
                   9230:        }
                   9231:     }
                   9232: 
                   9233:     nsname = xmlGetNamespace(ctxt, prefix);
                   9234:     if ((prefix != NULL) && (nsname == NULL)) {
                   9235:        xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
                   9236:                 "Namespace prefix %s on %s is not defined\n",
                   9237:                 prefix, localname, NULL);
                   9238:     }
                   9239:     *pref = prefix;
                   9240:     *URI = nsname;
                   9241: 
                   9242:     /*
                   9243:      * SAX: Start of Element !
                   9244:      */
                   9245:     if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
                   9246:        (!ctxt->disableSAX)) {
                   9247:        if (nbNs > 0)
                   9248:            ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
                   9249:                          nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
                   9250:                          nbatts / 5, nbdef, atts);
                   9251:        else
                   9252:            ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
                   9253:                          nsname, 0, NULL, nbatts / 5, nbdef, atts);
                   9254:     }
                   9255: 
                   9256:     /*
                   9257:      * Free up attribute allocated strings if needed
                   9258:      */
                   9259:     if (attval != 0) {
                   9260:        for (i = 3,j = 0; j < nratts;i += 5,j++)
                   9261:            if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
                   9262:                xmlFree((xmlChar *) atts[i]);
                   9263:     }
                   9264: 
                   9265:     return(localname);
                   9266: 
                   9267: base_changed:
                   9268:     /*
                   9269:      * the attribute strings are valid iif the base didn't changed
                   9270:      */
                   9271:     if (attval != 0) {
                   9272:        for (i = 3,j = 0; j < nratts;i += 5,j++)
                   9273:            if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
                   9274:                xmlFree((xmlChar *) atts[i]);
                   9275:     }
                   9276:     ctxt->input->cur = ctxt->input->base + cur;
                   9277:     ctxt->input->line = oldline;
                   9278:     ctxt->input->col = oldcol;
                   9279:     if (ctxt->wellFormed == 1) {
                   9280:        goto reparse;
                   9281:     }
                   9282:     return(NULL);
                   9283: }
                   9284: 
                   9285: /**
                   9286:  * xmlParseEndTag2:
                   9287:  * @ctxt:  an XML parser context
                   9288:  * @line:  line of the start tag
                   9289:  * @nsNr:  number of namespaces on the start tag
                   9290:  *
                   9291:  * parse an end of tag
                   9292:  *
                   9293:  * [42] ETag ::= '</' Name S? '>'
                   9294:  *
                   9295:  * With namespace
                   9296:  *
                   9297:  * [NS 9] ETag ::= '</' QName S? '>'
                   9298:  */
                   9299: 
                   9300: static void
                   9301: xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
                   9302:                 const xmlChar *URI, int line, int nsNr, int tlen) {
                   9303:     const xmlChar *name;
                   9304: 
                   9305:     GROW;
                   9306:     if ((RAW != '<') || (NXT(1) != '/')) {
                   9307:        xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
                   9308:        return;
                   9309:     }
                   9310:     SKIP(2);
                   9311: 
                   9312:     if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
                   9313:         if (ctxt->input->cur[tlen] == '>') {
                   9314:            ctxt->input->cur += tlen + 1;
                   9315:            goto done;
                   9316:        }
                   9317:        ctxt->input->cur += tlen;
                   9318:        name = (xmlChar*)1;
                   9319:     } else {
                   9320:        if (prefix == NULL)
                   9321:            name = xmlParseNameAndCompare(ctxt, ctxt->name);
                   9322:        else
                   9323:            name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
                   9324:     }
                   9325: 
                   9326:     /*
                   9327:      * We should definitely be at the ending "S? '>'" part
                   9328:      */
                   9329:     GROW;
                   9330:     SKIP_BLANKS;
                   9331:     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
                   9332:        xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
                   9333:     } else
                   9334:        NEXT1;
                   9335: 
                   9336:     /*
                   9337:      * [ WFC: Element Type Match ]
                   9338:      * The Name in an element's end-tag must match the element type in the
                   9339:      * start-tag. 
                   9340:      *
                   9341:      */
                   9342:     if (name != (xmlChar*)1) {
                   9343:         if (name == NULL) name = BAD_CAST "unparseable";
                   9344:         if ((line == 0) && (ctxt->node != NULL))
                   9345:             line = ctxt->node->line;
                   9346:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
                   9347:                     "Opening and ending tag mismatch: %s line %d and %s\n",
                   9348:                                ctxt->name, line, name);
                   9349:     }
                   9350: 
                   9351:     /*
                   9352:      * SAX: End of Tag
                   9353:      */
                   9354: done:
                   9355:     if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
                   9356:        (!ctxt->disableSAX))
                   9357:        ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
                   9358: 
                   9359:     spacePop(ctxt);
                   9360:     if (nsNr != 0)
                   9361:        nsPop(ctxt, nsNr);
                   9362:     return;
                   9363: }
                   9364: 
                   9365: /**
                   9366:  * xmlParseCDSect:
                   9367:  * @ctxt:  an XML parser context
                   9368:  * 
                   9369:  * Parse escaped pure raw content.
                   9370:  *
                   9371:  * [18] CDSect ::= CDStart CData CDEnd
                   9372:  *
                   9373:  * [19] CDStart ::= '<![CDATA['
                   9374:  *
                   9375:  * [20] Data ::= (Char* - (Char* ']]>' Char*))
                   9376:  *
                   9377:  * [21] CDEnd ::= ']]>'
                   9378:  */
                   9379: void
                   9380: xmlParseCDSect(xmlParserCtxtPtr ctxt) {
                   9381:     xmlChar *buf = NULL;
                   9382:     int len = 0;
                   9383:     int size = XML_PARSER_BUFFER_SIZE;
                   9384:     int r, rl;
                   9385:     int        s, sl;
                   9386:     int cur, l;
                   9387:     int count = 0;
                   9388: 
                   9389:     /* Check 2.6.0 was NXT(0) not RAW */
                   9390:     if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
                   9391:        SKIP(9);
                   9392:     } else
                   9393:         return;
                   9394: 
                   9395:     ctxt->instate = XML_PARSER_CDATA_SECTION;
                   9396:     r = CUR_CHAR(rl);
                   9397:     if (!IS_CHAR(r)) {
                   9398:        xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
                   9399:        ctxt->instate = XML_PARSER_CONTENT;
                   9400:         return;
                   9401:     }
                   9402:     NEXTL(rl);
                   9403:     s = CUR_CHAR(sl);
                   9404:     if (!IS_CHAR(s)) {
                   9405:        xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
                   9406:        ctxt->instate = XML_PARSER_CONTENT;
                   9407:         return;
                   9408:     }
                   9409:     NEXTL(sl);
                   9410:     cur = CUR_CHAR(l);
                   9411:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   9412:     if (buf == NULL) {
                   9413:        xmlErrMemory(ctxt, NULL);
                   9414:        return;
                   9415:     }
                   9416:     while (IS_CHAR(cur) &&
                   9417:            ((r != ']') || (s != ']') || (cur != '>'))) {
                   9418:        if (len + 5 >= size) {
                   9419:            xmlChar *tmp;
                   9420: 
                   9421:            size *= 2;
                   9422:            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   9423:            if (tmp == NULL) {
                   9424:                xmlFree(buf);
                   9425:                xmlErrMemory(ctxt, NULL);
                   9426:                return;
                   9427:            }
                   9428:            buf = tmp;
                   9429:        }
                   9430:        COPY_BUF(rl,buf,len,r);
                   9431:        r = s;
                   9432:        rl = sl;
                   9433:        s = cur;
                   9434:        sl = l;
                   9435:        count++;
                   9436:        if (count > 50) {
                   9437:            GROW;
                   9438:            count = 0;
                   9439:        }
                   9440:        NEXTL(l);
                   9441:        cur = CUR_CHAR(l);
                   9442:     }
                   9443:     buf[len] = 0;
                   9444:     ctxt->instate = XML_PARSER_CONTENT;
                   9445:     if (cur != '>') {
                   9446:        xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
                   9447:                             "CData section not finished\n%.50s\n", buf);
                   9448:        xmlFree(buf);
                   9449:         return;
                   9450:     }
                   9451:     NEXTL(l);
                   9452: 
                   9453:     /*
                   9454:      * OK the buffer is to be consumed as cdata.
                   9455:      */
                   9456:     if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
                   9457:        if (ctxt->sax->cdataBlock != NULL)
                   9458:            ctxt->sax->cdataBlock(ctxt->userData, buf, len);
                   9459:        else if (ctxt->sax->characters != NULL)
                   9460:            ctxt->sax->characters(ctxt->userData, buf, len);
                   9461:     }
                   9462:     xmlFree(buf);
                   9463: }
                   9464: 
                   9465: /**
                   9466:  * xmlParseContent:
                   9467:  * @ctxt:  an XML parser context
                   9468:  *
                   9469:  * Parse a content:
                   9470:  *
                   9471:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   9472:  */
                   9473: 
                   9474: void
                   9475: xmlParseContent(xmlParserCtxtPtr ctxt) {
                   9476:     GROW;
                   9477:     while ((RAW != 0) &&
                   9478:           ((RAW != '<') || (NXT(1) != '/')) &&
                   9479:           (ctxt->instate != XML_PARSER_EOF)) {
                   9480:        const xmlChar *test = CUR_PTR;
                   9481:        unsigned int cons = ctxt->input->consumed;
                   9482:        const xmlChar *cur = ctxt->input->cur;
                   9483: 
                   9484:        /*
                   9485:         * First case : a Processing Instruction.
                   9486:         */
                   9487:        if ((*cur == '<') && (cur[1] == '?')) {
                   9488:            xmlParsePI(ctxt);
                   9489:        }
                   9490: 
                   9491:        /*
                   9492:         * Second case : a CDSection
                   9493:         */
                   9494:        /* 2.6.0 test was *cur not RAW */
                   9495:        else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
                   9496:            xmlParseCDSect(ctxt);
                   9497:        }
                   9498: 
                   9499:        /*
                   9500:         * Third case :  a comment
                   9501:         */
                   9502:        else if ((*cur == '<') && (NXT(1) == '!') &&
                   9503:                 (NXT(2) == '-') && (NXT(3) == '-')) {
                   9504:            xmlParseComment(ctxt);
                   9505:            ctxt->instate = XML_PARSER_CONTENT;
                   9506:        }
                   9507: 
                   9508:        /*
                   9509:         * Fourth case :  a sub-element.
                   9510:         */
                   9511:        else if (*cur == '<') {
                   9512:            xmlParseElement(ctxt);
                   9513:        }
                   9514: 
                   9515:        /*
                   9516:         * Fifth case : a reference. If if has not been resolved,
                   9517:         *    parsing returns it's Name, create the node 
                   9518:         */
                   9519: 
                   9520:        else if (*cur == '&') {
                   9521:            xmlParseReference(ctxt);
                   9522:        }
                   9523: 
                   9524:        /*
                   9525:         * Last case, text. Note that References are handled directly.
                   9526:         */
                   9527:        else {
                   9528:            xmlParseCharData(ctxt, 0);
                   9529:        }
                   9530: 
                   9531:        GROW;
                   9532:        /*
                   9533:         * Pop-up of finished entities.
                   9534:         */
                   9535:        while ((RAW == 0) && (ctxt->inputNr > 1))
                   9536:            xmlPopInput(ctxt);
                   9537:        SHRINK;
                   9538: 
                   9539:        if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
                   9540:            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   9541:                        "detected an error in element content\n");
                   9542:            ctxt->instate = XML_PARSER_EOF;
                   9543:             break;
                   9544:        }
                   9545:     }
                   9546: }
                   9547: 
                   9548: /**
                   9549:  * xmlParseElement:
                   9550:  * @ctxt:  an XML parser context
                   9551:  *
                   9552:  * parse an XML element, this is highly recursive
                   9553:  *
                   9554:  * [39] element ::= EmptyElemTag | STag content ETag
                   9555:  *
                   9556:  * [ WFC: Element Type Match ]
                   9557:  * The Name in an element's end-tag must match the element type in the
                   9558:  * start-tag. 
                   9559:  *
                   9560:  */
                   9561: 
                   9562: void
                   9563: xmlParseElement(xmlParserCtxtPtr ctxt) {
                   9564:     const xmlChar *name;
                   9565:     const xmlChar *prefix = NULL;
                   9566:     const xmlChar *URI = NULL;
                   9567:     xmlParserNodeInfo node_info;
1.1.1.2 ! misho    9568:     int line, tlen = 0;
1.1       misho    9569:     xmlNodePtr ret;
                   9570:     int nsNr = ctxt->nsNr;
                   9571: 
                   9572:     if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
                   9573:         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                   9574:        xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
                   9575:                 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
                   9576:                          xmlParserMaxDepth);
                   9577:        ctxt->instate = XML_PARSER_EOF;
                   9578:        return;
                   9579:     }
                   9580: 
                   9581:     /* Capture start position */
                   9582:     if (ctxt->record_info) {
                   9583:         node_info.begin_pos = ctxt->input->consumed +
                   9584:                           (CUR_PTR - ctxt->input->base);
                   9585:        node_info.begin_line = ctxt->input->line;
                   9586:     }
                   9587: 
                   9588:     if (ctxt->spaceNr == 0)
                   9589:        spacePush(ctxt, -1);
                   9590:     else if (*ctxt->space == -2)
                   9591:        spacePush(ctxt, -1);
                   9592:     else
                   9593:        spacePush(ctxt, *ctxt->space);
                   9594: 
                   9595:     line = ctxt->input->line;
                   9596: #ifdef LIBXML_SAX1_ENABLED
                   9597:     if (ctxt->sax2)
                   9598: #endif /* LIBXML_SAX1_ENABLED */
                   9599:         name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
                   9600: #ifdef LIBXML_SAX1_ENABLED
                   9601:     else
                   9602:        name = xmlParseStartTag(ctxt);
                   9603: #endif /* LIBXML_SAX1_ENABLED */
1.1.1.2 ! misho    9604:     if (ctxt->instate == XML_PARSER_EOF)
        !          9605:        return;
1.1       misho    9606:     if (name == NULL) {
                   9607:        spacePop(ctxt);
                   9608:         return;
                   9609:     }
                   9610:     namePush(ctxt, name);
                   9611:     ret = ctxt->node;
                   9612: 
                   9613: #ifdef LIBXML_VALID_ENABLED
                   9614:     /*
                   9615:      * [ VC: Root Element Type ]
                   9616:      * The Name in the document type declaration must match the element
                   9617:      * type of the root element. 
                   9618:      */
                   9619:     if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
                   9620:         ctxt->node && (ctxt->node == ctxt->myDoc->children))
                   9621:         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
                   9622: #endif /* LIBXML_VALID_ENABLED */
                   9623: 
                   9624:     /*
                   9625:      * Check for an Empty Element.
                   9626:      */
                   9627:     if ((RAW == '/') && (NXT(1) == '>')) {
                   9628:         SKIP(2);
                   9629:        if (ctxt->sax2) {
                   9630:            if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
                   9631:                (!ctxt->disableSAX))
                   9632:                ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
                   9633: #ifdef LIBXML_SAX1_ENABLED
                   9634:        } else {
                   9635:            if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
                   9636:                (!ctxt->disableSAX))
                   9637:                ctxt->sax->endElement(ctxt->userData, name);
                   9638: #endif /* LIBXML_SAX1_ENABLED */
                   9639:        }
                   9640:        namePop(ctxt);
                   9641:        spacePop(ctxt);
                   9642:        if (nsNr != ctxt->nsNr)
                   9643:            nsPop(ctxt, ctxt->nsNr - nsNr);
                   9644:        if ( ret != NULL && ctxt->record_info ) {
                   9645:           node_info.end_pos = ctxt->input->consumed +
                   9646:                              (CUR_PTR - ctxt->input->base);
                   9647:           node_info.end_line = ctxt->input->line;
                   9648:           node_info.node = ret;
                   9649:           xmlParserAddNodeInfo(ctxt, &node_info);
                   9650:        }
                   9651:        return;
                   9652:     }
                   9653:     if (RAW == '>') {
                   9654:         NEXT1;
                   9655:     } else {
                   9656:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
                   9657:                     "Couldn't find end of Start Tag %s line %d\n",
                   9658:                                name, line, NULL);
                   9659: 
                   9660:        /*
                   9661:         * end of parsing of this node.
                   9662:         */
                   9663:        nodePop(ctxt);
                   9664:        namePop(ctxt);
                   9665:        spacePop(ctxt);
                   9666:        if (nsNr != ctxt->nsNr)
                   9667:            nsPop(ctxt, ctxt->nsNr - nsNr);
                   9668: 
                   9669:        /*
                   9670:         * Capture end position and add node
                   9671:         */
                   9672:        if ( ret != NULL && ctxt->record_info ) {
                   9673:           node_info.end_pos = ctxt->input->consumed +
                   9674:                              (CUR_PTR - ctxt->input->base);
                   9675:           node_info.end_line = ctxt->input->line;
                   9676:           node_info.node = ret;
                   9677:           xmlParserAddNodeInfo(ctxt, &node_info);
                   9678:        }
                   9679:        return;
                   9680:     }
                   9681: 
                   9682:     /*
                   9683:      * Parse the content of the element:
                   9684:      */
                   9685:     xmlParseContent(ctxt);
                   9686:     if (!IS_BYTE_CHAR(RAW)) {
                   9687:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
                   9688:         "Premature end of data in tag %s line %d\n",
                   9689:                                name, line, NULL);
                   9690: 
                   9691:        /*
                   9692:         * end of parsing of this node.
                   9693:         */
                   9694:        nodePop(ctxt);
                   9695:        namePop(ctxt);
                   9696:        spacePop(ctxt);
                   9697:        if (nsNr != ctxt->nsNr)
                   9698:            nsPop(ctxt, ctxt->nsNr - nsNr);
                   9699:        return;
                   9700:     }
                   9701: 
                   9702:     /*
                   9703:      * parse the end of tag: '</' should be here.
                   9704:      */
                   9705:     if (ctxt->sax2) {
                   9706:        xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
                   9707:        namePop(ctxt);
                   9708:     }
                   9709: #ifdef LIBXML_SAX1_ENABLED
                   9710:       else
                   9711:        xmlParseEndTag1(ctxt, line);
                   9712: #endif /* LIBXML_SAX1_ENABLED */
                   9713: 
                   9714:     /*
                   9715:      * Capture end position and add node
                   9716:      */
                   9717:     if ( ret != NULL && ctxt->record_info ) {
                   9718:        node_info.end_pos = ctxt->input->consumed +
                   9719:                           (CUR_PTR - ctxt->input->base);
                   9720:        node_info.end_line = ctxt->input->line;
                   9721:        node_info.node = ret;
                   9722:        xmlParserAddNodeInfo(ctxt, &node_info);
                   9723:     }
                   9724: }
                   9725: 
                   9726: /**
                   9727:  * xmlParseVersionNum:
                   9728:  * @ctxt:  an XML parser context
                   9729:  *
                   9730:  * parse the XML version value.
                   9731:  *
                   9732:  * [26] VersionNum ::= '1.' [0-9]+
                   9733:  *
                   9734:  * In practice allow [0-9].[0-9]+ at that level
                   9735:  *
                   9736:  * Returns the string giving the XML version number, or NULL
                   9737:  */
                   9738: xmlChar *
                   9739: xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
                   9740:     xmlChar *buf = NULL;
                   9741:     int len = 0;
                   9742:     int size = 10;
                   9743:     xmlChar cur;
                   9744: 
                   9745:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   9746:     if (buf == NULL) {
                   9747:        xmlErrMemory(ctxt, NULL);
                   9748:        return(NULL);
                   9749:     }
                   9750:     cur = CUR;
                   9751:     if (!((cur >= '0') && (cur <= '9'))) {
                   9752:        xmlFree(buf);
                   9753:        return(NULL);
                   9754:     }
                   9755:     buf[len++] = cur;
                   9756:     NEXT;
                   9757:     cur=CUR;
                   9758:     if (cur != '.') {
                   9759:        xmlFree(buf);
                   9760:        return(NULL);
                   9761:     }
                   9762:     buf[len++] = cur;
                   9763:     NEXT;
                   9764:     cur=CUR;
                   9765:     while ((cur >= '0') && (cur <= '9')) {
                   9766:        if (len + 1 >= size) {
                   9767:            xmlChar *tmp;
                   9768: 
                   9769:            size *= 2;
                   9770:            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   9771:            if (tmp == NULL) {
                   9772:                xmlFree(buf);
                   9773:                xmlErrMemory(ctxt, NULL);
                   9774:                return(NULL);
                   9775:            }
                   9776:            buf = tmp;
                   9777:        }
                   9778:        buf[len++] = cur;
                   9779:        NEXT;
                   9780:        cur=CUR;
                   9781:     }
                   9782:     buf[len] = 0;
                   9783:     return(buf);
                   9784: }
                   9785: 
                   9786: /**
                   9787:  * xmlParseVersionInfo:
                   9788:  * @ctxt:  an XML parser context
                   9789:  *
                   9790:  * parse the XML version.
                   9791:  *
                   9792:  * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
                   9793:  *
                   9794:  * [25] Eq ::= S? '=' S?
                   9795:  *
                   9796:  * Returns the version string, e.g. "1.0"
                   9797:  */
                   9798: 
                   9799: xmlChar *
                   9800: xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
                   9801:     xmlChar *version = NULL;
                   9802: 
                   9803:     if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
                   9804:        SKIP(7);
                   9805:        SKIP_BLANKS;
                   9806:        if (RAW != '=') {
                   9807:            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
                   9808:            return(NULL);
                   9809:         }
                   9810:        NEXT;
                   9811:        SKIP_BLANKS;
                   9812:        if (RAW == '"') {
                   9813:            NEXT;
                   9814:            version = xmlParseVersionNum(ctxt);
                   9815:            if (RAW != '"') {
                   9816:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   9817:            } else
                   9818:                NEXT;
                   9819:        } else if (RAW == '\''){
                   9820:            NEXT;
                   9821:            version = xmlParseVersionNum(ctxt);
                   9822:            if (RAW != '\'') {
                   9823:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   9824:            } else
                   9825:                NEXT;
                   9826:        } else {
                   9827:            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
                   9828:        }
                   9829:     }
                   9830:     return(version);
                   9831: }
                   9832: 
                   9833: /**
                   9834:  * xmlParseEncName:
                   9835:  * @ctxt:  an XML parser context
                   9836:  *
                   9837:  * parse the XML encoding name
                   9838:  *
                   9839:  * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
                   9840:  *
                   9841:  * Returns the encoding name value or NULL
                   9842:  */
                   9843: xmlChar *
                   9844: xmlParseEncName(xmlParserCtxtPtr ctxt) {
                   9845:     xmlChar *buf = NULL;
                   9846:     int len = 0;
                   9847:     int size = 10;
                   9848:     xmlChar cur;
                   9849: 
                   9850:     cur = CUR;
                   9851:     if (((cur >= 'a') && (cur <= 'z')) ||
                   9852:         ((cur >= 'A') && (cur <= 'Z'))) {
                   9853:        buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   9854:        if (buf == NULL) {
                   9855:            xmlErrMemory(ctxt, NULL);
                   9856:            return(NULL);
                   9857:        }
                   9858: 
                   9859:        buf[len++] = cur;
                   9860:        NEXT;
                   9861:        cur = CUR;
                   9862:        while (((cur >= 'a') && (cur <= 'z')) ||
                   9863:               ((cur >= 'A') && (cur <= 'Z')) ||
                   9864:               ((cur >= '0') && (cur <= '9')) ||
                   9865:               (cur == '.') || (cur == '_') ||
                   9866:               (cur == '-')) {
                   9867:            if (len + 1 >= size) {
                   9868:                xmlChar *tmp;
                   9869: 
                   9870:                size *= 2;
                   9871:                tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   9872:                if (tmp == NULL) {
                   9873:                    xmlErrMemory(ctxt, NULL);
                   9874:                    xmlFree(buf);
                   9875:                    return(NULL);
                   9876:                }
                   9877:                buf = tmp;
                   9878:            }
                   9879:            buf[len++] = cur;
                   9880:            NEXT;
                   9881:            cur = CUR;
                   9882:            if (cur == 0) {
                   9883:                SHRINK;
                   9884:                GROW;
                   9885:                cur = CUR;
                   9886:            }
                   9887:         }
                   9888:        buf[len] = 0;
                   9889:     } else {
                   9890:        xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
                   9891:     }
                   9892:     return(buf);
                   9893: }
                   9894: 
                   9895: /**
                   9896:  * xmlParseEncodingDecl:
                   9897:  * @ctxt:  an XML parser context
                   9898:  * 
                   9899:  * parse the XML encoding declaration
                   9900:  *
                   9901:  * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
                   9902:  *
                   9903:  * this setups the conversion filters.
                   9904:  *
                   9905:  * Returns the encoding value or NULL
                   9906:  */
                   9907: 
                   9908: const xmlChar *
                   9909: xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
                   9910:     xmlChar *encoding = NULL;
                   9911: 
                   9912:     SKIP_BLANKS;
                   9913:     if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
                   9914:        SKIP(8);
                   9915:        SKIP_BLANKS;
                   9916:        if (RAW != '=') {
                   9917:            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
                   9918:            return(NULL);
                   9919:         }
                   9920:        NEXT;
                   9921:        SKIP_BLANKS;
                   9922:        if (RAW == '"') {
                   9923:            NEXT;
                   9924:            encoding = xmlParseEncName(ctxt);
                   9925:            if (RAW != '"') {
                   9926:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   9927:            } else
                   9928:                NEXT;
                   9929:        } else if (RAW == '\''){
                   9930:            NEXT;
                   9931:            encoding = xmlParseEncName(ctxt);
                   9932:            if (RAW != '\'') {
                   9933:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   9934:            } else
                   9935:                NEXT;
                   9936:        } else {
                   9937:            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
                   9938:        }
1.1.1.2 ! misho    9939: 
        !          9940:         /*
        !          9941:          * Non standard parsing, allowing the user to ignore encoding
        !          9942:          */
        !          9943:         if (ctxt->options & XML_PARSE_IGNORE_ENC)
        !          9944:             return(encoding);
        !          9945: 
1.1       misho    9946:        /*
                   9947:         * UTF-16 encoding stwich has already taken place at this stage,
                   9948:         * more over the little-endian/big-endian selection is already done
                   9949:         */
                   9950:         if ((encoding != NULL) &&
                   9951:            ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
                   9952:             (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
                   9953:            /*
                   9954:             * If no encoding was passed to the parser, that we are
                   9955:             * using UTF-16 and no decoder is present i.e. the 
                   9956:             * document is apparently UTF-8 compatible, then raise an
                   9957:             * encoding mismatch fatal error
                   9958:             */
                   9959:            if ((ctxt->encoding == NULL) &&
                   9960:                (ctxt->input->buf != NULL) &&
                   9961:                (ctxt->input->buf->encoder == NULL)) {
                   9962:                xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
                   9963:                  "Document labelled UTF-16 but has UTF-8 content\n");
                   9964:            }
                   9965:            if (ctxt->encoding != NULL)
                   9966:                xmlFree((xmlChar *) ctxt->encoding);
                   9967:            ctxt->encoding = encoding;
                   9968:        }
                   9969:        /*
                   9970:         * UTF-8 encoding is handled natively
                   9971:         */
                   9972:         else if ((encoding != NULL) &&
                   9973:            ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
                   9974:             (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
                   9975:            if (ctxt->encoding != NULL)
                   9976:                xmlFree((xmlChar *) ctxt->encoding);
                   9977:            ctxt->encoding = encoding;
                   9978:        }
                   9979:        else if (encoding != NULL) {
                   9980:            xmlCharEncodingHandlerPtr handler;
                   9981: 
                   9982:            if (ctxt->input->encoding != NULL)
                   9983:                xmlFree((xmlChar *) ctxt->input->encoding);
                   9984:            ctxt->input->encoding = encoding;
                   9985: 
                   9986:             handler = xmlFindCharEncodingHandler((const char *) encoding);
                   9987:            if (handler != NULL) {
                   9988:                xmlSwitchToEncoding(ctxt, handler);
                   9989:            } else {
                   9990:                xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
                   9991:                        "Unsupported encoding %s\n", encoding);
                   9992:                return(NULL);
                   9993:            }
                   9994:        }
                   9995:     }
                   9996:     return(encoding);
                   9997: }
                   9998: 
                   9999: /**
                   10000:  * xmlParseSDDecl:
                   10001:  * @ctxt:  an XML parser context
                   10002:  *
                   10003:  * parse the XML standalone declaration
                   10004:  *
                   10005:  * [32] SDDecl ::= S 'standalone' Eq
                   10006:  *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"')) 
                   10007:  *
                   10008:  * [ VC: Standalone Document Declaration ]
                   10009:  * TODO The standalone document declaration must have the value "no"
                   10010:  * if any external markup declarations contain declarations of:
                   10011:  *  - attributes with default values, if elements to which these
                   10012:  *    attributes apply appear in the document without specifications
                   10013:  *    of values for these attributes, or
                   10014:  *  - entities (other than amp, lt, gt, apos, quot), if references
                   10015:  *    to those entities appear in the document, or
                   10016:  *  - attributes with values subject to normalization, where the
                   10017:  *    attribute appears in the document with a value which will change
                   10018:  *    as a result of normalization, or
                   10019:  *  - element types with element content, if white space occurs directly
                   10020:  *    within any instance of those types.
                   10021:  *
                   10022:  * Returns:
                   10023:  *   1 if standalone="yes"
                   10024:  *   0 if standalone="no"
                   10025:  *  -2 if standalone attribute is missing or invalid
                   10026:  *       (A standalone value of -2 means that the XML declaration was found,
                   10027:  *        but no value was specified for the standalone attribute).
                   10028:  */
                   10029: 
                   10030: int
                   10031: xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
                   10032:     int standalone = -2;
                   10033: 
                   10034:     SKIP_BLANKS;
                   10035:     if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
                   10036:        SKIP(10);
                   10037:         SKIP_BLANKS;
                   10038:        if (RAW != '=') {
                   10039:            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
                   10040:            return(standalone);
                   10041:         }
                   10042:        NEXT;
                   10043:        SKIP_BLANKS;
                   10044:         if (RAW == '\''){
                   10045:            NEXT;
                   10046:            if ((RAW == 'n') && (NXT(1) == 'o')) {
                   10047:                standalone = 0;
                   10048:                 SKIP(2);
                   10049:            } else if ((RAW == 'y') && (NXT(1) == 'e') &&
                   10050:                       (NXT(2) == 's')) {
                   10051:                standalone = 1;
                   10052:                SKIP(3);
                   10053:             } else {
                   10054:                xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
                   10055:            }
                   10056:            if (RAW != '\'') {
                   10057:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   10058:            } else
                   10059:                NEXT;
                   10060:        } else if (RAW == '"'){
                   10061:            NEXT;
                   10062:            if ((RAW == 'n') && (NXT(1) == 'o')) {
                   10063:                standalone = 0;
                   10064:                SKIP(2);
                   10065:            } else if ((RAW == 'y') && (NXT(1) == 'e') &&
                   10066:                       (NXT(2) == 's')) {
                   10067:                standalone = 1;
                   10068:                 SKIP(3);
                   10069:             } else {
                   10070:                xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
                   10071:            }
                   10072:            if (RAW != '"') {
                   10073:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   10074:            } else
                   10075:                NEXT;
                   10076:        } else {
                   10077:            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
                   10078:         }
                   10079:     }
                   10080:     return(standalone);
                   10081: }
                   10082: 
                   10083: /**
                   10084:  * xmlParseXMLDecl:
                   10085:  * @ctxt:  an XML parser context
                   10086:  * 
                   10087:  * parse an XML declaration header
                   10088:  *
                   10089:  * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
                   10090:  */
                   10091: 
                   10092: void
                   10093: xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
                   10094:     xmlChar *version;
                   10095: 
                   10096:     /*
                   10097:      * This value for standalone indicates that the document has an
                   10098:      * XML declaration but it does not have a standalone attribute.
                   10099:      * It will be overwritten later if a standalone attribute is found.
                   10100:      */
                   10101:     ctxt->input->standalone = -2;
                   10102: 
                   10103:     /*
                   10104:      * We know that '<?xml' is here.
                   10105:      */
                   10106:     SKIP(5);
                   10107: 
                   10108:     if (!IS_BLANK_CH(RAW)) {
                   10109:        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   10110:                       "Blank needed after '<?xml'\n");
                   10111:     }
                   10112:     SKIP_BLANKS;
                   10113: 
                   10114:     /*
                   10115:      * We must have the VersionInfo here.
                   10116:      */
                   10117:     version = xmlParseVersionInfo(ctxt);
                   10118:     if (version == NULL) {
                   10119:        xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
                   10120:     } else {
                   10121:        if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
                   10122:            /*
                   10123:             * Changed here for XML-1.0 5th edition
                   10124:             */
                   10125:            if (ctxt->options & XML_PARSE_OLD10) {
                   10126:                xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
                   10127:                                  "Unsupported version '%s'\n",
                   10128:                                  version);
                   10129:            } else {
                   10130:                if ((version[0] == '1') && ((version[1] == '.'))) {
                   10131:                    xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
                   10132:                                  "Unsupported version '%s'\n",
                   10133:                                  version, NULL);
                   10134:                } else {
                   10135:                    xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
                   10136:                                      "Unsupported version '%s'\n",
                   10137:                                      version);
                   10138:                }
                   10139:            }
                   10140:        }
                   10141:        if (ctxt->version != NULL)
                   10142:            xmlFree((void *) ctxt->version);
                   10143:        ctxt->version = version;
                   10144:     }
                   10145: 
                   10146:     /*
                   10147:      * We may have the encoding declaration
                   10148:      */
                   10149:     if (!IS_BLANK_CH(RAW)) {
                   10150:         if ((RAW == '?') && (NXT(1) == '>')) {
                   10151:            SKIP(2);
                   10152:            return;
                   10153:        }
                   10154:        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
                   10155:     }
                   10156:     xmlParseEncodingDecl(ctxt);
                   10157:     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   10158:        /*
                   10159:         * The XML REC instructs us to stop parsing right here
                   10160:         */
                   10161:         return;
                   10162:     }
                   10163: 
                   10164:     /*
                   10165:      * We may have the standalone status.
                   10166:      */
                   10167:     if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
                   10168:         if ((RAW == '?') && (NXT(1) == '>')) {
                   10169:            SKIP(2);
                   10170:            return;
                   10171:        }
                   10172:        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
                   10173:     }
                   10174: 
                   10175:     /*
                   10176:      * We can grow the input buffer freely at that point
                   10177:      */
                   10178:     GROW;
                   10179: 
                   10180:     SKIP_BLANKS;
                   10181:     ctxt->input->standalone = xmlParseSDDecl(ctxt);
                   10182: 
                   10183:     SKIP_BLANKS;
                   10184:     if ((RAW == '?') && (NXT(1) == '>')) {
                   10185:         SKIP(2);
                   10186:     } else if (RAW == '>') {
                   10187:         /* Deprecated old WD ... */
                   10188:        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
                   10189:        NEXT;
                   10190:     } else {
                   10191:        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
                   10192:        MOVETO_ENDTAG(CUR_PTR);
                   10193:        NEXT;
                   10194:     }
                   10195: }
                   10196: 
                   10197: /**
                   10198:  * xmlParseMisc:
                   10199:  * @ctxt:  an XML parser context
                   10200:  * 
                   10201:  * parse an XML Misc* optional field.
                   10202:  *
                   10203:  * [27] Misc ::= Comment | PI |  S
                   10204:  */
                   10205: 
                   10206: void
                   10207: xmlParseMisc(xmlParserCtxtPtr ctxt) {
                   10208:     while (((RAW == '<') && (NXT(1) == '?')) ||
                   10209:            (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
                   10210:            IS_BLANK_CH(CUR)) {
                   10211:         if ((RAW == '<') && (NXT(1) == '?')) {
                   10212:            xmlParsePI(ctxt);
                   10213:        } else if (IS_BLANK_CH(CUR)) {
                   10214:            NEXT;
                   10215:        } else
                   10216:            xmlParseComment(ctxt);
                   10217:     }
                   10218: }
                   10219: 
                   10220: /**
                   10221:  * xmlParseDocument:
                   10222:  * @ctxt:  an XML parser context
                   10223:  * 
                   10224:  * parse an XML document (and build a tree if using the standard SAX
                   10225:  * interface).
                   10226:  *
                   10227:  * [1] document ::= prolog element Misc*
                   10228:  *
                   10229:  * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
                   10230:  *
                   10231:  * Returns 0, -1 in case of error. the parser context is augmented
                   10232:  *                as a result of the parsing.
                   10233:  */
                   10234: 
                   10235: int
                   10236: xmlParseDocument(xmlParserCtxtPtr ctxt) {
                   10237:     xmlChar start[4];
                   10238:     xmlCharEncoding enc;
                   10239: 
                   10240:     xmlInitParser();
                   10241: 
                   10242:     if ((ctxt == NULL) || (ctxt->input == NULL))
                   10243:         return(-1);
                   10244: 
                   10245:     GROW;
                   10246: 
                   10247:     /*
                   10248:      * SAX: detecting the level.
                   10249:      */
                   10250:     xmlDetectSAX2(ctxt);
                   10251: 
                   10252:     /*
                   10253:      * SAX: beginning of the document processing.
                   10254:      */
                   10255:     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   10256:         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
                   10257: 
                   10258:     if ((ctxt->encoding == NULL) &&
                   10259:         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
                   10260:        /* 
                   10261:         * Get the 4 first bytes and decode the charset
                   10262:         * if enc != XML_CHAR_ENCODING_NONE
                   10263:         * plug some encoding conversion routines.
                   10264:         */
                   10265:        start[0] = RAW;
                   10266:        start[1] = NXT(1);
                   10267:        start[2] = NXT(2);
                   10268:        start[3] = NXT(3);
                   10269:        enc = xmlDetectCharEncoding(&start[0], 4);
                   10270:        if (enc != XML_CHAR_ENCODING_NONE) {
                   10271:            xmlSwitchEncoding(ctxt, enc);
                   10272:        }
                   10273:     }
                   10274: 
                   10275: 
                   10276:     if (CUR == 0) {
                   10277:        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
                   10278:     }
                   10279: 
                   10280:     /*
                   10281:      * Check for the XMLDecl in the Prolog.
                   10282:      * do not GROW here to avoid the detected encoder to decode more
                   10283:      * than just the first line, unless the amount of data is really
                   10284:      * too small to hold "<?xml version="1.0" encoding="foo"
                   10285:      */
                   10286:     if ((ctxt->input->end - ctxt->input->cur) < 35) {
                   10287:        GROW;
                   10288:     }
                   10289:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
                   10290: 
                   10291:        /*
                   10292:         * Note that we will switch encoding on the fly.
                   10293:         */
                   10294:        xmlParseXMLDecl(ctxt);
                   10295:        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   10296:            /*
                   10297:             * The XML REC instructs us to stop parsing right here
                   10298:             */
                   10299:            return(-1);
                   10300:        }
                   10301:        ctxt->standalone = ctxt->input->standalone;
                   10302:        SKIP_BLANKS;
                   10303:     } else {
                   10304:        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   10305:     }
                   10306:     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
                   10307:         ctxt->sax->startDocument(ctxt->userData);
                   10308: 
                   10309:     /*
                   10310:      * The Misc part of the Prolog
                   10311:      */
                   10312:     GROW;
                   10313:     xmlParseMisc(ctxt);
                   10314: 
                   10315:     /*
                   10316:      * Then possibly doc type declaration(s) and more Misc
                   10317:      * (doctypedecl Misc*)?
                   10318:      */
                   10319:     GROW;
                   10320:     if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
                   10321: 
                   10322:        ctxt->inSubset = 1;
                   10323:        xmlParseDocTypeDecl(ctxt);
                   10324:        if (RAW == '[') {
                   10325:            ctxt->instate = XML_PARSER_DTD;
                   10326:            xmlParseInternalSubset(ctxt);
                   10327:        }
                   10328: 
                   10329:        /*
                   10330:         * Create and update the external subset.
                   10331:         */
                   10332:        ctxt->inSubset = 2;
                   10333:        if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
                   10334:            (!ctxt->disableSAX))
                   10335:            ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
                   10336:                                      ctxt->extSubSystem, ctxt->extSubURI);
                   10337:        ctxt->inSubset = 0;
                   10338: 
                   10339:         xmlCleanSpecialAttr(ctxt);
                   10340: 
                   10341:        ctxt->instate = XML_PARSER_PROLOG;
                   10342:        xmlParseMisc(ctxt);
                   10343:     }
                   10344: 
                   10345:     /*
                   10346:      * Time to start parsing the tree itself
                   10347:      */
                   10348:     GROW;
                   10349:     if (RAW != '<') {
                   10350:        xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
                   10351:                       "Start tag expected, '<' not found\n");
                   10352:     } else {
                   10353:        ctxt->instate = XML_PARSER_CONTENT;
                   10354:        xmlParseElement(ctxt);
                   10355:        ctxt->instate = XML_PARSER_EPILOG;
                   10356: 
                   10357: 
                   10358:        /*
                   10359:         * The Misc part at the end
                   10360:         */
                   10361:        xmlParseMisc(ctxt);
                   10362: 
                   10363:        if (RAW != 0) {
                   10364:            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
                   10365:        }
                   10366:        ctxt->instate = XML_PARSER_EOF;
                   10367:     }
                   10368: 
                   10369:     /*
                   10370:      * SAX: end of the document processing.
                   10371:      */
                   10372:     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   10373:         ctxt->sax->endDocument(ctxt->userData);
                   10374: 
                   10375:     /*
                   10376:      * Remove locally kept entity definitions if the tree was not built
                   10377:      */
                   10378:     if ((ctxt->myDoc != NULL) &&
                   10379:        (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
                   10380:        xmlFreeDoc(ctxt->myDoc);
                   10381:        ctxt->myDoc = NULL;
                   10382:     }
                   10383: 
                   10384:     if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
                   10385:         ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
                   10386:        if (ctxt->valid)
                   10387:            ctxt->myDoc->properties |= XML_DOC_DTDVALID;
                   10388:        if (ctxt->nsWellFormed)
                   10389:            ctxt->myDoc->properties |= XML_DOC_NSVALID;
                   10390:        if (ctxt->options & XML_PARSE_OLD10)
                   10391:            ctxt->myDoc->properties |= XML_DOC_OLD10;
                   10392:     }
                   10393:     if (! ctxt->wellFormed) {
                   10394:        ctxt->valid = 0;
                   10395:        return(-1);
                   10396:     }
                   10397:     return(0);
                   10398: }
                   10399: 
                   10400: /**
                   10401:  * xmlParseExtParsedEnt:
                   10402:  * @ctxt:  an XML parser context
                   10403:  * 
                   10404:  * parse a general parsed entity
                   10405:  * An external general parsed entity is well-formed if it matches the
                   10406:  * production labeled extParsedEnt.
                   10407:  *
                   10408:  * [78] extParsedEnt ::= TextDecl? content
                   10409:  *
                   10410:  * Returns 0, -1 in case of error. the parser context is augmented
                   10411:  *                as a result of the parsing.
                   10412:  */
                   10413: 
                   10414: int
                   10415: xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
                   10416:     xmlChar start[4];
                   10417:     xmlCharEncoding enc;
                   10418: 
                   10419:     if ((ctxt == NULL) || (ctxt->input == NULL))
                   10420:         return(-1);
                   10421: 
                   10422:     xmlDefaultSAXHandlerInit();
                   10423: 
                   10424:     xmlDetectSAX2(ctxt);
                   10425: 
                   10426:     GROW;
                   10427: 
                   10428:     /*
                   10429:      * SAX: beginning of the document processing.
                   10430:      */
                   10431:     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   10432:         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
                   10433: 
                   10434:     /* 
                   10435:      * Get the 4 first bytes and decode the charset
                   10436:      * if enc != XML_CHAR_ENCODING_NONE
                   10437:      * plug some encoding conversion routines.
                   10438:      */
                   10439:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
                   10440:        start[0] = RAW;
                   10441:        start[1] = NXT(1);
                   10442:        start[2] = NXT(2);
                   10443:        start[3] = NXT(3);
                   10444:        enc = xmlDetectCharEncoding(start, 4);
                   10445:        if (enc != XML_CHAR_ENCODING_NONE) {
                   10446:            xmlSwitchEncoding(ctxt, enc);
                   10447:        }
                   10448:     }
                   10449: 
                   10450: 
                   10451:     if (CUR == 0) {
                   10452:        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
                   10453:     }
                   10454: 
                   10455:     /*
                   10456:      * Check for the XMLDecl in the Prolog.
                   10457:      */
                   10458:     GROW;
                   10459:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
                   10460: 
                   10461:        /*
                   10462:         * Note that we will switch encoding on the fly.
                   10463:         */
                   10464:        xmlParseXMLDecl(ctxt);
                   10465:        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   10466:            /*
                   10467:             * The XML REC instructs us to stop parsing right here
                   10468:             */
                   10469:            return(-1);
                   10470:        }
                   10471:        SKIP_BLANKS;
                   10472:     } else {
                   10473:        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   10474:     }
                   10475:     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
                   10476:         ctxt->sax->startDocument(ctxt->userData);
                   10477: 
                   10478:     /*
                   10479:      * Doing validity checking on chunk doesn't make sense
                   10480:      */
                   10481:     ctxt->instate = XML_PARSER_CONTENT;
                   10482:     ctxt->validate = 0;
                   10483:     ctxt->loadsubset = 0;
                   10484:     ctxt->depth = 0;
                   10485: 
                   10486:     xmlParseContent(ctxt);
                   10487:    
                   10488:     if ((RAW == '<') && (NXT(1) == '/')) {
                   10489:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   10490:     } else if (RAW != 0) {
                   10491:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   10492:     }
                   10493: 
                   10494:     /*
                   10495:      * SAX: end of the document processing.
                   10496:      */
                   10497:     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   10498:         ctxt->sax->endDocument(ctxt->userData);
                   10499: 
                   10500:     if (! ctxt->wellFormed) return(-1);
                   10501:     return(0);
                   10502: }
                   10503: 
                   10504: #ifdef LIBXML_PUSH_ENABLED
                   10505: /************************************************************************
                   10506:  *                                                                     *
                   10507:  *             Progressive parsing interfaces                          *
                   10508:  *                                                                     *
                   10509:  ************************************************************************/
                   10510: 
                   10511: /**
                   10512:  * xmlParseLookupSequence:
                   10513:  * @ctxt:  an XML parser context
                   10514:  * @first:  the first char to lookup
                   10515:  * @next:  the next char to lookup or zero
                   10516:  * @third:  the next char to lookup or zero
                   10517:  *
                   10518:  * Try to find if a sequence (first, next, third) or  just (first next) or
                   10519:  * (first) is available in the input stream.
                   10520:  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
                   10521:  * to avoid rescanning sequences of bytes, it DOES change the state of the
                   10522:  * parser, do not use liberally.
                   10523:  *
                   10524:  * Returns the index to the current parsing point if the full sequence
                   10525:  *      is available, -1 otherwise.
                   10526:  */
                   10527: static int
                   10528: xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
                   10529:                        xmlChar next, xmlChar third) {
                   10530:     int base, len;
                   10531:     xmlParserInputPtr in;
                   10532:     const xmlChar *buf;
                   10533: 
                   10534:     in = ctxt->input;
                   10535:     if (in == NULL) return(-1);
                   10536:     base = in->cur - in->base;
                   10537:     if (base < 0) return(-1);
                   10538:     if (ctxt->checkIndex > base)
                   10539:         base = ctxt->checkIndex;
                   10540:     if (in->buf == NULL) {
                   10541:        buf = in->base;
                   10542:        len = in->length;
                   10543:     } else {
                   10544:        buf = in->buf->buffer->content;
                   10545:        len = in->buf->buffer->use;
                   10546:     }
                   10547:     /* take into account the sequence length */
                   10548:     if (third) len -= 2;
                   10549:     else if (next) len --;
                   10550:     for (;base < len;base++) {
                   10551:         if (buf[base] == first) {
                   10552:            if (third != 0) {
                   10553:                if ((buf[base + 1] != next) ||
                   10554:                    (buf[base + 2] != third)) continue;
                   10555:            } else if (next != 0) {
                   10556:                if (buf[base + 1] != next) continue;
                   10557:            }
                   10558:            ctxt->checkIndex = 0;
                   10559: #ifdef DEBUG_PUSH
                   10560:            if (next == 0)
                   10561:                xmlGenericError(xmlGenericErrorContext,
                   10562:                        "PP: lookup '%c' found at %d\n",
                   10563:                        first, base);
                   10564:            else if (third == 0)
                   10565:                xmlGenericError(xmlGenericErrorContext,
                   10566:                        "PP: lookup '%c%c' found at %d\n",
                   10567:                        first, next, base);
                   10568:            else 
                   10569:                xmlGenericError(xmlGenericErrorContext,
                   10570:                        "PP: lookup '%c%c%c' found at %d\n",
                   10571:                        first, next, third, base);
                   10572: #endif
                   10573:            return(base - (in->cur - in->base));
                   10574:        }
                   10575:     }
                   10576:     ctxt->checkIndex = base;
                   10577: #ifdef DEBUG_PUSH
                   10578:     if (next == 0)
                   10579:        xmlGenericError(xmlGenericErrorContext,
                   10580:                "PP: lookup '%c' failed\n", first);
                   10581:     else if (third == 0)
                   10582:        xmlGenericError(xmlGenericErrorContext,
                   10583:                "PP: lookup '%c%c' failed\n", first, next);
                   10584:     else       
                   10585:        xmlGenericError(xmlGenericErrorContext,
                   10586:                "PP: lookup '%c%c%c' failed\n", first, next, third);
                   10587: #endif
                   10588:     return(-1);
                   10589: }
                   10590: 
                   10591: /**
                   10592:  * xmlParseGetLasts:
                   10593:  * @ctxt:  an XML parser context
                   10594:  * @lastlt:  pointer to store the last '<' from the input
                   10595:  * @lastgt:  pointer to store the last '>' from the input
                   10596:  *
                   10597:  * Lookup the last < and > in the current chunk
                   10598:  */
                   10599: static void
                   10600: xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
                   10601:                  const xmlChar **lastgt) {
                   10602:     const xmlChar *tmp;
                   10603: 
                   10604:     if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
                   10605:        xmlGenericError(xmlGenericErrorContext,
                   10606:                    "Internal error: xmlParseGetLasts\n");
                   10607:        return;
                   10608:     }
                   10609:     if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
                   10610:         tmp = ctxt->input->end;
                   10611:        tmp--;
                   10612:        while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
                   10613:        if (tmp < ctxt->input->base) {
                   10614:            *lastlt = NULL;
                   10615:            *lastgt = NULL;
                   10616:        } else {
                   10617:            *lastlt = tmp;
                   10618:            tmp++;
                   10619:            while ((tmp < ctxt->input->end) && (*tmp != '>')) {
                   10620:                if (*tmp == '\'') {
                   10621:                    tmp++;
                   10622:                    while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
                   10623:                    if (tmp < ctxt->input->end) tmp++;
                   10624:                } else if (*tmp == '"') {
                   10625:                    tmp++;
                   10626:                    while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
                   10627:                    if (tmp < ctxt->input->end) tmp++;
                   10628:                } else
                   10629:                    tmp++;
                   10630:            }
                   10631:            if (tmp < ctxt->input->end)
                   10632:                *lastgt = tmp;
                   10633:            else {
                   10634:                tmp = *lastlt;
                   10635:                tmp--;
                   10636:                while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
                   10637:                if (tmp >= ctxt->input->base)
                   10638:                    *lastgt = tmp;
                   10639:                else
                   10640:                    *lastgt = NULL;
                   10641:            }
                   10642:        }
                   10643:     } else {
                   10644:         *lastlt = NULL;
                   10645:        *lastgt = NULL;
                   10646:     }
                   10647: }
                   10648: /**
                   10649:  * xmlCheckCdataPush:
                   10650:  * @cur: pointer to the bock of characters
                   10651:  * @len: length of the block in bytes
                   10652:  *
                   10653:  * Check that the block of characters is okay as SCdata content [20]
                   10654:  *
                   10655:  * Returns the number of bytes to pass if okay, a negative index where an
                   10656:  *         UTF-8 error occured otherwise
                   10657:  */
                   10658: static int
                   10659: xmlCheckCdataPush(const xmlChar *utf, int len) {
                   10660:     int ix;
                   10661:     unsigned char c;
                   10662:     int codepoint;
                   10663: 
                   10664:     if ((utf == NULL) || (len <= 0))
                   10665:         return(0);
                   10666:     
                   10667:     for (ix = 0; ix < len;) {      /* string is 0-terminated */
                   10668:         c = utf[ix];
                   10669:         if ((c & 0x80) == 0x00) {      /* 1-byte code, starts with 10 */
                   10670:            if (c >= 0x20)
                   10671:                ix++;
                   10672:            else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
                   10673:                ix++;
                   10674:            else
                   10675:                return(-ix);
                   10676:        } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
                   10677:            if (ix + 2 > len) return(ix);
                   10678:            if ((utf[ix+1] & 0xc0 ) != 0x80)
                   10679:                return(-ix);
                   10680:            codepoint = (utf[ix] & 0x1f) << 6;
                   10681:            codepoint |= utf[ix+1] & 0x3f;
                   10682:            if (!xmlIsCharQ(codepoint))
                   10683:                return(-ix);
                   10684:            ix += 2;
                   10685:        } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
                   10686:            if (ix + 3 > len) return(ix);
                   10687:            if (((utf[ix+1] & 0xc0) != 0x80) ||
                   10688:                ((utf[ix+2] & 0xc0) != 0x80))
                   10689:                    return(-ix);
                   10690:            codepoint = (utf[ix] & 0xf) << 12;
                   10691:            codepoint |= (utf[ix+1] & 0x3f) << 6;
                   10692:            codepoint |= utf[ix+2] & 0x3f;
                   10693:            if (!xmlIsCharQ(codepoint))
                   10694:                return(-ix);
                   10695:            ix += 3;
                   10696:        } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
                   10697:            if (ix + 4 > len) return(ix);
                   10698:            if (((utf[ix+1] & 0xc0) != 0x80) ||
                   10699:                ((utf[ix+2] & 0xc0) != 0x80) ||
                   10700:                ((utf[ix+3] & 0xc0) != 0x80))
                   10701:                    return(-ix);
                   10702:            codepoint = (utf[ix] & 0x7) << 18;
                   10703:            codepoint |= (utf[ix+1] & 0x3f) << 12;
                   10704:            codepoint |= (utf[ix+2] & 0x3f) << 6;
                   10705:            codepoint |= utf[ix+3] & 0x3f;
                   10706:            if (!xmlIsCharQ(codepoint))
                   10707:                return(-ix);
                   10708:            ix += 4;
                   10709:        } else                          /* unknown encoding */
                   10710:            return(-ix);
                   10711:       }
                   10712:       return(ix);
                   10713: }
                   10714: 
                   10715: /**
                   10716:  * xmlParseTryOrFinish:
                   10717:  * @ctxt:  an XML parser context
                   10718:  * @terminate:  last chunk indicator
                   10719:  *
                   10720:  * Try to progress on parsing
                   10721:  *
                   10722:  * Returns zero if no parsing was possible
                   10723:  */
                   10724: static int
                   10725: xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                   10726:     int ret = 0;
                   10727:     int avail, tlen;
                   10728:     xmlChar cur, next;
                   10729:     const xmlChar *lastlt, *lastgt;
                   10730: 
                   10731:     if (ctxt->input == NULL)
                   10732:         return(0);
                   10733: 
                   10734: #ifdef DEBUG_PUSH
                   10735:     switch (ctxt->instate) {
                   10736:        case XML_PARSER_EOF:
                   10737:            xmlGenericError(xmlGenericErrorContext,
                   10738:                    "PP: try EOF\n"); break;
                   10739:        case XML_PARSER_START:
                   10740:            xmlGenericError(xmlGenericErrorContext,
                   10741:                    "PP: try START\n"); break;
                   10742:        case XML_PARSER_MISC:
                   10743:            xmlGenericError(xmlGenericErrorContext,
                   10744:                    "PP: try MISC\n");break;
                   10745:        case XML_PARSER_COMMENT:
                   10746:            xmlGenericError(xmlGenericErrorContext,
                   10747:                    "PP: try COMMENT\n");break;
                   10748:        case XML_PARSER_PROLOG:
                   10749:            xmlGenericError(xmlGenericErrorContext,
                   10750:                    "PP: try PROLOG\n");break;
                   10751:        case XML_PARSER_START_TAG:
                   10752:            xmlGenericError(xmlGenericErrorContext,
                   10753:                    "PP: try START_TAG\n");break;
                   10754:        case XML_PARSER_CONTENT:
                   10755:            xmlGenericError(xmlGenericErrorContext,
                   10756:                    "PP: try CONTENT\n");break;
                   10757:        case XML_PARSER_CDATA_SECTION:
                   10758:            xmlGenericError(xmlGenericErrorContext,
                   10759:                    "PP: try CDATA_SECTION\n");break;
                   10760:        case XML_PARSER_END_TAG:
                   10761:            xmlGenericError(xmlGenericErrorContext,
                   10762:                    "PP: try END_TAG\n");break;
                   10763:        case XML_PARSER_ENTITY_DECL:
                   10764:            xmlGenericError(xmlGenericErrorContext,
                   10765:                    "PP: try ENTITY_DECL\n");break;
                   10766:        case XML_PARSER_ENTITY_VALUE:
                   10767:            xmlGenericError(xmlGenericErrorContext,
                   10768:                    "PP: try ENTITY_VALUE\n");break;
                   10769:        case XML_PARSER_ATTRIBUTE_VALUE:
                   10770:            xmlGenericError(xmlGenericErrorContext,
                   10771:                    "PP: try ATTRIBUTE_VALUE\n");break;
                   10772:        case XML_PARSER_DTD:
                   10773:            xmlGenericError(xmlGenericErrorContext,
                   10774:                    "PP: try DTD\n");break;
                   10775:        case XML_PARSER_EPILOG:
                   10776:            xmlGenericError(xmlGenericErrorContext,
                   10777:                    "PP: try EPILOG\n");break;
                   10778:        case XML_PARSER_PI:
                   10779:            xmlGenericError(xmlGenericErrorContext,
                   10780:                    "PP: try PI\n");break;
                   10781:         case XML_PARSER_IGNORE:
                   10782:             xmlGenericError(xmlGenericErrorContext,
                   10783:                    "PP: try IGNORE\n");break;
                   10784:     }
                   10785: #endif
                   10786: 
                   10787:     if ((ctxt->input != NULL) &&
                   10788:         (ctxt->input->cur - ctxt->input->base > 4096)) {
                   10789:        xmlSHRINK(ctxt);
                   10790:        ctxt->checkIndex = 0;
                   10791:     }
                   10792:     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
                   10793: 
                   10794:     while (1) {
                   10795:        if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
                   10796:            return(0);
                   10797: 
                   10798:         
                   10799:        /*
                   10800:         * Pop-up of finished entities.
                   10801:         */
                   10802:        while ((RAW == 0) && (ctxt->inputNr > 1))
                   10803:            xmlPopInput(ctxt);
                   10804: 
                   10805:        if (ctxt->input == NULL) break;
                   10806:        if (ctxt->input->buf == NULL)
                   10807:            avail = ctxt->input->length -
                   10808:                    (ctxt->input->cur - ctxt->input->base);
                   10809:        else {
                   10810:            /*
                   10811:             * If we are operating on converted input, try to flush
                   10812:             * remainng chars to avoid them stalling in the non-converted
                   10813:             * buffer.
                   10814:             */
                   10815:            if ((ctxt->input->buf->raw != NULL) &&
                   10816:                (ctxt->input->buf->raw->use > 0)) {
                   10817:                int base = ctxt->input->base -
                   10818:                           ctxt->input->buf->buffer->content;
                   10819:                int current = ctxt->input->cur - ctxt->input->base;
                   10820: 
                   10821:                xmlParserInputBufferPush(ctxt->input->buf, 0, "");
                   10822:                ctxt->input->base = ctxt->input->buf->buffer->content + base;
                   10823:                ctxt->input->cur = ctxt->input->base + current;
                   10824:                ctxt->input->end =
                   10825:                    &ctxt->input->buf->buffer->content[
                   10826:                                       ctxt->input->buf->buffer->use];
                   10827:            }
                   10828:            avail = ctxt->input->buf->buffer->use -
                   10829:                    (ctxt->input->cur - ctxt->input->base);
                   10830:        }
                   10831:         if (avail < 1)
                   10832:            goto done;
                   10833:         switch (ctxt->instate) {
                   10834:             case XML_PARSER_EOF:
                   10835:                /*
                   10836:                 * Document parsing is done !
                   10837:                 */
                   10838:                goto done;
                   10839:             case XML_PARSER_START:
                   10840:                if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
                   10841:                    xmlChar start[4];
                   10842:                    xmlCharEncoding enc;
                   10843: 
                   10844:                    /*
                   10845:                     * Very first chars read from the document flow.
                   10846:                     */
                   10847:                    if (avail < 4)
                   10848:                        goto done;
                   10849: 
                   10850:                    /* 
                   10851:                     * Get the 4 first bytes and decode the charset
                   10852:                     * if enc != XML_CHAR_ENCODING_NONE
                   10853:                     * plug some encoding conversion routines,
                   10854:                     * else xmlSwitchEncoding will set to (default)
                   10855:                     * UTF8.
                   10856:                     */
                   10857:                    start[0] = RAW;
                   10858:                    start[1] = NXT(1);
                   10859:                    start[2] = NXT(2);
                   10860:                    start[3] = NXT(3);
                   10861:                    enc = xmlDetectCharEncoding(start, 4);
                   10862:                    xmlSwitchEncoding(ctxt, enc);
                   10863:                    break;
                   10864:                }
                   10865: 
                   10866:                if (avail < 2)
                   10867:                    goto done;
                   10868:                cur = ctxt->input->cur[0];
                   10869:                next = ctxt->input->cur[1];
                   10870:                if (cur == 0) {
                   10871:                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   10872:                        ctxt->sax->setDocumentLocator(ctxt->userData,
                   10873:                                                      &xmlDefaultSAXLocator);
                   10874:                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
                   10875:                    ctxt->instate = XML_PARSER_EOF;
                   10876: #ifdef DEBUG_PUSH
                   10877:                    xmlGenericError(xmlGenericErrorContext,
                   10878:                            "PP: entering EOF\n");
                   10879: #endif
                   10880:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   10881:                        ctxt->sax->endDocument(ctxt->userData);
                   10882:                    goto done;
                   10883:                }
                   10884:                if ((cur == '<') && (next == '?')) {
                   10885:                    /* PI or XML decl */
                   10886:                    if (avail < 5) return(ret);
                   10887:                    if ((!terminate) &&
                   10888:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
                   10889:                        return(ret);
                   10890:                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   10891:                        ctxt->sax->setDocumentLocator(ctxt->userData,
                   10892:                                                      &xmlDefaultSAXLocator);
                   10893:                    if ((ctxt->input->cur[2] == 'x') &&
                   10894:                        (ctxt->input->cur[3] == 'm') &&
                   10895:                        (ctxt->input->cur[4] == 'l') &&
                   10896:                        (IS_BLANK_CH(ctxt->input->cur[5]))) {
                   10897:                        ret += 5;
                   10898: #ifdef DEBUG_PUSH
                   10899:                        xmlGenericError(xmlGenericErrorContext,
                   10900:                                "PP: Parsing XML Decl\n");
                   10901: #endif
                   10902:                        xmlParseXMLDecl(ctxt);
                   10903:                        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   10904:                            /*
                   10905:                             * The XML REC instructs us to stop parsing right
                   10906:                             * here
                   10907:                             */
                   10908:                            ctxt->instate = XML_PARSER_EOF;
                   10909:                            return(0);
                   10910:                        }
                   10911:                        ctxt->standalone = ctxt->input->standalone;
                   10912:                        if ((ctxt->encoding == NULL) &&
                   10913:                            (ctxt->input->encoding != NULL))
                   10914:                            ctxt->encoding = xmlStrdup(ctxt->input->encoding);
                   10915:                        if ((ctxt->sax) && (ctxt->sax->startDocument) &&
                   10916:                            (!ctxt->disableSAX))
                   10917:                            ctxt->sax->startDocument(ctxt->userData);
                   10918:                        ctxt->instate = XML_PARSER_MISC;
                   10919: #ifdef DEBUG_PUSH
                   10920:                        xmlGenericError(xmlGenericErrorContext,
                   10921:                                "PP: entering MISC\n");
                   10922: #endif
                   10923:                    } else {
                   10924:                        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   10925:                        if ((ctxt->sax) && (ctxt->sax->startDocument) &&
                   10926:                            (!ctxt->disableSAX))
                   10927:                            ctxt->sax->startDocument(ctxt->userData);
                   10928:                        ctxt->instate = XML_PARSER_MISC;
                   10929: #ifdef DEBUG_PUSH
                   10930:                        xmlGenericError(xmlGenericErrorContext,
                   10931:                                "PP: entering MISC\n");
                   10932: #endif
                   10933:                    }
                   10934:                } else {
                   10935:                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   10936:                        ctxt->sax->setDocumentLocator(ctxt->userData,
                   10937:                                                      &xmlDefaultSAXLocator);
                   10938:                    ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   10939:                    if (ctxt->version == NULL) {
                   10940:                        xmlErrMemory(ctxt, NULL);
                   10941:                        break;
                   10942:                    }
                   10943:                    if ((ctxt->sax) && (ctxt->sax->startDocument) &&
                   10944:                        (!ctxt->disableSAX))
                   10945:                        ctxt->sax->startDocument(ctxt->userData);
                   10946:                    ctxt->instate = XML_PARSER_MISC;
                   10947: #ifdef DEBUG_PUSH
                   10948:                    xmlGenericError(xmlGenericErrorContext,
                   10949:                            "PP: entering MISC\n");
                   10950: #endif
                   10951:                }
                   10952:                break;
                   10953:             case XML_PARSER_START_TAG: {
                   10954:                const xmlChar *name;
                   10955:                const xmlChar *prefix = NULL;
                   10956:                const xmlChar *URI = NULL;
                   10957:                int nsNr = ctxt->nsNr;
                   10958: 
                   10959:                if ((avail < 2) && (ctxt->inputNr == 1))
                   10960:                    goto done;
                   10961:                cur = ctxt->input->cur[0];
                   10962:                if (cur != '<') {
                   10963:                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
                   10964:                    ctxt->instate = XML_PARSER_EOF;
                   10965:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   10966:                        ctxt->sax->endDocument(ctxt->userData);
                   10967:                    goto done;
                   10968:                }
                   10969:                if (!terminate) {
                   10970:                    if (ctxt->progressive) {
                   10971:                        /* > can be found unescaped in attribute values */
                   10972:                        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
                   10973:                            goto done;
                   10974:                    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
                   10975:                        goto done;
                   10976:                    }
                   10977:                }
                   10978:                if (ctxt->spaceNr == 0)
                   10979:                    spacePush(ctxt, -1);
                   10980:                else if (*ctxt->space == -2)
                   10981:                    spacePush(ctxt, -1);
                   10982:                else
                   10983:                    spacePush(ctxt, *ctxt->space);
                   10984: #ifdef LIBXML_SAX1_ENABLED
                   10985:                if (ctxt->sax2)
                   10986: #endif /* LIBXML_SAX1_ENABLED */
                   10987:                    name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
                   10988: #ifdef LIBXML_SAX1_ENABLED
                   10989:                else
                   10990:                    name = xmlParseStartTag(ctxt);
                   10991: #endif /* LIBXML_SAX1_ENABLED */
1.1.1.2 ! misho    10992:                if (ctxt->instate == XML_PARSER_EOF)
        !          10993:                    goto done;
1.1       misho    10994:                if (name == NULL) {
                   10995:                    spacePop(ctxt);
                   10996:                    ctxt->instate = XML_PARSER_EOF;
                   10997:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   10998:                        ctxt->sax->endDocument(ctxt->userData);
                   10999:                    goto done;
                   11000:                }
                   11001: #ifdef LIBXML_VALID_ENABLED
                   11002:                /*
                   11003:                 * [ VC: Root Element Type ]
                   11004:                 * The Name in the document type declaration must match
                   11005:                 * the element type of the root element. 
                   11006:                 */
                   11007:                if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
                   11008:                    ctxt->node && (ctxt->node == ctxt->myDoc->children))
                   11009:                    ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
                   11010: #endif /* LIBXML_VALID_ENABLED */
                   11011: 
                   11012:                /*
                   11013:                 * Check for an Empty Element.
                   11014:                 */
                   11015:                if ((RAW == '/') && (NXT(1) == '>')) {
                   11016:                    SKIP(2);
                   11017: 
                   11018:                    if (ctxt->sax2) {
                   11019:                        if ((ctxt->sax != NULL) &&
                   11020:                            (ctxt->sax->endElementNs != NULL) &&
                   11021:                            (!ctxt->disableSAX))
                   11022:                            ctxt->sax->endElementNs(ctxt->userData, name,
                   11023:                                                    prefix, URI);
                   11024:                        if (ctxt->nsNr - nsNr > 0)
                   11025:                            nsPop(ctxt, ctxt->nsNr - nsNr);
                   11026: #ifdef LIBXML_SAX1_ENABLED
                   11027:                    } else {
                   11028:                        if ((ctxt->sax != NULL) &&
                   11029:                            (ctxt->sax->endElement != NULL) &&
                   11030:                            (!ctxt->disableSAX))
                   11031:                            ctxt->sax->endElement(ctxt->userData, name);
                   11032: #endif /* LIBXML_SAX1_ENABLED */
                   11033:                    }
                   11034:                    spacePop(ctxt);
                   11035:                    if (ctxt->nameNr == 0) {
                   11036:                        ctxt->instate = XML_PARSER_EPILOG;
                   11037:                    } else {
                   11038:                        ctxt->instate = XML_PARSER_CONTENT;
                   11039:                    }
                   11040:                    break;
                   11041:                }
                   11042:                if (RAW == '>') {
                   11043:                    NEXT;
                   11044:                } else {
                   11045:                    xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
                   11046:                                         "Couldn't find end of Start Tag %s\n",
                   11047:                                         name);
                   11048:                    nodePop(ctxt);
                   11049:                    spacePop(ctxt);
                   11050:                }
                   11051:                if (ctxt->sax2)
                   11052:                    nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
                   11053: #ifdef LIBXML_SAX1_ENABLED
                   11054:                else
                   11055:                    namePush(ctxt, name);
                   11056: #endif /* LIBXML_SAX1_ENABLED */
                   11057: 
                   11058:                ctxt->instate = XML_PARSER_CONTENT;
                   11059:                 break;
                   11060:            }
                   11061:             case XML_PARSER_CONTENT: {
                   11062:                const xmlChar *test;
                   11063:                unsigned int cons;
                   11064:                if ((avail < 2) && (ctxt->inputNr == 1))
                   11065:                    goto done;
                   11066:                cur = ctxt->input->cur[0];
                   11067:                next = ctxt->input->cur[1];
                   11068: 
                   11069:                test = CUR_PTR;
                   11070:                cons = ctxt->input->consumed;
                   11071:                if ((cur == '<') && (next == '/')) {
                   11072:                    ctxt->instate = XML_PARSER_END_TAG;
                   11073:                    break;
                   11074:                } else if ((cur == '<') && (next == '?')) {
                   11075:                    if ((!terminate) &&
                   11076:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
                   11077:                        goto done;
                   11078:                    xmlParsePI(ctxt);
                   11079:                } else if ((cur == '<') && (next != '!')) {
                   11080:                    ctxt->instate = XML_PARSER_START_TAG;
                   11081:                    break;
                   11082:                } else if ((cur == '<') && (next == '!') &&
                   11083:                           (ctxt->input->cur[2] == '-') &&
                   11084:                           (ctxt->input->cur[3] == '-')) {
                   11085:                    int term;
                   11086: 
                   11087:                    if (avail < 4)
                   11088:                        goto done;
                   11089:                    ctxt->input->cur += 4;
                   11090:                    term = xmlParseLookupSequence(ctxt, '-', '-', '>');
                   11091:                    ctxt->input->cur -= 4;
                   11092:                    if ((!terminate) && (term < 0))
                   11093:                        goto done;
                   11094:                    xmlParseComment(ctxt);
                   11095:                    ctxt->instate = XML_PARSER_CONTENT;
                   11096:                } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
                   11097:                    (ctxt->input->cur[2] == '[') &&
                   11098:                    (ctxt->input->cur[3] == 'C') &&
                   11099:                    (ctxt->input->cur[4] == 'D') &&
                   11100:                    (ctxt->input->cur[5] == 'A') &&
                   11101:                    (ctxt->input->cur[6] == 'T') &&
                   11102:                    (ctxt->input->cur[7] == 'A') &&
                   11103:                    (ctxt->input->cur[8] == '[')) {
                   11104:                    SKIP(9);
                   11105:                    ctxt->instate = XML_PARSER_CDATA_SECTION;
                   11106:                    break;
                   11107:                } else if ((cur == '<') && (next == '!') &&
                   11108:                           (avail < 9)) {
                   11109:                    goto done;
                   11110:                } else if (cur == '&') {
                   11111:                    if ((!terminate) &&
                   11112:                        (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
                   11113:                        goto done;
                   11114:                    xmlParseReference(ctxt);
                   11115:                } else {
                   11116:                    /* TODO Avoid the extra copy, handle directly !!! */
                   11117:                    /*
                   11118:                     * Goal of the following test is:
                   11119:                     *  - minimize calls to the SAX 'character' callback
                   11120:                     *    when they are mergeable
                   11121:                     *  - handle an problem for isBlank when we only parse
                   11122:                     *    a sequence of blank chars and the next one is
                   11123:                     *    not available to check against '<' presence.
                   11124:                     *  - tries to homogenize the differences in SAX
                   11125:                     *    callbacks between the push and pull versions
                   11126:                     *    of the parser.
                   11127:                     */
                   11128:                    if ((ctxt->inputNr == 1) &&
                   11129:                        (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
                   11130:                        if (!terminate) {
                   11131:                            if (ctxt->progressive) {
                   11132:                                if ((lastlt == NULL) ||
                   11133:                                    (ctxt->input->cur > lastlt))
                   11134:                                    goto done;
                   11135:                            } else if (xmlParseLookupSequence(ctxt,
                   11136:                                                              '<', 0, 0) < 0) {
                   11137:                                goto done;
                   11138:                            }
                   11139:                        }
                   11140:                     }
                   11141:                    ctxt->checkIndex = 0;
                   11142:                    xmlParseCharData(ctxt, 0);
                   11143:                }
                   11144:                /*
                   11145:                 * Pop-up of finished entities.
                   11146:                 */
                   11147:                while ((RAW == 0) && (ctxt->inputNr > 1))
                   11148:                    xmlPopInput(ctxt);
                   11149:                if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
                   11150:                    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   11151:                                "detected an error in element content\n");
                   11152:                    ctxt->instate = XML_PARSER_EOF;
                   11153:                    break;
                   11154:                }
                   11155:                break;
                   11156:            }
                   11157:             case XML_PARSER_END_TAG:
                   11158:                if (avail < 2)
                   11159:                    goto done;
                   11160:                if (!terminate) {
                   11161:                    if (ctxt->progressive) {
                   11162:                        /* > can be found unescaped in attribute values */
                   11163:                        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
                   11164:                            goto done;
                   11165:                    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
                   11166:                        goto done;
                   11167:                    }
                   11168:                }
                   11169:                if (ctxt->sax2) {
                   11170:                    xmlParseEndTag2(ctxt,
                   11171:                           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
                   11172:                           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
                   11173:                       (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
                   11174:                    nameNsPop(ctxt);
                   11175:                }
                   11176: #ifdef LIBXML_SAX1_ENABLED
                   11177:                  else
                   11178:                    xmlParseEndTag1(ctxt, 0);
                   11179: #endif /* LIBXML_SAX1_ENABLED */
1.1.1.2 ! misho    11180:                if (ctxt->instate == XML_PARSER_EOF) {
        !          11181:                    /* Nothing */
        !          11182:                } else if (ctxt->nameNr == 0) {
1.1       misho    11183:                    ctxt->instate = XML_PARSER_EPILOG;
                   11184:                } else {
                   11185:                    ctxt->instate = XML_PARSER_CONTENT;
                   11186:                }
                   11187:                break;
                   11188:             case XML_PARSER_CDATA_SECTION: {
                   11189:                /*
                   11190:                 * The Push mode need to have the SAX callback for 
                   11191:                 * cdataBlock merge back contiguous callbacks.
                   11192:                 */
                   11193:                int base;
                   11194: 
                   11195:                base = xmlParseLookupSequence(ctxt, ']', ']', '>');
                   11196:                if (base < 0) {
                   11197:                    if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
                   11198:                        int tmp;
                   11199: 
                   11200:                        tmp = xmlCheckCdataPush(ctxt->input->cur, 
                   11201:                                                XML_PARSER_BIG_BUFFER_SIZE);
                   11202:                        if (tmp < 0) {
                   11203:                            tmp = -tmp;
                   11204:                            ctxt->input->cur += tmp;
                   11205:                            goto encoding_error;
                   11206:                        }
                   11207:                        if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
                   11208:                            if (ctxt->sax->cdataBlock != NULL)
                   11209:                                ctxt->sax->cdataBlock(ctxt->userData,
                   11210:                                                      ctxt->input->cur, tmp);
                   11211:                            else if (ctxt->sax->characters != NULL)
                   11212:                                ctxt->sax->characters(ctxt->userData,
                   11213:                                                      ctxt->input->cur, tmp);
                   11214:                        }
                   11215:                        SKIPL(tmp);
                   11216:                        ctxt->checkIndex = 0;
                   11217:                    }
                   11218:                    goto done;
                   11219:                } else {
                   11220:                    int tmp;
                   11221: 
                   11222:                    tmp = xmlCheckCdataPush(ctxt->input->cur, base);
                   11223:                    if ((tmp < 0) || (tmp != base)) {
                   11224:                        tmp = -tmp;
                   11225:                        ctxt->input->cur += tmp;
                   11226:                        goto encoding_error;
                   11227:                    }
                   11228:                    if ((ctxt->sax != NULL) && (base == 0) &&
                   11229:                        (ctxt->sax->cdataBlock != NULL) &&
                   11230:                        (!ctxt->disableSAX)) {
                   11231:                        /*
                   11232:                         * Special case to provide identical behaviour
                   11233:                         * between pull and push parsers on enpty CDATA
                   11234:                         * sections
                   11235:                         */
                   11236:                         if ((ctxt->input->cur - ctxt->input->base >= 9) &&
                   11237:                             (!strncmp((const char *)&ctxt->input->cur[-9],
                   11238:                                       "<![CDATA[", 9)))
                   11239:                             ctxt->sax->cdataBlock(ctxt->userData,
                   11240:                                                   BAD_CAST "", 0);
                   11241:                    } else if ((ctxt->sax != NULL) && (base > 0) &&
                   11242:                        (!ctxt->disableSAX)) {
                   11243:                        if (ctxt->sax->cdataBlock != NULL)
                   11244:                            ctxt->sax->cdataBlock(ctxt->userData,
                   11245:                                                  ctxt->input->cur, base);
                   11246:                        else if (ctxt->sax->characters != NULL)
                   11247:                            ctxt->sax->characters(ctxt->userData,
                   11248:                                                  ctxt->input->cur, base);
                   11249:                    }
                   11250:                    SKIPL(base + 3);
                   11251:                    ctxt->checkIndex = 0;
                   11252:                    ctxt->instate = XML_PARSER_CONTENT;
                   11253: #ifdef DEBUG_PUSH
                   11254:                    xmlGenericError(xmlGenericErrorContext,
                   11255:                            "PP: entering CONTENT\n");
                   11256: #endif
                   11257:                }
                   11258:                break;
                   11259:            }
                   11260:             case XML_PARSER_MISC:
                   11261:                SKIP_BLANKS;
                   11262:                if (ctxt->input->buf == NULL)
                   11263:                    avail = ctxt->input->length -
                   11264:                            (ctxt->input->cur - ctxt->input->base);
                   11265:                else
                   11266:                    avail = ctxt->input->buf->buffer->use -
                   11267:                            (ctxt->input->cur - ctxt->input->base);
                   11268:                if (avail < 2)
                   11269:                    goto done;
                   11270:                cur = ctxt->input->cur[0];
                   11271:                next = ctxt->input->cur[1];
                   11272:                if ((cur == '<') && (next == '?')) {
                   11273:                    if ((!terminate) &&
                   11274:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
                   11275:                        goto done;
                   11276: #ifdef DEBUG_PUSH
                   11277:                    xmlGenericError(xmlGenericErrorContext,
                   11278:                            "PP: Parsing PI\n");
                   11279: #endif
                   11280:                    xmlParsePI(ctxt);
                   11281:                    ctxt->checkIndex = 0;
                   11282:                } else if ((cur == '<') && (next == '!') &&
                   11283:                    (ctxt->input->cur[2] == '-') &&
                   11284:                    (ctxt->input->cur[3] == '-')) {
                   11285:                    if ((!terminate) &&
                   11286:                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
                   11287:                        goto done;
                   11288: #ifdef DEBUG_PUSH
                   11289:                    xmlGenericError(xmlGenericErrorContext,
                   11290:                            "PP: Parsing Comment\n");
                   11291: #endif
                   11292:                    xmlParseComment(ctxt);
                   11293:                    ctxt->instate = XML_PARSER_MISC;
                   11294:                    ctxt->checkIndex = 0;
                   11295:                } else if ((cur == '<') && (next == '!') &&
                   11296:                    (ctxt->input->cur[2] == 'D') &&
                   11297:                    (ctxt->input->cur[3] == 'O') &&
                   11298:                    (ctxt->input->cur[4] == 'C') &&
                   11299:                    (ctxt->input->cur[5] == 'T') &&
                   11300:                    (ctxt->input->cur[6] == 'Y') &&
                   11301:                    (ctxt->input->cur[7] == 'P') &&
                   11302:                    (ctxt->input->cur[8] == 'E')) {
                   11303:                    if ((!terminate) &&
                   11304:                        (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
                   11305:                        goto done;
                   11306: #ifdef DEBUG_PUSH
                   11307:                    xmlGenericError(xmlGenericErrorContext,
                   11308:                            "PP: Parsing internal subset\n");
                   11309: #endif
                   11310:                    ctxt->inSubset = 1;
                   11311:                    xmlParseDocTypeDecl(ctxt);
                   11312:                    if (RAW == '[') {
                   11313:                        ctxt->instate = XML_PARSER_DTD;
                   11314: #ifdef DEBUG_PUSH
                   11315:                        xmlGenericError(xmlGenericErrorContext,
                   11316:                                "PP: entering DTD\n");
                   11317: #endif
                   11318:                    } else {
                   11319:                        /*
                   11320:                         * Create and update the external subset.
                   11321:                         */
                   11322:                        ctxt->inSubset = 2;
                   11323:                        if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   11324:                            (ctxt->sax->externalSubset != NULL))
                   11325:                            ctxt->sax->externalSubset(ctxt->userData,
                   11326:                                    ctxt->intSubName, ctxt->extSubSystem,
                   11327:                                    ctxt->extSubURI);
                   11328:                        ctxt->inSubset = 0;
                   11329:                        xmlCleanSpecialAttr(ctxt);
                   11330:                        ctxt->instate = XML_PARSER_PROLOG;
                   11331: #ifdef DEBUG_PUSH
                   11332:                        xmlGenericError(xmlGenericErrorContext,
                   11333:                                "PP: entering PROLOG\n");
                   11334: #endif
                   11335:                    }
                   11336:                } else if ((cur == '<') && (next == '!') &&
                   11337:                           (avail < 9)) {
                   11338:                    goto done;
                   11339:                } else {
                   11340:                    ctxt->instate = XML_PARSER_START_TAG;
                   11341:                    ctxt->progressive = 1;
                   11342:                    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
                   11343: #ifdef DEBUG_PUSH
                   11344:                    xmlGenericError(xmlGenericErrorContext,
                   11345:                            "PP: entering START_TAG\n");
                   11346: #endif
                   11347:                }
                   11348:                break;
                   11349:             case XML_PARSER_PROLOG:
                   11350:                SKIP_BLANKS;
                   11351:                if (ctxt->input->buf == NULL)
                   11352:                    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
                   11353:                else
                   11354:                    avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
                   11355:                if (avail < 2) 
                   11356:                    goto done;
                   11357:                cur = ctxt->input->cur[0];
                   11358:                next = ctxt->input->cur[1];
                   11359:                if ((cur == '<') && (next == '?')) {
                   11360:                    if ((!terminate) &&
                   11361:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
                   11362:                        goto done;
                   11363: #ifdef DEBUG_PUSH
                   11364:                    xmlGenericError(xmlGenericErrorContext,
                   11365:                            "PP: Parsing PI\n");
                   11366: #endif
                   11367:                    xmlParsePI(ctxt);
                   11368:                } else if ((cur == '<') && (next == '!') &&
                   11369:                    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
                   11370:                    if ((!terminate) &&
                   11371:                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
                   11372:                        goto done;
                   11373: #ifdef DEBUG_PUSH
                   11374:                    xmlGenericError(xmlGenericErrorContext,
                   11375:                            "PP: Parsing Comment\n");
                   11376: #endif
                   11377:                    xmlParseComment(ctxt);
                   11378:                    ctxt->instate = XML_PARSER_PROLOG;
                   11379:                } else if ((cur == '<') && (next == '!') &&
                   11380:                           (avail < 4)) {
                   11381:                    goto done;
                   11382:                } else {
                   11383:                    ctxt->instate = XML_PARSER_START_TAG;
                   11384:                    if (ctxt->progressive == 0)
                   11385:                        ctxt->progressive = 1;
                   11386:                    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
                   11387: #ifdef DEBUG_PUSH
                   11388:                    xmlGenericError(xmlGenericErrorContext,
                   11389:                            "PP: entering START_TAG\n");
                   11390: #endif
                   11391:                }
                   11392:                break;
                   11393:             case XML_PARSER_EPILOG:
                   11394:                SKIP_BLANKS;
                   11395:                if (ctxt->input->buf == NULL)
                   11396:                    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
                   11397:                else
                   11398:                    avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
                   11399:                if (avail < 2)
                   11400:                    goto done;
                   11401:                cur = ctxt->input->cur[0];
                   11402:                next = ctxt->input->cur[1];
                   11403:                if ((cur == '<') && (next == '?')) {
                   11404:                    if ((!terminate) &&
                   11405:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
                   11406:                        goto done;
                   11407: #ifdef DEBUG_PUSH
                   11408:                    xmlGenericError(xmlGenericErrorContext,
                   11409:                            "PP: Parsing PI\n");
                   11410: #endif
                   11411:                    xmlParsePI(ctxt);
                   11412:                    ctxt->instate = XML_PARSER_EPILOG;
                   11413:                } else if ((cur == '<') && (next == '!') &&
                   11414:                    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
                   11415:                    if ((!terminate) &&
                   11416:                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
                   11417:                        goto done;
                   11418: #ifdef DEBUG_PUSH
                   11419:                    xmlGenericError(xmlGenericErrorContext,
                   11420:                            "PP: Parsing Comment\n");
                   11421: #endif
                   11422:                    xmlParseComment(ctxt);
                   11423:                    ctxt->instate = XML_PARSER_EPILOG;
                   11424:                } else if ((cur == '<') && (next == '!') &&
                   11425:                           (avail < 4)) {
                   11426:                    goto done;
                   11427:                } else {
                   11428:                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
                   11429:                    ctxt->instate = XML_PARSER_EOF;
                   11430: #ifdef DEBUG_PUSH
                   11431:                    xmlGenericError(xmlGenericErrorContext,
                   11432:                            "PP: entering EOF\n");
                   11433: #endif
                   11434:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   11435:                        ctxt->sax->endDocument(ctxt->userData);
                   11436:                    goto done;
                   11437:                }
                   11438:                break;
                   11439:             case XML_PARSER_DTD: {
                   11440:                /*
                   11441:                 * Sorry but progressive parsing of the internal subset
                   11442:                 * is not expected to be supported. We first check that
                   11443:                 * the full content of the internal subset is available and
                   11444:                 * the parsing is launched only at that point.
                   11445:                 * Internal subset ends up with "']' S? '>'" in an unescaped
                   11446:                 * section and not in a ']]>' sequence which are conditional
                   11447:                 * sections (whoever argued to keep that crap in XML deserve
                   11448:                 * a place in hell !).
                   11449:                 */
                   11450:                int base, i;
                   11451:                xmlChar *buf;
                   11452:                xmlChar quote = 0;
                   11453: 
                   11454:                base = ctxt->input->cur - ctxt->input->base;
                   11455:                if (base < 0) return(0);
                   11456:                if (ctxt->checkIndex > base)
                   11457:                    base = ctxt->checkIndex;
                   11458:                buf = ctxt->input->buf->buffer->content;
                   11459:                for (;(unsigned int) base < ctxt->input->buf->buffer->use;
                   11460:                     base++) {
                   11461:                    if (quote != 0) {
                   11462:                        if (buf[base] == quote)
                   11463:                            quote = 0;
                   11464:                        continue;    
                   11465:                    }
                   11466:                    if ((quote == 0) && (buf[base] == '<')) {
                   11467:                        int found  = 0;
                   11468:                        /* special handling of comments */
                   11469:                        if (((unsigned int) base + 4 <
                   11470:                             ctxt->input->buf->buffer->use) &&
                   11471:                            (buf[base + 1] == '!') &&
                   11472:                            (buf[base + 2] == '-') &&
                   11473:                            (buf[base + 3] == '-')) {
                   11474:                            for (;(unsigned int) base + 3 <
                   11475:                                  ctxt->input->buf->buffer->use; base++) {
                   11476:                                if ((buf[base] == '-') &&
                   11477:                                    (buf[base + 1] == '-') &&
                   11478:                                    (buf[base + 2] == '>')) {
                   11479:                                    found = 1;
                   11480:                                    base += 2;
                   11481:                                    break;
                   11482:                                }
                   11483:                            }
                   11484:                            if (!found) {
                   11485: #if 0
                   11486:                                fprintf(stderr, "unfinished comment\n");
                   11487: #endif
                   11488:                                break; /* for */
                   11489:                            }
                   11490:                            continue;
                   11491:                        }
                   11492:                    }
                   11493:                    if (buf[base] == '"') {
                   11494:                        quote = '"';
                   11495:                        continue;
                   11496:                    }
                   11497:                    if (buf[base] == '\'') {
                   11498:                        quote = '\'';
                   11499:                        continue;
                   11500:                    }
                   11501:                    if (buf[base] == ']') {
                   11502: #if 0
                   11503:                        fprintf(stderr, "%c%c%c%c: ", buf[base],
                   11504:                                buf[base + 1], buf[base + 2], buf[base + 3]);
                   11505: #endif
                   11506:                        if ((unsigned int) base +1 >=
                   11507:                            ctxt->input->buf->buffer->use)
                   11508:                            break;
                   11509:                        if (buf[base + 1] == ']') {
                   11510:                            /* conditional crap, skip both ']' ! */
                   11511:                            base++;
                   11512:                            continue;
                   11513:                        }
                   11514:                        for (i = 1;
                   11515:                     (unsigned int) base + i < ctxt->input->buf->buffer->use;
                   11516:                             i++) {
                   11517:                            if (buf[base + i] == '>') {
                   11518: #if 0
                   11519:                                fprintf(stderr, "found\n");
                   11520: #endif
                   11521:                                goto found_end_int_subset;
                   11522:                            }
                   11523:                            if (!IS_BLANK_CH(buf[base + i])) {
                   11524: #if 0
                   11525:                                fprintf(stderr, "not found\n");
                   11526: #endif
                   11527:                                goto not_end_of_int_subset;
                   11528:                            }
                   11529:                        }
                   11530: #if 0
                   11531:                        fprintf(stderr, "end of stream\n");
                   11532: #endif
                   11533:                        break;
                   11534:                         
                   11535:                    }
                   11536: not_end_of_int_subset:
                   11537:                     continue; /* for */
                   11538:                }
                   11539:                /*
                   11540:                 * We didn't found the end of the Internal subset
                   11541:                 */
                   11542: #ifdef DEBUG_PUSH
                   11543:                if (next == 0)
                   11544:                    xmlGenericError(xmlGenericErrorContext,
                   11545:                            "PP: lookup of int subset end filed\n");
                   11546: #endif
                   11547:                goto done;
                   11548: 
                   11549: found_end_int_subset:
                   11550:                xmlParseInternalSubset(ctxt);
                   11551:                ctxt->inSubset = 2;
                   11552:                if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   11553:                    (ctxt->sax->externalSubset != NULL))
                   11554:                    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
                   11555:                            ctxt->extSubSystem, ctxt->extSubURI);
                   11556:                ctxt->inSubset = 0;
                   11557:                xmlCleanSpecialAttr(ctxt);
                   11558:                ctxt->instate = XML_PARSER_PROLOG;
                   11559:                ctxt->checkIndex = 0;
                   11560: #ifdef DEBUG_PUSH
                   11561:                xmlGenericError(xmlGenericErrorContext,
                   11562:                        "PP: entering PROLOG\n");
                   11563: #endif
                   11564:                 break;
                   11565:            }
                   11566:             case XML_PARSER_COMMENT:
                   11567:                xmlGenericError(xmlGenericErrorContext,
                   11568:                        "PP: internal error, state == COMMENT\n");
                   11569:                ctxt->instate = XML_PARSER_CONTENT;
                   11570: #ifdef DEBUG_PUSH
                   11571:                xmlGenericError(xmlGenericErrorContext,
                   11572:                        "PP: entering CONTENT\n");
                   11573: #endif
                   11574:                break;
                   11575:             case XML_PARSER_IGNORE:
                   11576:                xmlGenericError(xmlGenericErrorContext,
                   11577:                        "PP: internal error, state == IGNORE");
                   11578:                ctxt->instate = XML_PARSER_DTD;
                   11579: #ifdef DEBUG_PUSH
                   11580:                xmlGenericError(xmlGenericErrorContext,
                   11581:                        "PP: entering DTD\n");
                   11582: #endif
                   11583:                break;
                   11584:             case XML_PARSER_PI:
                   11585:                xmlGenericError(xmlGenericErrorContext,
                   11586:                        "PP: internal error, state == PI\n");
                   11587:                ctxt->instate = XML_PARSER_CONTENT;
                   11588: #ifdef DEBUG_PUSH
                   11589:                xmlGenericError(xmlGenericErrorContext,
                   11590:                        "PP: entering CONTENT\n");
                   11591: #endif
                   11592:                break;
                   11593:             case XML_PARSER_ENTITY_DECL:
                   11594:                xmlGenericError(xmlGenericErrorContext,
                   11595:                        "PP: internal error, state == ENTITY_DECL\n");
                   11596:                ctxt->instate = XML_PARSER_DTD;
                   11597: #ifdef DEBUG_PUSH
                   11598:                xmlGenericError(xmlGenericErrorContext,
                   11599:                        "PP: entering DTD\n");
                   11600: #endif
                   11601:                break;
                   11602:             case XML_PARSER_ENTITY_VALUE:
                   11603:                xmlGenericError(xmlGenericErrorContext,
                   11604:                        "PP: internal error, state == ENTITY_VALUE\n");
                   11605:                ctxt->instate = XML_PARSER_CONTENT;
                   11606: #ifdef DEBUG_PUSH
                   11607:                xmlGenericError(xmlGenericErrorContext,
                   11608:                        "PP: entering DTD\n");
                   11609: #endif
                   11610:                break;
                   11611:             case XML_PARSER_ATTRIBUTE_VALUE:
                   11612:                xmlGenericError(xmlGenericErrorContext,
                   11613:                        "PP: internal error, state == ATTRIBUTE_VALUE\n");
                   11614:                ctxt->instate = XML_PARSER_START_TAG;
                   11615: #ifdef DEBUG_PUSH
                   11616:                xmlGenericError(xmlGenericErrorContext,
                   11617:                        "PP: entering START_TAG\n");
                   11618: #endif
                   11619:                break;
                   11620:             case XML_PARSER_SYSTEM_LITERAL:
                   11621:                xmlGenericError(xmlGenericErrorContext,
                   11622:                        "PP: internal error, state == SYSTEM_LITERAL\n");
                   11623:                ctxt->instate = XML_PARSER_START_TAG;
                   11624: #ifdef DEBUG_PUSH
                   11625:                xmlGenericError(xmlGenericErrorContext,
                   11626:                        "PP: entering START_TAG\n");
                   11627: #endif
                   11628:                break;
                   11629:             case XML_PARSER_PUBLIC_LITERAL:
                   11630:                xmlGenericError(xmlGenericErrorContext,
                   11631:                        "PP: internal error, state == PUBLIC_LITERAL\n");
                   11632:                ctxt->instate = XML_PARSER_START_TAG;
                   11633: #ifdef DEBUG_PUSH
                   11634:                xmlGenericError(xmlGenericErrorContext,
                   11635:                        "PP: entering START_TAG\n");
                   11636: #endif
                   11637:                break;
                   11638:        }
                   11639:     }
                   11640: done:    
                   11641: #ifdef DEBUG_PUSH
                   11642:     xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
                   11643: #endif
                   11644:     return(ret);
                   11645: encoding_error:
                   11646:     {
                   11647:         char buffer[150];
                   11648: 
                   11649:        snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
                   11650:                        ctxt->input->cur[0], ctxt->input->cur[1],
                   11651:                        ctxt->input->cur[2], ctxt->input->cur[3]);
                   11652:        __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
                   11653:                     "Input is not proper UTF-8, indicate encoding !\n%s",
                   11654:                     BAD_CAST buffer, NULL);
                   11655:     }
                   11656:     return(0);
                   11657: }
                   11658: 
                   11659: /**
                   11660:  * xmlParseChunk:
                   11661:  * @ctxt:  an XML parser context
                   11662:  * @chunk:  an char array
                   11663:  * @size:  the size in byte of the chunk
                   11664:  * @terminate:  last chunk indicator
                   11665:  *
                   11666:  * Parse a Chunk of memory
                   11667:  *
                   11668:  * Returns zero if no error, the xmlParserErrors otherwise.
                   11669:  */
                   11670: int
                   11671: xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
                   11672:               int terminate) {
                   11673:     int end_in_lf = 0;
                   11674:     int remain = 0;
                   11675: 
                   11676:     if (ctxt == NULL)
                   11677:         return(XML_ERR_INTERNAL_ERROR);
                   11678:     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
                   11679:         return(ctxt->errNo);
                   11680:     if (ctxt->instate == XML_PARSER_START)
                   11681:         xmlDetectSAX2(ctxt);
                   11682:     if ((size > 0) && (chunk != NULL) && (!terminate) &&
                   11683:         (chunk[size - 1] == '\r')) {
                   11684:        end_in_lf = 1;
                   11685:        size--;
                   11686:     }
                   11687: 
                   11688: xmldecl_done:
                   11689: 
                   11690:     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
                   11691:         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
                   11692:        int base = ctxt->input->base - ctxt->input->buf->buffer->content;
                   11693:        int cur = ctxt->input->cur - ctxt->input->base;
                   11694:        int res;
                   11695: 
                   11696:         /*
                   11697:          * Specific handling if we autodetected an encoding, we should not
                   11698:          * push more than the first line ... which depend on the encoding
                   11699:          * And only push the rest once the final encoding was detected
                   11700:          */
                   11701:         if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
                   11702:             (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
                   11703:             unsigned int len = 45;
                   11704: 
                   11705:             if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
                   11706:                                BAD_CAST "UTF-16")) ||
                   11707:                 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
                   11708:                                BAD_CAST "UTF16")))
                   11709:                 len = 90;
                   11710:             else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
                   11711:                                     BAD_CAST "UCS-4")) ||
                   11712:                      (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
                   11713:                                     BAD_CAST "UCS4")))
                   11714:                 len = 180;
                   11715: 
                   11716:             if (ctxt->input->buf->rawconsumed < len)
                   11717:                 len -= ctxt->input->buf->rawconsumed;
                   11718: 
                   11719:             /*
                   11720:              * Change size for reading the initial declaration only
                   11721:              * if size is greater than len. Otherwise, memmove in xmlBufferAdd
                   11722:              * will blindly copy extra bytes from memory.
                   11723:              */
                   11724:             if ((unsigned int) size > len) {
                   11725:                 remain = size - len;
                   11726:                 size = len;
                   11727:             } else {
                   11728:                 remain = 0;
                   11729:             }
                   11730:         }
                   11731:        res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
                   11732:        if (res < 0) {
                   11733:            ctxt->errNo = XML_PARSER_EOF;
                   11734:            ctxt->disableSAX = 1;
                   11735:            return (XML_PARSER_EOF);
                   11736:        }
                   11737:        ctxt->input->base = ctxt->input->buf->buffer->content + base;
                   11738:        ctxt->input->cur = ctxt->input->base + cur;
                   11739:        ctxt->input->end =
                   11740:            &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
                   11741: #ifdef DEBUG_PUSH
                   11742:        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
                   11743: #endif
                   11744: 
                   11745:     } else if (ctxt->instate != XML_PARSER_EOF) {
                   11746:        if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
                   11747:            xmlParserInputBufferPtr in = ctxt->input->buf;
                   11748:            if ((in->encoder != NULL) && (in->buffer != NULL) &&
                   11749:                    (in->raw != NULL)) {
                   11750:                int nbchars;
                   11751: 
                   11752:                nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
                   11753:                if (nbchars < 0) {
                   11754:                    /* TODO 2.6.0 */
                   11755:                    xmlGenericError(xmlGenericErrorContext,
                   11756:                                    "xmlParseChunk: encoder error\n");
                   11757:                    return(XML_ERR_INVALID_ENCODING);
                   11758:                }
                   11759:            }
                   11760:        }
                   11761:     }
                   11762:     if (remain != 0)
                   11763:         xmlParseTryOrFinish(ctxt, 0);
                   11764:     else
                   11765:         xmlParseTryOrFinish(ctxt, terminate);
                   11766:     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
                   11767:         return(ctxt->errNo);
                   11768: 
                   11769:     if (remain != 0) {
                   11770:         chunk += size;
                   11771:         size = remain;
                   11772:         remain = 0;
                   11773:         goto xmldecl_done;
                   11774:     }
                   11775:     if ((end_in_lf == 1) && (ctxt->input != NULL) &&
                   11776:         (ctxt->input->buf != NULL)) {
                   11777:        xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
                   11778:     }
                   11779:     if (terminate) {
                   11780:        /*
                   11781:         * Check for termination
                   11782:         */
                   11783:        int avail = 0;
                   11784: 
                   11785:        if (ctxt->input != NULL) {
                   11786:            if (ctxt->input->buf == NULL)
                   11787:                avail = ctxt->input->length -
                   11788:                        (ctxt->input->cur - ctxt->input->base);
                   11789:            else
                   11790:                avail = ctxt->input->buf->buffer->use -
                   11791:                        (ctxt->input->cur - ctxt->input->base);
                   11792:        }
                   11793:                            
                   11794:        if ((ctxt->instate != XML_PARSER_EOF) &&
                   11795:            (ctxt->instate != XML_PARSER_EPILOG)) {
                   11796:            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
                   11797:        } 
                   11798:        if ((ctxt->instate == XML_PARSER_EPILOG) && (avail > 0)) {
                   11799:            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
                   11800:        }
                   11801:        if (ctxt->instate != XML_PARSER_EOF) {
                   11802:            if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   11803:                ctxt->sax->endDocument(ctxt->userData);
                   11804:        }
                   11805:        ctxt->instate = XML_PARSER_EOF;
                   11806:     }
                   11807:     return((xmlParserErrors) ctxt->errNo);           
                   11808: }
                   11809: 
                   11810: /************************************************************************
                   11811:  *                                                                     *
                   11812:  *             I/O front end functions to the parser                   *
                   11813:  *                                                                     *
                   11814:  ************************************************************************/
                   11815: 
                   11816: /**
                   11817:  * xmlCreatePushParserCtxt:
                   11818:  * @sax:  a SAX handler
                   11819:  * @user_data:  The user data returned on SAX callbacks
                   11820:  * @chunk:  a pointer to an array of chars
                   11821:  * @size:  number of chars in the array
                   11822:  * @filename:  an optional file name or URI
                   11823:  *
                   11824:  * Create a parser context for using the XML parser in push mode.
                   11825:  * If @buffer and @size are non-NULL, the data is used to detect
                   11826:  * the encoding.  The remaining characters will be parsed so they
                   11827:  * don't need to be fed in again through xmlParseChunk.
                   11828:  * To allow content encoding detection, @size should be >= 4
                   11829:  * The value of @filename is used for fetching external entities
                   11830:  * and error/warning reports.
                   11831:  *
                   11832:  * Returns the new parser context or NULL
                   11833:  */
                   11834: 
                   11835: xmlParserCtxtPtr
                   11836: xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data, 
                   11837:                         const char *chunk, int size, const char *filename) {
                   11838:     xmlParserCtxtPtr ctxt;
                   11839:     xmlParserInputPtr inputStream;
                   11840:     xmlParserInputBufferPtr buf;
                   11841:     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
                   11842: 
                   11843:     /*
                   11844:      * plug some encoding conversion routines
                   11845:      */
                   11846:     if ((chunk != NULL) && (size >= 4))
                   11847:        enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
                   11848: 
                   11849:     buf = xmlAllocParserInputBuffer(enc);
                   11850:     if (buf == NULL) return(NULL);
                   11851: 
                   11852:     ctxt = xmlNewParserCtxt();
                   11853:     if (ctxt == NULL) {
                   11854:         xmlErrMemory(NULL, "creating parser: out of memory\n");
                   11855:        xmlFreeParserInputBuffer(buf);
                   11856:        return(NULL);
                   11857:     }
                   11858:     ctxt->dictNames = 1;
                   11859:     ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
                   11860:     if (ctxt->pushTab == NULL) {
                   11861:         xmlErrMemory(ctxt, NULL);
                   11862:        xmlFreeParserInputBuffer(buf);
                   11863:        xmlFreeParserCtxt(ctxt);
                   11864:        return(NULL);
                   11865:     }
                   11866:     if (sax != NULL) {
                   11867: #ifdef LIBXML_SAX1_ENABLED
                   11868:        if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
                   11869: #endif /* LIBXML_SAX1_ENABLED */
                   11870:            xmlFree(ctxt->sax);
                   11871:        ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
                   11872:        if (ctxt->sax == NULL) {
                   11873:            xmlErrMemory(ctxt, NULL);
                   11874:            xmlFreeParserInputBuffer(buf);
                   11875:            xmlFreeParserCtxt(ctxt);
                   11876:            return(NULL);
                   11877:        }
                   11878:        memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
                   11879:        if (sax->initialized == XML_SAX2_MAGIC)
                   11880:            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
                   11881:        else
                   11882:            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
                   11883:        if (user_data != NULL)
                   11884:            ctxt->userData = user_data;
                   11885:     }  
                   11886:     if (filename == NULL) {
                   11887:        ctxt->directory = NULL;
                   11888:     } else {
                   11889:         ctxt->directory = xmlParserGetDirectory(filename);
                   11890:     }
                   11891: 
                   11892:     inputStream = xmlNewInputStream(ctxt);
                   11893:     if (inputStream == NULL) {
                   11894:        xmlFreeParserCtxt(ctxt);
                   11895:        xmlFreeParserInputBuffer(buf);
                   11896:        return(NULL);
                   11897:     }
                   11898: 
                   11899:     if (filename == NULL)
                   11900:        inputStream->filename = NULL;
                   11901:     else {
                   11902:        inputStream->filename = (char *)
                   11903:            xmlCanonicPath((const xmlChar *) filename);
                   11904:        if (inputStream->filename == NULL) {
                   11905:            xmlFreeParserCtxt(ctxt);
                   11906:            xmlFreeParserInputBuffer(buf);
                   11907:            return(NULL);
                   11908:        }
                   11909:     }
                   11910:     inputStream->buf = buf;
                   11911:     inputStream->base = inputStream->buf->buffer->content;
                   11912:     inputStream->cur = inputStream->buf->buffer->content;
                   11913:     inputStream->end = 
                   11914:        &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
                   11915: 
                   11916:     inputPush(ctxt, inputStream);
                   11917: 
                   11918:     /*
                   11919:      * If the caller didn't provide an initial 'chunk' for determining
                   11920:      * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
                   11921:      * that it can be automatically determined later
                   11922:      */
                   11923:     if ((size == 0) || (chunk == NULL)) {
                   11924:        ctxt->charset = XML_CHAR_ENCODING_NONE;
                   11925:     } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
                   11926:        int base = ctxt->input->base - ctxt->input->buf->buffer->content;
                   11927:        int cur = ctxt->input->cur - ctxt->input->base;
                   11928: 
                   11929:        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);              
                   11930: 
                   11931:        ctxt->input->base = ctxt->input->buf->buffer->content + base;
                   11932:        ctxt->input->cur = ctxt->input->base + cur;
                   11933:        ctxt->input->end =
                   11934:            &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
                   11935: #ifdef DEBUG_PUSH
                   11936:        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
                   11937: #endif
                   11938:     }
                   11939: 
                   11940:     if (enc != XML_CHAR_ENCODING_NONE) {
                   11941:         xmlSwitchEncoding(ctxt, enc);
                   11942:     }
                   11943: 
                   11944:     return(ctxt);
                   11945: }
                   11946: #endif /* LIBXML_PUSH_ENABLED */
                   11947: 
                   11948: /**
                   11949:  * xmlStopParser:
                   11950:  * @ctxt:  an XML parser context
                   11951:  *
                   11952:  * Blocks further parser processing
                   11953:  */
                   11954: void           
                   11955: xmlStopParser(xmlParserCtxtPtr ctxt) {
                   11956:     if (ctxt == NULL)
                   11957:         return;
                   11958:     ctxt->instate = XML_PARSER_EOF;
                   11959:     ctxt->disableSAX = 1;
                   11960:     if (ctxt->input != NULL) {
                   11961:        ctxt->input->cur = BAD_CAST"";
                   11962:        ctxt->input->base = ctxt->input->cur;
                   11963:     }
                   11964: }
                   11965: 
                   11966: /**
                   11967:  * xmlCreateIOParserCtxt:
                   11968:  * @sax:  a SAX handler
                   11969:  * @user_data:  The user data returned on SAX callbacks
                   11970:  * @ioread:  an I/O read function
                   11971:  * @ioclose:  an I/O close function
                   11972:  * @ioctx:  an I/O handler
                   11973:  * @enc:  the charset encoding if known
                   11974:  *
                   11975:  * Create a parser context for using the XML parser with an existing
                   11976:  * I/O stream
                   11977:  *
                   11978:  * Returns the new parser context or NULL
                   11979:  */
                   11980: xmlParserCtxtPtr
                   11981: xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
                   11982:        xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
                   11983:        void *ioctx, xmlCharEncoding enc) {
                   11984:     xmlParserCtxtPtr ctxt;
                   11985:     xmlParserInputPtr inputStream;
                   11986:     xmlParserInputBufferPtr buf;
1.1.1.2 ! misho    11987: 
1.1       misho    11988:     if (ioread == NULL) return(NULL);
                   11989: 
                   11990:     buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
1.1.1.2 ! misho    11991:     if (buf == NULL) {
        !          11992:         if (ioclose != NULL)
        !          11993:             ioclose(ioctx);
        !          11994:         return (NULL);
        !          11995:     }
1.1       misho    11996: 
                   11997:     ctxt = xmlNewParserCtxt();
                   11998:     if (ctxt == NULL) {
                   11999:        xmlFreeParserInputBuffer(buf);
                   12000:        return(NULL);
                   12001:     }
                   12002:     if (sax != NULL) {
                   12003: #ifdef LIBXML_SAX1_ENABLED
                   12004:        if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
                   12005: #endif /* LIBXML_SAX1_ENABLED */
                   12006:            xmlFree(ctxt->sax);
                   12007:        ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
                   12008:        if (ctxt->sax == NULL) {
                   12009:            xmlErrMemory(ctxt, NULL);
                   12010:            xmlFreeParserCtxt(ctxt);
                   12011:            return(NULL);
                   12012:        }
                   12013:        memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
                   12014:        if (sax->initialized == XML_SAX2_MAGIC)
                   12015:            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
                   12016:        else
                   12017:            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
                   12018:        if (user_data != NULL)
                   12019:            ctxt->userData = user_data;
1.1.1.2 ! misho    12020:     }
1.1       misho    12021: 
                   12022:     inputStream = xmlNewIOInputStream(ctxt, buf, enc);
                   12023:     if (inputStream == NULL) {
                   12024:        xmlFreeParserCtxt(ctxt);
                   12025:        return(NULL);
                   12026:     }
                   12027:     inputPush(ctxt, inputStream);
                   12028: 
                   12029:     return(ctxt);
                   12030: }
                   12031: 
                   12032: #ifdef LIBXML_VALID_ENABLED
                   12033: /************************************************************************
                   12034:  *                                                                     *
                   12035:  *             Front ends when parsing a DTD                           *
                   12036:  *                                                                     *
                   12037:  ************************************************************************/
                   12038: 
                   12039: /**
                   12040:  * xmlIOParseDTD:
                   12041:  * @sax:  the SAX handler block or NULL
                   12042:  * @input:  an Input Buffer
                   12043:  * @enc:  the charset encoding if known
                   12044:  *
                   12045:  * Load and parse a DTD
                   12046:  * 
                   12047:  * Returns the resulting xmlDtdPtr or NULL in case of error.
                   12048:  * @input will be freed by the function in any case.
                   12049:  */
                   12050: 
                   12051: xmlDtdPtr
                   12052: xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
                   12053:              xmlCharEncoding enc) {
                   12054:     xmlDtdPtr ret = NULL;
                   12055:     xmlParserCtxtPtr ctxt;
                   12056:     xmlParserInputPtr pinput = NULL;
                   12057:     xmlChar start[4];
                   12058: 
                   12059:     if (input == NULL)
                   12060:        return(NULL);
                   12061: 
                   12062:     ctxt = xmlNewParserCtxt();
                   12063:     if (ctxt == NULL) {
                   12064:         xmlFreeParserInputBuffer(input);
                   12065:        return(NULL);
                   12066:     }
                   12067: 
                   12068:     /*
                   12069:      * Set-up the SAX context
                   12070:      */
                   12071:     if (sax != NULL) { 
                   12072:        if (ctxt->sax != NULL)
                   12073:            xmlFree(ctxt->sax);
                   12074:         ctxt->sax = sax;
                   12075:         ctxt->userData = ctxt;
                   12076:     }
                   12077:     xmlDetectSAX2(ctxt);
                   12078: 
                   12079:     /*
                   12080:      * generate a parser input from the I/O handler
                   12081:      */
                   12082: 
                   12083:     pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   12084:     if (pinput == NULL) {
                   12085:         if (sax != NULL) ctxt->sax = NULL;
                   12086:         xmlFreeParserInputBuffer(input);
                   12087:        xmlFreeParserCtxt(ctxt);
                   12088:        return(NULL);
                   12089:     }
                   12090: 
                   12091:     /*
                   12092:      * plug some encoding conversion routines here.
                   12093:      */
                   12094:     if (xmlPushInput(ctxt, pinput) < 0) {
                   12095:         if (sax != NULL) ctxt->sax = NULL;
                   12096:        xmlFreeParserCtxt(ctxt);
                   12097:        return(NULL);
                   12098:     }
                   12099:     if (enc != XML_CHAR_ENCODING_NONE) {
                   12100:         xmlSwitchEncoding(ctxt, enc);
                   12101:     }
                   12102: 
                   12103:     pinput->filename = NULL;
                   12104:     pinput->line = 1;
                   12105:     pinput->col = 1;
                   12106:     pinput->base = ctxt->input->cur;
                   12107:     pinput->cur = ctxt->input->cur;
                   12108:     pinput->free = NULL;
                   12109: 
                   12110:     /*
                   12111:      * let's parse that entity knowing it's an external subset.
                   12112:      */
                   12113:     ctxt->inSubset = 2;
                   12114:     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
                   12115:     if (ctxt->myDoc == NULL) {
                   12116:        xmlErrMemory(ctxt, "New Doc failed");
                   12117:        return(NULL);
                   12118:     }
                   12119:     ctxt->myDoc->properties = XML_DOC_INTERNAL;
                   12120:     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
                   12121:                                       BAD_CAST "none", BAD_CAST "none");
                   12122: 
                   12123:     if ((enc == XML_CHAR_ENCODING_NONE) &&
                   12124:         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
                   12125:        /* 
                   12126:         * Get the 4 first bytes and decode the charset
                   12127:         * if enc != XML_CHAR_ENCODING_NONE
                   12128:         * plug some encoding conversion routines.
                   12129:         */
                   12130:        start[0] = RAW;
                   12131:        start[1] = NXT(1);
                   12132:        start[2] = NXT(2);
                   12133:        start[3] = NXT(3);
                   12134:        enc = xmlDetectCharEncoding(start, 4);
                   12135:        if (enc != XML_CHAR_ENCODING_NONE) {
                   12136:            xmlSwitchEncoding(ctxt, enc);
                   12137:        }
                   12138:     }
                   12139: 
                   12140:     xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
                   12141: 
                   12142:     if (ctxt->myDoc != NULL) {
                   12143:        if (ctxt->wellFormed) {
                   12144:            ret = ctxt->myDoc->extSubset;
                   12145:            ctxt->myDoc->extSubset = NULL;
                   12146:            if (ret != NULL) {
                   12147:                xmlNodePtr tmp;
                   12148: 
                   12149:                ret->doc = NULL;
                   12150:                tmp = ret->children;
                   12151:                while (tmp != NULL) {
                   12152:                    tmp->doc = NULL;
                   12153:                    tmp = tmp->next;
                   12154:                }
                   12155:            }
                   12156:        } else {
                   12157:            ret = NULL;
                   12158:        }
                   12159:         xmlFreeDoc(ctxt->myDoc);
                   12160:         ctxt->myDoc = NULL;
                   12161:     }
                   12162:     if (sax != NULL) ctxt->sax = NULL;
                   12163:     xmlFreeParserCtxt(ctxt);
                   12164:     
                   12165:     return(ret);
                   12166: }
                   12167: 
                   12168: /**
                   12169:  * xmlSAXParseDTD:
                   12170:  * @sax:  the SAX handler block
                   12171:  * @ExternalID:  a NAME* containing the External ID of the DTD
                   12172:  * @SystemID:  a NAME* containing the URL to the DTD
                   12173:  *
                   12174:  * Load and parse an external subset.
                   12175:  * 
                   12176:  * Returns the resulting xmlDtdPtr or NULL in case of error.
                   12177:  */
                   12178: 
                   12179: xmlDtdPtr
                   12180: xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
                   12181:                           const xmlChar *SystemID) {
                   12182:     xmlDtdPtr ret = NULL;
                   12183:     xmlParserCtxtPtr ctxt;
                   12184:     xmlParserInputPtr input = NULL;
                   12185:     xmlCharEncoding enc;
                   12186:     xmlChar* systemIdCanonic;
                   12187: 
                   12188:     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
                   12189: 
                   12190:     ctxt = xmlNewParserCtxt();
                   12191:     if (ctxt == NULL) {
                   12192:        return(NULL);
                   12193:     }
                   12194: 
                   12195:     /*
                   12196:      * Set-up the SAX context
                   12197:      */
                   12198:     if (sax != NULL) { 
                   12199:        if (ctxt->sax != NULL)
                   12200:            xmlFree(ctxt->sax);
                   12201:         ctxt->sax = sax;
                   12202:         ctxt->userData = ctxt;
                   12203:     }
                   12204:     
                   12205:     /*
                   12206:      * Canonicalise the system ID
                   12207:      */
                   12208:     systemIdCanonic = xmlCanonicPath(SystemID);
                   12209:     if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
                   12210:        xmlFreeParserCtxt(ctxt);
                   12211:        return(NULL);
                   12212:     }
                   12213: 
                   12214:     /*
                   12215:      * Ask the Entity resolver to load the damn thing
                   12216:      */
                   12217: 
                   12218:     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
                   12219:        input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
                   12220:                                         systemIdCanonic);
                   12221:     if (input == NULL) {
                   12222:         if (sax != NULL) ctxt->sax = NULL;
                   12223:        xmlFreeParserCtxt(ctxt);
                   12224:        if (systemIdCanonic != NULL)
                   12225:            xmlFree(systemIdCanonic);
                   12226:        return(NULL);
                   12227:     }
                   12228: 
                   12229:     /*
                   12230:      * plug some encoding conversion routines here.
                   12231:      */
                   12232:     if (xmlPushInput(ctxt, input) < 0) {
                   12233:         if (sax != NULL) ctxt->sax = NULL;
                   12234:        xmlFreeParserCtxt(ctxt);
                   12235:        if (systemIdCanonic != NULL)
                   12236:            xmlFree(systemIdCanonic);
                   12237:        return(NULL);
                   12238:     }
                   12239:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
                   12240:        enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
                   12241:        xmlSwitchEncoding(ctxt, enc);
                   12242:     }
                   12243: 
                   12244:     if (input->filename == NULL)
                   12245:        input->filename = (char *) systemIdCanonic;
                   12246:     else
                   12247:        xmlFree(systemIdCanonic);
                   12248:     input->line = 1;
                   12249:     input->col = 1;
                   12250:     input->base = ctxt->input->cur;
                   12251:     input->cur = ctxt->input->cur;
                   12252:     input->free = NULL;
                   12253: 
                   12254:     /*
                   12255:      * let's parse that entity knowing it's an external subset.
                   12256:      */
                   12257:     ctxt->inSubset = 2;
                   12258:     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
                   12259:     if (ctxt->myDoc == NULL) {
                   12260:        xmlErrMemory(ctxt, "New Doc failed");
                   12261:         if (sax != NULL) ctxt->sax = NULL;
                   12262:        xmlFreeParserCtxt(ctxt);
                   12263:        return(NULL);
                   12264:     }
                   12265:     ctxt->myDoc->properties = XML_DOC_INTERNAL;
                   12266:     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
                   12267:                                       ExternalID, SystemID);
                   12268:     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
                   12269: 
                   12270:     if (ctxt->myDoc != NULL) {
                   12271:        if (ctxt->wellFormed) {
                   12272:            ret = ctxt->myDoc->extSubset;
                   12273:            ctxt->myDoc->extSubset = NULL;
                   12274:            if (ret != NULL) {
                   12275:                xmlNodePtr tmp;
                   12276: 
                   12277:                ret->doc = NULL;
                   12278:                tmp = ret->children;
                   12279:                while (tmp != NULL) {
                   12280:                    tmp->doc = NULL;
                   12281:                    tmp = tmp->next;
                   12282:                }
                   12283:            }
                   12284:        } else {
                   12285:            ret = NULL;
                   12286:        }
                   12287:         xmlFreeDoc(ctxt->myDoc);
                   12288:         ctxt->myDoc = NULL;
                   12289:     }
                   12290:     if (sax != NULL) ctxt->sax = NULL;
                   12291:     xmlFreeParserCtxt(ctxt);
                   12292: 
                   12293:     return(ret);
                   12294: }
                   12295: 
                   12296: 
                   12297: /**
                   12298:  * xmlParseDTD:
                   12299:  * @ExternalID:  a NAME* containing the External ID of the DTD
                   12300:  * @SystemID:  a NAME* containing the URL to the DTD
                   12301:  *
                   12302:  * Load and parse an external subset.
                   12303:  *
                   12304:  * Returns the resulting xmlDtdPtr or NULL in case of error.
                   12305:  */
                   12306: 
                   12307: xmlDtdPtr
                   12308: xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
                   12309:     return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
                   12310: }
                   12311: #endif /* LIBXML_VALID_ENABLED */
                   12312: 
                   12313: /************************************************************************
                   12314:  *                                                                     *
                   12315:  *             Front ends when parsing an Entity                       *
                   12316:  *                                                                     *
                   12317:  ************************************************************************/
                   12318: 
                   12319: /**
                   12320:  * xmlParseCtxtExternalEntity:
                   12321:  * @ctx:  the existing parsing context
                   12322:  * @URL:  the URL for the entity to load
                   12323:  * @ID:  the System ID for the entity to load
                   12324:  * @lst:  the return value for the set of parsed nodes
                   12325:  *
                   12326:  * Parse an external general entity within an existing parsing context
                   12327:  * An external general parsed entity is well-formed if it matches the
                   12328:  * production labeled extParsedEnt.
                   12329:  *
                   12330:  * [78] extParsedEnt ::= TextDecl? content
                   12331:  *
                   12332:  * Returns 0 if the entity is well formed, -1 in case of args problem and
                   12333:  *    the parser error code otherwise
                   12334:  */
                   12335: 
                   12336: int
                   12337: xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
                   12338:                       const xmlChar *ID, xmlNodePtr *lst) {
                   12339:     xmlParserCtxtPtr ctxt;
                   12340:     xmlDocPtr newDoc;
                   12341:     xmlNodePtr newRoot;
                   12342:     xmlSAXHandlerPtr oldsax = NULL;
                   12343:     int ret = 0;
                   12344:     xmlChar start[4];
                   12345:     xmlCharEncoding enc;
                   12346: 
                   12347:     if (ctx == NULL) return(-1);
                   12348: 
                   12349:     if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
                   12350:         (ctx->depth > 1024)) {
                   12351:        return(XML_ERR_ENTITY_LOOP);
                   12352:     }
                   12353: 
                   12354:     if (lst != NULL)
                   12355:         *lst = NULL;
                   12356:     if ((URL == NULL) && (ID == NULL))
                   12357:        return(-1);
                   12358:     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
                   12359:        return(-1);
                   12360: 
                   12361:     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
                   12362:     if (ctxt == NULL) {
                   12363:        return(-1);
                   12364:     }
                   12365: 
                   12366:     oldsax = ctxt->sax;
                   12367:     ctxt->sax = ctx->sax;
                   12368:     xmlDetectSAX2(ctxt);
                   12369:     newDoc = xmlNewDoc(BAD_CAST "1.0");
                   12370:     if (newDoc == NULL) {
                   12371:        xmlFreeParserCtxt(ctxt);
                   12372:        return(-1);
                   12373:     }
                   12374:     newDoc->properties = XML_DOC_INTERNAL;
                   12375:     if (ctx->myDoc->dict) {
                   12376:        newDoc->dict = ctx->myDoc->dict;
                   12377:        xmlDictReference(newDoc->dict);
                   12378:     }
                   12379:     if (ctx->myDoc != NULL) {
                   12380:        newDoc->intSubset = ctx->myDoc->intSubset;
                   12381:        newDoc->extSubset = ctx->myDoc->extSubset;
                   12382:     }
                   12383:     if (ctx->myDoc->URL != NULL) {
                   12384:        newDoc->URL = xmlStrdup(ctx->myDoc->URL);
                   12385:     }
                   12386:     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
                   12387:     if (newRoot == NULL) {
                   12388:        ctxt->sax = oldsax;
                   12389:        xmlFreeParserCtxt(ctxt);
                   12390:        newDoc->intSubset = NULL;
                   12391:        newDoc->extSubset = NULL;
                   12392:         xmlFreeDoc(newDoc);
                   12393:        return(-1);
                   12394:     }
                   12395:     xmlAddChild((xmlNodePtr) newDoc, newRoot);
                   12396:     nodePush(ctxt, newDoc->children);
                   12397:     if (ctx->myDoc == NULL) {
                   12398:        ctxt->myDoc = newDoc;
                   12399:     } else {
                   12400:        ctxt->myDoc = ctx->myDoc;
                   12401:        newDoc->children->doc = ctx->myDoc;
                   12402:     }
                   12403: 
                   12404:     /*
                   12405:      * Get the 4 first bytes and decode the charset
                   12406:      * if enc != XML_CHAR_ENCODING_NONE
                   12407:      * plug some encoding conversion routines.
                   12408:      */
                   12409:     GROW
                   12410:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
                   12411:        start[0] = RAW;
                   12412:        start[1] = NXT(1);
                   12413:        start[2] = NXT(2);
                   12414:        start[3] = NXT(3);
                   12415:        enc = xmlDetectCharEncoding(start, 4);
                   12416:        if (enc != XML_CHAR_ENCODING_NONE) {
                   12417:            xmlSwitchEncoding(ctxt, enc);
                   12418:        }
                   12419:     }
                   12420: 
                   12421:     /*
                   12422:      * Parse a possible text declaration first
                   12423:      */
                   12424:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
                   12425:        xmlParseTextDecl(ctxt);
                   12426:        /*
                   12427:         * An XML-1.0 document can't reference an entity not XML-1.0
                   12428:         */
                   12429:        if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
                   12430:            (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
                   12431:            xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH, 
                   12432:                           "Version mismatch between document and entity\n");
                   12433:        }
                   12434:     }
                   12435: 
                   12436:     /*
1.1.1.2 ! misho    12437:      * If the user provided its own SAX callbacks then reuse the
        !          12438:      * useData callback field, otherwise the expected setup in a
        !          12439:      * DOM builder is to have userData == ctxt
        !          12440:      */
        !          12441:     if (ctx->userData == ctx)
        !          12442:         ctxt->userData = ctxt;
        !          12443:     else
        !          12444:         ctxt->userData = ctx->userData;
        !          12445: 
        !          12446:     /*
1.1       misho    12447:      * Doing validity checking on chunk doesn't make sense
                   12448:      */
                   12449:     ctxt->instate = XML_PARSER_CONTENT;
                   12450:     ctxt->validate = ctx->validate;
                   12451:     ctxt->valid = ctx->valid;
                   12452:     ctxt->loadsubset = ctx->loadsubset;
                   12453:     ctxt->depth = ctx->depth + 1;
                   12454:     ctxt->replaceEntities = ctx->replaceEntities;
                   12455:     if (ctxt->validate) {
                   12456:        ctxt->vctxt.error = ctx->vctxt.error;
                   12457:        ctxt->vctxt.warning = ctx->vctxt.warning;
                   12458:     } else {
                   12459:        ctxt->vctxt.error = NULL;
                   12460:        ctxt->vctxt.warning = NULL;
                   12461:     }
                   12462:     ctxt->vctxt.nodeTab = NULL;
                   12463:     ctxt->vctxt.nodeNr = 0;
                   12464:     ctxt->vctxt.nodeMax = 0;
                   12465:     ctxt->vctxt.node = NULL;
                   12466:     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
                   12467:     ctxt->dict = ctx->dict;
                   12468:     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
                   12469:     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
                   12470:     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
                   12471:     ctxt->dictNames = ctx->dictNames;
                   12472:     ctxt->attsDefault = ctx->attsDefault;
                   12473:     ctxt->attsSpecial = ctx->attsSpecial;
                   12474:     ctxt->linenumbers = ctx->linenumbers;
                   12475: 
                   12476:     xmlParseContent(ctxt);
                   12477: 
                   12478:     ctx->validate = ctxt->validate;
                   12479:     ctx->valid = ctxt->valid;
                   12480:     if ((RAW == '<') && (NXT(1) == '/')) {
                   12481:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12482:     } else if (RAW != 0) {
                   12483:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   12484:     }
                   12485:     if (ctxt->node != newDoc->children) {
                   12486:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12487:     }
                   12488: 
                   12489:     if (!ctxt->wellFormed) {
                   12490:         if (ctxt->errNo == 0)
                   12491:            ret = 1;
                   12492:        else
                   12493:            ret = ctxt->errNo;
                   12494:     } else {
                   12495:        if (lst != NULL) {
                   12496:            xmlNodePtr cur;
                   12497: 
                   12498:            /*
                   12499:             * Return the newly created nodeset after unlinking it from
                   12500:             * they pseudo parent.
                   12501:             */
                   12502:            cur = newDoc->children->children;
                   12503:            *lst = cur;
                   12504:            while (cur != NULL) {
                   12505:                cur->parent = NULL;
                   12506:                cur = cur->next;
                   12507:            }
                   12508:             newDoc->children->children = NULL;
                   12509:        }
                   12510:        ret = 0;
                   12511:     }
                   12512:     ctxt->sax = oldsax;
                   12513:     ctxt->dict = NULL;
                   12514:     ctxt->attsDefault = NULL;
                   12515:     ctxt->attsSpecial = NULL;
                   12516:     xmlFreeParserCtxt(ctxt);
                   12517:     newDoc->intSubset = NULL;
                   12518:     newDoc->extSubset = NULL;
                   12519:     xmlFreeDoc(newDoc);
                   12520: 
                   12521:     return(ret);
                   12522: }
                   12523: 
                   12524: /**
                   12525:  * xmlParseExternalEntityPrivate:
                   12526:  * @doc:  the document the chunk pertains to
                   12527:  * @oldctxt:  the previous parser context if available
                   12528:  * @sax:  the SAX handler bloc (possibly NULL)
                   12529:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
                   12530:  * @depth:  Used for loop detection, use 0
                   12531:  * @URL:  the URL for the entity to load
                   12532:  * @ID:  the System ID for the entity to load
                   12533:  * @list:  the return value for the set of parsed nodes
                   12534:  *
                   12535:  * Private version of xmlParseExternalEntity()
                   12536:  *
                   12537:  * Returns 0 if the entity is well formed, -1 in case of args problem and
                   12538:  *    the parser error code otherwise
                   12539:  */
                   12540: 
                   12541: static xmlParserErrors
                   12542: xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
                   12543:                      xmlSAXHandlerPtr sax,
                   12544:                      void *user_data, int depth, const xmlChar *URL,
                   12545:                      const xmlChar *ID, xmlNodePtr *list) {
                   12546:     xmlParserCtxtPtr ctxt;
                   12547:     xmlDocPtr newDoc;
                   12548:     xmlNodePtr newRoot;
                   12549:     xmlSAXHandlerPtr oldsax = NULL;
                   12550:     xmlParserErrors ret = XML_ERR_OK;
                   12551:     xmlChar start[4];
                   12552:     xmlCharEncoding enc;
                   12553: 
                   12554:     if (((depth > 40) &&
                   12555:        ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
                   12556:        (depth > 1024)) {
                   12557:        return(XML_ERR_ENTITY_LOOP);
                   12558:     }
                   12559: 
                   12560:     if (list != NULL)
                   12561:         *list = NULL;
                   12562:     if ((URL == NULL) && (ID == NULL))
                   12563:        return(XML_ERR_INTERNAL_ERROR);
                   12564:     if (doc == NULL)
                   12565:        return(XML_ERR_INTERNAL_ERROR);
                   12566: 
                   12567: 
                   12568:     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
                   12569:     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
                   12570:     ctxt->userData = ctxt;
                   12571:     if (oldctxt != NULL) {
                   12572:        ctxt->_private = oldctxt->_private;
                   12573:        ctxt->loadsubset = oldctxt->loadsubset;
                   12574:        ctxt->validate = oldctxt->validate;
                   12575:        ctxt->external = oldctxt->external;
                   12576:        ctxt->record_info = oldctxt->record_info;
                   12577:        ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
                   12578:        ctxt->node_seq.length = oldctxt->node_seq.length;
                   12579:        ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
                   12580:     } else {
                   12581:        /*
                   12582:         * Doing validity checking on chunk without context
                   12583:         * doesn't make sense
                   12584:         */
                   12585:        ctxt->_private = NULL;
                   12586:        ctxt->validate = 0;
                   12587:        ctxt->external = 2;
                   12588:        ctxt->loadsubset = 0;
                   12589:     }
                   12590:     if (sax != NULL) {
                   12591:        oldsax = ctxt->sax;
                   12592:         ctxt->sax = sax;
                   12593:        if (user_data != NULL)
                   12594:            ctxt->userData = user_data;
                   12595:     }
                   12596:     xmlDetectSAX2(ctxt);
                   12597:     newDoc = xmlNewDoc(BAD_CAST "1.0");
                   12598:     if (newDoc == NULL) {
                   12599:        ctxt->node_seq.maximum = 0;
                   12600:        ctxt->node_seq.length = 0;
                   12601:        ctxt->node_seq.buffer = NULL;
                   12602:        xmlFreeParserCtxt(ctxt);
                   12603:        return(XML_ERR_INTERNAL_ERROR);
                   12604:     }
                   12605:     newDoc->properties = XML_DOC_INTERNAL;
                   12606:     newDoc->intSubset = doc->intSubset;
                   12607:     newDoc->extSubset = doc->extSubset;
                   12608:     newDoc->dict = doc->dict;
                   12609:     xmlDictReference(newDoc->dict);
                   12610: 
                   12611:     if (doc->URL != NULL) {
                   12612:        newDoc->URL = xmlStrdup(doc->URL);
                   12613:     }
                   12614:     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
                   12615:     if (newRoot == NULL) {
                   12616:        if (sax != NULL)
                   12617:            ctxt->sax = oldsax;
                   12618:        ctxt->node_seq.maximum = 0;
                   12619:        ctxt->node_seq.length = 0;
                   12620:        ctxt->node_seq.buffer = NULL;
                   12621:        xmlFreeParserCtxt(ctxt);
                   12622:        newDoc->intSubset = NULL;
                   12623:        newDoc->extSubset = NULL;
                   12624:         xmlFreeDoc(newDoc);
                   12625:        return(XML_ERR_INTERNAL_ERROR);
                   12626:     }
                   12627:     xmlAddChild((xmlNodePtr) newDoc, newRoot);
                   12628:     nodePush(ctxt, newDoc->children);
                   12629:     ctxt->myDoc = doc;
                   12630:     newRoot->doc = doc;
                   12631: 
                   12632:     /*
                   12633:      * Get the 4 first bytes and decode the charset
                   12634:      * if enc != XML_CHAR_ENCODING_NONE
                   12635:      * plug some encoding conversion routines.
                   12636:      */
                   12637:     GROW;
                   12638:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
                   12639:        start[0] = RAW;
                   12640:        start[1] = NXT(1);
                   12641:        start[2] = NXT(2);
                   12642:        start[3] = NXT(3);
                   12643:        enc = xmlDetectCharEncoding(start, 4);
                   12644:        if (enc != XML_CHAR_ENCODING_NONE) {
                   12645:            xmlSwitchEncoding(ctxt, enc);
                   12646:        }
                   12647:     }
                   12648: 
                   12649:     /*
                   12650:      * Parse a possible text declaration first
                   12651:      */
                   12652:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
                   12653:        xmlParseTextDecl(ctxt);
                   12654:     }
                   12655: 
                   12656:     ctxt->instate = XML_PARSER_CONTENT;
                   12657:     ctxt->depth = depth;
                   12658: 
                   12659:     xmlParseContent(ctxt);
                   12660: 
                   12661:     if ((RAW == '<') && (NXT(1) == '/')) {
                   12662:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12663:     } else if (RAW != 0) {
                   12664:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   12665:     }
                   12666:     if (ctxt->node != newDoc->children) {
                   12667:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12668:     }
                   12669: 
                   12670:     if (!ctxt->wellFormed) {
                   12671:         if (ctxt->errNo == 0)
                   12672:            ret = XML_ERR_INTERNAL_ERROR;
                   12673:        else
                   12674:            ret = (xmlParserErrors)ctxt->errNo;
                   12675:     } else {
                   12676:        if (list != NULL) {
                   12677:            xmlNodePtr cur;
                   12678: 
                   12679:            /*
                   12680:             * Return the newly created nodeset after unlinking it from
                   12681:             * they pseudo parent.
                   12682:             */
                   12683:            cur = newDoc->children->children;
                   12684:            *list = cur;
                   12685:            while (cur != NULL) {
                   12686:                cur->parent = NULL;
                   12687:                cur = cur->next;
                   12688:            }
                   12689:             newDoc->children->children = NULL;
                   12690:        }
                   12691:        ret = XML_ERR_OK;
                   12692:     }
                   12693: 
                   12694:     /*
                   12695:      * Record in the parent context the number of entities replacement
                   12696:      * done when parsing that reference.
                   12697:      */
                   12698:     if (oldctxt != NULL)
                   12699:         oldctxt->nbentities += ctxt->nbentities;
                   12700: 
                   12701:     /*
                   12702:      * Also record the size of the entity parsed
                   12703:      */
                   12704:     if (ctxt->input != NULL) {
                   12705:        oldctxt->sizeentities += ctxt->input->consumed;
                   12706:        oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
                   12707:     }
                   12708:     /*
                   12709:      * And record the last error if any
                   12710:      */
                   12711:     if (ctxt->lastError.code != XML_ERR_OK)
                   12712:         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
                   12713: 
                   12714:     if (sax != NULL) 
                   12715:        ctxt->sax = oldsax;
                   12716:     oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
                   12717:     oldctxt->node_seq.length = ctxt->node_seq.length;
                   12718:     oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
                   12719:     ctxt->node_seq.maximum = 0;
                   12720:     ctxt->node_seq.length = 0;
                   12721:     ctxt->node_seq.buffer = NULL;
                   12722:     xmlFreeParserCtxt(ctxt);
                   12723:     newDoc->intSubset = NULL;
                   12724:     newDoc->extSubset = NULL;
                   12725:     xmlFreeDoc(newDoc);
                   12726: 
                   12727:     return(ret);
                   12728: }
                   12729: 
                   12730: #ifdef LIBXML_SAX1_ENABLED
                   12731: /**
                   12732:  * xmlParseExternalEntity:
                   12733:  * @doc:  the document the chunk pertains to
                   12734:  * @sax:  the SAX handler bloc (possibly NULL)
                   12735:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
                   12736:  * @depth:  Used for loop detection, use 0
                   12737:  * @URL:  the URL for the entity to load
                   12738:  * @ID:  the System ID for the entity to load
                   12739:  * @lst:  the return value for the set of parsed nodes
                   12740:  *
                   12741:  * Parse an external general entity
                   12742:  * An external general parsed entity is well-formed if it matches the
                   12743:  * production labeled extParsedEnt.
                   12744:  *
                   12745:  * [78] extParsedEnt ::= TextDecl? content
                   12746:  *
                   12747:  * Returns 0 if the entity is well formed, -1 in case of args problem and
                   12748:  *    the parser error code otherwise
                   12749:  */
                   12750: 
                   12751: int
                   12752: xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
                   12753:          int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
                   12754:     return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
                   12755:                                       ID, lst));
                   12756: }
                   12757: 
                   12758: /**
                   12759:  * xmlParseBalancedChunkMemory:
                   12760:  * @doc:  the document the chunk pertains to
                   12761:  * @sax:  the SAX handler bloc (possibly NULL)
                   12762:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
                   12763:  * @depth:  Used for loop detection, use 0
                   12764:  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
                   12765:  * @lst:  the return value for the set of parsed nodes
                   12766:  *
                   12767:  * Parse a well-balanced chunk of an XML document
                   12768:  * called by the parser
                   12769:  * The allowed sequence for the Well Balanced Chunk is the one defined by
                   12770:  * the content production in the XML grammar:
                   12771:  *
                   12772:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   12773:  *
                   12774:  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
                   12775:  *    the parser error code otherwise
                   12776:  */
                   12777: 
                   12778: int
                   12779: xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
                   12780:      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
                   12781:     return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
                   12782:                                                 depth, string, lst, 0 );
                   12783: }
                   12784: #endif /* LIBXML_SAX1_ENABLED */
                   12785: 
                   12786: /**
                   12787:  * xmlParseBalancedChunkMemoryInternal:
                   12788:  * @oldctxt:  the existing parsing context
                   12789:  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
                   12790:  * @user_data:  the user data field for the parser context
                   12791:  * @lst:  the return value for the set of parsed nodes
                   12792:  *
                   12793:  *
                   12794:  * Parse a well-balanced chunk of an XML document
                   12795:  * called by the parser
                   12796:  * The allowed sequence for the Well Balanced Chunk is the one defined by
                   12797:  * the content production in the XML grammar:
                   12798:  *
                   12799:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   12800:  *
                   12801:  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
                   12802:  * error code otherwise
                   12803:  *
                   12804:  * In case recover is set to 1, the nodelist will not be empty even if
                   12805:  * the parsed chunk is not well balanced.
                   12806:  */
                   12807: static xmlParserErrors
                   12808: xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
                   12809:        const xmlChar *string, void *user_data, xmlNodePtr *lst) {
                   12810:     xmlParserCtxtPtr ctxt;
                   12811:     xmlDocPtr newDoc = NULL;
                   12812:     xmlNodePtr newRoot;
                   12813:     xmlSAXHandlerPtr oldsax = NULL;
                   12814:     xmlNodePtr content = NULL;
                   12815:     xmlNodePtr last = NULL;
                   12816:     int size;
                   12817:     xmlParserErrors ret = XML_ERR_OK;
                   12818: #ifdef SAX2
                   12819:     int i;
                   12820: #endif
                   12821: 
                   12822:     if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
                   12823:         (oldctxt->depth >  1024)) {
                   12824:        return(XML_ERR_ENTITY_LOOP);
                   12825:     }
                   12826: 
                   12827: 
                   12828:     if (lst != NULL)
                   12829:         *lst = NULL;
                   12830:     if (string == NULL)
                   12831:         return(XML_ERR_INTERNAL_ERROR);
                   12832: 
                   12833:     size = xmlStrlen(string);
                   12834: 
                   12835:     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
                   12836:     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
                   12837:     if (user_data != NULL)
                   12838:        ctxt->userData = user_data;
                   12839:     else
                   12840:        ctxt->userData = ctxt;
                   12841:     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
                   12842:     ctxt->dict = oldctxt->dict;
                   12843:     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
                   12844:     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
                   12845:     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
                   12846: 
                   12847: #ifdef SAX2
                   12848:     /* propagate namespaces down the entity */
                   12849:     for (i = 0;i < oldctxt->nsNr;i += 2) {
                   12850:         nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
                   12851:     }
                   12852: #endif
                   12853: 
                   12854:     oldsax = ctxt->sax;
                   12855:     ctxt->sax = oldctxt->sax;
                   12856:     xmlDetectSAX2(ctxt);
                   12857:     ctxt->replaceEntities = oldctxt->replaceEntities;
                   12858:     ctxt->options = oldctxt->options;
                   12859: 
                   12860:     ctxt->_private = oldctxt->_private;
                   12861:     if (oldctxt->myDoc == NULL) {
                   12862:        newDoc = xmlNewDoc(BAD_CAST "1.0");
                   12863:        if (newDoc == NULL) {
                   12864:            ctxt->sax = oldsax;
                   12865:            ctxt->dict = NULL;
                   12866:            xmlFreeParserCtxt(ctxt);
                   12867:            return(XML_ERR_INTERNAL_ERROR);
                   12868:        }
                   12869:        newDoc->properties = XML_DOC_INTERNAL;
                   12870:        newDoc->dict = ctxt->dict;
                   12871:        xmlDictReference(newDoc->dict);
                   12872:        ctxt->myDoc = newDoc;
                   12873:     } else {
                   12874:        ctxt->myDoc = oldctxt->myDoc;
                   12875:         content = ctxt->myDoc->children;
                   12876:        last = ctxt->myDoc->last;
                   12877:     }
                   12878:     newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
                   12879:     if (newRoot == NULL) {
                   12880:        ctxt->sax = oldsax;
                   12881:        ctxt->dict = NULL;
                   12882:        xmlFreeParserCtxt(ctxt);
                   12883:        if (newDoc != NULL) {
                   12884:            xmlFreeDoc(newDoc);
                   12885:        }
                   12886:        return(XML_ERR_INTERNAL_ERROR);
                   12887:     }
                   12888:     ctxt->myDoc->children = NULL;
                   12889:     ctxt->myDoc->last = NULL;
                   12890:     xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
                   12891:     nodePush(ctxt, ctxt->myDoc->children);
                   12892:     ctxt->instate = XML_PARSER_CONTENT;
                   12893:     ctxt->depth = oldctxt->depth + 1;
                   12894: 
                   12895:     ctxt->validate = 0;
                   12896:     ctxt->loadsubset = oldctxt->loadsubset;
                   12897:     if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
                   12898:        /*
                   12899:         * ID/IDREF registration will be done in xmlValidateElement below
                   12900:         */
                   12901:        ctxt->loadsubset |= XML_SKIP_IDS;
                   12902:     }
                   12903:     ctxt->dictNames = oldctxt->dictNames;
                   12904:     ctxt->attsDefault = oldctxt->attsDefault;
                   12905:     ctxt->attsSpecial = oldctxt->attsSpecial;
                   12906: 
                   12907:     xmlParseContent(ctxt);
                   12908:     if ((RAW == '<') && (NXT(1) == '/')) {
                   12909:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12910:     } else if (RAW != 0) {
                   12911:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   12912:     }
                   12913:     if (ctxt->node != ctxt->myDoc->children) {
                   12914:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12915:     }
                   12916: 
                   12917:     if (!ctxt->wellFormed) {
                   12918:         if (ctxt->errNo == 0)
                   12919:            ret = XML_ERR_INTERNAL_ERROR;
                   12920:        else
                   12921:            ret = (xmlParserErrors)ctxt->errNo;
                   12922:     } else {
                   12923:       ret = XML_ERR_OK;
                   12924:     }
                   12925: 
                   12926:     if ((lst != NULL) && (ret == XML_ERR_OK)) {
                   12927:        xmlNodePtr cur;
                   12928: 
                   12929:        /*
                   12930:         * Return the newly created nodeset after unlinking it from
                   12931:         * they pseudo parent.
                   12932:         */
                   12933:        cur = ctxt->myDoc->children->children;
                   12934:        *lst = cur;
                   12935:        while (cur != NULL) {
                   12936: #ifdef LIBXML_VALID_ENABLED
                   12937:            if ((oldctxt->validate) && (oldctxt->wellFormed) &&
                   12938:                (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
                   12939:                (cur->type == XML_ELEMENT_NODE)) {
                   12940:                oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
                   12941:                        oldctxt->myDoc, cur);
                   12942:            }
                   12943: #endif /* LIBXML_VALID_ENABLED */
                   12944:            cur->parent = NULL;
                   12945:            cur = cur->next;
                   12946:        }
                   12947:        ctxt->myDoc->children->children = NULL;
                   12948:     }
                   12949:     if (ctxt->myDoc != NULL) {
                   12950:        xmlFreeNode(ctxt->myDoc->children);
                   12951:         ctxt->myDoc->children = content;
                   12952:         ctxt->myDoc->last = last;
                   12953:     }
                   12954: 
                   12955:     /*
                   12956:      * Record in the parent context the number of entities replacement
                   12957:      * done when parsing that reference.
                   12958:      */
                   12959:     if (oldctxt != NULL)
                   12960:         oldctxt->nbentities += ctxt->nbentities;
                   12961: 
                   12962:     /*
                   12963:      * Also record the last error if any
                   12964:      */
                   12965:     if (ctxt->lastError.code != XML_ERR_OK)
                   12966:         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
                   12967: 
                   12968:     ctxt->sax = oldsax;
                   12969:     ctxt->dict = NULL;
                   12970:     ctxt->attsDefault = NULL;
                   12971:     ctxt->attsSpecial = NULL;
                   12972:     xmlFreeParserCtxt(ctxt);
                   12973:     if (newDoc != NULL) {
                   12974:        xmlFreeDoc(newDoc);
                   12975:     }
                   12976: 
                   12977:     return(ret);
                   12978: }
                   12979: 
                   12980: /**
                   12981:  * xmlParseInNodeContext:
                   12982:  * @node:  the context node
                   12983:  * @data:  the input string
                   12984:  * @datalen:  the input string length in bytes
                   12985:  * @options:  a combination of xmlParserOption
                   12986:  * @lst:  the return value for the set of parsed nodes
                   12987:  *
                   12988:  * Parse a well-balanced chunk of an XML document
                   12989:  * within the context (DTD, namespaces, etc ...) of the given node.
                   12990:  *
                   12991:  * The allowed sequence for the data is a Well Balanced Chunk defined by
                   12992:  * the content production in the XML grammar:
                   12993:  *
                   12994:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   12995:  *
                   12996:  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
                   12997:  * error code otherwise
                   12998:  */
                   12999: xmlParserErrors
                   13000: xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
                   13001:                       int options, xmlNodePtr *lst) {
                   13002: #ifdef SAX2
                   13003:     xmlParserCtxtPtr ctxt;
                   13004:     xmlDocPtr doc = NULL;
                   13005:     xmlNodePtr fake, cur;
                   13006:     int nsnr = 0;
                   13007: 
                   13008:     xmlParserErrors ret = XML_ERR_OK;
                   13009: 
                   13010:     /*
                   13011:      * check all input parameters, grab the document
                   13012:      */
                   13013:     if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
                   13014:         return(XML_ERR_INTERNAL_ERROR);
                   13015:     switch (node->type) {
                   13016:         case XML_ELEMENT_NODE:
                   13017:         case XML_ATTRIBUTE_NODE:
                   13018:         case XML_TEXT_NODE:
                   13019:         case XML_CDATA_SECTION_NODE:
                   13020:         case XML_ENTITY_REF_NODE:
                   13021:         case XML_PI_NODE:
                   13022:         case XML_COMMENT_NODE:
                   13023:         case XML_DOCUMENT_NODE:
                   13024:         case XML_HTML_DOCUMENT_NODE:
                   13025:            break;
                   13026:        default:
                   13027:            return(XML_ERR_INTERNAL_ERROR);
                   13028: 
                   13029:     }
                   13030:     while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
                   13031:            (node->type != XML_DOCUMENT_NODE) &&
                   13032:           (node->type != XML_HTML_DOCUMENT_NODE))
                   13033:        node = node->parent;
                   13034:     if (node == NULL)
                   13035:        return(XML_ERR_INTERNAL_ERROR);
                   13036:     if (node->type == XML_ELEMENT_NODE)
                   13037:        doc = node->doc;
                   13038:     else
                   13039:         doc = (xmlDocPtr) node;
                   13040:     if (doc == NULL)
                   13041:        return(XML_ERR_INTERNAL_ERROR);
                   13042: 
                   13043:     /*
                   13044:      * allocate a context and set-up everything not related to the
                   13045:      * node position in the tree
                   13046:      */
                   13047:     if (doc->type == XML_DOCUMENT_NODE)
                   13048:        ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
                   13049: #ifdef LIBXML_HTML_ENABLED
                   13050:     else if (doc->type == XML_HTML_DOCUMENT_NODE) {
                   13051:        ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
                   13052:         /*
                   13053:          * When parsing in context, it makes no sense to add implied
                   13054:          * elements like html/body/etc...
                   13055:          */
                   13056:         options |= HTML_PARSE_NOIMPLIED;
                   13057:     }
                   13058: #endif
                   13059:     else
                   13060:         return(XML_ERR_INTERNAL_ERROR);
                   13061: 
                   13062:     if (ctxt == NULL)
                   13063:         return(XML_ERR_NO_MEMORY);
                   13064: 
                   13065:     /*
                   13066:      * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
                   13067:      * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
                   13068:      * we must wait until the last moment to free the original one.
                   13069:      */
                   13070:     if (doc->dict != NULL) {
                   13071:         if (ctxt->dict != NULL)
                   13072:            xmlDictFree(ctxt->dict);
                   13073:        ctxt->dict = doc->dict;
                   13074:     } else
                   13075:         options |= XML_PARSE_NODICT;
                   13076: 
                   13077:     if (doc->encoding != NULL) {
                   13078:         xmlCharEncodingHandlerPtr hdlr;
                   13079: 
                   13080:         if (ctxt->encoding != NULL)
                   13081:            xmlFree((xmlChar *) ctxt->encoding);
                   13082:         ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
                   13083: 
                   13084:         hdlr = xmlFindCharEncodingHandler(doc->encoding);
                   13085:         if (hdlr != NULL) {
                   13086:             xmlSwitchToEncoding(ctxt, hdlr);
                   13087:        } else {
                   13088:             return(XML_ERR_UNSUPPORTED_ENCODING);
                   13089:         }
                   13090:     }
                   13091: 
                   13092:     xmlCtxtUseOptionsInternal(ctxt, options, NULL);
                   13093:     xmlDetectSAX2(ctxt);
                   13094:     ctxt->myDoc = doc;
                   13095: 
                   13096:     fake = xmlNewComment(NULL);
                   13097:     if (fake == NULL) {
                   13098:         xmlFreeParserCtxt(ctxt);
                   13099:        return(XML_ERR_NO_MEMORY);
                   13100:     }
                   13101:     xmlAddChild(node, fake);
                   13102: 
                   13103:     if (node->type == XML_ELEMENT_NODE) {
                   13104:        nodePush(ctxt, node);
                   13105:        /*
                   13106:         * initialize the SAX2 namespaces stack
                   13107:         */
                   13108:        cur = node;
                   13109:        while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
                   13110:            xmlNsPtr ns = cur->nsDef;
                   13111:            const xmlChar *iprefix, *ihref;
                   13112: 
                   13113:            while (ns != NULL) {
                   13114:                if (ctxt->dict) {
                   13115:                    iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
                   13116:                    ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
                   13117:                } else {
                   13118:                    iprefix = ns->prefix;
                   13119:                    ihref = ns->href;
                   13120:                }
                   13121: 
                   13122:                if (xmlGetNamespace(ctxt, iprefix) == NULL) {
                   13123:                    nsPush(ctxt, iprefix, ihref);
                   13124:                    nsnr++;
                   13125:                }
                   13126:                ns = ns->next;
                   13127:            }
                   13128:            cur = cur->parent;
                   13129:        }
                   13130:        ctxt->instate = XML_PARSER_CONTENT;
                   13131:     }
                   13132: 
                   13133:     if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
                   13134:        /*
                   13135:         * ID/IDREF registration will be done in xmlValidateElement below
                   13136:         */
                   13137:        ctxt->loadsubset |= XML_SKIP_IDS;
                   13138:     }
                   13139: 
                   13140: #ifdef LIBXML_HTML_ENABLED
                   13141:     if (doc->type == XML_HTML_DOCUMENT_NODE)
                   13142:         __htmlParseContent(ctxt);
                   13143:     else
                   13144: #endif
                   13145:        xmlParseContent(ctxt);
                   13146: 
                   13147:     nsPop(ctxt, nsnr);
                   13148:     if ((RAW == '<') && (NXT(1) == '/')) {
                   13149:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   13150:     } else if (RAW != 0) {
                   13151:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   13152:     }
                   13153:     if ((ctxt->node != NULL) && (ctxt->node != node)) {
                   13154:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   13155:        ctxt->wellFormed = 0;
                   13156:     }
                   13157: 
                   13158:     if (!ctxt->wellFormed) {
                   13159:         if (ctxt->errNo == 0)
                   13160:            ret = XML_ERR_INTERNAL_ERROR;
                   13161:        else
                   13162:            ret = (xmlParserErrors)ctxt->errNo;
                   13163:     } else {
                   13164:         ret = XML_ERR_OK;
                   13165:     }
                   13166: 
                   13167:     /*
                   13168:      * Return the newly created nodeset after unlinking it from
                   13169:      * the pseudo sibling.
                   13170:      */
                   13171: 
                   13172:     cur = fake->next;
                   13173:     fake->next = NULL;
                   13174:     node->last = fake;
                   13175: 
                   13176:     if (cur != NULL) {
                   13177:        cur->prev = NULL;
                   13178:     }
                   13179: 
                   13180:     *lst = cur;
                   13181: 
                   13182:     while (cur != NULL) {
                   13183:        cur->parent = NULL;
                   13184:        cur = cur->next;
                   13185:     }
                   13186: 
                   13187:     xmlUnlinkNode(fake);
                   13188:     xmlFreeNode(fake);
                   13189: 
                   13190: 
                   13191:     if (ret != XML_ERR_OK) {
                   13192:         xmlFreeNodeList(*lst);
                   13193:        *lst = NULL;
                   13194:     }
                   13195: 
                   13196:     if (doc->dict != NULL)
                   13197:         ctxt->dict = NULL;
                   13198:     xmlFreeParserCtxt(ctxt);
                   13199: 
                   13200:     return(ret);
                   13201: #else /* !SAX2 */
                   13202:     return(XML_ERR_INTERNAL_ERROR);
                   13203: #endif
                   13204: }
                   13205: 
                   13206: #ifdef LIBXML_SAX1_ENABLED
                   13207: /**
                   13208:  * xmlParseBalancedChunkMemoryRecover:
                   13209:  * @doc:  the document the chunk pertains to
                   13210:  * @sax:  the SAX handler bloc (possibly NULL)
                   13211:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
                   13212:  * @depth:  Used for loop detection, use 0
                   13213:  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
                   13214:  * @lst:  the return value for the set of parsed nodes
                   13215:  * @recover: return nodes even if the data is broken (use 0)
                   13216:  *
                   13217:  *
                   13218:  * Parse a well-balanced chunk of an XML document
                   13219:  * called by the parser
                   13220:  * The allowed sequence for the Well Balanced Chunk is the one defined by
                   13221:  * the content production in the XML grammar:
                   13222:  *
                   13223:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   13224:  *
                   13225:  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
                   13226:  *    the parser error code otherwise
                   13227:  *
                   13228:  * In case recover is set to 1, the nodelist will not be empty even if
                   13229:  * the parsed chunk is not well balanced, assuming the parsing succeeded to
                   13230:  * some extent.
                   13231:  */
                   13232: int
                   13233: xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
                   13234:      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
                   13235:      int recover) {
                   13236:     xmlParserCtxtPtr ctxt;
                   13237:     xmlDocPtr newDoc;
                   13238:     xmlSAXHandlerPtr oldsax = NULL;
                   13239:     xmlNodePtr content, newRoot;
                   13240:     int size;
                   13241:     int ret = 0;
                   13242: 
                   13243:     if (depth > 40) {
                   13244:        return(XML_ERR_ENTITY_LOOP);
                   13245:     }
                   13246: 
                   13247: 
                   13248:     if (lst != NULL)
                   13249:         *lst = NULL;
                   13250:     if (string == NULL)
                   13251:         return(-1);
                   13252: 
                   13253:     size = xmlStrlen(string);
                   13254: 
                   13255:     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
                   13256:     if (ctxt == NULL) return(-1);
                   13257:     ctxt->userData = ctxt;
                   13258:     if (sax != NULL) {
                   13259:        oldsax = ctxt->sax;
                   13260:         ctxt->sax = sax;
                   13261:        if (user_data != NULL)
                   13262:            ctxt->userData = user_data;
                   13263:     }
                   13264:     newDoc = xmlNewDoc(BAD_CAST "1.0");
                   13265:     if (newDoc == NULL) {
                   13266:        xmlFreeParserCtxt(ctxt);
                   13267:        return(-1);
                   13268:     }
                   13269:     newDoc->properties = XML_DOC_INTERNAL;
                   13270:     if ((doc != NULL) && (doc->dict != NULL)) {
                   13271:         xmlDictFree(ctxt->dict);
                   13272:        ctxt->dict = doc->dict;
                   13273:        xmlDictReference(ctxt->dict);
                   13274:        ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
                   13275:        ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
                   13276:        ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
                   13277:        ctxt->dictNames = 1;
                   13278:     } else {
                   13279:        xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
                   13280:     }
                   13281:     if (doc != NULL) {
                   13282:        newDoc->intSubset = doc->intSubset;
                   13283:        newDoc->extSubset = doc->extSubset;
                   13284:     }
                   13285:     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
                   13286:     if (newRoot == NULL) {
                   13287:        if (sax != NULL)
                   13288:            ctxt->sax = oldsax;
                   13289:        xmlFreeParserCtxt(ctxt);
                   13290:        newDoc->intSubset = NULL;
                   13291:        newDoc->extSubset = NULL;
                   13292:         xmlFreeDoc(newDoc);
                   13293:        return(-1);
                   13294:     }
                   13295:     xmlAddChild((xmlNodePtr) newDoc, newRoot);
                   13296:     nodePush(ctxt, newRoot);
                   13297:     if (doc == NULL) {
                   13298:        ctxt->myDoc = newDoc;
                   13299:     } else {
                   13300:        ctxt->myDoc = newDoc;
                   13301:        newDoc->children->doc = doc;
                   13302:        /* Ensure that doc has XML spec namespace */
                   13303:        xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
                   13304:        newDoc->oldNs = doc->oldNs;
                   13305:     }
                   13306:     ctxt->instate = XML_PARSER_CONTENT;
                   13307:     ctxt->depth = depth;
                   13308: 
                   13309:     /*
                   13310:      * Doing validity checking on chunk doesn't make sense
                   13311:      */
                   13312:     ctxt->validate = 0;
                   13313:     ctxt->loadsubset = 0;
                   13314:     xmlDetectSAX2(ctxt);
                   13315: 
                   13316:     if ( doc != NULL ){
                   13317:         content = doc->children;
                   13318:         doc->children = NULL;
                   13319:         xmlParseContent(ctxt);
                   13320:         doc->children = content;
                   13321:     }
                   13322:     else {
                   13323:         xmlParseContent(ctxt);
                   13324:     }
                   13325:     if ((RAW == '<') && (NXT(1) == '/')) {
                   13326:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   13327:     } else if (RAW != 0) {
                   13328:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   13329:     }
                   13330:     if (ctxt->node != newDoc->children) {
                   13331:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   13332:     }
                   13333: 
                   13334:     if (!ctxt->wellFormed) {
                   13335:         if (ctxt->errNo == 0)
                   13336:            ret = 1;
                   13337:        else
                   13338:            ret = ctxt->errNo;
                   13339:     } else {
                   13340:       ret = 0;
                   13341:     }
                   13342: 
                   13343:     if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
                   13344:        xmlNodePtr cur;
                   13345: 
                   13346:        /*
                   13347:         * Return the newly created nodeset after unlinking it from
                   13348:         * they pseudo parent.
                   13349:         */
                   13350:        cur = newDoc->children->children;
                   13351:        *lst = cur;
                   13352:        while (cur != NULL) {
                   13353:            xmlSetTreeDoc(cur, doc);
                   13354:            cur->parent = NULL;
                   13355:            cur = cur->next;
                   13356:        }
                   13357:        newDoc->children->children = NULL;
                   13358:     }
                   13359: 
                   13360:     if (sax != NULL)
                   13361:        ctxt->sax = oldsax;
                   13362:     xmlFreeParserCtxt(ctxt);
                   13363:     newDoc->intSubset = NULL;
                   13364:     newDoc->extSubset = NULL;
                   13365:     newDoc->oldNs = NULL;
                   13366:     xmlFreeDoc(newDoc);
                   13367: 
                   13368:     return(ret);
                   13369: }
                   13370: 
                   13371: /**
                   13372:  * xmlSAXParseEntity:
                   13373:  * @sax:  the SAX handler block
                   13374:  * @filename:  the filename
                   13375:  *
                   13376:  * parse an XML external entity out of context and build a tree.
                   13377:  * It use the given SAX function block to handle the parsing callback.
                   13378:  * If sax is NULL, fallback to the default DOM tree building routines.
                   13379:  *
                   13380:  * [78] extParsedEnt ::= TextDecl? content
                   13381:  *
                   13382:  * This correspond to a "Well Balanced" chunk
                   13383:  *
                   13384:  * Returns the resulting document tree
                   13385:  */
                   13386: 
                   13387: xmlDocPtr
                   13388: xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
                   13389:     xmlDocPtr ret;
                   13390:     xmlParserCtxtPtr ctxt;
                   13391: 
                   13392:     ctxt = xmlCreateFileParserCtxt(filename);
                   13393:     if (ctxt == NULL) {
                   13394:        return(NULL);
                   13395:     }
                   13396:     if (sax != NULL) {
                   13397:        if (ctxt->sax != NULL)
                   13398:            xmlFree(ctxt->sax);
                   13399:         ctxt->sax = sax;
                   13400:         ctxt->userData = NULL;
                   13401:     }
                   13402: 
                   13403:     xmlParseExtParsedEnt(ctxt);
                   13404: 
                   13405:     if (ctxt->wellFormed)
                   13406:        ret = ctxt->myDoc;
                   13407:     else {
                   13408:         ret = NULL;
                   13409:         xmlFreeDoc(ctxt->myDoc);
                   13410:         ctxt->myDoc = NULL;
                   13411:     }
                   13412:     if (sax != NULL)
                   13413:         ctxt->sax = NULL;
                   13414:     xmlFreeParserCtxt(ctxt);
                   13415: 
                   13416:     return(ret);
                   13417: }
                   13418: 
                   13419: /**
                   13420:  * xmlParseEntity:
                   13421:  * @filename:  the filename
                   13422:  *
                   13423:  * parse an XML external entity out of context and build a tree.
                   13424:  *
                   13425:  * [78] extParsedEnt ::= TextDecl? content
                   13426:  *
                   13427:  * This correspond to a "Well Balanced" chunk
                   13428:  *
                   13429:  * Returns the resulting document tree
                   13430:  */
                   13431: 
                   13432: xmlDocPtr
                   13433: xmlParseEntity(const char *filename) {
                   13434:     return(xmlSAXParseEntity(NULL, filename));
                   13435: }
                   13436: #endif /* LIBXML_SAX1_ENABLED */
                   13437: 
                   13438: /**
                   13439:  * xmlCreateEntityParserCtxtInternal:
                   13440:  * @URL:  the entity URL
                   13441:  * @ID:  the entity PUBLIC ID
                   13442:  * @base:  a possible base for the target URI
                   13443:  * @pctx:  parser context used to set options on new context
                   13444:  *
                   13445:  * Create a parser context for an external entity
                   13446:  * Automatic support for ZLIB/Compress compressed document is provided
                   13447:  * by default if found at compile-time.
                   13448:  *
                   13449:  * Returns the new parser context or NULL
                   13450:  */
                   13451: static xmlParserCtxtPtr
                   13452: xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
                   13453:                          const xmlChar *base, xmlParserCtxtPtr pctx) {
                   13454:     xmlParserCtxtPtr ctxt;
                   13455:     xmlParserInputPtr inputStream;
                   13456:     char *directory = NULL;
                   13457:     xmlChar *uri;
                   13458: 
                   13459:     ctxt = xmlNewParserCtxt();
                   13460:     if (ctxt == NULL) {
                   13461:        return(NULL);
                   13462:     }
                   13463: 
                   13464:     if (pctx != NULL) {
                   13465:         ctxt->options = pctx->options;
                   13466:         ctxt->_private = pctx->_private;
                   13467:     }
                   13468: 
                   13469:     uri = xmlBuildURI(URL, base);
                   13470: 
                   13471:     if (uri == NULL) {
                   13472:        inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
                   13473:        if (inputStream == NULL) {
                   13474:            xmlFreeParserCtxt(ctxt);
                   13475:            return(NULL);
                   13476:        }
                   13477: 
                   13478:        inputPush(ctxt, inputStream);
                   13479: 
                   13480:        if ((ctxt->directory == NULL) && (directory == NULL))
                   13481:            directory = xmlParserGetDirectory((char *)URL);
                   13482:        if ((ctxt->directory == NULL) && (directory != NULL))
                   13483:            ctxt->directory = directory;
                   13484:     } else {
                   13485:        inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
                   13486:        if (inputStream == NULL) {
                   13487:            xmlFree(uri);
                   13488:            xmlFreeParserCtxt(ctxt);
                   13489:            return(NULL);
                   13490:        }
                   13491: 
                   13492:        inputPush(ctxt, inputStream);
                   13493: 
                   13494:        if ((ctxt->directory == NULL) && (directory == NULL))
                   13495:            directory = xmlParserGetDirectory((char *)uri);
                   13496:        if ((ctxt->directory == NULL) && (directory != NULL))
                   13497:            ctxt->directory = directory;
                   13498:        xmlFree(uri);
                   13499:     }
                   13500:     return(ctxt);
                   13501: }
                   13502: 
                   13503: /**
                   13504:  * xmlCreateEntityParserCtxt:
                   13505:  * @URL:  the entity URL
                   13506:  * @ID:  the entity PUBLIC ID
                   13507:  * @base:  a possible base for the target URI
                   13508:  *
                   13509:  * Create a parser context for an external entity
                   13510:  * Automatic support for ZLIB/Compress compressed document is provided
                   13511:  * by default if found at compile-time.
                   13512:  *
                   13513:  * Returns the new parser context or NULL
                   13514:  */
                   13515: xmlParserCtxtPtr
                   13516: xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
                   13517:                          const xmlChar *base) {
                   13518:     return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
                   13519: 
                   13520: }
                   13521: 
                   13522: /************************************************************************
                   13523:  *                                                                     *
                   13524:  *             Front ends when parsing from a file                     *
                   13525:  *                                                                     *
                   13526:  ************************************************************************/
                   13527: 
                   13528: /**
                   13529:  * xmlCreateURLParserCtxt:
                   13530:  * @filename:  the filename or URL
                   13531:  * @options:  a combination of xmlParserOption
                   13532:  *
                   13533:  * Create a parser context for a file or URL content. 
                   13534:  * Automatic support for ZLIB/Compress compressed document is provided
                   13535:  * by default if found at compile-time and for file accesses
                   13536:  *
                   13537:  * Returns the new parser context or NULL
                   13538:  */
                   13539: xmlParserCtxtPtr
                   13540: xmlCreateURLParserCtxt(const char *filename, int options)
                   13541: {
                   13542:     xmlParserCtxtPtr ctxt;
                   13543:     xmlParserInputPtr inputStream;
                   13544:     char *directory = NULL;
                   13545: 
                   13546:     ctxt = xmlNewParserCtxt();
                   13547:     if (ctxt == NULL) {
                   13548:        xmlErrMemory(NULL, "cannot allocate parser context");
                   13549:        return(NULL);
                   13550:     }
                   13551: 
                   13552:     if (options)
                   13553:        xmlCtxtUseOptionsInternal(ctxt, options, NULL);
                   13554:     ctxt->linenumbers = 1;
                   13555: 
                   13556:     inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
                   13557:     if (inputStream == NULL) {
                   13558:        xmlFreeParserCtxt(ctxt);
                   13559:        return(NULL);
                   13560:     }
                   13561: 
                   13562:     inputPush(ctxt, inputStream);
                   13563:     if ((ctxt->directory == NULL) && (directory == NULL))
                   13564:         directory = xmlParserGetDirectory(filename);
                   13565:     if ((ctxt->directory == NULL) && (directory != NULL))
                   13566:         ctxt->directory = directory;
                   13567: 
                   13568:     return(ctxt);
                   13569: }
                   13570: 
                   13571: /**
                   13572:  * xmlCreateFileParserCtxt:
                   13573:  * @filename:  the filename
                   13574:  *
                   13575:  * Create a parser context for a file content. 
                   13576:  * Automatic support for ZLIB/Compress compressed document is provided
                   13577:  * by default if found at compile-time.
                   13578:  *
                   13579:  * Returns the new parser context or NULL
                   13580:  */
                   13581: xmlParserCtxtPtr
                   13582: xmlCreateFileParserCtxt(const char *filename)
                   13583: {
                   13584:     return(xmlCreateURLParserCtxt(filename, 0));
                   13585: }
                   13586: 
                   13587: #ifdef LIBXML_SAX1_ENABLED
                   13588: /**
                   13589:  * xmlSAXParseFileWithData:
                   13590:  * @sax:  the SAX handler block
                   13591:  * @filename:  the filename
                   13592:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
                   13593:  *             documents
                   13594:  * @data:  the userdata
                   13595:  *
                   13596:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   13597:  * compressed document is provided by default if found at compile-time.
                   13598:  * It use the given SAX function block to handle the parsing callback.
                   13599:  * If sax is NULL, fallback to the default DOM tree building routines.
                   13600:  *
                   13601:  * User data (void *) is stored within the parser context in the
                   13602:  * context's _private member, so it is available nearly everywhere in libxml
                   13603:  *
                   13604:  * Returns the resulting document tree
                   13605:  */
                   13606: 
                   13607: xmlDocPtr
                   13608: xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
                   13609:                         int recovery, void *data) {
                   13610:     xmlDocPtr ret;
                   13611:     xmlParserCtxtPtr ctxt;
                   13612: 
                   13613:     xmlInitParser();
                   13614: 
                   13615:     ctxt = xmlCreateFileParserCtxt(filename);
                   13616:     if (ctxt == NULL) {
                   13617:        return(NULL);
                   13618:     }
                   13619:     if (sax != NULL) {
                   13620:        if (ctxt->sax != NULL)
                   13621:            xmlFree(ctxt->sax);
                   13622:         ctxt->sax = sax;
                   13623:     }
                   13624:     xmlDetectSAX2(ctxt);
                   13625:     if (data!=NULL) {
                   13626:        ctxt->_private = data;
                   13627:     }
                   13628: 
                   13629:     if (ctxt->directory == NULL)
                   13630:         ctxt->directory = xmlParserGetDirectory(filename);
                   13631: 
                   13632:     ctxt->recovery = recovery;
                   13633: 
                   13634:     xmlParseDocument(ctxt);
                   13635: 
                   13636:     if ((ctxt->wellFormed) || recovery) {
                   13637:         ret = ctxt->myDoc;
                   13638:        if (ret != NULL) {
                   13639:            if (ctxt->input->buf->compressed > 0)
                   13640:                ret->compression = 9;
                   13641:            else
                   13642:                ret->compression = ctxt->input->buf->compressed;
                   13643:        }
                   13644:     }
                   13645:     else {
                   13646:        ret = NULL;
                   13647:        xmlFreeDoc(ctxt->myDoc);
                   13648:        ctxt->myDoc = NULL;
                   13649:     }
                   13650:     if (sax != NULL)
                   13651:         ctxt->sax = NULL;
                   13652:     xmlFreeParserCtxt(ctxt);
                   13653:     
                   13654:     return(ret);
                   13655: }
                   13656: 
                   13657: /**
                   13658:  * xmlSAXParseFile:
                   13659:  * @sax:  the SAX handler block
                   13660:  * @filename:  the filename
                   13661:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
                   13662:  *             documents
                   13663:  *
                   13664:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   13665:  * compressed document is provided by default if found at compile-time.
                   13666:  * It use the given SAX function block to handle the parsing callback.
                   13667:  * If sax is NULL, fallback to the default DOM tree building routines.
                   13668:  *
                   13669:  * Returns the resulting document tree
                   13670:  */
                   13671: 
                   13672: xmlDocPtr
                   13673: xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
                   13674:                           int recovery) {
                   13675:     return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
                   13676: }
                   13677: 
                   13678: /**
                   13679:  * xmlRecoverDoc:
                   13680:  * @cur:  a pointer to an array of xmlChar
                   13681:  *
                   13682:  * parse an XML in-memory document and build a tree.
                   13683:  * In the case the document is not Well Formed, a attempt to build a
                   13684:  * tree is tried anyway
                   13685:  *
                   13686:  * Returns the resulting document tree or NULL in case of failure
                   13687:  */
                   13688: 
                   13689: xmlDocPtr
                   13690: xmlRecoverDoc(const xmlChar *cur) {
                   13691:     return(xmlSAXParseDoc(NULL, cur, 1));
                   13692: }
                   13693: 
                   13694: /**
                   13695:  * xmlParseFile:
                   13696:  * @filename:  the filename
                   13697:  *
                   13698:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   13699:  * compressed document is provided by default if found at compile-time.
                   13700:  *
                   13701:  * Returns the resulting document tree if the file was wellformed,
                   13702:  * NULL otherwise.
                   13703:  */
                   13704: 
                   13705: xmlDocPtr
                   13706: xmlParseFile(const char *filename) {
                   13707:     return(xmlSAXParseFile(NULL, filename, 0));
                   13708: }
                   13709: 
                   13710: /**
                   13711:  * xmlRecoverFile:
                   13712:  * @filename:  the filename
                   13713:  *
                   13714:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   13715:  * compressed document is provided by default if found at compile-time.
                   13716:  * In the case the document is not Well Formed, it attempts to build
                   13717:  * a tree anyway
                   13718:  *
                   13719:  * Returns the resulting document tree or NULL in case of failure
                   13720:  */
                   13721: 
                   13722: xmlDocPtr
                   13723: xmlRecoverFile(const char *filename) {
                   13724:     return(xmlSAXParseFile(NULL, filename, 1));
                   13725: }
                   13726: 
                   13727: 
                   13728: /**
                   13729:  * xmlSetupParserForBuffer:
                   13730:  * @ctxt:  an XML parser context
                   13731:  * @buffer:  a xmlChar * buffer
                   13732:  * @filename:  a file name
                   13733:  *
                   13734:  * Setup the parser context to parse a new buffer; Clears any prior
                   13735:  * contents from the parser context. The buffer parameter must not be
                   13736:  * NULL, but the filename parameter can be
                   13737:  */
                   13738: void
                   13739: xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
                   13740:                              const char* filename)
                   13741: {
                   13742:     xmlParserInputPtr input;
                   13743: 
                   13744:     if ((ctxt == NULL) || (buffer == NULL))
                   13745:         return;
                   13746: 
                   13747:     input = xmlNewInputStream(ctxt);
                   13748:     if (input == NULL) {
                   13749:         xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
                   13750:         xmlClearParserCtxt(ctxt);
                   13751:         return;
                   13752:     }
                   13753:   
                   13754:     xmlClearParserCtxt(ctxt);
                   13755:     if (filename != NULL)
                   13756:         input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
                   13757:     input->base = buffer;
                   13758:     input->cur = buffer;
                   13759:     input->end = &buffer[xmlStrlen(buffer)];
                   13760:     inputPush(ctxt, input);
                   13761: }
                   13762: 
                   13763: /**
                   13764:  * xmlSAXUserParseFile:
                   13765:  * @sax:  a SAX handler
                   13766:  * @user_data:  The user data returned on SAX callbacks
                   13767:  * @filename:  a file name
                   13768:  *
                   13769:  * parse an XML file and call the given SAX handler routines.
                   13770:  * Automatic support for ZLIB/Compress compressed document is provided
                   13771:  * 
                   13772:  * Returns 0 in case of success or a error number otherwise
                   13773:  */
                   13774: int
                   13775: xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
                   13776:                     const char *filename) {
                   13777:     int ret = 0;
                   13778:     xmlParserCtxtPtr ctxt;
                   13779:     
                   13780:     ctxt = xmlCreateFileParserCtxt(filename);
                   13781:     if (ctxt == NULL) return -1;
                   13782:     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
                   13783:        xmlFree(ctxt->sax);
                   13784:     ctxt->sax = sax;
                   13785:     xmlDetectSAX2(ctxt);
                   13786: 
                   13787:     if (user_data != NULL)
                   13788:        ctxt->userData = user_data;
                   13789:     
                   13790:     xmlParseDocument(ctxt);
                   13791:     
                   13792:     if (ctxt->wellFormed)
                   13793:        ret = 0;
                   13794:     else {
                   13795:         if (ctxt->errNo != 0)
                   13796:            ret = ctxt->errNo;
                   13797:        else
                   13798:            ret = -1;
                   13799:     }
                   13800:     if (sax != NULL)
                   13801:        ctxt->sax = NULL;
                   13802:     if (ctxt->myDoc != NULL) {
                   13803:         xmlFreeDoc(ctxt->myDoc);
                   13804:        ctxt->myDoc = NULL;
                   13805:     }
                   13806:     xmlFreeParserCtxt(ctxt);
                   13807:     
                   13808:     return ret;
                   13809: }
                   13810: #endif /* LIBXML_SAX1_ENABLED */
                   13811: 
                   13812: /************************************************************************
                   13813:  *                                                                     *
                   13814:  *             Front ends when parsing from memory                     *
                   13815:  *                                                                     *
                   13816:  ************************************************************************/
                   13817: 
                   13818: /**
                   13819:  * xmlCreateMemoryParserCtxt:
                   13820:  * @buffer:  a pointer to a char array
                   13821:  * @size:  the size of the array
                   13822:  *
                   13823:  * Create a parser context for an XML in-memory document.
                   13824:  *
                   13825:  * Returns the new parser context or NULL
                   13826:  */
                   13827: xmlParserCtxtPtr
                   13828: xmlCreateMemoryParserCtxt(const char *buffer, int size) {
                   13829:     xmlParserCtxtPtr ctxt;
                   13830:     xmlParserInputPtr input;
                   13831:     xmlParserInputBufferPtr buf;
                   13832: 
                   13833:     if (buffer == NULL)
                   13834:        return(NULL);
                   13835:     if (size <= 0)
                   13836:        return(NULL);
                   13837: 
                   13838:     ctxt = xmlNewParserCtxt();
                   13839:     if (ctxt == NULL)
                   13840:        return(NULL);
                   13841: 
                   13842:     /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
                   13843:     buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
                   13844:     if (buf == NULL) {
                   13845:        xmlFreeParserCtxt(ctxt);
                   13846:        return(NULL);
                   13847:     }
                   13848: 
                   13849:     input = xmlNewInputStream(ctxt);
                   13850:     if (input == NULL) {
                   13851:        xmlFreeParserInputBuffer(buf);
                   13852:        xmlFreeParserCtxt(ctxt);
                   13853:        return(NULL);
                   13854:     }
                   13855: 
                   13856:     input->filename = NULL;
                   13857:     input->buf = buf;
                   13858:     input->base = input->buf->buffer->content;
                   13859:     input->cur = input->buf->buffer->content;
                   13860:     input->end = &input->buf->buffer->content[input->buf->buffer->use];
                   13861: 
                   13862:     inputPush(ctxt, input);
                   13863:     return(ctxt);
                   13864: }
                   13865: 
                   13866: #ifdef LIBXML_SAX1_ENABLED
                   13867: /**
                   13868:  * xmlSAXParseMemoryWithData:
                   13869:  * @sax:  the SAX handler block
                   13870:  * @buffer:  an pointer to a char array
                   13871:  * @size:  the size of the array
                   13872:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
                   13873:  *             documents
                   13874:  * @data:  the userdata
                   13875:  *
                   13876:  * parse an XML in-memory block and use the given SAX function block
                   13877:  * to handle the parsing callback. If sax is NULL, fallback to the default
                   13878:  * DOM tree building routines.
                   13879:  *
                   13880:  * User data (void *) is stored within the parser context in the
                   13881:  * context's _private member, so it is available nearly everywhere in libxml
                   13882:  *
                   13883:  * Returns the resulting document tree
                   13884:  */
                   13885: 
                   13886: xmlDocPtr
                   13887: xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
                   13888:                  int size, int recovery, void *data) {
                   13889:     xmlDocPtr ret;
                   13890:     xmlParserCtxtPtr ctxt;
                   13891: 
                   13892:     xmlInitParser();
                   13893: 
                   13894:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
                   13895:     if (ctxt == NULL) return(NULL);
                   13896:     if (sax != NULL) {
                   13897:        if (ctxt->sax != NULL)
                   13898:            xmlFree(ctxt->sax);
                   13899:         ctxt->sax = sax;
                   13900:     }
                   13901:     xmlDetectSAX2(ctxt);
                   13902:     if (data!=NULL) {
                   13903:        ctxt->_private=data;
                   13904:     }
                   13905: 
                   13906:     ctxt->recovery = recovery;
                   13907: 
                   13908:     xmlParseDocument(ctxt);
                   13909: 
                   13910:     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
                   13911:     else {
                   13912:        ret = NULL;
                   13913:        xmlFreeDoc(ctxt->myDoc);
                   13914:        ctxt->myDoc = NULL;
                   13915:     }
                   13916:     if (sax != NULL) 
                   13917:        ctxt->sax = NULL;
                   13918:     xmlFreeParserCtxt(ctxt);
                   13919: 
                   13920:     return(ret);
                   13921: }
                   13922: 
                   13923: /**
                   13924:  * xmlSAXParseMemory:
                   13925:  * @sax:  the SAX handler block
                   13926:  * @buffer:  an pointer to a char array
                   13927:  * @size:  the size of the array
                   13928:  * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
                   13929:  *             documents
                   13930:  *
                   13931:  * parse an XML in-memory block and use the given SAX function block
                   13932:  * to handle the parsing callback. If sax is NULL, fallback to the default
                   13933:  * DOM tree building routines.
                   13934:  * 
                   13935:  * Returns the resulting document tree
                   13936:  */
                   13937: xmlDocPtr
                   13938: xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
                   13939:                  int size, int recovery) {
                   13940:     return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
                   13941: }
                   13942: 
                   13943: /**
                   13944:  * xmlParseMemory:
                   13945:  * @buffer:  an pointer to a char array
                   13946:  * @size:  the size of the array
                   13947:  *
                   13948:  * parse an XML in-memory block and build a tree.
                   13949:  * 
                   13950:  * Returns the resulting document tree
                   13951:  */
                   13952: 
                   13953: xmlDocPtr xmlParseMemory(const char *buffer, int size) {
                   13954:    return(xmlSAXParseMemory(NULL, buffer, size, 0));
                   13955: }
                   13956: 
                   13957: /**
                   13958:  * xmlRecoverMemory:
                   13959:  * @buffer:  an pointer to a char array
                   13960:  * @size:  the size of the array
                   13961:  *
                   13962:  * parse an XML in-memory block and build a tree.
                   13963:  * In the case the document is not Well Formed, an attempt to
                   13964:  * build a tree is tried anyway
                   13965:  *
                   13966:  * Returns the resulting document tree or NULL in case of error
                   13967:  */
                   13968: 
                   13969: xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
                   13970:    return(xmlSAXParseMemory(NULL, buffer, size, 1));
                   13971: }
                   13972: 
                   13973: /**
                   13974:  * xmlSAXUserParseMemory:
                   13975:  * @sax:  a SAX handler
                   13976:  * @user_data:  The user data returned on SAX callbacks
                   13977:  * @buffer:  an in-memory XML document input
                   13978:  * @size:  the length of the XML document in bytes
                   13979:  *
                   13980:  * A better SAX parsing routine.
                   13981:  * parse an XML in-memory buffer and call the given SAX handler routines.
                   13982:  *
                   13983:  * Returns 0 in case of success or a error number otherwise
                   13984:  */
                   13985: int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
                   13986:                          const char *buffer, int size) {
                   13987:     int ret = 0;
                   13988:     xmlParserCtxtPtr ctxt;
                   13989: 
                   13990:     xmlInitParser();
                   13991: 
                   13992:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
                   13993:     if (ctxt == NULL) return -1;
                   13994:     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
                   13995:         xmlFree(ctxt->sax);
                   13996:     ctxt->sax = sax;
                   13997:     xmlDetectSAX2(ctxt);
                   13998: 
                   13999:     if (user_data != NULL)
                   14000:        ctxt->userData = user_data;
                   14001: 
                   14002:     xmlParseDocument(ctxt);
                   14003:     
                   14004:     if (ctxt->wellFormed)
                   14005:        ret = 0;
                   14006:     else {
                   14007:         if (ctxt->errNo != 0)
                   14008:            ret = ctxt->errNo;
                   14009:        else
                   14010:            ret = -1;
                   14011:     }
                   14012:     if (sax != NULL)
                   14013:         ctxt->sax = NULL;
                   14014:     if (ctxt->myDoc != NULL) {
                   14015:         xmlFreeDoc(ctxt->myDoc);
                   14016:        ctxt->myDoc = NULL;
                   14017:     }
                   14018:     xmlFreeParserCtxt(ctxt);
                   14019:     
                   14020:     return ret;
                   14021: }
                   14022: #endif /* LIBXML_SAX1_ENABLED */
                   14023: 
                   14024: /**
                   14025:  * xmlCreateDocParserCtxt:
                   14026:  * @cur:  a pointer to an array of xmlChar
                   14027:  *
                   14028:  * Creates a parser context for an XML in-memory document.
                   14029:  *
                   14030:  * Returns the new parser context or NULL
                   14031:  */
                   14032: xmlParserCtxtPtr
                   14033: xmlCreateDocParserCtxt(const xmlChar *cur) {
                   14034:     int len;
                   14035: 
                   14036:     if (cur == NULL)
                   14037:        return(NULL);
                   14038:     len = xmlStrlen(cur);
                   14039:     return(xmlCreateMemoryParserCtxt((const char *)cur, len));
                   14040: }
                   14041: 
                   14042: #ifdef LIBXML_SAX1_ENABLED
                   14043: /**
                   14044:  * xmlSAXParseDoc:
                   14045:  * @sax:  the SAX handler block
                   14046:  * @cur:  a pointer to an array of xmlChar
                   14047:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
                   14048:  *             documents
                   14049:  *
                   14050:  * parse an XML in-memory document and build a tree.
                   14051:  * It use the given SAX function block to handle the parsing callback.
                   14052:  * If sax is NULL, fallback to the default DOM tree building routines.
                   14053:  * 
                   14054:  * Returns the resulting document tree
                   14055:  */
                   14056: 
                   14057: xmlDocPtr
                   14058: xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
                   14059:     xmlDocPtr ret;
                   14060:     xmlParserCtxtPtr ctxt;
                   14061:     xmlSAXHandlerPtr oldsax = NULL;
                   14062: 
                   14063:     if (cur == NULL) return(NULL);
                   14064: 
                   14065: 
                   14066:     ctxt = xmlCreateDocParserCtxt(cur);
                   14067:     if (ctxt == NULL) return(NULL);
                   14068:     if (sax != NULL) { 
                   14069:         oldsax = ctxt->sax;
                   14070:         ctxt->sax = sax;
                   14071:         ctxt->userData = NULL;
                   14072:     }
                   14073:     xmlDetectSAX2(ctxt);
                   14074: 
                   14075:     xmlParseDocument(ctxt);
                   14076:     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
                   14077:     else {
                   14078:        ret = NULL;
                   14079:        xmlFreeDoc(ctxt->myDoc);
                   14080:        ctxt->myDoc = NULL;
                   14081:     }
                   14082:     if (sax != NULL)
                   14083:        ctxt->sax = oldsax;
                   14084:     xmlFreeParserCtxt(ctxt);
                   14085:     
                   14086:     return(ret);
                   14087: }
                   14088: 
                   14089: /**
                   14090:  * xmlParseDoc:
                   14091:  * @cur:  a pointer to an array of xmlChar
                   14092:  *
                   14093:  * parse an XML in-memory document and build a tree.
                   14094:  * 
                   14095:  * Returns the resulting document tree
                   14096:  */
                   14097: 
                   14098: xmlDocPtr
                   14099: xmlParseDoc(const xmlChar *cur) {
                   14100:     return(xmlSAXParseDoc(NULL, cur, 0));
                   14101: }
                   14102: #endif /* LIBXML_SAX1_ENABLED */
                   14103: 
                   14104: #ifdef LIBXML_LEGACY_ENABLED
                   14105: /************************************************************************
                   14106:  *                                                                     *
                   14107:  *     Specific function to keep track of entities references          *
                   14108:  *     and used by the XSLT debugger                                   *
                   14109:  *                                                                     *
                   14110:  ************************************************************************/
                   14111: 
                   14112: static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
                   14113: 
                   14114: /**
                   14115:  * xmlAddEntityReference:
                   14116:  * @ent : A valid entity
                   14117:  * @firstNode : A valid first node for children of entity
                   14118:  * @lastNode : A valid last node of children entity 
                   14119:  *
                   14120:  * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
                   14121:  */
                   14122: static void
                   14123: xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
                   14124:                       xmlNodePtr lastNode)
                   14125: {
                   14126:     if (xmlEntityRefFunc != NULL) {
                   14127:         (*xmlEntityRefFunc) (ent, firstNode, lastNode);
                   14128:     }
                   14129: }
                   14130: 
                   14131: 
                   14132: /**
                   14133:  * xmlSetEntityReferenceFunc:
                   14134:  * @func: A valid function
                   14135:  *
                   14136:  * Set the function to call call back when a xml reference has been made
                   14137:  */
                   14138: void
                   14139: xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
                   14140: {
                   14141:     xmlEntityRefFunc = func;
                   14142: }
                   14143: #endif /* LIBXML_LEGACY_ENABLED */
                   14144: 
                   14145: /************************************************************************
                   14146:  *                                                                     *
                   14147:  *                             Miscellaneous                           *
                   14148:  *                                                                     *
                   14149:  ************************************************************************/
                   14150: 
                   14151: #ifdef LIBXML_XPATH_ENABLED
                   14152: #include <libxml/xpath.h>
                   14153: #endif
                   14154: 
                   14155: extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
                   14156: static int xmlParserInitialized = 0;
                   14157: 
                   14158: /**
                   14159:  * xmlInitParser:
                   14160:  *
                   14161:  * Initialization function for the XML parser.
                   14162:  * This is not reentrant. Call once before processing in case of
                   14163:  * use in multithreaded programs.
                   14164:  */
                   14165: 
                   14166: void
                   14167: xmlInitParser(void) {
                   14168:     if (xmlParserInitialized != 0)
                   14169:        return;
                   14170: 
                   14171: #ifdef LIBXML_THREAD_ENABLED
                   14172:     __xmlGlobalInitMutexLock();
                   14173:     if (xmlParserInitialized == 0) {
                   14174: #endif
                   14175:        xmlInitThreads();
                   14176:        xmlInitGlobals();
                   14177:        if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
                   14178:            (xmlGenericError == NULL))
                   14179:            initGenericErrorDefaultFunc(NULL);
                   14180:        xmlInitMemory();
1.1.1.2 ! misho    14181:         xmlInitializeDict();
1.1       misho    14182:        xmlInitCharEncodingHandlers();
                   14183:        xmlDefaultSAXHandlerInit();
                   14184:        xmlRegisterDefaultInputCallbacks();
                   14185: #ifdef LIBXML_OUTPUT_ENABLED
                   14186:        xmlRegisterDefaultOutputCallbacks();
                   14187: #endif /* LIBXML_OUTPUT_ENABLED */
                   14188: #ifdef LIBXML_HTML_ENABLED
                   14189:        htmlInitAutoClose();
                   14190:        htmlDefaultSAXHandlerInit();
                   14191: #endif
                   14192: #ifdef LIBXML_XPATH_ENABLED
                   14193:        xmlXPathInit();
                   14194: #endif
                   14195:        xmlParserInitialized = 1;
                   14196: #ifdef LIBXML_THREAD_ENABLED
                   14197:     }
                   14198:     __xmlGlobalInitMutexUnlock();
                   14199: #endif
                   14200: }
                   14201: 
                   14202: /**
                   14203:  * xmlCleanupParser:
                   14204:  *
                   14205:  * This function name is somewhat misleading. It does not clean up
                   14206:  * parser state, it cleans up memory allocated by the library itself.
                   14207:  * It is a cleanup function for the XML library. It tries to reclaim all
                   14208:  * related global memory allocated for the library processing.
                   14209:  * It doesn't deallocate any document related memory. One should
                   14210:  * call xmlCleanupParser() only when the process has finished using
                   14211:  * the library and all XML/HTML documents built with it.
                   14212:  * See also xmlInitParser() which has the opposite function of preparing
                   14213:  * the library for operations.
                   14214:  *
                   14215:  * WARNING: if your application is multithreaded or has plugin support
                   14216:  *          calling this may crash the application if another thread or
                   14217:  *          a plugin is still using libxml2. It's sometimes very hard to
                   14218:  *          guess if libxml2 is in use in the application, some libraries
                   14219:  *          or plugins may use it without notice. In case of doubt abstain
                   14220:  *          from calling this function or do it just before calling exit()
                   14221:  *          to avoid leak reports from valgrind !
                   14222:  */
                   14223: 
                   14224: void
                   14225: xmlCleanupParser(void) {
                   14226:     if (!xmlParserInitialized)
                   14227:        return;
                   14228: 
                   14229:     xmlCleanupCharEncodingHandlers();
                   14230: #ifdef LIBXML_CATALOG_ENABLED
                   14231:     xmlCatalogCleanup();
                   14232: #endif
                   14233:     xmlDictCleanup();
                   14234:     xmlCleanupInputCallbacks();
                   14235: #ifdef LIBXML_OUTPUT_ENABLED
                   14236:     xmlCleanupOutputCallbacks();
                   14237: #endif
                   14238: #ifdef LIBXML_SCHEMAS_ENABLED
                   14239:     xmlSchemaCleanupTypes();
                   14240:     xmlRelaxNGCleanupTypes();
                   14241: #endif
                   14242:     xmlCleanupGlobals();
                   14243:     xmlResetLastError();
                   14244:     xmlCleanupThreads(); /* must be last if called not from the main thread */
                   14245:     xmlCleanupMemory();
                   14246:     xmlParserInitialized = 0;
                   14247: }
                   14248: 
                   14249: /************************************************************************
                   14250:  *                                                                     *
                   14251:  *     New set (2.6.0) of simpler and more flexible APIs               *
                   14252:  *                                                                     *
                   14253:  ************************************************************************/
                   14254: 
                   14255: /**
                   14256:  * DICT_FREE:
                   14257:  * @str:  a string
                   14258:  *
                   14259:  * Free a string if it is not owned by the "dict" dictionnary in the
                   14260:  * current scope
                   14261:  */
                   14262: #define DICT_FREE(str)                                         \
                   14263:        if ((str) && ((!dict) ||                                \
                   14264:            (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
                   14265:            xmlFree((char *)(str));
                   14266: 
                   14267: /**
                   14268:  * xmlCtxtReset:
                   14269:  * @ctxt: an XML parser context
                   14270:  *
                   14271:  * Reset a parser context
                   14272:  */
                   14273: void
                   14274: xmlCtxtReset(xmlParserCtxtPtr ctxt)
                   14275: {
                   14276:     xmlParserInputPtr input;
                   14277:     xmlDictPtr dict;
                   14278:     
                   14279:     if (ctxt == NULL)
                   14280:         return;
                   14281: 
                   14282:     dict = ctxt->dict;
                   14283: 
                   14284:     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
                   14285:         xmlFreeInputStream(input);
                   14286:     }
                   14287:     ctxt->inputNr = 0;
                   14288:     ctxt->input = NULL;
                   14289: 
                   14290:     ctxt->spaceNr = 0;
                   14291:     if (ctxt->spaceTab != NULL) {
                   14292:        ctxt->spaceTab[0] = -1;
                   14293:        ctxt->space = &ctxt->spaceTab[0];
                   14294:     } else {
                   14295:         ctxt->space = NULL;
                   14296:     }
                   14297: 
                   14298: 
                   14299:     ctxt->nodeNr = 0;
                   14300:     ctxt->node = NULL;
                   14301: 
                   14302:     ctxt->nameNr = 0;
                   14303:     ctxt->name = NULL;
                   14304: 
                   14305:     DICT_FREE(ctxt->version);
                   14306:     ctxt->version = NULL;
                   14307:     DICT_FREE(ctxt->encoding);
                   14308:     ctxt->encoding = NULL;
                   14309:     DICT_FREE(ctxt->directory);
                   14310:     ctxt->directory = NULL;
                   14311:     DICT_FREE(ctxt->extSubURI);
                   14312:     ctxt->extSubURI = NULL;
                   14313:     DICT_FREE(ctxt->extSubSystem);
                   14314:     ctxt->extSubSystem = NULL;
                   14315:     if (ctxt->myDoc != NULL)
                   14316:         xmlFreeDoc(ctxt->myDoc);
                   14317:     ctxt->myDoc = NULL;
                   14318: 
                   14319:     ctxt->standalone = -1;
                   14320:     ctxt->hasExternalSubset = 0;
                   14321:     ctxt->hasPErefs = 0;
                   14322:     ctxt->html = 0;
                   14323:     ctxt->external = 0;
                   14324:     ctxt->instate = XML_PARSER_START;
                   14325:     ctxt->token = 0;
                   14326: 
                   14327:     ctxt->wellFormed = 1;
                   14328:     ctxt->nsWellFormed = 1;
                   14329:     ctxt->disableSAX = 0;
                   14330:     ctxt->valid = 1;
                   14331: #if 0
                   14332:     ctxt->vctxt.userData = ctxt;
                   14333:     ctxt->vctxt.error = xmlParserValidityError;
                   14334:     ctxt->vctxt.warning = xmlParserValidityWarning;
                   14335: #endif
                   14336:     ctxt->record_info = 0;
                   14337:     ctxt->nbChars = 0;
                   14338:     ctxt->checkIndex = 0;
                   14339:     ctxt->inSubset = 0;
                   14340:     ctxt->errNo = XML_ERR_OK;
                   14341:     ctxt->depth = 0;
                   14342:     ctxt->charset = XML_CHAR_ENCODING_UTF8;
                   14343:     ctxt->catalogs = NULL;
                   14344:     ctxt->nbentities = 0;
                   14345:     ctxt->sizeentities = 0;
                   14346:     xmlInitNodeInfoSeq(&ctxt->node_seq);
                   14347: 
                   14348:     if (ctxt->attsDefault != NULL) {
                   14349:         xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
                   14350:         ctxt->attsDefault = NULL;
                   14351:     }
                   14352:     if (ctxt->attsSpecial != NULL) {
                   14353:         xmlHashFree(ctxt->attsSpecial, NULL);
                   14354:         ctxt->attsSpecial = NULL;
                   14355:     }
                   14356: 
                   14357: #ifdef LIBXML_CATALOG_ENABLED
                   14358:     if (ctxt->catalogs != NULL)
                   14359:        xmlCatalogFreeLocal(ctxt->catalogs);
                   14360: #endif
                   14361:     if (ctxt->lastError.code != XML_ERR_OK)
                   14362:         xmlResetError(&ctxt->lastError);
                   14363: }
                   14364: 
                   14365: /**
                   14366:  * xmlCtxtResetPush:
                   14367:  * @ctxt: an XML parser context
                   14368:  * @chunk:  a pointer to an array of chars
                   14369:  * @size:  number of chars in the array
                   14370:  * @filename:  an optional file name or URI
                   14371:  * @encoding:  the document encoding, or NULL
                   14372:  *
                   14373:  * Reset a push parser context
                   14374:  *
                   14375:  * Returns 0 in case of success and 1 in case of error
                   14376:  */
                   14377: int
                   14378: xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
                   14379:                  int size, const char *filename, const char *encoding)
                   14380: {
                   14381:     xmlParserInputPtr inputStream;
                   14382:     xmlParserInputBufferPtr buf;
                   14383:     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
                   14384: 
                   14385:     if (ctxt == NULL)
                   14386:         return(1);
                   14387: 
                   14388:     if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
                   14389:         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
                   14390: 
                   14391:     buf = xmlAllocParserInputBuffer(enc);
                   14392:     if (buf == NULL)
                   14393:         return(1);
                   14394: 
                   14395:     if (ctxt == NULL) {
                   14396:         xmlFreeParserInputBuffer(buf);
                   14397:         return(1);
                   14398:     }
                   14399: 
                   14400:     xmlCtxtReset(ctxt);
                   14401: 
                   14402:     if (ctxt->pushTab == NULL) {
                   14403:         ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
                   14404:                                            sizeof(xmlChar *));
                   14405:         if (ctxt->pushTab == NULL) {
                   14406:            xmlErrMemory(ctxt, NULL);
                   14407:             xmlFreeParserInputBuffer(buf);
                   14408:             return(1);
                   14409:         }
                   14410:     }
                   14411: 
                   14412:     if (filename == NULL) {
                   14413:         ctxt->directory = NULL;
                   14414:     } else {
                   14415:         ctxt->directory = xmlParserGetDirectory(filename);
                   14416:     }
                   14417: 
                   14418:     inputStream = xmlNewInputStream(ctxt);
                   14419:     if (inputStream == NULL) {
                   14420:         xmlFreeParserInputBuffer(buf);
                   14421:         return(1);
                   14422:     }
                   14423: 
                   14424:     if (filename == NULL)
                   14425:         inputStream->filename = NULL;
                   14426:     else
                   14427:         inputStream->filename = (char *)
                   14428:             xmlCanonicPath((const xmlChar *) filename);
                   14429:     inputStream->buf = buf;
                   14430:     inputStream->base = inputStream->buf->buffer->content;
                   14431:     inputStream->cur = inputStream->buf->buffer->content;
                   14432:     inputStream->end =
                   14433:         &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
                   14434: 
                   14435:     inputPush(ctxt, inputStream);
                   14436: 
                   14437:     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
                   14438:         (ctxt->input->buf != NULL)) {
                   14439:         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
                   14440:         int cur = ctxt->input->cur - ctxt->input->base;
                   14441: 
                   14442:         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
                   14443: 
                   14444:         ctxt->input->base = ctxt->input->buf->buffer->content + base;
                   14445:         ctxt->input->cur = ctxt->input->base + cur;
                   14446:         ctxt->input->end =
                   14447:             &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->
                   14448:                                                use];
                   14449: #ifdef DEBUG_PUSH
                   14450:         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
                   14451: #endif
                   14452:     }
                   14453: 
                   14454:     if (encoding != NULL) {
                   14455:         xmlCharEncodingHandlerPtr hdlr;
                   14456: 
                   14457:         if (ctxt->encoding != NULL)
                   14458:            xmlFree((xmlChar *) ctxt->encoding);
                   14459:         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
                   14460: 
                   14461:         hdlr = xmlFindCharEncodingHandler(encoding);
                   14462:         if (hdlr != NULL) {
                   14463:             xmlSwitchToEncoding(ctxt, hdlr);
                   14464:        } else {
                   14465:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
                   14466:                              "Unsupported encoding %s\n", BAD_CAST encoding);
                   14467:         }
                   14468:     } else if (enc != XML_CHAR_ENCODING_NONE) {
                   14469:         xmlSwitchEncoding(ctxt, enc);
                   14470:     }
                   14471: 
                   14472:     return(0);
                   14473: }
                   14474: 
                   14475: 
                   14476: /**
                   14477:  * xmlCtxtUseOptionsInternal:
                   14478:  * @ctxt: an XML parser context
                   14479:  * @options:  a combination of xmlParserOption
                   14480:  * @encoding:  the user provided encoding to use
                   14481:  *
                   14482:  * Applies the options to the parser context
                   14483:  *
                   14484:  * Returns 0 in case of success, the set of unknown or unimplemented options
                   14485:  *         in case of error.
                   14486:  */
                   14487: static int
                   14488: xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
                   14489: {
                   14490:     if (ctxt == NULL)
                   14491:         return(-1);
                   14492:     if (encoding != NULL) {
                   14493:         if (ctxt->encoding != NULL)
                   14494:            xmlFree((xmlChar *) ctxt->encoding);
                   14495:         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
                   14496:     }
                   14497:     if (options & XML_PARSE_RECOVER) {
                   14498:         ctxt->recovery = 1;
                   14499:         options -= XML_PARSE_RECOVER;
                   14500:        ctxt->options |= XML_PARSE_RECOVER;
                   14501:     } else
                   14502:         ctxt->recovery = 0;
                   14503:     if (options & XML_PARSE_DTDLOAD) {
                   14504:         ctxt->loadsubset = XML_DETECT_IDS;
                   14505:         options -= XML_PARSE_DTDLOAD;
                   14506:        ctxt->options |= XML_PARSE_DTDLOAD;
                   14507:     } else
                   14508:         ctxt->loadsubset = 0;
                   14509:     if (options & XML_PARSE_DTDATTR) {
                   14510:         ctxt->loadsubset |= XML_COMPLETE_ATTRS;
                   14511:         options -= XML_PARSE_DTDATTR;
                   14512:        ctxt->options |= XML_PARSE_DTDATTR;
                   14513:     }
                   14514:     if (options & XML_PARSE_NOENT) {
                   14515:         ctxt->replaceEntities = 1;
                   14516:         /* ctxt->loadsubset |= XML_DETECT_IDS; */
                   14517:         options -= XML_PARSE_NOENT;
                   14518:        ctxt->options |= XML_PARSE_NOENT;
                   14519:     } else
                   14520:         ctxt->replaceEntities = 0;
                   14521:     if (options & XML_PARSE_PEDANTIC) {
                   14522:         ctxt->pedantic = 1;
                   14523:         options -= XML_PARSE_PEDANTIC;
                   14524:        ctxt->options |= XML_PARSE_PEDANTIC;
                   14525:     } else
                   14526:         ctxt->pedantic = 0;
                   14527:     if (options & XML_PARSE_NOBLANKS) {
                   14528:         ctxt->keepBlanks = 0;
                   14529:         ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
                   14530:         options -= XML_PARSE_NOBLANKS;
                   14531:        ctxt->options |= XML_PARSE_NOBLANKS;
                   14532:     } else
                   14533:         ctxt->keepBlanks = 1;
                   14534:     if (options & XML_PARSE_DTDVALID) {
                   14535:         ctxt->validate = 1;
                   14536:         if (options & XML_PARSE_NOWARNING)
                   14537:             ctxt->vctxt.warning = NULL;
                   14538:         if (options & XML_PARSE_NOERROR)
                   14539:             ctxt->vctxt.error = NULL;
                   14540:         options -= XML_PARSE_DTDVALID;
                   14541:        ctxt->options |= XML_PARSE_DTDVALID;
                   14542:     } else
                   14543:         ctxt->validate = 0;
                   14544:     if (options & XML_PARSE_NOWARNING) {
                   14545:         ctxt->sax->warning = NULL;
                   14546:         options -= XML_PARSE_NOWARNING;
                   14547:     }
                   14548:     if (options & XML_PARSE_NOERROR) {
                   14549:         ctxt->sax->error = NULL;
                   14550:         ctxt->sax->fatalError = NULL;
                   14551:         options -= XML_PARSE_NOERROR;
                   14552:     }
                   14553: #ifdef LIBXML_SAX1_ENABLED
                   14554:     if (options & XML_PARSE_SAX1) {
                   14555:         ctxt->sax->startElement = xmlSAX2StartElement;
                   14556:         ctxt->sax->endElement = xmlSAX2EndElement;
                   14557:         ctxt->sax->startElementNs = NULL;
                   14558:         ctxt->sax->endElementNs = NULL;
                   14559:         ctxt->sax->initialized = 1;
                   14560:         options -= XML_PARSE_SAX1;
                   14561:        ctxt->options |= XML_PARSE_SAX1;
                   14562:     }
                   14563: #endif /* LIBXML_SAX1_ENABLED */
                   14564:     if (options & XML_PARSE_NODICT) {
                   14565:         ctxt->dictNames = 0;
                   14566:         options -= XML_PARSE_NODICT;
                   14567:        ctxt->options |= XML_PARSE_NODICT;
                   14568:     } else {
                   14569:         ctxt->dictNames = 1;
                   14570:     }
                   14571:     if (options & XML_PARSE_NOCDATA) {
                   14572:         ctxt->sax->cdataBlock = NULL;
                   14573:         options -= XML_PARSE_NOCDATA;
                   14574:        ctxt->options |= XML_PARSE_NOCDATA;
                   14575:     }
                   14576:     if (options & XML_PARSE_NSCLEAN) {
                   14577:        ctxt->options |= XML_PARSE_NSCLEAN;
                   14578:         options -= XML_PARSE_NSCLEAN;
                   14579:     }
                   14580:     if (options & XML_PARSE_NONET) {
                   14581:        ctxt->options |= XML_PARSE_NONET;
                   14582:         options -= XML_PARSE_NONET;
                   14583:     }
                   14584:     if (options & XML_PARSE_COMPACT) {
                   14585:        ctxt->options |= XML_PARSE_COMPACT;
                   14586:         options -= XML_PARSE_COMPACT;
                   14587:     }
                   14588:     if (options & XML_PARSE_OLD10) {
                   14589:        ctxt->options |= XML_PARSE_OLD10;
                   14590:         options -= XML_PARSE_OLD10;
                   14591:     }
                   14592:     if (options & XML_PARSE_NOBASEFIX) {
                   14593:        ctxt->options |= XML_PARSE_NOBASEFIX;
                   14594:         options -= XML_PARSE_NOBASEFIX;
                   14595:     }
                   14596:     if (options & XML_PARSE_HUGE) {
                   14597:        ctxt->options |= XML_PARSE_HUGE;
                   14598:         options -= XML_PARSE_HUGE;
                   14599:     }
                   14600:     if (options & XML_PARSE_OLDSAX) {
                   14601:        ctxt->options |= XML_PARSE_OLDSAX;
                   14602:         options -= XML_PARSE_OLDSAX;
                   14603:     }
1.1.1.2 ! misho    14604:     if (options & XML_PARSE_IGNORE_ENC) {
        !          14605:        ctxt->options |= XML_PARSE_IGNORE_ENC;
        !          14606:         options -= XML_PARSE_IGNORE_ENC;
        !          14607:     }
1.1       misho    14608:     ctxt->linenumbers = 1;
                   14609:     return (options);
                   14610: }
                   14611: 
                   14612: /**
                   14613:  * xmlCtxtUseOptions:
                   14614:  * @ctxt: an XML parser context
                   14615:  * @options:  a combination of xmlParserOption
                   14616:  *
                   14617:  * Applies the options to the parser context
                   14618:  *
                   14619:  * Returns 0 in case of success, the set of unknown or unimplemented options
                   14620:  *         in case of error.
                   14621:  */
                   14622: int
                   14623: xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
                   14624: {
                   14625:    return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
                   14626: }
                   14627: 
                   14628: /**
                   14629:  * xmlDoRead:
                   14630:  * @ctxt:  an XML parser context
                   14631:  * @URL:  the base URL to use for the document
                   14632:  * @encoding:  the document encoding, or NULL
                   14633:  * @options:  a combination of xmlParserOption
                   14634:  * @reuse:  keep the context for reuse
                   14635:  *
                   14636:  * Common front-end for the xmlRead functions
                   14637:  *
                   14638:  * Returns the resulting document tree or NULL
                   14639:  */
                   14640: static xmlDocPtr
                   14641: xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
                   14642:           int options, int reuse)
                   14643: {
                   14644:     xmlDocPtr ret;
                   14645: 
                   14646:     xmlCtxtUseOptionsInternal(ctxt, options, encoding);
                   14647:     if (encoding != NULL) {
                   14648:         xmlCharEncodingHandlerPtr hdlr;
                   14649: 
                   14650:        hdlr = xmlFindCharEncodingHandler(encoding);
                   14651:        if (hdlr != NULL)
                   14652:            xmlSwitchToEncoding(ctxt, hdlr);
                   14653:     }
                   14654:     if ((URL != NULL) && (ctxt->input != NULL) &&
                   14655:         (ctxt->input->filename == NULL))
                   14656:         ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
                   14657:     xmlParseDocument(ctxt);
                   14658:     if ((ctxt->wellFormed) || ctxt->recovery)
                   14659:         ret = ctxt->myDoc;
                   14660:     else {
                   14661:         ret = NULL;
                   14662:        if (ctxt->myDoc != NULL) {
                   14663:            xmlFreeDoc(ctxt->myDoc);
                   14664:        }
                   14665:     }
                   14666:     ctxt->myDoc = NULL;
                   14667:     if (!reuse) {
                   14668:        xmlFreeParserCtxt(ctxt);
                   14669:     }
                   14670: 
                   14671:     return (ret);
                   14672: }
                   14673: 
                   14674: /**
                   14675:  * xmlReadDoc:
                   14676:  * @cur:  a pointer to a zero terminated string
                   14677:  * @URL:  the base URL to use for the document
                   14678:  * @encoding:  the document encoding, or NULL
                   14679:  * @options:  a combination of xmlParserOption
                   14680:  *
                   14681:  * parse an XML in-memory document and build a tree.
                   14682:  * 
                   14683:  * Returns the resulting document tree
                   14684:  */
                   14685: xmlDocPtr
                   14686: xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
                   14687: {
                   14688:     xmlParserCtxtPtr ctxt;
                   14689: 
                   14690:     if (cur == NULL)
                   14691:         return (NULL);
                   14692: 
                   14693:     ctxt = xmlCreateDocParserCtxt(cur);
                   14694:     if (ctxt == NULL)
                   14695:         return (NULL);
                   14696:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
                   14697: }
                   14698: 
                   14699: /**
                   14700:  * xmlReadFile:
                   14701:  * @filename:  a file or URL
                   14702:  * @encoding:  the document encoding, or NULL
                   14703:  * @options:  a combination of xmlParserOption
                   14704:  *
                   14705:  * parse an XML file from the filesystem or the network.
                   14706:  * 
                   14707:  * Returns the resulting document tree
                   14708:  */
                   14709: xmlDocPtr
                   14710: xmlReadFile(const char *filename, const char *encoding, int options)
                   14711: {
                   14712:     xmlParserCtxtPtr ctxt;
                   14713: 
                   14714:     ctxt = xmlCreateURLParserCtxt(filename, options);
                   14715:     if (ctxt == NULL)
                   14716:         return (NULL);
                   14717:     return (xmlDoRead(ctxt, NULL, encoding, options, 0));
                   14718: }
                   14719: 
                   14720: /**
                   14721:  * xmlReadMemory:
                   14722:  * @buffer:  a pointer to a char array
                   14723:  * @size:  the size of the array
                   14724:  * @URL:  the base URL to use for the document
                   14725:  * @encoding:  the document encoding, or NULL
                   14726:  * @options:  a combination of xmlParserOption
                   14727:  *
                   14728:  * parse an XML in-memory document and build a tree.
                   14729:  * 
                   14730:  * Returns the resulting document tree
                   14731:  */
                   14732: xmlDocPtr
                   14733: xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
                   14734: {
                   14735:     xmlParserCtxtPtr ctxt;
                   14736: 
                   14737:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
                   14738:     if (ctxt == NULL)
                   14739:         return (NULL);
                   14740:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
                   14741: }
                   14742: 
                   14743: /**
                   14744:  * xmlReadFd:
                   14745:  * @fd:  an open file descriptor
                   14746:  * @URL:  the base URL to use for the document
                   14747:  * @encoding:  the document encoding, or NULL
                   14748:  * @options:  a combination of xmlParserOption
                   14749:  *
                   14750:  * parse an XML from a file descriptor and build a tree.
                   14751:  * NOTE that the file descriptor will not be closed when the
                   14752:  *      reader is closed or reset.
                   14753:  * 
                   14754:  * Returns the resulting document tree
                   14755:  */
                   14756: xmlDocPtr
                   14757: xmlReadFd(int fd, const char *URL, const char *encoding, int options)
                   14758: {
                   14759:     xmlParserCtxtPtr ctxt;
                   14760:     xmlParserInputBufferPtr input;
                   14761:     xmlParserInputPtr stream;
                   14762: 
                   14763:     if (fd < 0)
                   14764:         return (NULL);
                   14765: 
                   14766:     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
                   14767:     if (input == NULL)
                   14768:         return (NULL);
                   14769:     input->closecallback = NULL;
                   14770:     ctxt = xmlNewParserCtxt();
                   14771:     if (ctxt == NULL) {
                   14772:         xmlFreeParserInputBuffer(input);
                   14773:         return (NULL);
                   14774:     }
                   14775:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   14776:     if (stream == NULL) {
                   14777:         xmlFreeParserInputBuffer(input);
                   14778:        xmlFreeParserCtxt(ctxt);
                   14779:         return (NULL);
                   14780:     }
                   14781:     inputPush(ctxt, stream);
                   14782:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
                   14783: }
                   14784: 
                   14785: /**
                   14786:  * xmlReadIO:
                   14787:  * @ioread:  an I/O read function
                   14788:  * @ioclose:  an I/O close function
                   14789:  * @ioctx:  an I/O handler
                   14790:  * @URL:  the base URL to use for the document
                   14791:  * @encoding:  the document encoding, or NULL
                   14792:  * @options:  a combination of xmlParserOption
                   14793:  *
                   14794:  * parse an XML document from I/O functions and source and build a tree.
1.1.1.2 ! misho    14795:  *
1.1       misho    14796:  * Returns the resulting document tree
                   14797:  */
                   14798: xmlDocPtr
                   14799: xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
                   14800:           void *ioctx, const char *URL, const char *encoding, int options)
                   14801: {
                   14802:     xmlParserCtxtPtr ctxt;
                   14803:     xmlParserInputBufferPtr input;
                   14804:     xmlParserInputPtr stream;
                   14805: 
                   14806:     if (ioread == NULL)
                   14807:         return (NULL);
                   14808: 
                   14809:     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
                   14810:                                          XML_CHAR_ENCODING_NONE);
1.1.1.2 ! misho    14811:     if (input == NULL) {
        !          14812:         if (ioclose != NULL)
        !          14813:             ioclose(ioctx);
1.1       misho    14814:         return (NULL);
1.1.1.2 ! misho    14815:     }
1.1       misho    14816:     ctxt = xmlNewParserCtxt();
                   14817:     if (ctxt == NULL) {
                   14818:         xmlFreeParserInputBuffer(input);
                   14819:         return (NULL);
                   14820:     }
                   14821:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   14822:     if (stream == NULL) {
                   14823:         xmlFreeParserInputBuffer(input);
                   14824:        xmlFreeParserCtxt(ctxt);
                   14825:         return (NULL);
                   14826:     }
                   14827:     inputPush(ctxt, stream);
                   14828:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
                   14829: }
                   14830: 
                   14831: /**
                   14832:  * xmlCtxtReadDoc:
                   14833:  * @ctxt:  an XML parser context
                   14834:  * @cur:  a pointer to a zero terminated string
                   14835:  * @URL:  the base URL to use for the document
                   14836:  * @encoding:  the document encoding, or NULL
                   14837:  * @options:  a combination of xmlParserOption
                   14838:  *
                   14839:  * parse an XML in-memory document and build a tree.
                   14840:  * This reuses the existing @ctxt parser context
1.1.1.2 ! misho    14841:  *
1.1       misho    14842:  * Returns the resulting document tree
                   14843:  */
                   14844: xmlDocPtr
                   14845: xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
                   14846:                const char *URL, const char *encoding, int options)
                   14847: {
                   14848:     xmlParserInputPtr stream;
                   14849: 
                   14850:     if (cur == NULL)
                   14851:         return (NULL);
                   14852:     if (ctxt == NULL)
                   14853:         return (NULL);
                   14854: 
                   14855:     xmlCtxtReset(ctxt);
                   14856: 
                   14857:     stream = xmlNewStringInputStream(ctxt, cur);
                   14858:     if (stream == NULL) {
                   14859:         return (NULL);
                   14860:     }
                   14861:     inputPush(ctxt, stream);
                   14862:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
                   14863: }
                   14864: 
                   14865: /**
                   14866:  * xmlCtxtReadFile:
                   14867:  * @ctxt:  an XML parser context
                   14868:  * @filename:  a file or URL
                   14869:  * @encoding:  the document encoding, or NULL
                   14870:  * @options:  a combination of xmlParserOption
                   14871:  *
                   14872:  * parse an XML file from the filesystem or the network.
                   14873:  * This reuses the existing @ctxt parser context
                   14874:  * 
                   14875:  * Returns the resulting document tree
                   14876:  */
                   14877: xmlDocPtr
                   14878: xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
                   14879:                 const char *encoding, int options)
                   14880: {
                   14881:     xmlParserInputPtr stream;
                   14882: 
                   14883:     if (filename == NULL)
                   14884:         return (NULL);
                   14885:     if (ctxt == NULL)
                   14886:         return (NULL);
                   14887: 
                   14888:     xmlCtxtReset(ctxt);
                   14889: 
                   14890:     stream = xmlLoadExternalEntity(filename, NULL, ctxt);
                   14891:     if (stream == NULL) {
                   14892:         return (NULL);
                   14893:     }
                   14894:     inputPush(ctxt, stream);
                   14895:     return (xmlDoRead(ctxt, NULL, encoding, options, 1));
                   14896: }
                   14897: 
                   14898: /**
                   14899:  * xmlCtxtReadMemory:
                   14900:  * @ctxt:  an XML parser context
                   14901:  * @buffer:  a pointer to a char array
                   14902:  * @size:  the size of the array
                   14903:  * @URL:  the base URL to use for the document
                   14904:  * @encoding:  the document encoding, or NULL
                   14905:  * @options:  a combination of xmlParserOption
                   14906:  *
                   14907:  * parse an XML in-memory document and build a tree.
                   14908:  * This reuses the existing @ctxt parser context
                   14909:  * 
                   14910:  * Returns the resulting document tree
                   14911:  */
                   14912: xmlDocPtr
                   14913: xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
                   14914:                   const char *URL, const char *encoding, int options)
                   14915: {
                   14916:     xmlParserInputBufferPtr input;
                   14917:     xmlParserInputPtr stream;
                   14918: 
                   14919:     if (ctxt == NULL)
                   14920:         return (NULL);
                   14921:     if (buffer == NULL)
                   14922:         return (NULL);
                   14923: 
                   14924:     xmlCtxtReset(ctxt);
                   14925: 
                   14926:     input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
                   14927:     if (input == NULL) {
                   14928:        return(NULL);
                   14929:     }
                   14930: 
                   14931:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   14932:     if (stream == NULL) {
                   14933:        xmlFreeParserInputBuffer(input);
                   14934:        return(NULL);
                   14935:     }
                   14936: 
                   14937:     inputPush(ctxt, stream);
                   14938:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
                   14939: }
                   14940: 
                   14941: /**
                   14942:  * xmlCtxtReadFd:
                   14943:  * @ctxt:  an XML parser context
                   14944:  * @fd:  an open file descriptor
                   14945:  * @URL:  the base URL to use for the document
                   14946:  * @encoding:  the document encoding, or NULL
                   14947:  * @options:  a combination of xmlParserOption
                   14948:  *
                   14949:  * parse an XML from a file descriptor and build a tree.
                   14950:  * This reuses the existing @ctxt parser context
                   14951:  * NOTE that the file descriptor will not be closed when the
                   14952:  *      reader is closed or reset.
                   14953:  * 
                   14954:  * Returns the resulting document tree
                   14955:  */
                   14956: xmlDocPtr
                   14957: xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
                   14958:               const char *URL, const char *encoding, int options)
                   14959: {
                   14960:     xmlParserInputBufferPtr input;
                   14961:     xmlParserInputPtr stream;
                   14962: 
                   14963:     if (fd < 0)
                   14964:         return (NULL);
                   14965:     if (ctxt == NULL)
                   14966:         return (NULL);
                   14967: 
                   14968:     xmlCtxtReset(ctxt);
                   14969: 
                   14970: 
                   14971:     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
                   14972:     if (input == NULL)
                   14973:         return (NULL);
                   14974:     input->closecallback = NULL;
                   14975:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   14976:     if (stream == NULL) {
                   14977:         xmlFreeParserInputBuffer(input);
                   14978:         return (NULL);
                   14979:     }
                   14980:     inputPush(ctxt, stream);
                   14981:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
                   14982: }
                   14983: 
                   14984: /**
                   14985:  * xmlCtxtReadIO:
                   14986:  * @ctxt:  an XML parser context
                   14987:  * @ioread:  an I/O read function
                   14988:  * @ioclose:  an I/O close function
                   14989:  * @ioctx:  an I/O handler
                   14990:  * @URL:  the base URL to use for the document
                   14991:  * @encoding:  the document encoding, or NULL
                   14992:  * @options:  a combination of xmlParserOption
                   14993:  *
                   14994:  * parse an XML document from I/O functions and source and build a tree.
                   14995:  * This reuses the existing @ctxt parser context
1.1.1.2 ! misho    14996:  *
1.1       misho    14997:  * Returns the resulting document tree
                   14998:  */
                   14999: xmlDocPtr
                   15000: xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
                   15001:               xmlInputCloseCallback ioclose, void *ioctx,
                   15002:              const char *URL,
                   15003:               const char *encoding, int options)
                   15004: {
                   15005:     xmlParserInputBufferPtr input;
                   15006:     xmlParserInputPtr stream;
                   15007: 
                   15008:     if (ioread == NULL)
                   15009:         return (NULL);
                   15010:     if (ctxt == NULL)
                   15011:         return (NULL);
                   15012: 
                   15013:     xmlCtxtReset(ctxt);
                   15014: 
                   15015:     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
                   15016:                                          XML_CHAR_ENCODING_NONE);
1.1.1.2 ! misho    15017:     if (input == NULL) {
        !          15018:         if (ioclose != NULL)
        !          15019:             ioclose(ioctx);
1.1       misho    15020:         return (NULL);
1.1.1.2 ! misho    15021:     }
1.1       misho    15022:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   15023:     if (stream == NULL) {
                   15024:         xmlFreeParserInputBuffer(input);
                   15025:         return (NULL);
                   15026:     }
                   15027:     inputPush(ctxt, stream);
                   15028:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
                   15029: }
                   15030: 
                   15031: #define bottom_parser
                   15032: #include "elfgcchack.h"

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