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

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
                     82: 
                     83: static void
                     84: xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
                     85: 
                     86: static xmlParserCtxtPtr
                     87: xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
                     88:                          const xmlChar *base, xmlParserCtxtPtr pctx);
                     89: 
                     90: /************************************************************************
                     91:  *                                                                     *
                     92:  *     Arbitrary limits set in the parser. See XML_PARSE_HUGE          *
                     93:  *                                                                     *
                     94:  ************************************************************************/
                     95: 
                     96: #define XML_PARSER_BIG_ENTITY 1000
                     97: #define XML_PARSER_LOT_ENTITY 5000
                     98: 
                     99: /*
                    100:  * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
                    101:  *    replacement over the size in byte of the input indicates that you have
                    102:  *    and eponential behaviour. A value of 10 correspond to at least 3 entity
                    103:  *    replacement per byte of input.
                    104:  */
                    105: #define XML_PARSER_NON_LINEAR 10
                    106: 
                    107: /*
                    108:  * xmlParserEntityCheck
                    109:  *
                    110:  * Function to check non-linear entity expansion behaviour
                    111:  * This is here to detect and stop exponential linear entity expansion
                    112:  * This is not a limitation of the parser but a safety
                    113:  * boundary feature. It can be disabled with the XML_PARSE_HUGE
                    114:  * parser option.
                    115:  */
                    116: static int
                    117: xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long size,
                    118:                      xmlEntityPtr ent)
                    119: {
                    120:     unsigned long consumed = 0;
                    121: 
                    122:     if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
                    123:         return (0);
                    124:     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
                    125:         return (1);
                    126:     if (size != 0) {
                    127:         /*
                    128:          * Do the check based on the replacement size of the entity
                    129:          */
                    130:         if (size < XML_PARSER_BIG_ENTITY)
                    131:            return(0);
                    132: 
                    133:         /*
                    134:          * A limit on the amount of text data reasonably used
                    135:          */
                    136:         if (ctxt->input != NULL) {
                    137:             consumed = ctxt->input->consumed +
                    138:                 (ctxt->input->cur - ctxt->input->base);
                    139:         }
                    140:         consumed += ctxt->sizeentities;
                    141: 
                    142:         if ((size < XML_PARSER_NON_LINEAR * consumed) &&
                    143:            (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
                    144:             return (0);
                    145:     } else if (ent != NULL) {
                    146:         /*
                    147:          * use the number of parsed entities in the replacement
                    148:          */
                    149:         size = ent->checked;
                    150: 
                    151:         /*
                    152:          * The amount of data parsed counting entities size only once
                    153:          */
                    154:         if (ctxt->input != NULL) {
                    155:             consumed = ctxt->input->consumed +
                    156:                 (ctxt->input->cur - ctxt->input->base);
                    157:         }
                    158:         consumed += ctxt->sizeentities;
                    159: 
                    160:         /*
                    161:          * Check the density of entities for the amount of data
                    162:         * knowing an entity reference will take at least 3 bytes
                    163:          */
                    164:         if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
                    165:             return (0);
                    166:     } else {
                    167:         /*
                    168:          * strange we got no data for checking just return
                    169:          */
                    170:         return (0);
                    171:     }
                    172: 
                    173:     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
                    174:     return (1);
                    175: }
                    176: 
                    177: /**
                    178:  * xmlParserMaxDepth:
                    179:  *
                    180:  * arbitrary depth limit for the XML documents that we allow to
                    181:  * process. This is not a limitation of the parser but a safety
                    182:  * boundary feature. It can be disabled with the XML_PARSE_HUGE
                    183:  * parser option.
                    184:  */
                    185: unsigned int xmlParserMaxDepth = 256;
                    186: 
                    187: 
                    188: 
                    189: #define SAX2 1
                    190: #define XML_PARSER_BIG_BUFFER_SIZE 300
                    191: #define XML_PARSER_BUFFER_SIZE 100
                    192: #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
                    193: 
                    194: /*
                    195:  * List of XML prefixed PI allowed by W3C specs
                    196:  */
                    197: 
                    198: static const char *xmlW3CPIs[] = {
                    199:     "xml-stylesheet",
                    200:     NULL
                    201: };
                    202: 
                    203: 
                    204: /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
                    205: static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
                    206:                                               const xmlChar **str);
                    207: 
                    208: static xmlParserErrors
                    209: xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
                    210:                      xmlSAXHandlerPtr sax,
                    211:                      void *user_data, int depth, const xmlChar *URL,
                    212:                      const xmlChar *ID, xmlNodePtr *list);
                    213: 
                    214: static int
                    215: xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
                    216:                           const char *encoding);
                    217: #ifdef LIBXML_LEGACY_ENABLED
                    218: static void
                    219: xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
                    220:                       xmlNodePtr lastNode);
                    221: #endif /* LIBXML_LEGACY_ENABLED */
                    222: 
                    223: static xmlParserErrors
                    224: xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
                    225:                      const xmlChar *string, void *user_data, xmlNodePtr *lst);
                    226: 
                    227: static int
                    228: xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
                    229: 
                    230: /************************************************************************
                    231:  *                                                                     *
                    232:  *             Some factorized error routines                          *
                    233:  *                                                                     *
                    234:  ************************************************************************/
                    235: 
                    236: /**
                    237:  * xmlErrAttributeDup:
                    238:  * @ctxt:  an XML parser context
                    239:  * @prefix:  the attribute prefix
                    240:  * @localname:  the attribute localname
                    241:  *
                    242:  * Handle a redefinition of attribute error
                    243:  */
                    244: static void
                    245: xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
                    246:                    const xmlChar * localname)
                    247: {
                    248:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    249:         (ctxt->instate == XML_PARSER_EOF))
                    250:        return;
                    251:     if (ctxt != NULL)
                    252:        ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
                    253: 
                    254:     if (prefix == NULL)
                    255:         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                    256:                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
                    257:                         (const char *) localname, NULL, NULL, 0, 0,
                    258:                         "Attribute %s redefined\n", localname);
                    259:     else
                    260:         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
                    261:                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
                    262:                         (const char *) prefix, (const char *) localname,
                    263:                         NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
                    264:                         localname);
                    265:     if (ctxt != NULL) {
                    266:        ctxt->wellFormed = 0;
                    267:        if (ctxt->recovery == 0)
                    268:            ctxt->disableSAX = 1;
                    269:     }
                    270: }
                    271: 
                    272: /**
                    273:  * xmlFatalErr:
                    274:  * @ctxt:  an XML parser context
                    275:  * @error:  the error number
                    276:  * @extra:  extra information string
                    277:  *
                    278:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    279:  */
                    280: static void
                    281: xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
                    282: {
                    283:     const char *errmsg;
                    284: 
                    285:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    286:         (ctxt->instate == XML_PARSER_EOF))
                    287:        return;
                    288:     switch (error) {
                    289:         case XML_ERR_INVALID_HEX_CHARREF:
                    290:             errmsg = "CharRef: invalid hexadecimal value\n";
                    291:             break;
                    292:         case XML_ERR_INVALID_DEC_CHARREF:
                    293:             errmsg = "CharRef: invalid decimal value\n";
                    294:             break;
                    295:         case XML_ERR_INVALID_CHARREF:
                    296:             errmsg = "CharRef: invalid value\n";
                    297:             break;
                    298:         case XML_ERR_INTERNAL_ERROR:
                    299:             errmsg = "internal error";
                    300:             break;
                    301:         case XML_ERR_PEREF_AT_EOF:
                    302:             errmsg = "PEReference at end of document\n";
                    303:             break;
                    304:         case XML_ERR_PEREF_IN_PROLOG:
                    305:             errmsg = "PEReference in prolog\n";
                    306:             break;
                    307:         case XML_ERR_PEREF_IN_EPILOG:
                    308:             errmsg = "PEReference in epilog\n";
                    309:             break;
                    310:         case XML_ERR_PEREF_NO_NAME:
                    311:             errmsg = "PEReference: no name\n";
                    312:             break;
                    313:         case XML_ERR_PEREF_SEMICOL_MISSING:
                    314:             errmsg = "PEReference: expecting ';'\n";
                    315:             break;
                    316:         case XML_ERR_ENTITY_LOOP:
                    317:             errmsg = "Detected an entity reference loop\n";
                    318:             break;
                    319:         case XML_ERR_ENTITY_NOT_STARTED:
                    320:             errmsg = "EntityValue: \" or ' expected\n";
                    321:             break;
                    322:         case XML_ERR_ENTITY_PE_INTERNAL:
                    323:             errmsg = "PEReferences forbidden in internal subset\n";
                    324:             break;
                    325:         case XML_ERR_ENTITY_NOT_FINISHED:
                    326:             errmsg = "EntityValue: \" or ' expected\n";
                    327:             break;
                    328:         case XML_ERR_ATTRIBUTE_NOT_STARTED:
                    329:             errmsg = "AttValue: \" or ' expected\n";
                    330:             break;
                    331:         case XML_ERR_LT_IN_ATTRIBUTE:
                    332:             errmsg = "Unescaped '<' not allowed in attributes values\n";
                    333:             break;
                    334:         case XML_ERR_LITERAL_NOT_STARTED:
                    335:             errmsg = "SystemLiteral \" or ' expected\n";
                    336:             break;
                    337:         case XML_ERR_LITERAL_NOT_FINISHED:
                    338:             errmsg = "Unfinished System or Public ID \" or ' expected\n";
                    339:             break;
                    340:         case XML_ERR_MISPLACED_CDATA_END:
                    341:             errmsg = "Sequence ']]>' not allowed in content\n";
                    342:             break;
                    343:         case XML_ERR_URI_REQUIRED:
                    344:             errmsg = "SYSTEM or PUBLIC, the URI is missing\n";
                    345:             break;
                    346:         case XML_ERR_PUBID_REQUIRED:
                    347:             errmsg = "PUBLIC, the Public Identifier is missing\n";
                    348:             break;
                    349:         case XML_ERR_HYPHEN_IN_COMMENT:
                    350:             errmsg = "Comment must not contain '--' (double-hyphen)\n";
                    351:             break;
                    352:         case XML_ERR_PI_NOT_STARTED:
                    353:             errmsg = "xmlParsePI : no target name\n";
                    354:             break;
                    355:         case XML_ERR_RESERVED_XML_NAME:
                    356:             errmsg = "Invalid PI name\n";
                    357:             break;
                    358:         case XML_ERR_NOTATION_NOT_STARTED:
                    359:             errmsg = "NOTATION: Name expected here\n";
                    360:             break;
                    361:         case XML_ERR_NOTATION_NOT_FINISHED:
                    362:             errmsg = "'>' required to close NOTATION declaration\n";
                    363:             break;
                    364:         case XML_ERR_VALUE_REQUIRED:
                    365:             errmsg = "Entity value required\n";
                    366:             break;
                    367:         case XML_ERR_URI_FRAGMENT:
                    368:             errmsg = "Fragment not allowed";
                    369:             break;
                    370:         case XML_ERR_ATTLIST_NOT_STARTED:
                    371:             errmsg = "'(' required to start ATTLIST enumeration\n";
                    372:             break;
                    373:         case XML_ERR_NMTOKEN_REQUIRED:
                    374:             errmsg = "NmToken expected in ATTLIST enumeration\n";
                    375:             break;
                    376:         case XML_ERR_ATTLIST_NOT_FINISHED:
                    377:             errmsg = "')' required to finish ATTLIST enumeration\n";
                    378:             break;
                    379:         case XML_ERR_MIXED_NOT_STARTED:
                    380:             errmsg = "MixedContentDecl : '|' or ')*' expected\n";
                    381:             break;
                    382:         case XML_ERR_PCDATA_REQUIRED:
                    383:             errmsg = "MixedContentDecl : '#PCDATA' expected\n";
                    384:             break;
                    385:         case XML_ERR_ELEMCONTENT_NOT_STARTED:
                    386:             errmsg = "ContentDecl : Name or '(' expected\n";
                    387:             break;
                    388:         case XML_ERR_ELEMCONTENT_NOT_FINISHED:
                    389:             errmsg = "ContentDecl : ',' '|' or ')' expected\n";
                    390:             break;
                    391:         case XML_ERR_PEREF_IN_INT_SUBSET:
                    392:             errmsg =
                    393:                 "PEReference: forbidden within markup decl in internal subset\n";
                    394:             break;
                    395:         case XML_ERR_GT_REQUIRED:
                    396:             errmsg = "expected '>'\n";
                    397:             break;
                    398:         case XML_ERR_CONDSEC_INVALID:
                    399:             errmsg = "XML conditional section '[' expected\n";
                    400:             break;
                    401:         case XML_ERR_EXT_SUBSET_NOT_FINISHED:
                    402:             errmsg = "Content error in the external subset\n";
                    403:             break;
                    404:         case XML_ERR_CONDSEC_INVALID_KEYWORD:
                    405:             errmsg =
                    406:                 "conditional section INCLUDE or IGNORE keyword expected\n";
                    407:             break;
                    408:         case XML_ERR_CONDSEC_NOT_FINISHED:
                    409:             errmsg = "XML conditional section not closed\n";
                    410:             break;
                    411:         case XML_ERR_XMLDECL_NOT_STARTED:
                    412:             errmsg = "Text declaration '<?xml' required\n";
                    413:             break;
                    414:         case XML_ERR_XMLDECL_NOT_FINISHED:
                    415:             errmsg = "parsing XML declaration: '?>' expected\n";
                    416:             break;
                    417:         case XML_ERR_EXT_ENTITY_STANDALONE:
                    418:             errmsg = "external parsed entities cannot be standalone\n";
                    419:             break;
                    420:         case XML_ERR_ENTITYREF_SEMICOL_MISSING:
                    421:             errmsg = "EntityRef: expecting ';'\n";
                    422:             break;
                    423:         case XML_ERR_DOCTYPE_NOT_FINISHED:
                    424:             errmsg = "DOCTYPE improperly terminated\n";
                    425:             break;
                    426:         case XML_ERR_LTSLASH_REQUIRED:
                    427:             errmsg = "EndTag: '</' not found\n";
                    428:             break;
                    429:         case XML_ERR_EQUAL_REQUIRED:
                    430:             errmsg = "expected '='\n";
                    431:             break;
                    432:         case XML_ERR_STRING_NOT_CLOSED:
                    433:             errmsg = "String not closed expecting \" or '\n";
                    434:             break;
                    435:         case XML_ERR_STRING_NOT_STARTED:
                    436:             errmsg = "String not started expecting ' or \"\n";
                    437:             break;
                    438:         case XML_ERR_ENCODING_NAME:
                    439:             errmsg = "Invalid XML encoding name\n";
                    440:             break;
                    441:         case XML_ERR_STANDALONE_VALUE:
                    442:             errmsg = "standalone accepts only 'yes' or 'no'\n";
                    443:             break;
                    444:         case XML_ERR_DOCUMENT_EMPTY:
                    445:             errmsg = "Document is empty\n";
                    446:             break;
                    447:         case XML_ERR_DOCUMENT_END:
                    448:             errmsg = "Extra content at the end of the document\n";
                    449:             break;
                    450:         case XML_ERR_NOT_WELL_BALANCED:
                    451:             errmsg = "chunk is not well balanced\n";
                    452:             break;
                    453:         case XML_ERR_EXTRA_CONTENT:
                    454:             errmsg = "extra content at the end of well balanced chunk\n";
                    455:             break;
                    456:         case XML_ERR_VERSION_MISSING:
                    457:             errmsg = "Malformed declaration expecting version\n";
                    458:             break;
                    459: #if 0
                    460:         case:
                    461:             errmsg = "\n";
                    462:             break;
                    463: #endif
                    464:         default:
                    465:             errmsg = "Unregistered error message\n";
                    466:     }
                    467:     if (ctxt != NULL)
                    468:        ctxt->errNo = error;
                    469:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
                    470:                     XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, errmsg,
                    471:                     info);
                    472:     if (ctxt != NULL) {
                    473:        ctxt->wellFormed = 0;
                    474:        if (ctxt->recovery == 0)
                    475:            ctxt->disableSAX = 1;
                    476:     }
                    477: }
                    478: 
                    479: /**
                    480:  * xmlFatalErrMsg:
                    481:  * @ctxt:  an XML parser context
                    482:  * @error:  the error number
                    483:  * @msg:  the error message
                    484:  *
                    485:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    486:  */
                    487: static void
                    488: xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    489:                const char *msg)
                    490: {
                    491:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    492:         (ctxt->instate == XML_PARSER_EOF))
                    493:        return;
                    494:     if (ctxt != NULL)
                    495:        ctxt->errNo = error;
                    496:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
                    497:                     XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
                    498:     if (ctxt != NULL) {
                    499:        ctxt->wellFormed = 0;
                    500:        if (ctxt->recovery == 0)
                    501:            ctxt->disableSAX = 1;
                    502:     }
                    503: }
                    504: 
                    505: /**
                    506:  * xmlWarningMsg:
                    507:  * @ctxt:  an XML parser context
                    508:  * @error:  the error number
                    509:  * @msg:  the error message
                    510:  * @str1:  extra data
                    511:  * @str2:  extra data
                    512:  *
                    513:  * Handle a warning.
                    514:  */
                    515: static void
                    516: xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    517:               const char *msg, const xmlChar *str1, const xmlChar *str2)
                    518: {
                    519:     xmlStructuredErrorFunc schannel = NULL;
                    520: 
                    521:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    522:         (ctxt->instate == XML_PARSER_EOF))
                    523:        return;
                    524:     if ((ctxt != NULL) && (ctxt->sax != NULL) &&
                    525:         (ctxt->sax->initialized == XML_SAX2_MAGIC))
                    526:         schannel = ctxt->sax->serror;
                    527:     if (ctxt != NULL) {
                    528:         __xmlRaiseError(schannel,
                    529:                     (ctxt->sax) ? ctxt->sax->warning : NULL,
                    530:                     ctxt->userData,
                    531:                     ctxt, NULL, XML_FROM_PARSER, error,
                    532:                     XML_ERR_WARNING, NULL, 0,
                    533:                    (const char *) str1, (const char *) str2, NULL, 0, 0,
                    534:                    msg, (const char *) str1, (const char *) str2);
                    535:     } else {
                    536:         __xmlRaiseError(schannel, NULL, NULL,
                    537:                     ctxt, NULL, XML_FROM_PARSER, error,
                    538:                     XML_ERR_WARNING, NULL, 0,
                    539:                    (const char *) str1, (const char *) str2, NULL, 0, 0,
                    540:                    msg, (const char *) str1, (const char *) str2);
                    541:     }
                    542: }
                    543: 
                    544: /**
                    545:  * xmlValidityError:
                    546:  * @ctxt:  an XML parser context
                    547:  * @error:  the error number
                    548:  * @msg:  the error message
                    549:  * @str1:  extra data
                    550:  *
                    551:  * Handle a validity error.
                    552:  */
                    553: static void
                    554: xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    555:               const char *msg, const xmlChar *str1, const xmlChar *str2)
                    556: {
                    557:     xmlStructuredErrorFunc schannel = NULL;
                    558: 
                    559:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    560:         (ctxt->instate == XML_PARSER_EOF))
                    561:        return;
                    562:     if (ctxt != NULL) {
                    563:        ctxt->errNo = error;
                    564:        if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
                    565:            schannel = ctxt->sax->serror;
                    566:     }
                    567:     if (ctxt != NULL) {
                    568:         __xmlRaiseError(schannel,
                    569:                     ctxt->vctxt.error, ctxt->vctxt.userData,
                    570:                     ctxt, NULL, XML_FROM_DTD, error,
                    571:                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
                    572:                    (const char *) str2, NULL, 0, 0,
                    573:                    msg, (const char *) str1, (const char *) str2);
                    574:        ctxt->valid = 0;
                    575:     } else {
                    576:         __xmlRaiseError(schannel, NULL, NULL,
                    577:                     ctxt, NULL, XML_FROM_DTD, error,
                    578:                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
                    579:                    (const char *) str2, NULL, 0, 0,
                    580:                    msg, (const char *) str1, (const char *) str2);
                    581:     }
                    582: }
                    583: 
                    584: /**
                    585:  * xmlFatalErrMsgInt:
                    586:  * @ctxt:  an XML parser context
                    587:  * @error:  the error number
                    588:  * @msg:  the error message
                    589:  * @val:  an integer value
                    590:  *
                    591:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    592:  */
                    593: static void
                    594: xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    595:                   const char *msg, int val)
                    596: {
                    597:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    598:         (ctxt->instate == XML_PARSER_EOF))
                    599:        return;
                    600:     if (ctxt != NULL)
                    601:        ctxt->errNo = error;
                    602:     __xmlRaiseError(NULL, NULL, NULL,
                    603:                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                    604:                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
                    605:     if (ctxt != NULL) {
                    606:        ctxt->wellFormed = 0;
                    607:        if (ctxt->recovery == 0)
                    608:            ctxt->disableSAX = 1;
                    609:     }
                    610: }
                    611: 
                    612: /**
                    613:  * xmlFatalErrMsgStrIntStr:
                    614:  * @ctxt:  an XML parser context
                    615:  * @error:  the error number
                    616:  * @msg:  the error message
                    617:  * @str1:  an string info
                    618:  * @val:  an integer value
                    619:  * @str2:  an string info
                    620:  *
                    621:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    622:  */
                    623: static void
                    624: xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    625:                   const char *msg, const xmlChar *str1, int val, 
                    626:                  const xmlChar *str2)
                    627: {
                    628:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    629:         (ctxt->instate == XML_PARSER_EOF))
                    630:        return;
                    631:     if (ctxt != NULL)
                    632:        ctxt->errNo = error;
                    633:     __xmlRaiseError(NULL, NULL, NULL,
                    634:                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
                    635:                     NULL, 0, (const char *) str1, (const char *) str2,
                    636:                    NULL, val, 0, msg, str1, val, str2);
                    637:     if (ctxt != NULL) {
                    638:        ctxt->wellFormed = 0;
                    639:        if (ctxt->recovery == 0)
                    640:            ctxt->disableSAX = 1;
                    641:     }
                    642: }
                    643: 
                    644: /**
                    645:  * xmlFatalErrMsgStr:
                    646:  * @ctxt:  an XML parser context
                    647:  * @error:  the error number
                    648:  * @msg:  the error message
                    649:  * @val:  a string value
                    650:  *
                    651:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    652:  */
                    653: static void
                    654: xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    655:                   const char *msg, const xmlChar * val)
                    656: {
                    657:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    658:         (ctxt->instate == XML_PARSER_EOF))
                    659:        return;
                    660:     if (ctxt != NULL)
                    661:        ctxt->errNo = error;
                    662:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
                    663:                     XML_FROM_PARSER, error, XML_ERR_FATAL,
                    664:                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
                    665:                     val);
                    666:     if (ctxt != NULL) {
                    667:        ctxt->wellFormed = 0;
                    668:        if (ctxt->recovery == 0)
                    669:            ctxt->disableSAX = 1;
                    670:     }
                    671: }
                    672: 
                    673: /**
                    674:  * xmlErrMsgStr:
                    675:  * @ctxt:  an XML parser context
                    676:  * @error:  the error number
                    677:  * @msg:  the error message
                    678:  * @val:  a string value
                    679:  *
                    680:  * Handle a non fatal parser error
                    681:  */
                    682: static void
                    683: xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    684:                   const char *msg, const xmlChar * val)
                    685: {
                    686:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    687:         (ctxt->instate == XML_PARSER_EOF))
                    688:        return;
                    689:     if (ctxt != NULL)
                    690:        ctxt->errNo = error;
                    691:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
                    692:                     XML_FROM_PARSER, error, XML_ERR_ERROR,
                    693:                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
                    694:                     val);
                    695: }
                    696: 
                    697: /**
                    698:  * xmlNsErr:
                    699:  * @ctxt:  an XML parser context
                    700:  * @error:  the error number
                    701:  * @msg:  the message
                    702:  * @info1:  extra information string
                    703:  * @info2:  extra information string
                    704:  *
                    705:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    706:  */
                    707: static void
                    708: xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    709:          const char *msg,
                    710:          const xmlChar * info1, const xmlChar * info2,
                    711:          const xmlChar * info3)
                    712: {
                    713:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    714:         (ctxt->instate == XML_PARSER_EOF))
                    715:        return;
                    716:     if (ctxt != NULL)
                    717:        ctxt->errNo = error;
                    718:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
                    719:                     XML_ERR_ERROR, NULL, 0, (const char *) info1,
                    720:                     (const char *) info2, (const char *) info3, 0, 0, msg,
                    721:                     info1, info2, info3);
                    722:     if (ctxt != NULL)
                    723:        ctxt->nsWellFormed = 0;
                    724: }
                    725: 
                    726: /**
                    727:  * xmlNsWarn
                    728:  * @ctxt:  an XML parser context
                    729:  * @error:  the error number
                    730:  * @msg:  the message
                    731:  * @info1:  extra information string
                    732:  * @info2:  extra information string
                    733:  *
                    734:  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
                    735:  */
                    736: static void
                    737: xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                    738:          const char *msg,
                    739:          const xmlChar * info1, const xmlChar * info2,
                    740:          const xmlChar * info3)
                    741: {
                    742:     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
                    743:         (ctxt->instate == XML_PARSER_EOF))
                    744:        return;
                    745:     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
                    746:                     XML_ERR_WARNING, NULL, 0, (const char *) info1,
                    747:                     (const char *) info2, (const char *) info3, 0, 0, msg,
                    748:                     info1, info2, info3);
                    749: }
                    750: 
                    751: /************************************************************************
                    752:  *                                                                     *
                    753:  *             Library wide options                                    *
                    754:  *                                                                     *
                    755:  ************************************************************************/
                    756: 
                    757: /**
                    758:   * xmlHasFeature:
                    759:   * @feature: the feature to be examined
                    760:   *
                    761:   * Examines if the library has been compiled with a given feature.
                    762:   *
                    763:   * Returns a non-zero value if the feature exist, otherwise zero.
                    764:   * Returns zero (0) if the feature does not exist or an unknown
                    765:   * unknown feature is requested, non-zero otherwise.
                    766:   */
                    767: int
                    768: xmlHasFeature(xmlFeature feature)
                    769: {
                    770:     switch (feature) {
                    771:        case XML_WITH_THREAD:
                    772: #ifdef LIBXML_THREAD_ENABLED
                    773:            return(1);
                    774: #else
                    775:            return(0);
                    776: #endif
                    777:         case XML_WITH_TREE:
                    778: #ifdef LIBXML_TREE_ENABLED
                    779:             return(1);
                    780: #else
                    781:             return(0);
                    782: #endif
                    783:         case XML_WITH_OUTPUT:
                    784: #ifdef LIBXML_OUTPUT_ENABLED
                    785:             return(1);
                    786: #else
                    787:             return(0);
                    788: #endif
                    789:         case XML_WITH_PUSH:
                    790: #ifdef LIBXML_PUSH_ENABLED
                    791:             return(1);
                    792: #else
                    793:             return(0);
                    794: #endif
                    795:         case XML_WITH_READER:
                    796: #ifdef LIBXML_READER_ENABLED
                    797:             return(1);
                    798: #else
                    799:             return(0);
                    800: #endif
                    801:         case XML_WITH_PATTERN:
                    802: #ifdef LIBXML_PATTERN_ENABLED
                    803:             return(1);
                    804: #else
                    805:             return(0);
                    806: #endif
                    807:         case XML_WITH_WRITER:
                    808: #ifdef LIBXML_WRITER_ENABLED
                    809:             return(1);
                    810: #else
                    811:             return(0);
                    812: #endif
                    813:         case XML_WITH_SAX1:
                    814: #ifdef LIBXML_SAX1_ENABLED
                    815:             return(1);
                    816: #else
                    817:             return(0);
                    818: #endif
                    819:         case XML_WITH_FTP:
                    820: #ifdef LIBXML_FTP_ENABLED
                    821:             return(1);
                    822: #else
                    823:             return(0);
                    824: #endif
                    825:         case XML_WITH_HTTP:
                    826: #ifdef LIBXML_HTTP_ENABLED
                    827:             return(1);
                    828: #else
                    829:             return(0);
                    830: #endif
                    831:         case XML_WITH_VALID:
                    832: #ifdef LIBXML_VALID_ENABLED
                    833:             return(1);
                    834: #else
                    835:             return(0);
                    836: #endif
                    837:         case XML_WITH_HTML:
                    838: #ifdef LIBXML_HTML_ENABLED
                    839:             return(1);
                    840: #else
                    841:             return(0);
                    842: #endif
                    843:         case XML_WITH_LEGACY:
                    844: #ifdef LIBXML_LEGACY_ENABLED
                    845:             return(1);
                    846: #else
                    847:             return(0);
                    848: #endif
                    849:         case XML_WITH_C14N:
                    850: #ifdef LIBXML_C14N_ENABLED
                    851:             return(1);
                    852: #else
                    853:             return(0);
                    854: #endif
                    855:         case XML_WITH_CATALOG:
                    856: #ifdef LIBXML_CATALOG_ENABLED
                    857:             return(1);
                    858: #else
                    859:             return(0);
                    860: #endif
                    861:         case XML_WITH_XPATH:
                    862: #ifdef LIBXML_XPATH_ENABLED
                    863:             return(1);
                    864: #else
                    865:             return(0);
                    866: #endif
                    867:         case XML_WITH_XPTR:
                    868: #ifdef LIBXML_XPTR_ENABLED
                    869:             return(1);
                    870: #else
                    871:             return(0);
                    872: #endif
                    873:         case XML_WITH_XINCLUDE:
                    874: #ifdef LIBXML_XINCLUDE_ENABLED
                    875:             return(1);
                    876: #else
                    877:             return(0);
                    878: #endif
                    879:         case XML_WITH_ICONV:
                    880: #ifdef LIBXML_ICONV_ENABLED
                    881:             return(1);
                    882: #else
                    883:             return(0);
                    884: #endif
                    885:         case XML_WITH_ISO8859X:
                    886: #ifdef LIBXML_ISO8859X_ENABLED
                    887:             return(1);
                    888: #else
                    889:             return(0);
                    890: #endif
                    891:         case XML_WITH_UNICODE:
                    892: #ifdef LIBXML_UNICODE_ENABLED
                    893:             return(1);
                    894: #else
                    895:             return(0);
                    896: #endif
                    897:         case XML_WITH_REGEXP:
                    898: #ifdef LIBXML_REGEXP_ENABLED
                    899:             return(1);
                    900: #else
                    901:             return(0);
                    902: #endif
                    903:         case XML_WITH_AUTOMATA:
                    904: #ifdef LIBXML_AUTOMATA_ENABLED
                    905:             return(1);
                    906: #else
                    907:             return(0);
                    908: #endif
                    909:         case XML_WITH_EXPR:
                    910: #ifdef LIBXML_EXPR_ENABLED
                    911:             return(1);
                    912: #else
                    913:             return(0);
                    914: #endif
                    915:         case XML_WITH_SCHEMAS:
                    916: #ifdef LIBXML_SCHEMAS_ENABLED
                    917:             return(1);
                    918: #else
                    919:             return(0);
                    920: #endif
                    921:         case XML_WITH_SCHEMATRON:
                    922: #ifdef LIBXML_SCHEMATRON_ENABLED
                    923:             return(1);
                    924: #else
                    925:             return(0);
                    926: #endif
                    927:         case XML_WITH_MODULES:
                    928: #ifdef LIBXML_MODULES_ENABLED
                    929:             return(1);
                    930: #else
                    931:             return(0);
                    932: #endif
                    933:         case XML_WITH_DEBUG:
                    934: #ifdef LIBXML_DEBUG_ENABLED
                    935:             return(1);
                    936: #else
                    937:             return(0);
                    938: #endif
                    939:         case XML_WITH_DEBUG_MEM:
                    940: #ifdef DEBUG_MEMORY_LOCATION
                    941:             return(1);
                    942: #else
                    943:             return(0);
                    944: #endif
                    945:         case XML_WITH_DEBUG_RUN:
                    946: #ifdef LIBXML_DEBUG_RUNTIME
                    947:             return(1);
                    948: #else
                    949:             return(0);
                    950: #endif
                    951:         case XML_WITH_ZLIB:
                    952: #ifdef LIBXML_ZLIB_ENABLED
                    953:             return(1);
                    954: #else
                    955:             return(0);
                    956: #endif
                    957:         case XML_WITH_ICU:
                    958: #ifdef LIBXML_ICU_ENABLED
                    959:             return(1);
                    960: #else
                    961:             return(0);
                    962: #endif
                    963:         default:
                    964:            break;
                    965:      }
                    966:      return(0);
                    967: }
                    968: 
                    969: /************************************************************************
                    970:  *                                                                     *
                    971:  *             SAX2 defaulted attributes handling                      *
                    972:  *                                                                     *
                    973:  ************************************************************************/
                    974: 
                    975: /**
                    976:  * xmlDetectSAX2:
                    977:  * @ctxt:  an XML parser context
                    978:  *
                    979:  * Do the SAX2 detection and specific intialization
                    980:  */
                    981: static void
                    982: xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
                    983:     if (ctxt == NULL) return;
                    984: #ifdef LIBXML_SAX1_ENABLED
                    985:     if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
                    986:         ((ctxt->sax->startElementNs != NULL) ||
                    987:          (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
                    988: #else
                    989:     ctxt->sax2 = 1;
                    990: #endif /* LIBXML_SAX1_ENABLED */
                    991: 
                    992:     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
                    993:     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
                    994:     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
                    995:     if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) || 
                    996:                (ctxt->str_xml_ns == NULL)) {
                    997:         xmlErrMemory(ctxt, NULL);
                    998:     }
                    999: }
                   1000: 
                   1001: typedef struct _xmlDefAttrs xmlDefAttrs;
                   1002: typedef xmlDefAttrs *xmlDefAttrsPtr;
                   1003: struct _xmlDefAttrs {
                   1004:     int nbAttrs;       /* number of defaulted attributes on that element */
                   1005:     int maxAttrs;       /* the size of the array */
                   1006:     const xmlChar *values[5]; /* array of localname/prefix/values/external */
                   1007: };
                   1008: 
                   1009: /**
                   1010:  * xmlAttrNormalizeSpace:
                   1011:  * @src: the source string
                   1012:  * @dst: the target string
                   1013:  *
                   1014:  * Normalize the space in non CDATA attribute values:
                   1015:  * If the attribute type is not CDATA, then the XML processor MUST further
                   1016:  * process the normalized attribute value by discarding any leading and
                   1017:  * trailing space (#x20) characters, and by replacing sequences of space
                   1018:  * (#x20) characters by a single space (#x20) character.
                   1019:  * Note that the size of dst need to be at least src, and if one doesn't need
                   1020:  * to preserve dst (and it doesn't come from a dictionary or read-only) then
                   1021:  * passing src as dst is just fine.
                   1022:  *
                   1023:  * Returns a pointer to the normalized value (dst) or NULL if no conversion
                   1024:  *         is needed.
                   1025:  */
                   1026: static xmlChar *
                   1027: xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
                   1028: {
                   1029:     if ((src == NULL) || (dst == NULL))
                   1030:         return(NULL);
                   1031: 
                   1032:     while (*src == 0x20) src++;
                   1033:     while (*src != 0) {
                   1034:        if (*src == 0x20) {
                   1035:            while (*src == 0x20) src++;
                   1036:            if (*src != 0)
                   1037:                *dst++ = 0x20;
                   1038:        } else {
                   1039:            *dst++ = *src++;
                   1040:        }
                   1041:     }
                   1042:     *dst = 0;
                   1043:     if (dst == src)
                   1044:        return(NULL);
                   1045:     return(dst);
                   1046: }
                   1047: 
                   1048: /**
                   1049:  * xmlAttrNormalizeSpace2:
                   1050:  * @src: the source string
                   1051:  *
                   1052:  * Normalize the space in non CDATA attribute values, a slightly more complex
                   1053:  * front end to avoid allocation problems when running on attribute values
                   1054:  * coming from the input.
                   1055:  *
                   1056:  * Returns a pointer to the normalized value (dst) or NULL if no conversion
                   1057:  *         is needed.
                   1058:  */
                   1059: static const xmlChar *
                   1060: xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
                   1061: {
                   1062:     int i;
                   1063:     int remove_head = 0;
                   1064:     int need_realloc = 0;
                   1065:     const xmlChar *cur;
                   1066: 
                   1067:     if ((ctxt == NULL) || (src == NULL) || (len == NULL))
                   1068:         return(NULL);
                   1069:     i = *len;
                   1070:     if (i <= 0)
                   1071:         return(NULL);
                   1072: 
                   1073:     cur = src;
                   1074:     while (*cur == 0x20) {
                   1075:         cur++;
                   1076:        remove_head++;
                   1077:     }
                   1078:     while (*cur != 0) {
                   1079:        if (*cur == 0x20) {
                   1080:            cur++;
                   1081:            if ((*cur == 0x20) || (*cur == 0)) {
                   1082:                need_realloc = 1;
                   1083:                break;
                   1084:            }
                   1085:        } else
                   1086:            cur++;
                   1087:     }
                   1088:     if (need_realloc) {
                   1089:         xmlChar *ret;
                   1090: 
                   1091:        ret = xmlStrndup(src + remove_head, i - remove_head + 1);
                   1092:        if (ret == NULL) {
                   1093:            xmlErrMemory(ctxt, NULL);
                   1094:            return(NULL);
                   1095:        }
                   1096:        xmlAttrNormalizeSpace(ret, ret);
                   1097:        *len = (int) strlen((const char *)ret);
                   1098:         return(ret);
                   1099:     } else if (remove_head) {
                   1100:         *len -= remove_head;
                   1101:         memmove(src, src + remove_head, 1 + *len);
                   1102:        return(src);
                   1103:     }
                   1104:     return(NULL);
                   1105: }
                   1106: 
                   1107: /**
                   1108:  * xmlAddDefAttrs:
                   1109:  * @ctxt:  an XML parser context
                   1110:  * @fullname:  the element fullname
                   1111:  * @fullattr:  the attribute fullname
                   1112:  * @value:  the attribute value
                   1113:  *
                   1114:  * Add a defaulted attribute for an element
                   1115:  */
                   1116: static void
                   1117: xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
                   1118:                const xmlChar *fullname,
                   1119:                const xmlChar *fullattr,
                   1120:                const xmlChar *value) {
                   1121:     xmlDefAttrsPtr defaults;
                   1122:     int len;
                   1123:     const xmlChar *name;
                   1124:     const xmlChar *prefix;
                   1125: 
                   1126:     /*
                   1127:      * Allows to detect attribute redefinitions
                   1128:      */
                   1129:     if (ctxt->attsSpecial != NULL) {
                   1130:         if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
                   1131:            return;
                   1132:     }
                   1133: 
                   1134:     if (ctxt->attsDefault == NULL) {
                   1135:         ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
                   1136:        if (ctxt->attsDefault == NULL)
                   1137:            goto mem_error;
                   1138:     }
                   1139: 
                   1140:     /*
                   1141:      * split the element name into prefix:localname , the string found
                   1142:      * are within the DTD and then not associated to namespace names.
                   1143:      */
                   1144:     name = xmlSplitQName3(fullname, &len);
                   1145:     if (name == NULL) {
                   1146:         name = xmlDictLookup(ctxt->dict, fullname, -1);
                   1147:        prefix = NULL;
                   1148:     } else {
                   1149:         name = xmlDictLookup(ctxt->dict, name, -1);
                   1150:        prefix = xmlDictLookup(ctxt->dict, fullname, len);
                   1151:     }
                   1152: 
                   1153:     /*
                   1154:      * make sure there is some storage
                   1155:      */
                   1156:     defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
                   1157:     if (defaults == NULL) {
                   1158:         defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
                   1159:                           (4 * 5) * sizeof(const xmlChar *));
                   1160:        if (defaults == NULL)
                   1161:            goto mem_error;
                   1162:        defaults->nbAttrs = 0;
                   1163:        defaults->maxAttrs = 4;
                   1164:        if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
                   1165:                                defaults, NULL) < 0) {
                   1166:            xmlFree(defaults);
                   1167:            goto mem_error;
                   1168:        }
                   1169:     } else if (defaults->nbAttrs >= defaults->maxAttrs) {
                   1170:         xmlDefAttrsPtr temp;
                   1171: 
                   1172:         temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
                   1173:                       (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
                   1174:        if (temp == NULL)
                   1175:            goto mem_error;
                   1176:        defaults = temp;
                   1177:        defaults->maxAttrs *= 2;
                   1178:        if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
                   1179:                                defaults, NULL) < 0) {
                   1180:            xmlFree(defaults);
                   1181:            goto mem_error;
                   1182:        }
                   1183:     }
                   1184: 
                   1185:     /*
                   1186:      * Split the element name into prefix:localname , the string found
                   1187:      * are within the DTD and hen not associated to namespace names.
                   1188:      */
                   1189:     name = xmlSplitQName3(fullattr, &len);
                   1190:     if (name == NULL) {
                   1191:         name = xmlDictLookup(ctxt->dict, fullattr, -1);
                   1192:        prefix = NULL;
                   1193:     } else {
                   1194:         name = xmlDictLookup(ctxt->dict, name, -1);
                   1195:        prefix = xmlDictLookup(ctxt->dict, fullattr, len);
                   1196:     }
                   1197: 
                   1198:     defaults->values[5 * defaults->nbAttrs] = name;
                   1199:     defaults->values[5 * defaults->nbAttrs + 1] = prefix;
                   1200:     /* intern the string and precompute the end */
                   1201:     len = xmlStrlen(value);
                   1202:     value = xmlDictLookup(ctxt->dict, value, len);
                   1203:     defaults->values[5 * defaults->nbAttrs + 2] = value;
                   1204:     defaults->values[5 * defaults->nbAttrs + 3] = value + len;
                   1205:     if (ctxt->external)
                   1206:         defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
                   1207:     else
                   1208:         defaults->values[5 * defaults->nbAttrs + 4] = NULL;
                   1209:     defaults->nbAttrs++;
                   1210: 
                   1211:     return;
                   1212: 
                   1213: mem_error:
                   1214:     xmlErrMemory(ctxt, NULL);
                   1215:     return;
                   1216: }
                   1217: 
                   1218: /**
                   1219:  * xmlAddSpecialAttr:
                   1220:  * @ctxt:  an XML parser context
                   1221:  * @fullname:  the element fullname
                   1222:  * @fullattr:  the attribute fullname
                   1223:  * @type:  the attribute type
                   1224:  *
                   1225:  * Register this attribute type
                   1226:  */
                   1227: static void
                   1228: xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
                   1229:                  const xmlChar *fullname,
                   1230:                  const xmlChar *fullattr,
                   1231:                  int type)
                   1232: {
                   1233:     if (ctxt->attsSpecial == NULL) {
                   1234:         ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
                   1235:        if (ctxt->attsSpecial == NULL)
                   1236:            goto mem_error;
                   1237:     }
                   1238: 
                   1239:     if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
                   1240:         return;
                   1241: 
                   1242:     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
                   1243:                      (void *) (long) type);
                   1244:     return;
                   1245: 
                   1246: mem_error:
                   1247:     xmlErrMemory(ctxt, NULL);
                   1248:     return;
                   1249: }
                   1250: 
                   1251: /**
                   1252:  * xmlCleanSpecialAttrCallback:
                   1253:  *
                   1254:  * Removes CDATA attributes from the special attribute table
                   1255:  */
                   1256: static void
                   1257: xmlCleanSpecialAttrCallback(void *payload, void *data,
                   1258:                             const xmlChar *fullname, const xmlChar *fullattr,
                   1259:                             const xmlChar *unused ATTRIBUTE_UNUSED) {
                   1260:     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
                   1261: 
                   1262:     if (((long) payload) == XML_ATTRIBUTE_CDATA) {
                   1263:         xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
                   1264:     }
                   1265: }
                   1266: 
                   1267: /**
                   1268:  * xmlCleanSpecialAttr:
                   1269:  * @ctxt:  an XML parser context
                   1270:  *
                   1271:  * Trim the list of attributes defined to remove all those of type
                   1272:  * CDATA as they are not special. This call should be done when finishing
                   1273:  * to parse the DTD and before starting to parse the document root.
                   1274:  */
                   1275: static void
                   1276: xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
                   1277: {
                   1278:     if (ctxt->attsSpecial == NULL)
                   1279:         return;
                   1280: 
                   1281:     xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
                   1282: 
                   1283:     if (xmlHashSize(ctxt->attsSpecial) == 0) {
                   1284:         xmlHashFree(ctxt->attsSpecial, NULL);
                   1285:         ctxt->attsSpecial = NULL;
                   1286:     }
                   1287:     return;
                   1288: }
                   1289: 
                   1290: /**
                   1291:  * xmlCheckLanguageID:
                   1292:  * @lang:  pointer to the string value
                   1293:  *
                   1294:  * Checks that the value conforms to the LanguageID production:
                   1295:  *
                   1296:  * NOTE: this is somewhat deprecated, those productions were removed from
                   1297:  *       the XML Second edition.
                   1298:  *
                   1299:  * [33] LanguageID ::= Langcode ('-' Subcode)*
                   1300:  * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
                   1301:  * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
                   1302:  * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
                   1303:  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
                   1304:  * [38] Subcode ::= ([a-z] | [A-Z])+
                   1305:  *
                   1306:  * The current REC reference the sucessors of RFC 1766, currently 5646
                   1307:  *
                   1308:  * http://www.rfc-editor.org/rfc/rfc5646.txt
                   1309:  * langtag       = language
                   1310:  *                 ["-" script]
                   1311:  *                 ["-" region]
                   1312:  *                 *("-" variant)
                   1313:  *                 *("-" extension)
                   1314:  *                 ["-" privateuse]
                   1315:  * language      = 2*3ALPHA            ; shortest ISO 639 code
                   1316:  *                 ["-" extlang]       ; sometimes followed by
                   1317:  *                                     ; extended language subtags
                   1318:  *               / 4ALPHA              ; or reserved for future use
                   1319:  *               / 5*8ALPHA            ; or registered language subtag
                   1320:  *
                   1321:  * extlang       = 3ALPHA              ; selected ISO 639 codes
                   1322:  *                 *2("-" 3ALPHA)      ; permanently reserved
                   1323:  *
                   1324:  * script        = 4ALPHA              ; ISO 15924 code
                   1325:  *
                   1326:  * region        = 2ALPHA              ; ISO 3166-1 code
                   1327:  *               / 3DIGIT              ; UN M.49 code
                   1328:  *
                   1329:  * variant       = 5*8alphanum         ; registered variants
                   1330:  *               / (DIGIT 3alphanum)
                   1331:  *
                   1332:  * extension     = singleton 1*("-" (2*8alphanum))
                   1333:  *
                   1334:  *                                     ; Single alphanumerics
                   1335:  *                                     ; "x" reserved for private use
                   1336:  * singleton     = DIGIT               ; 0 - 9
                   1337:  *               / %x41-57             ; A - W
                   1338:  *               / %x59-5A             ; Y - Z
                   1339:  *               / %x61-77             ; a - w
                   1340:  *               / %x79-7A             ; y - z
                   1341:  *
                   1342:  * it sounds right to still allow Irregular i-xxx IANA and user codes too
                   1343:  * The parser below doesn't try to cope with extension or privateuse
                   1344:  * that could be added but that's not interoperable anyway
                   1345:  *
                   1346:  * Returns 1 if correct 0 otherwise
                   1347:  **/
                   1348: int
                   1349: xmlCheckLanguageID(const xmlChar * lang)
                   1350: {
                   1351:     const xmlChar *cur = lang, *nxt;
                   1352: 
                   1353:     if (cur == NULL)
                   1354:         return (0);
                   1355:     if (((cur[0] == 'i') && (cur[1] == '-')) ||
                   1356:         ((cur[0] == 'I') && (cur[1] == '-')) ||
                   1357:         ((cur[0] == 'x') && (cur[1] == '-')) ||
                   1358:         ((cur[0] == 'X') && (cur[1] == '-'))) {
                   1359:         /*
                   1360:          * Still allow IANA code and user code which were coming
                   1361:          * from the previous version of the XML-1.0 specification
                   1362:          * it's deprecated but we should not fail
                   1363:          */
                   1364:         cur += 2;
                   1365:         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
                   1366:                ((cur[0] >= 'a') && (cur[0] <= 'z')))
                   1367:             cur++;
                   1368:         return(cur[0] == 0);
                   1369:     }
                   1370:     nxt = cur;
                   1371:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
                   1372:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
                   1373:            nxt++;
                   1374:     if (nxt - cur >= 4) {
                   1375:         /*
                   1376:          * Reserved
                   1377:          */
                   1378:         if ((nxt - cur > 8) || (nxt[0] != 0))
                   1379:             return(0);
                   1380:         return(1);
                   1381:     }
                   1382:     if (nxt - cur < 2)
                   1383:         return(0);
                   1384:     /* we got an ISO 639 code */
                   1385:     if (nxt[0] == 0)
                   1386:         return(1);
                   1387:     if (nxt[0] != '-')
                   1388:         return(0);
                   1389: 
                   1390:     nxt++;
                   1391:     cur = nxt;
                   1392:     /* now we can have extlang or script or region or variant */
                   1393:     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
                   1394:         goto region_m49;
                   1395: 
                   1396:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
                   1397:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
                   1398:            nxt++;
                   1399:     if (nxt - cur == 4)
                   1400:         goto script;
                   1401:     if (nxt - cur == 2)
                   1402:         goto region;
                   1403:     if ((nxt - cur >= 5) && (nxt - cur <= 8))
                   1404:         goto variant;
                   1405:     if (nxt - cur != 3)
                   1406:         return(0);
                   1407:     /* we parsed an extlang */
                   1408:     if (nxt[0] == 0)
                   1409:         return(1);
                   1410:     if (nxt[0] != '-')
                   1411:         return(0);
                   1412: 
                   1413:     nxt++;
                   1414:     cur = nxt;
                   1415:     /* now we can have script or region or variant */
                   1416:     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
                   1417:         goto region_m49;
                   1418: 
                   1419:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
                   1420:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
                   1421:            nxt++;
                   1422:     if (nxt - cur == 2)
                   1423:         goto region;
                   1424:     if ((nxt - cur >= 5) && (nxt - cur <= 8))
                   1425:         goto variant;
                   1426:     if (nxt - cur != 4)
                   1427:         return(0);
                   1428:     /* we parsed a script */
                   1429: script:
                   1430:     if (nxt[0] == 0)
                   1431:         return(1);
                   1432:     if (nxt[0] != '-')
                   1433:         return(0);
                   1434: 
                   1435:     nxt++;
                   1436:     cur = nxt;
                   1437:     /* now we can have region or variant */
                   1438:     if ((nxt[0] >= '0') && (nxt[0] <= '9'))
                   1439:         goto region_m49;
                   1440: 
                   1441:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
                   1442:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
                   1443:            nxt++;
                   1444: 
                   1445:     if ((nxt - cur >= 5) && (nxt - cur <= 8))
                   1446:         goto variant;
                   1447:     if (nxt - cur != 2)
                   1448:         return(0);
                   1449:     /* we parsed a region */
                   1450: region:
                   1451:     if (nxt[0] == 0)
                   1452:         return(1);
                   1453:     if (nxt[0] != '-')
                   1454:         return(0);
                   1455: 
                   1456:     nxt++;
                   1457:     cur = nxt;
                   1458:     /* now we can just have a variant */
                   1459:     while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
                   1460:            ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
                   1461:            nxt++;
                   1462: 
                   1463:     if ((nxt - cur < 5) || (nxt - cur > 8))
                   1464:         return(0);
                   1465: 
                   1466:     /* we parsed a variant */
                   1467: variant:
                   1468:     if (nxt[0] == 0)
                   1469:         return(1);
                   1470:     if (nxt[0] != '-')
                   1471:         return(0);
                   1472:     /* extensions and private use subtags not checked */
                   1473:     return (1);
                   1474: 
                   1475: region_m49:
                   1476:     if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
                   1477:         ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
                   1478:         nxt += 3;
                   1479:         goto region;
                   1480:     }
                   1481:     return(0);
                   1482: }
                   1483: 
                   1484: /************************************************************************
                   1485:  *                                                                     *
                   1486:  *             Parser stacks related functions and macros              *
                   1487:  *                                                                     *
                   1488:  ************************************************************************/
                   1489: 
                   1490: static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
                   1491:                                             const xmlChar ** str);
                   1492: 
                   1493: #ifdef SAX2
                   1494: /**
                   1495:  * nsPush:
                   1496:  * @ctxt:  an XML parser context
                   1497:  * @prefix:  the namespace prefix or NULL
                   1498:  * @URL:  the namespace name
                   1499:  *
                   1500:  * Pushes a new parser namespace on top of the ns stack
                   1501:  *
                   1502:  * Returns -1 in case of error, -2 if the namespace should be discarded
                   1503:  *        and the index in the stack otherwise.
                   1504:  */
                   1505: static int
                   1506: nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
                   1507: {
                   1508:     if (ctxt->options & XML_PARSE_NSCLEAN) {
                   1509:         int i;
                   1510:        for (i = 0;i < ctxt->nsNr;i += 2) {
                   1511:            if (ctxt->nsTab[i] == prefix) {
                   1512:                /* in scope */
                   1513:                if (ctxt->nsTab[i + 1] == URL)
                   1514:                    return(-2);
                   1515:                /* out of scope keep it */
                   1516:                break;
                   1517:            }
                   1518:        }
                   1519:     }
                   1520:     if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
                   1521:        ctxt->nsMax = 10;
                   1522:        ctxt->nsNr = 0;
                   1523:        ctxt->nsTab = (const xmlChar **)
                   1524:                      xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
                   1525:        if (ctxt->nsTab == NULL) {
                   1526:            xmlErrMemory(ctxt, NULL);
                   1527:            ctxt->nsMax = 0;
                   1528:             return (-1);
                   1529:        }
                   1530:     } else if (ctxt->nsNr >= ctxt->nsMax) {
                   1531:         const xmlChar ** tmp;
                   1532:         ctxt->nsMax *= 2;
                   1533:         tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
                   1534:                                    ctxt->nsMax * sizeof(ctxt->nsTab[0]));
                   1535:         if (tmp == NULL) {
                   1536:             xmlErrMemory(ctxt, NULL);
                   1537:            ctxt->nsMax /= 2;
                   1538:             return (-1);
                   1539:         }
                   1540:        ctxt->nsTab = tmp;
                   1541:     }
                   1542:     ctxt->nsTab[ctxt->nsNr++] = prefix;
                   1543:     ctxt->nsTab[ctxt->nsNr++] = URL;
                   1544:     return (ctxt->nsNr);
                   1545: }
                   1546: /**
                   1547:  * nsPop:
                   1548:  * @ctxt: an XML parser context
                   1549:  * @nr:  the number to pop
                   1550:  *
                   1551:  * Pops the top @nr parser prefix/namespace from the ns stack
                   1552:  *
                   1553:  * Returns the number of namespaces removed
                   1554:  */
                   1555: static int
                   1556: nsPop(xmlParserCtxtPtr ctxt, int nr)
                   1557: {
                   1558:     int i;
                   1559: 
                   1560:     if (ctxt->nsTab == NULL) return(0);
                   1561:     if (ctxt->nsNr < nr) {
                   1562:         xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
                   1563:         nr = ctxt->nsNr;
                   1564:     }
                   1565:     if (ctxt->nsNr <= 0)
                   1566:         return (0);
                   1567: 
                   1568:     for (i = 0;i < nr;i++) {
                   1569:          ctxt->nsNr--;
                   1570:         ctxt->nsTab[ctxt->nsNr] = NULL;
                   1571:     }
                   1572:     return(nr);
                   1573: }
                   1574: #endif
                   1575: 
                   1576: static int
                   1577: xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
                   1578:     const xmlChar **atts;
                   1579:     int *attallocs;
                   1580:     int maxatts;
                   1581: 
                   1582:     if (ctxt->atts == NULL) {
                   1583:        maxatts = 55; /* allow for 10 attrs by default */
                   1584:        atts = (const xmlChar **)
                   1585:               xmlMalloc(maxatts * sizeof(xmlChar *));
                   1586:        if (atts == NULL) goto mem_error;
                   1587:        ctxt->atts = atts;
                   1588:        attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
                   1589:        if (attallocs == NULL) goto mem_error;
                   1590:        ctxt->attallocs = attallocs;
                   1591:        ctxt->maxatts = maxatts;
                   1592:     } else if (nr + 5 > ctxt->maxatts) {
                   1593:        maxatts = (nr + 5) * 2;
                   1594:        atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
                   1595:                                     maxatts * sizeof(const xmlChar *));
                   1596:        if (atts == NULL) goto mem_error;
                   1597:        ctxt->atts = atts;
                   1598:        attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
                   1599:                                     (maxatts / 5) * sizeof(int));
                   1600:        if (attallocs == NULL) goto mem_error;
                   1601:        ctxt->attallocs = attallocs;
                   1602:        ctxt->maxatts = maxatts;
                   1603:     }
                   1604:     return(ctxt->maxatts);
                   1605: mem_error:
                   1606:     xmlErrMemory(ctxt, NULL);
                   1607:     return(-1);
                   1608: }
                   1609: 
                   1610: /**
                   1611:  * inputPush:
                   1612:  * @ctxt:  an XML parser context
                   1613:  * @value:  the parser input
                   1614:  *
                   1615:  * Pushes a new parser input on top of the input stack
                   1616:  *
                   1617:  * Returns -1 in case of error, the index in the stack otherwise
                   1618:  */
                   1619: int
                   1620: inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
                   1621: {
                   1622:     if ((ctxt == NULL) || (value == NULL))
                   1623:         return(-1);
                   1624:     if (ctxt->inputNr >= ctxt->inputMax) {
                   1625:         ctxt->inputMax *= 2;
                   1626:         ctxt->inputTab =
                   1627:             (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
                   1628:                                              ctxt->inputMax *
                   1629:                                              sizeof(ctxt->inputTab[0]));
                   1630:         if (ctxt->inputTab == NULL) {
                   1631:             xmlErrMemory(ctxt, NULL);
                   1632:            xmlFreeInputStream(value);
                   1633:            ctxt->inputMax /= 2;
                   1634:            value = NULL;
                   1635:             return (-1);
                   1636:         }
                   1637:     }
                   1638:     ctxt->inputTab[ctxt->inputNr] = value;
                   1639:     ctxt->input = value;
                   1640:     return (ctxt->inputNr++);
                   1641: }
                   1642: /**
                   1643:  * inputPop:
                   1644:  * @ctxt: an XML parser context
                   1645:  *
                   1646:  * Pops the top parser input from the input stack
                   1647:  *
                   1648:  * Returns the input just removed
                   1649:  */
                   1650: xmlParserInputPtr
                   1651: inputPop(xmlParserCtxtPtr ctxt)
                   1652: {
                   1653:     xmlParserInputPtr ret;
                   1654: 
                   1655:     if (ctxt == NULL)
                   1656:         return(NULL);
                   1657:     if (ctxt->inputNr <= 0)
                   1658:         return (NULL);
                   1659:     ctxt->inputNr--;
                   1660:     if (ctxt->inputNr > 0)
                   1661:         ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
                   1662:     else
                   1663:         ctxt->input = NULL;
                   1664:     ret = ctxt->inputTab[ctxt->inputNr];
                   1665:     ctxt->inputTab[ctxt->inputNr] = NULL;
                   1666:     return (ret);
                   1667: }
                   1668: /**
                   1669:  * nodePush:
                   1670:  * @ctxt:  an XML parser context
                   1671:  * @value:  the element node
                   1672:  *
                   1673:  * Pushes a new element node on top of the node stack
                   1674:  *
                   1675:  * Returns -1 in case of error, the index in the stack otherwise
                   1676:  */
                   1677: int
                   1678: nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
                   1679: {
                   1680:     if (ctxt == NULL) return(0);
                   1681:     if (ctxt->nodeNr >= ctxt->nodeMax) {
                   1682:         xmlNodePtr *tmp;
                   1683: 
                   1684:        tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
                   1685:                                       ctxt->nodeMax * 2 *
                   1686:                                       sizeof(ctxt->nodeTab[0]));
                   1687:         if (tmp == NULL) {
                   1688:             xmlErrMemory(ctxt, NULL);
                   1689:             return (-1);
                   1690:         }
                   1691:         ctxt->nodeTab = tmp;
                   1692:        ctxt->nodeMax *= 2;
                   1693:     }
                   1694:     if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
                   1695:         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                   1696:        xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
                   1697:                 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
                   1698:                          xmlParserMaxDepth);
                   1699:        ctxt->instate = XML_PARSER_EOF;
                   1700:        return(-1);
                   1701:     }
                   1702:     ctxt->nodeTab[ctxt->nodeNr] = value;
                   1703:     ctxt->node = value;
                   1704:     return (ctxt->nodeNr++);
                   1705: }
                   1706: 
                   1707: /**
                   1708:  * nodePop:
                   1709:  * @ctxt: an XML parser context
                   1710:  *
                   1711:  * Pops the top element node from the node stack
                   1712:  *
                   1713:  * Returns the node just removed
                   1714:  */
                   1715: xmlNodePtr
                   1716: nodePop(xmlParserCtxtPtr ctxt)
                   1717: {
                   1718:     xmlNodePtr ret;
                   1719: 
                   1720:     if (ctxt == NULL) return(NULL);
                   1721:     if (ctxt->nodeNr <= 0)
                   1722:         return (NULL);
                   1723:     ctxt->nodeNr--;
                   1724:     if (ctxt->nodeNr > 0)
                   1725:         ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
                   1726:     else
                   1727:         ctxt->node = NULL;
                   1728:     ret = ctxt->nodeTab[ctxt->nodeNr];
                   1729:     ctxt->nodeTab[ctxt->nodeNr] = NULL;
                   1730:     return (ret);
                   1731: }
                   1732: 
                   1733: #ifdef LIBXML_PUSH_ENABLED
                   1734: /**
                   1735:  * nameNsPush:
                   1736:  * @ctxt:  an XML parser context
                   1737:  * @value:  the element name
                   1738:  * @prefix:  the element prefix
                   1739:  * @URI:  the element namespace name
                   1740:  *
                   1741:  * Pushes a new element name/prefix/URL on top of the name stack
                   1742:  *
                   1743:  * Returns -1 in case of error, the index in the stack otherwise
                   1744:  */
                   1745: static int
                   1746: nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
                   1747:            const xmlChar *prefix, const xmlChar *URI, int nsNr)
                   1748: {
                   1749:     if (ctxt->nameNr >= ctxt->nameMax) {
                   1750:         const xmlChar * *tmp;
                   1751:         void **tmp2;
                   1752:         ctxt->nameMax *= 2;
                   1753:         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
                   1754:                                     ctxt->nameMax *
                   1755:                                     sizeof(ctxt->nameTab[0]));
                   1756:         if (tmp == NULL) {
                   1757:            ctxt->nameMax /= 2;
                   1758:            goto mem_error;
                   1759:         }
                   1760:        ctxt->nameTab = tmp;
                   1761:         tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
                   1762:                                     ctxt->nameMax * 3 *
                   1763:                                     sizeof(ctxt->pushTab[0]));
                   1764:         if (tmp2 == NULL) {
                   1765:            ctxt->nameMax /= 2;
                   1766:            goto mem_error;
                   1767:         }
                   1768:        ctxt->pushTab = tmp2;
                   1769:     }
                   1770:     ctxt->nameTab[ctxt->nameNr] = value;
                   1771:     ctxt->name = value;
                   1772:     ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
                   1773:     ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
                   1774:     ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
                   1775:     return (ctxt->nameNr++);
                   1776: mem_error:
                   1777:     xmlErrMemory(ctxt, NULL);
                   1778:     return (-1);
                   1779: }
                   1780: /**
                   1781:  * nameNsPop:
                   1782:  * @ctxt: an XML parser context
                   1783:  *
                   1784:  * Pops the top element/prefix/URI name from the name stack
                   1785:  *
                   1786:  * Returns the name just removed
                   1787:  */
                   1788: static const xmlChar *
                   1789: nameNsPop(xmlParserCtxtPtr ctxt)
                   1790: {
                   1791:     const xmlChar *ret;
                   1792: 
                   1793:     if (ctxt->nameNr <= 0)
                   1794:         return (NULL);
                   1795:     ctxt->nameNr--;
                   1796:     if (ctxt->nameNr > 0)
                   1797:         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
                   1798:     else
                   1799:         ctxt->name = NULL;
                   1800:     ret = ctxt->nameTab[ctxt->nameNr];
                   1801:     ctxt->nameTab[ctxt->nameNr] = NULL;
                   1802:     return (ret);
                   1803: }
                   1804: #endif /* LIBXML_PUSH_ENABLED */
                   1805: 
                   1806: /**
                   1807:  * namePush:
                   1808:  * @ctxt:  an XML parser context
                   1809:  * @value:  the element name
                   1810:  *
                   1811:  * Pushes a new element name on top of the name stack
                   1812:  *
                   1813:  * Returns -1 in case of error, the index in the stack otherwise
                   1814:  */
                   1815: int
                   1816: namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
                   1817: {
                   1818:     if (ctxt == NULL) return (-1);
                   1819: 
                   1820:     if (ctxt->nameNr >= ctxt->nameMax) {
                   1821:         const xmlChar * *tmp;
                   1822:         ctxt->nameMax *= 2;
                   1823:         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
                   1824:                                     ctxt->nameMax *
                   1825:                                     sizeof(ctxt->nameTab[0]));
                   1826:         if (tmp == NULL) {
                   1827:            ctxt->nameMax /= 2;
                   1828:            goto mem_error;
                   1829:         }
                   1830:        ctxt->nameTab = tmp;
                   1831:     }
                   1832:     ctxt->nameTab[ctxt->nameNr] = value;
                   1833:     ctxt->name = value;
                   1834:     return (ctxt->nameNr++);
                   1835: mem_error:
                   1836:     xmlErrMemory(ctxt, NULL);
                   1837:     return (-1);
                   1838: }
                   1839: /**
                   1840:  * namePop:
                   1841:  * @ctxt: an XML parser context
                   1842:  *
                   1843:  * Pops the top element name from the name stack
                   1844:  *
                   1845:  * Returns the name just removed
                   1846:  */
                   1847: const xmlChar *
                   1848: namePop(xmlParserCtxtPtr ctxt)
                   1849: {
                   1850:     const xmlChar *ret;
                   1851: 
                   1852:     if ((ctxt == NULL) || (ctxt->nameNr <= 0))
                   1853:         return (NULL);
                   1854:     ctxt->nameNr--;
                   1855:     if (ctxt->nameNr > 0)
                   1856:         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
                   1857:     else
                   1858:         ctxt->name = NULL;
                   1859:     ret = ctxt->nameTab[ctxt->nameNr];
                   1860:     ctxt->nameTab[ctxt->nameNr] = NULL;
                   1861:     return (ret);
                   1862: }
                   1863: 
                   1864: static int spacePush(xmlParserCtxtPtr ctxt, int val) {
                   1865:     if (ctxt->spaceNr >= ctxt->spaceMax) {
                   1866:         int *tmp;
                   1867: 
                   1868:        ctxt->spaceMax *= 2;
                   1869:         tmp = (int *) xmlRealloc(ctxt->spaceTab,
                   1870:                                 ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
                   1871:         if (tmp == NULL) {
                   1872:            xmlErrMemory(ctxt, NULL);
                   1873:            ctxt->spaceMax /=2;
                   1874:            return(-1);
                   1875:        }
                   1876:        ctxt->spaceTab = tmp;
                   1877:     }
                   1878:     ctxt->spaceTab[ctxt->spaceNr] = val;
                   1879:     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
                   1880:     return(ctxt->spaceNr++);
                   1881: }
                   1882: 
                   1883: static int spacePop(xmlParserCtxtPtr ctxt) {
                   1884:     int ret;
                   1885:     if (ctxt->spaceNr <= 0) return(0);
                   1886:     ctxt->spaceNr--;
                   1887:     if (ctxt->spaceNr > 0)
                   1888:        ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
                   1889:     else
                   1890:         ctxt->space = &ctxt->spaceTab[0];
                   1891:     ret = ctxt->spaceTab[ctxt->spaceNr];
                   1892:     ctxt->spaceTab[ctxt->spaceNr] = -1;
                   1893:     return(ret);
                   1894: }
                   1895: 
                   1896: /*
                   1897:  * Macros for accessing the content. Those should be used only by the parser,
                   1898:  * and not exported.
                   1899:  *
                   1900:  * Dirty macros, i.e. one often need to make assumption on the context to
                   1901:  * use them
                   1902:  *
                   1903:  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
                   1904:  *           To be used with extreme caution since operations consuming
                   1905:  *           characters may move the input buffer to a different location !
                   1906:  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
                   1907:  *           This should be used internally by the parser
                   1908:  *           only to compare to ASCII values otherwise it would break when
                   1909:  *           running with UTF-8 encoding.
                   1910:  *   RAW     same as CUR but in the input buffer, bypass any token
                   1911:  *           extraction that may have been done
                   1912:  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
                   1913:  *           to compare on ASCII based substring.
                   1914:  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
                   1915:  *           strings without newlines within the parser.
                   1916:  *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII 
                   1917:  *           defined char within the parser.
                   1918:  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
                   1919:  *
                   1920:  *   NEXT    Skip to the next character, this does the proper decoding
                   1921:  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
                   1922:  *   NEXTL(l) Skip the current unicode character of l xmlChars long.
                   1923:  *   CUR_CHAR(l) returns the current unicode character (int), set l
                   1924:  *           to the number of xmlChars used for the encoding [0-5].
                   1925:  *   CUR_SCHAR  same but operate on a string instead of the context
                   1926:  *   COPY_BUF  copy the current unicode char to the target buffer, increment
                   1927:  *            the index
                   1928:  *   GROW, SHRINK  handling of input buffers
                   1929:  */
                   1930: 
                   1931: #define RAW (*ctxt->input->cur)
                   1932: #define CUR (*ctxt->input->cur)
                   1933: #define NXT(val) ctxt->input->cur[(val)]
                   1934: #define CUR_PTR ctxt->input->cur
                   1935: 
                   1936: #define CMP4( s, c1, c2, c3, c4 ) \
                   1937:   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
                   1938:     ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
                   1939: #define CMP5( s, c1, c2, c3, c4, c5 ) \
                   1940:   ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
                   1941: #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
                   1942:   ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
                   1943: #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
                   1944:   ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
                   1945: #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
                   1946:   ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
                   1947: #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
                   1948:   ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
                   1949:     ((unsigned char *) s)[ 8 ] == c9 )
                   1950: #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
                   1951:   ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
                   1952:     ((unsigned char *) s)[ 9 ] == c10 )
                   1953: 
                   1954: #define SKIP(val) do {                                                 \
                   1955:     ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);                  \
                   1956:     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);    \
                   1957:     if ((*ctxt->input->cur == 0) &&                                    \
                   1958:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))           \
                   1959:            xmlPopInput(ctxt);                                          \
                   1960:   } while (0)
                   1961: 
                   1962: #define SKIPL(val) do {                                                        \
                   1963:     int skipl;                                                         \
                   1964:     for(skipl=0; skipl<val; skipl++) {                                 \
                   1965:        if (*(ctxt->input->cur) == '\n') {                              \
                   1966:        ctxt->input->line++; ctxt->input->col = 1;                      \
                   1967:        } else ctxt->input->col++;                                      \
                   1968:        ctxt->nbChars++;                                                \
                   1969:        ctxt->input->cur++;                                             \
                   1970:     }                                                                  \
                   1971:     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);    \
                   1972:     if ((*ctxt->input->cur == 0) &&                                    \
                   1973:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))           \
                   1974:            xmlPopInput(ctxt);                                          \
                   1975:   } while (0)
                   1976: 
                   1977: #define SHRINK if ((ctxt->progressive == 0) &&                         \
                   1978:                   (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
                   1979:                   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
                   1980:        xmlSHRINK (ctxt);
                   1981: 
                   1982: static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
                   1983:     xmlParserInputShrink(ctxt->input);
                   1984:     if ((*ctxt->input->cur == 0) &&
                   1985:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
                   1986:            xmlPopInput(ctxt);
                   1987:   }
                   1988: 
                   1989: #define GROW if ((ctxt->progressive == 0) &&                           \
                   1990:                 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))   \
                   1991:        xmlGROW (ctxt);
                   1992: 
                   1993: static void xmlGROW (xmlParserCtxtPtr ctxt) {
                   1994:     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
                   1995:     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
                   1996:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
                   1997:            xmlPopInput(ctxt);
                   1998: }
                   1999: 
                   2000: #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
                   2001: 
                   2002: #define NEXT xmlNextChar(ctxt)
                   2003: 
                   2004: #define NEXT1 {                                                                \
                   2005:        ctxt->input->col++;                                             \
                   2006:        ctxt->input->cur++;                                             \
                   2007:        ctxt->nbChars++;                                                \
                   2008:        if (*ctxt->input->cur == 0)                                     \
                   2009:            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);               \
                   2010:     }
                   2011: 
                   2012: #define NEXTL(l) do {                                                  \
                   2013:     if (*(ctxt->input->cur) == '\n') {                                 \
                   2014:        ctxt->input->line++; ctxt->input->col = 1;                      \
                   2015:     } else ctxt->input->col++;                                         \
                   2016:     ctxt->input->cur += l;                             \
                   2017:     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);    \
                   2018:   } while (0)
                   2019: 
                   2020: #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
                   2021: #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
                   2022: 
                   2023: #define COPY_BUF(l,b,i,v)                                              \
                   2024:     if (l == 1) b[i++] = (xmlChar) v;                                  \
                   2025:     else i += xmlCopyCharMultiByte(&b[i],v)
                   2026: 
                   2027: /**
                   2028:  * xmlSkipBlankChars:
                   2029:  * @ctxt:  the XML parser context
                   2030:  *
                   2031:  * skip all blanks character found at that point in the input streams.
                   2032:  * It pops up finished entities in the process if allowable at that point.
                   2033:  *
                   2034:  * Returns the number of space chars skipped
                   2035:  */
                   2036: 
                   2037: int
                   2038: xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
                   2039:     int res = 0;
                   2040: 
                   2041:     /*
                   2042:      * It's Okay to use CUR/NEXT here since all the blanks are on
                   2043:      * the ASCII range.
                   2044:      */
                   2045:     if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
                   2046:        const xmlChar *cur;
                   2047:        /*
                   2048:         * if we are in the document content, go really fast
                   2049:         */
                   2050:        cur = ctxt->input->cur;
                   2051:        while (IS_BLANK_CH(*cur)) {
                   2052:            if (*cur == '\n') {
                   2053:                ctxt->input->line++; ctxt->input->col = 1;
                   2054:            }
                   2055:            cur++;
                   2056:            res++;
                   2057:            if (*cur == 0) {
                   2058:                ctxt->input->cur = cur;
                   2059:                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
                   2060:                cur = ctxt->input->cur;
                   2061:            }
                   2062:        }
                   2063:        ctxt->input->cur = cur;
                   2064:     } else {
                   2065:        int cur;
                   2066:        do {
                   2067:            cur = CUR;
                   2068:            while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
                   2069:                NEXT;
                   2070:                cur = CUR;
                   2071:                res++;
                   2072:            }
                   2073:            while ((cur == 0) && (ctxt->inputNr > 1) &&
                   2074:                   (ctxt->instate != XML_PARSER_COMMENT)) {
                   2075:                xmlPopInput(ctxt);
                   2076:                cur = CUR;
                   2077:            }
                   2078:            /*
                   2079:             * Need to handle support of entities branching here
                   2080:             */
                   2081:            if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
                   2082:        } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
                   2083:     }
                   2084:     return(res);
                   2085: }
                   2086: 
                   2087: /************************************************************************
                   2088:  *                                                                     *
                   2089:  *             Commodity functions to handle entities                  *
                   2090:  *                                                                     *
                   2091:  ************************************************************************/
                   2092: 
                   2093: /**
                   2094:  * xmlPopInput:
                   2095:  * @ctxt:  an XML parser context
                   2096:  *
                   2097:  * xmlPopInput: the current input pointed by ctxt->input came to an end
                   2098:  *          pop it and return the next char.
                   2099:  *
                   2100:  * Returns the current xmlChar in the parser context
                   2101:  */
                   2102: xmlChar
                   2103: xmlPopInput(xmlParserCtxtPtr ctxt) {
                   2104:     if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
                   2105:     if (xmlParserDebugEntities)
                   2106:        xmlGenericError(xmlGenericErrorContext,
                   2107:                "Popping input %d\n", ctxt->inputNr);
                   2108:     xmlFreeInputStream(inputPop(ctxt));
                   2109:     if ((*ctxt->input->cur == 0) &&
                   2110:         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
                   2111:            return(xmlPopInput(ctxt));
                   2112:     return(CUR);
                   2113: }
                   2114: 
                   2115: /**
                   2116:  * xmlPushInput:
                   2117:  * @ctxt:  an XML parser context
                   2118:  * @input:  an XML parser input fragment (entity, XML fragment ...).
                   2119:  *
                   2120:  * xmlPushInput: switch to a new input stream which is stacked on top
                   2121:  *               of the previous one(s).
                   2122:  * Returns -1 in case of error or the index in the input stack
                   2123:  */
                   2124: int
                   2125: xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
                   2126:     int ret;
                   2127:     if (input == NULL) return(-1);
                   2128: 
                   2129:     if (xmlParserDebugEntities) {
                   2130:        if ((ctxt->input != NULL) && (ctxt->input->filename))
                   2131:            xmlGenericError(xmlGenericErrorContext,
                   2132:                    "%s(%d): ", ctxt->input->filename,
                   2133:                    ctxt->input->line);
                   2134:        xmlGenericError(xmlGenericErrorContext,
                   2135:                "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
                   2136:     }
                   2137:     ret = inputPush(ctxt, input);
                   2138:     GROW;
                   2139:     return(ret);
                   2140: }
                   2141: 
                   2142: /**
                   2143:  * xmlParseCharRef:
                   2144:  * @ctxt:  an XML parser context
                   2145:  *
                   2146:  * parse Reference declarations
                   2147:  *
                   2148:  * [66] CharRef ::= '&#' [0-9]+ ';' |
                   2149:  *                  '&#x' [0-9a-fA-F]+ ';'
                   2150:  *
                   2151:  * [ WFC: Legal Character ]
                   2152:  * Characters referred to using character references must match the
                   2153:  * production for Char. 
                   2154:  *
                   2155:  * Returns the value parsed (as an int), 0 in case of error
                   2156:  */
                   2157: int
                   2158: xmlParseCharRef(xmlParserCtxtPtr ctxt) {
                   2159:     unsigned int val = 0;
                   2160:     int count = 0;
                   2161:     unsigned int outofrange = 0;
                   2162: 
                   2163:     /*
                   2164:      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
                   2165:      */
                   2166:     if ((RAW == '&') && (NXT(1) == '#') &&
                   2167:         (NXT(2) == 'x')) {
                   2168:        SKIP(3);
                   2169:        GROW;
                   2170:        while (RAW != ';') { /* loop blocked by count */
                   2171:            if (count++ > 20) {
                   2172:                count = 0;
                   2173:                GROW;
                   2174:            }
                   2175:            if ((RAW >= '0') && (RAW <= '9')) 
                   2176:                val = val * 16 + (CUR - '0');
                   2177:            else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
                   2178:                val = val * 16 + (CUR - 'a') + 10;
                   2179:            else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
                   2180:                val = val * 16 + (CUR - 'A') + 10;
                   2181:            else {
                   2182:                xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
                   2183:                val = 0;
                   2184:                break;
                   2185:            }
                   2186:            if (val > 0x10FFFF)
                   2187:                outofrange = val;
                   2188: 
                   2189:            NEXT;
                   2190:            count++;
                   2191:        }
                   2192:        if (RAW == ';') {
                   2193:            /* on purpose to avoid reentrancy problems with NEXT and SKIP */
                   2194:            ctxt->input->col++;
                   2195:            ctxt->nbChars ++;
                   2196:            ctxt->input->cur++;
                   2197:        }
                   2198:     } else if  ((RAW == '&') && (NXT(1) == '#')) {
                   2199:        SKIP(2);
                   2200:        GROW;
                   2201:        while (RAW != ';') { /* loop blocked by count */
                   2202:            if (count++ > 20) {
                   2203:                count = 0;
                   2204:                GROW;
                   2205:            }
                   2206:            if ((RAW >= '0') && (RAW <= '9')) 
                   2207:                val = val * 10 + (CUR - '0');
                   2208:            else {
                   2209:                xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
                   2210:                val = 0;
                   2211:                break;
                   2212:            }
                   2213:            if (val > 0x10FFFF)
                   2214:                outofrange = val;
                   2215: 
                   2216:            NEXT;
                   2217:            count++;
                   2218:        }
                   2219:        if (RAW == ';') {
                   2220:            /* on purpose to avoid reentrancy problems with NEXT and SKIP */
                   2221:            ctxt->input->col++;
                   2222:            ctxt->nbChars ++;
                   2223:            ctxt->input->cur++;
                   2224:        }
                   2225:     } else {
                   2226:         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
                   2227:     }
                   2228: 
                   2229:     /*
                   2230:      * [ WFC: Legal Character ]
                   2231:      * Characters referred to using character references must match the
                   2232:      * production for Char. 
                   2233:      */
                   2234:     if ((IS_CHAR(val) && (outofrange == 0))) {
                   2235:         return(val);
                   2236:     } else {
                   2237:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   2238:                           "xmlParseCharRef: invalid xmlChar value %d\n",
                   2239:                          val);
                   2240:     }
                   2241:     return(0);
                   2242: }
                   2243: 
                   2244: /**
                   2245:  * xmlParseStringCharRef:
                   2246:  * @ctxt:  an XML parser context
                   2247:  * @str:  a pointer to an index in the string
                   2248:  *
                   2249:  * parse Reference declarations, variant parsing from a string rather
                   2250:  * than an an input flow.
                   2251:  *
                   2252:  * [66] CharRef ::= '&#' [0-9]+ ';' |
                   2253:  *                  '&#x' [0-9a-fA-F]+ ';'
                   2254:  *
                   2255:  * [ WFC: Legal Character ]
                   2256:  * Characters referred to using character references must match the
                   2257:  * production for Char. 
                   2258:  *
                   2259:  * Returns the value parsed (as an int), 0 in case of error, str will be
                   2260:  *         updated to the current value of the index
                   2261:  */
                   2262: static int
                   2263: xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
                   2264:     const xmlChar *ptr;
                   2265:     xmlChar cur;
                   2266:     unsigned int val = 0;
                   2267:     unsigned int outofrange = 0;
                   2268: 
                   2269:     if ((str == NULL) || (*str == NULL)) return(0);
                   2270:     ptr = *str;
                   2271:     cur = *ptr;
                   2272:     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
                   2273:        ptr += 3;
                   2274:        cur = *ptr;
                   2275:        while (cur != ';') { /* Non input consuming loop */
                   2276:            if ((cur >= '0') && (cur <= '9')) 
                   2277:                val = val * 16 + (cur - '0');
                   2278:            else if ((cur >= 'a') && (cur <= 'f'))
                   2279:                val = val * 16 + (cur - 'a') + 10;
                   2280:            else if ((cur >= 'A') && (cur <= 'F'))
                   2281:                val = val * 16 + (cur - 'A') + 10;
                   2282:            else {
                   2283:                xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
                   2284:                val = 0;
                   2285:                break;
                   2286:            }
                   2287:            if (val > 0x10FFFF)
                   2288:                outofrange = val;
                   2289: 
                   2290:            ptr++;
                   2291:            cur = *ptr;
                   2292:        }
                   2293:        if (cur == ';')
                   2294:            ptr++;
                   2295:     } else if  ((cur == '&') && (ptr[1] == '#')){
                   2296:        ptr += 2;
                   2297:        cur = *ptr;
                   2298:        while (cur != ';') { /* Non input consuming loops */
                   2299:            if ((cur >= '0') && (cur <= '9')) 
                   2300:                val = val * 10 + (cur - '0');
                   2301:            else {
                   2302:                xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
                   2303:                val = 0;
                   2304:                break;
                   2305:            }
                   2306:            if (val > 0x10FFFF)
                   2307:                outofrange = val;
                   2308: 
                   2309:            ptr++;
                   2310:            cur = *ptr;
                   2311:        }
                   2312:        if (cur == ';')
                   2313:            ptr++;
                   2314:     } else {
                   2315:        xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
                   2316:        return(0);
                   2317:     }
                   2318:     *str = ptr;
                   2319: 
                   2320:     /*
                   2321:      * [ WFC: Legal Character ]
                   2322:      * Characters referred to using character references must match the
                   2323:      * production for Char. 
                   2324:      */
                   2325:     if ((IS_CHAR(val) && (outofrange == 0))) {
                   2326:         return(val);
                   2327:     } else {
                   2328:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   2329:                          "xmlParseStringCharRef: invalid xmlChar value %d\n",
                   2330:                          val);
                   2331:     }
                   2332:     return(0);
                   2333: }
                   2334: 
                   2335: /**
                   2336:  * xmlNewBlanksWrapperInputStream:
                   2337:  * @ctxt:  an XML parser context
                   2338:  * @entity:  an Entity pointer
                   2339:  *
                   2340:  * Create a new input stream for wrapping
                   2341:  * blanks around a PEReference
                   2342:  *
                   2343:  * Returns the new input stream or NULL
                   2344:  */
                   2345:  
                   2346: static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
                   2347:  
                   2348: static xmlParserInputPtr
                   2349: xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
                   2350:     xmlParserInputPtr input;
                   2351:     xmlChar *buffer;
                   2352:     size_t length;
                   2353:     if (entity == NULL) {
                   2354:        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   2355:                    "xmlNewBlanksWrapperInputStream entity\n");
                   2356:        return(NULL);
                   2357:     }
                   2358:     if (xmlParserDebugEntities)
                   2359:        xmlGenericError(xmlGenericErrorContext,
                   2360:                "new blanks wrapper for entity: %s\n", entity->name);
                   2361:     input = xmlNewInputStream(ctxt);
                   2362:     if (input == NULL) {
                   2363:        return(NULL);
                   2364:     }
                   2365:     length = xmlStrlen(entity->name) + 5;
                   2366:     buffer = xmlMallocAtomic(length);
                   2367:     if (buffer == NULL) {
                   2368:        xmlErrMemory(ctxt, NULL);
                   2369:         xmlFree(input);
                   2370:        return(NULL);
                   2371:     }
                   2372:     buffer [0] = ' ';
                   2373:     buffer [1] = '%';
                   2374:     buffer [length-3] = ';';
                   2375:     buffer [length-2] = ' ';
                   2376:     buffer [length-1] = 0;
                   2377:     memcpy(buffer + 2, entity->name, length - 5);
                   2378:     input->free = deallocblankswrapper;
                   2379:     input->base = buffer;
                   2380:     input->cur = buffer;
                   2381:     input->length = length;
                   2382:     input->end = &buffer[length];
                   2383:     return(input);
                   2384: }
                   2385: 
                   2386: /**
                   2387:  * xmlParserHandlePEReference:
                   2388:  * @ctxt:  the parser context
                   2389:  * 
                   2390:  * [69] PEReference ::= '%' Name ';'
                   2391:  *
                   2392:  * [ WFC: No Recursion ]
                   2393:  * A parsed entity must not contain a recursive
                   2394:  * reference to itself, either directly or indirectly. 
                   2395:  *
                   2396:  * [ WFC: Entity Declared ]
                   2397:  * In a document without any DTD, a document with only an internal DTD
                   2398:  * subset which contains no parameter entity references, or a document
                   2399:  * with "standalone='yes'", ...  ... The declaration of a parameter
                   2400:  * entity must precede any reference to it...
                   2401:  *
                   2402:  * [ VC: Entity Declared ]
                   2403:  * In a document with an external subset or external parameter entities
                   2404:  * with "standalone='no'", ...  ... The declaration of a parameter entity
                   2405:  * must precede any reference to it...
                   2406:  *
                   2407:  * [ WFC: In DTD ]
                   2408:  * Parameter-entity references may only appear in the DTD.
                   2409:  * NOTE: misleading but this is handled.
                   2410:  *
                   2411:  * A PEReference may have been detected in the current input stream
                   2412:  * the handling is done accordingly to 
                   2413:  *      http://www.w3.org/TR/REC-xml#entproc
                   2414:  * i.e. 
                   2415:  *   - Included in literal in entity values
                   2416:  *   - Included as Parameter Entity reference within DTDs
                   2417:  */
                   2418: void
                   2419: xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
                   2420:     const xmlChar *name;
                   2421:     xmlEntityPtr entity = NULL;
                   2422:     xmlParserInputPtr input;
                   2423: 
                   2424:     if (RAW != '%') return;
                   2425:     switch(ctxt->instate) {
                   2426:        case XML_PARSER_CDATA_SECTION:
                   2427:            return;
                   2428:         case XML_PARSER_COMMENT:
                   2429:            return;
                   2430:        case XML_PARSER_START_TAG:
                   2431:            return;
                   2432:        case XML_PARSER_END_TAG:
                   2433:            return;
                   2434:         case XML_PARSER_EOF:
                   2435:            xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
                   2436:            return;
                   2437:         case XML_PARSER_PROLOG:
                   2438:        case XML_PARSER_START:
                   2439:        case XML_PARSER_MISC:
                   2440:            xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
                   2441:            return;
                   2442:        case XML_PARSER_ENTITY_DECL:
                   2443:         case XML_PARSER_CONTENT:
                   2444:         case XML_PARSER_ATTRIBUTE_VALUE:
                   2445:         case XML_PARSER_PI:
                   2446:        case XML_PARSER_SYSTEM_LITERAL:
                   2447:        case XML_PARSER_PUBLIC_LITERAL:
                   2448:            /* we just ignore it there */
                   2449:            return;
                   2450:         case XML_PARSER_EPILOG:
                   2451:            xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
                   2452:            return;
                   2453:        case XML_PARSER_ENTITY_VALUE:
                   2454:            /*
                   2455:             * NOTE: in the case of entity values, we don't do the
                   2456:             *       substitution here since we need the literal
                   2457:             *       entity value to be able to save the internal
                   2458:             *       subset of the document.
                   2459:             *       This will be handled by xmlStringDecodeEntities
                   2460:             */
                   2461:            return;
                   2462:         case XML_PARSER_DTD:
                   2463:            /*
                   2464:             * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
                   2465:             * In the internal DTD subset, parameter-entity references
                   2466:             * can occur only where markup declarations can occur, not
                   2467:             * within markup declarations.
                   2468:             * In that case this is handled in xmlParseMarkupDecl
                   2469:             */
                   2470:            if ((ctxt->external == 0) && (ctxt->inputNr == 1))
                   2471:                return;
                   2472:            if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
                   2473:                return;
                   2474:             break;
                   2475:         case XML_PARSER_IGNORE:
                   2476:             return;
                   2477:     }
                   2478: 
                   2479:     NEXT;
                   2480:     name = xmlParseName(ctxt);
                   2481:     if (xmlParserDebugEntities)
                   2482:        xmlGenericError(xmlGenericErrorContext,
                   2483:                "PEReference: %s\n", name);
                   2484:     if (name == NULL) {
                   2485:        xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
                   2486:     } else {
                   2487:        if (RAW == ';') {
                   2488:            NEXT;
                   2489:            if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
                   2490:                entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
                   2491:            if (entity == NULL) {
                   2492:                
                   2493:                /*
                   2494:                 * [ WFC: Entity Declared ]
                   2495:                 * In a document without any DTD, a document with only an
                   2496:                 * internal DTD subset which contains no parameter entity
                   2497:                 * references, or a document with "standalone='yes'", ...
                   2498:                 * ... The declaration of a parameter entity must precede
                   2499:                 * any reference to it...
                   2500:                 */
                   2501:                if ((ctxt->standalone == 1) ||
                   2502:                    ((ctxt->hasExternalSubset == 0) &&
                   2503:                     (ctxt->hasPErefs == 0))) {
                   2504:                    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   2505:                         "PEReference: %%%s; not found\n", name);
                   2506:                } else {
                   2507:                    /*
                   2508:                     * [ VC: Entity Declared ]
                   2509:                     * In a document with an external subset or external
                   2510:                     * parameter entities with "standalone='no'", ...
                   2511:                     * ... The declaration of a parameter entity must precede
                   2512:                     * any reference to it...
                   2513:                     */
                   2514:                    if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
                   2515:                        xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   2516:                                         "PEReference: %%%s; not found\n",
                   2517:                                         name, NULL);
                   2518:                    } else 
                   2519:                        xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   2520:                                      "PEReference: %%%s; not found\n",
                   2521:                                      name, NULL);
                   2522:                    ctxt->valid = 0;
                   2523:                }
                   2524:            } else if (ctxt->input->free != deallocblankswrapper) {
                   2525:                    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
                   2526:                    if (xmlPushInput(ctxt, input) < 0)
                   2527:                        return;
                   2528:            } else {
                   2529:                if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
                   2530:                    (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
                   2531:                    xmlChar start[4];
                   2532:                    xmlCharEncoding enc;
                   2533: 
                   2534:                    /*
                   2535:                     * handle the extra spaces added before and after
                   2536:                     * c.f. http://www.w3.org/TR/REC-xml#as-PE
                   2537:                     * this is done independently.
                   2538:                     */
                   2539:                    input = xmlNewEntityInputStream(ctxt, entity);
                   2540:                    if (xmlPushInput(ctxt, input) < 0)
                   2541:                        return;
                   2542: 
                   2543:                    /* 
                   2544:                     * Get the 4 first bytes and decode the charset
                   2545:                     * if enc != XML_CHAR_ENCODING_NONE
                   2546:                     * plug some encoding conversion routines.
                   2547:                     * Note that, since we may have some non-UTF8
                   2548:                     * encoding (like UTF16, bug 135229), the 'length'
                   2549:                     * is not known, but we can calculate based upon
                   2550:                     * the amount of data in the buffer.
                   2551:                     */
                   2552:                    GROW
                   2553:                    if ((ctxt->input->end - ctxt->input->cur)>=4) {
                   2554:                        start[0] = RAW;
                   2555:                        start[1] = NXT(1);
                   2556:                        start[2] = NXT(2);
                   2557:                        start[3] = NXT(3);
                   2558:                        enc = xmlDetectCharEncoding(start, 4);
                   2559:                        if (enc != XML_CHAR_ENCODING_NONE) {
                   2560:                            xmlSwitchEncoding(ctxt, enc);
                   2561:                        }
                   2562:                    }
                   2563: 
                   2564:                    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
                   2565:                        (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
                   2566:                        (IS_BLANK_CH(NXT(5)))) {
                   2567:                        xmlParseTextDecl(ctxt);
                   2568:                    }
                   2569:                } else {
                   2570:                    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
                   2571:                             "PEReference: %s is not a parameter entity\n",
                   2572:                                      name);
                   2573:                }
                   2574:            }
                   2575:        } else {
                   2576:            xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
                   2577:        }
                   2578:     }
                   2579: }
                   2580: 
                   2581: /*
                   2582:  * Macro used to grow the current buffer.
                   2583:  */
                   2584: #define growBuffer(buffer, n) {                                                \
                   2585:     xmlChar *tmp;                                                      \
                   2586:     buffer##_size *= 2;                                                        \
                   2587:     buffer##_size += n;                                                        \
                   2588:     tmp = (xmlChar *)                                                  \
                   2589:                xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));    \
                   2590:     if (tmp == NULL) goto mem_error;                                   \
                   2591:     buffer = tmp;                                                      \
                   2592: }
                   2593: 
                   2594: /**
                   2595:  * xmlStringLenDecodeEntities:
                   2596:  * @ctxt:  the parser context
                   2597:  * @str:  the input string
                   2598:  * @len: the string length
                   2599:  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
                   2600:  * @end:  an end marker xmlChar, 0 if none
                   2601:  * @end2:  an end marker xmlChar, 0 if none
                   2602:  * @end3:  an end marker xmlChar, 0 if none
                   2603:  * 
                   2604:  * Takes a entity string content and process to do the adequate substitutions.
                   2605:  *
                   2606:  * [67] Reference ::= EntityRef | CharRef
                   2607:  *
                   2608:  * [69] PEReference ::= '%' Name ';'
                   2609:  *
                   2610:  * Returns A newly allocated string with the substitution done. The caller
                   2611:  *      must deallocate it !
                   2612:  */
                   2613: xmlChar *
                   2614: xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                   2615:                      int what, xmlChar end, xmlChar  end2, xmlChar end3) {
                   2616:     xmlChar *buffer = NULL;
                   2617:     int buffer_size = 0;
                   2618: 
                   2619:     xmlChar *current = NULL;
                   2620:     xmlChar *rep = NULL;
                   2621:     const xmlChar *last;
                   2622:     xmlEntityPtr ent;
                   2623:     int c,l;
                   2624:     int nbchars = 0;
                   2625: 
                   2626:     if ((ctxt == NULL) || (str == NULL) || (len < 0))
                   2627:        return(NULL);
                   2628:     last = str + len;
                   2629: 
                   2630:     if (((ctxt->depth > 40) &&
                   2631:          ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
                   2632:        (ctxt->depth > 1024)) {
                   2633:        xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
                   2634:        return(NULL);
                   2635:     }
                   2636: 
                   2637:     /*
                   2638:      * allocate a translation buffer.
                   2639:      */
                   2640:     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
                   2641:     buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
                   2642:     if (buffer == NULL) goto mem_error;
                   2643: 
                   2644:     /*
                   2645:      * OK loop until we reach one of the ending char or a size limit.
                   2646:      * we are operating on already parsed values.
                   2647:      */
                   2648:     if (str < last)
                   2649:        c = CUR_SCHAR(str, l);
                   2650:     else
                   2651:         c = 0;
                   2652:     while ((c != 0) && (c != end) && /* non input consuming loop */
                   2653:           (c != end2) && (c != end3)) {
                   2654: 
                   2655:        if (c == 0) break;
                   2656:         if ((c == '&') && (str[1] == '#')) {
                   2657:            int val = xmlParseStringCharRef(ctxt, &str);
                   2658:            if (val != 0) {
                   2659:                COPY_BUF(0,buffer,nbchars,val);
                   2660:            }
                   2661:            if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
                   2662:                growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2663:            }
                   2664:        } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
                   2665:            if (xmlParserDebugEntities)
                   2666:                xmlGenericError(xmlGenericErrorContext,
                   2667:                        "String decoding Entity Reference: %.30s\n",
                   2668:                        str);
                   2669:            ent = xmlParseStringEntityRef(ctxt, &str);
                   2670:            if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
                   2671:                (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
                   2672:                goto int_error;
                   2673:            if (ent != NULL)
                   2674:                ctxt->nbentities += ent->checked;
                   2675:            if ((ent != NULL) &&
                   2676:                (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
                   2677:                if (ent->content != NULL) {
                   2678:                    COPY_BUF(0,buffer,nbchars,ent->content[0]);
                   2679:                    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
                   2680:                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2681:                    }
                   2682:                } else {
                   2683:                    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
                   2684:                            "predefined entity has no content\n");
                   2685:                }
                   2686:            } else if ((ent != NULL) && (ent->content != NULL)) {
                   2687:                ctxt->depth++;
                   2688:                rep = xmlStringDecodeEntities(ctxt, ent->content, what,
                   2689:                                              0, 0, 0);
                   2690:                ctxt->depth--;
                   2691: 
                   2692:                if (rep != NULL) {
                   2693:                    current = rep;
                   2694:                    while (*current != 0) { /* non input consuming loop */
                   2695:                        buffer[nbchars++] = *current++;
                   2696:                        if (nbchars >
                   2697:                            buffer_size - XML_PARSER_BUFFER_SIZE) {
                   2698:                            if (xmlParserEntityCheck(ctxt, nbchars, ent))
                   2699:                                goto int_error;
                   2700:                            growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2701:                        }
                   2702:                    }
                   2703:                    xmlFree(rep);
                   2704:                    rep = NULL;
                   2705:                }
                   2706:            } else if (ent != NULL) {
                   2707:                int i = xmlStrlen(ent->name);
                   2708:                const xmlChar *cur = ent->name;
                   2709: 
                   2710:                buffer[nbchars++] = '&';
                   2711:                if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
                   2712:                    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2713:                }
                   2714:                for (;i > 0;i--)
                   2715:                    buffer[nbchars++] = *cur++;
                   2716:                buffer[nbchars++] = ';';
                   2717:            }
                   2718:        } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
                   2719:            if (xmlParserDebugEntities)
                   2720:                xmlGenericError(xmlGenericErrorContext,
                   2721:                        "String decoding PE Reference: %.30s\n", str);
                   2722:            ent = xmlParseStringPEReference(ctxt, &str);
                   2723:            if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
                   2724:                goto int_error;
                   2725:            if (ent != NULL)
                   2726:                ctxt->nbentities += ent->checked;
                   2727:            if (ent != NULL) {
                   2728:                 if (ent->content == NULL) {
                   2729:                    xmlLoadEntityContent(ctxt, ent);
                   2730:                }
                   2731:                ctxt->depth++;
                   2732:                rep = xmlStringDecodeEntities(ctxt, ent->content, what,
                   2733:                                              0, 0, 0);
                   2734:                ctxt->depth--;
                   2735:                if (rep != NULL) {
                   2736:                    current = rep;
                   2737:                    while (*current != 0) { /* non input consuming loop */
                   2738:                        buffer[nbchars++] = *current++;
                   2739:                        if (nbchars >
                   2740:                            buffer_size - XML_PARSER_BUFFER_SIZE) {
                   2741:                            if (xmlParserEntityCheck(ctxt, nbchars, ent))
                   2742:                                goto int_error;
                   2743:                            growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2744:                        }
                   2745:                    }
                   2746:                    xmlFree(rep);
                   2747:                    rep = NULL;
                   2748:                }
                   2749:            }
                   2750:        } else {
                   2751:            COPY_BUF(l,buffer,nbchars,c);
                   2752:            str += l;
                   2753:            if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
                   2754:              growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                   2755:            }
                   2756:        }
                   2757:        if (str < last)
                   2758:            c = CUR_SCHAR(str, l);
                   2759:        else
                   2760:            c = 0;
                   2761:     }
                   2762:     buffer[nbchars] = 0;
                   2763:     return(buffer);
                   2764: 
                   2765: mem_error:
                   2766:     xmlErrMemory(ctxt, NULL);
                   2767: int_error:
                   2768:     if (rep != NULL)
                   2769:         xmlFree(rep);
                   2770:     if (buffer != NULL)
                   2771:         xmlFree(buffer);
                   2772:     return(NULL);
                   2773: }
                   2774: 
                   2775: /**
                   2776:  * xmlStringDecodeEntities:
                   2777:  * @ctxt:  the parser context
                   2778:  * @str:  the input string
                   2779:  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
                   2780:  * @end:  an end marker xmlChar, 0 if none
                   2781:  * @end2:  an end marker xmlChar, 0 if none
                   2782:  * @end3:  an end marker xmlChar, 0 if none
                   2783:  * 
                   2784:  * Takes a entity string content and process to do the adequate substitutions.
                   2785:  *
                   2786:  * [67] Reference ::= EntityRef | CharRef
                   2787:  *
                   2788:  * [69] PEReference ::= '%' Name ';'
                   2789:  *
                   2790:  * Returns A newly allocated string with the substitution done. The caller
                   2791:  *      must deallocate it !
                   2792:  */
                   2793: xmlChar *
                   2794: xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
                   2795:                        xmlChar end, xmlChar  end2, xmlChar end3) {
                   2796:     if ((ctxt == NULL) || (str == NULL)) return(NULL);
                   2797:     return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
                   2798:            end, end2, end3));
                   2799: }
                   2800: 
                   2801: /************************************************************************
                   2802:  *                                                                     *
                   2803:  *             Commodity functions, cleanup needed ?                   *
                   2804:  *                                                                     *
                   2805:  ************************************************************************/
                   2806: 
                   2807: /**
                   2808:  * areBlanks:
                   2809:  * @ctxt:  an XML parser context
                   2810:  * @str:  a xmlChar *
                   2811:  * @len:  the size of @str
                   2812:  * @blank_chars: we know the chars are blanks
                   2813:  *
                   2814:  * Is this a sequence of blank chars that one can ignore ?
                   2815:  *
                   2816:  * Returns 1 if ignorable 0 otherwise.
                   2817:  */
                   2818: 
                   2819: static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                   2820:                      int blank_chars) {
                   2821:     int i, ret;
                   2822:     xmlNodePtr lastChild;
                   2823: 
                   2824:     /*
                   2825:      * Don't spend time trying to differentiate them, the same callback is
                   2826:      * used !
                   2827:      */
                   2828:     if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
                   2829:        return(0);
                   2830: 
                   2831:     /*
                   2832:      * Check for xml:space value.
                   2833:      */
                   2834:     if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
                   2835:         (*(ctxt->space) == -2))
                   2836:        return(0);
                   2837: 
                   2838:     /*
                   2839:      * Check that the string is made of blanks
                   2840:      */
                   2841:     if (blank_chars == 0) {
                   2842:        for (i = 0;i < len;i++)
                   2843:            if (!(IS_BLANK_CH(str[i]))) return(0);
                   2844:     }
                   2845: 
                   2846:     /*
                   2847:      * Look if the element is mixed content in the DTD if available
                   2848:      */
                   2849:     if (ctxt->node == NULL) return(0);
                   2850:     if (ctxt->myDoc != NULL) {
                   2851:        ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
                   2852:         if (ret == 0) return(1);
                   2853:         if (ret == 1) return(0);
                   2854:     }
                   2855: 
                   2856:     /*
                   2857:      * Otherwise, heuristic :-\
                   2858:      */
                   2859:     if ((RAW != '<') && (RAW != 0xD)) return(0);
                   2860:     if ((ctxt->node->children == NULL) &&
                   2861:        (RAW == '<') && (NXT(1) == '/')) return(0);
                   2862: 
                   2863:     lastChild = xmlGetLastChild(ctxt->node);
                   2864:     if (lastChild == NULL) {
                   2865:         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
                   2866:             (ctxt->node->content != NULL)) return(0);
                   2867:     } else if (xmlNodeIsText(lastChild))
                   2868:         return(0);
                   2869:     else if ((ctxt->node->children != NULL) &&
                   2870:              (xmlNodeIsText(ctxt->node->children)))
                   2871:         return(0);
                   2872:     return(1);
                   2873: }
                   2874: 
                   2875: /************************************************************************
                   2876:  *                                                                     *
                   2877:  *             Extra stuff for namespace support                       *
                   2878:  *     Relates to http://www.w3.org/TR/WD-xml-names                    *
                   2879:  *                                                                     *
                   2880:  ************************************************************************/
                   2881: 
                   2882: /**
                   2883:  * xmlSplitQName:
                   2884:  * @ctxt:  an XML parser context
                   2885:  * @name:  an XML parser context
                   2886:  * @prefix:  a xmlChar **
                   2887:  *
                   2888:  * parse an UTF8 encoded XML qualified name string
                   2889:  *
                   2890:  * [NS 5] QName ::= (Prefix ':')? LocalPart
                   2891:  *
                   2892:  * [NS 6] Prefix ::= NCName
                   2893:  *
                   2894:  * [NS 7] LocalPart ::= NCName
                   2895:  *
                   2896:  * Returns the local part, and prefix is updated
                   2897:  *   to get the Prefix if any.
                   2898:  */
                   2899: 
                   2900: xmlChar *
                   2901: xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
                   2902:     xmlChar buf[XML_MAX_NAMELEN + 5];
                   2903:     xmlChar *buffer = NULL;
                   2904:     int len = 0;
                   2905:     int max = XML_MAX_NAMELEN;
                   2906:     xmlChar *ret = NULL;
                   2907:     const xmlChar *cur = name;
                   2908:     int c;
                   2909: 
                   2910:     if (prefix == NULL) return(NULL);
                   2911:     *prefix = NULL;
                   2912: 
                   2913:     if (cur == NULL) return(NULL);
                   2914: 
                   2915: #ifndef XML_XML_NAMESPACE
                   2916:     /* xml: prefix is not really a namespace */
                   2917:     if ((cur[0] == 'x') && (cur[1] == 'm') &&
                   2918:         (cur[2] == 'l') && (cur[3] == ':'))
                   2919:        return(xmlStrdup(name));
                   2920: #endif
                   2921: 
                   2922:     /* nasty but well=formed */
                   2923:     if (cur[0] == ':')
                   2924:        return(xmlStrdup(name));
                   2925: 
                   2926:     c = *cur++;
                   2927:     while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
                   2928:        buf[len++] = c;
                   2929:        c = *cur++;
                   2930:     }
                   2931:     if (len >= max) {
                   2932:        /*
                   2933:         * Okay someone managed to make a huge name, so he's ready to pay
                   2934:         * for the processing speed.
                   2935:         */
                   2936:        max = len * 2;
                   2937: 
                   2938:        buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
                   2939:        if (buffer == NULL) {
                   2940:            xmlErrMemory(ctxt, NULL);
                   2941:            return(NULL);
                   2942:        }
                   2943:        memcpy(buffer, buf, len);
                   2944:        while ((c != 0) && (c != ':')) { /* tested bigname.xml */
                   2945:            if (len + 10 > max) {
                   2946:                xmlChar *tmp;
                   2947: 
                   2948:                max *= 2;
                   2949:                tmp = (xmlChar *) xmlRealloc(buffer,
                   2950:                                                max * sizeof(xmlChar));
                   2951:                if (tmp == NULL) {
                   2952:                    xmlFree(buffer);
                   2953:                    xmlErrMemory(ctxt, NULL);
                   2954:                    return(NULL);
                   2955:                }
                   2956:                buffer = tmp;
                   2957:            }
                   2958:            buffer[len++] = c;
                   2959:            c = *cur++;
                   2960:        }
                   2961:        buffer[len] = 0;
                   2962:     }
                   2963: 
                   2964:     if ((c == ':') && (*cur == 0)) {
                   2965:         if (buffer != NULL)
                   2966:            xmlFree(buffer);
                   2967:        *prefix = NULL;
                   2968:        return(xmlStrdup(name));
                   2969:     }
                   2970: 
                   2971:     if (buffer == NULL)
                   2972:        ret = xmlStrndup(buf, len);
                   2973:     else {
                   2974:        ret = buffer;
                   2975:        buffer = NULL;
                   2976:        max = XML_MAX_NAMELEN;
                   2977:     }
                   2978: 
                   2979: 
                   2980:     if (c == ':') {
                   2981:        c = *cur;
                   2982:         *prefix = ret;
                   2983:        if (c == 0) {
                   2984:            return(xmlStrndup(BAD_CAST "", 0));
                   2985:        }
                   2986:        len = 0;
                   2987: 
                   2988:        /*
                   2989:         * Check that the first character is proper to start
                   2990:         * a new name
                   2991:         */
                   2992:        if (!(((c >= 0x61) && (c <= 0x7A)) ||
                   2993:              ((c >= 0x41) && (c <= 0x5A)) ||
                   2994:              (c == '_') || (c == ':'))) {
                   2995:            int l;
                   2996:            int first = CUR_SCHAR(cur, l);
                   2997: 
                   2998:            if (!IS_LETTER(first) && (first != '_')) {
                   2999:                xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
                   3000:                            "Name %s is not XML Namespace compliant\n",
                   3001:                                  name);
                   3002:            }
                   3003:        }
                   3004:        cur++;
                   3005: 
                   3006:        while ((c != 0) && (len < max)) { /* tested bigname2.xml */
                   3007:            buf[len++] = c;
                   3008:            c = *cur++;
                   3009:        }
                   3010:        if (len >= max) {
                   3011:            /*
                   3012:             * Okay someone managed to make a huge name, so he's ready to pay
                   3013:             * for the processing speed.
                   3014:             */
                   3015:            max = len * 2;
                   3016: 
                   3017:            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
                   3018:            if (buffer == NULL) {
                   3019:                xmlErrMemory(ctxt, NULL);
                   3020:                return(NULL);
                   3021:            }
                   3022:            memcpy(buffer, buf, len);
                   3023:            while (c != 0) { /* tested bigname2.xml */
                   3024:                if (len + 10 > max) {
                   3025:                    xmlChar *tmp;
                   3026: 
                   3027:                    max *= 2;
                   3028:                    tmp = (xmlChar *) xmlRealloc(buffer,
                   3029:                                                    max * sizeof(xmlChar));
                   3030:                    if (tmp == NULL) {
                   3031:                        xmlErrMemory(ctxt, NULL);
                   3032:                        xmlFree(buffer);
                   3033:                        return(NULL);
                   3034:                    }
                   3035:                    buffer = tmp;
                   3036:                }
                   3037:                buffer[len++] = c;
                   3038:                c = *cur++;
                   3039:            }
                   3040:            buffer[len] = 0;
                   3041:        }
                   3042: 
                   3043:        if (buffer == NULL)
                   3044:            ret = xmlStrndup(buf, len);
                   3045:        else {
                   3046:            ret = buffer;
                   3047:        }
                   3048:     }
                   3049: 
                   3050:     return(ret);
                   3051: }
                   3052: 
                   3053: /************************************************************************
                   3054:  *                                                                     *
                   3055:  *                     The parser itself                               *
                   3056:  *     Relates to http://www.w3.org/TR/REC-xml                         *
                   3057:  *                                                                     *
                   3058:  ************************************************************************/
                   3059: 
                   3060: /************************************************************************
                   3061:  *                                                                     *
                   3062:  *     Routines to parse Name, NCName and NmToken                      *
                   3063:  *                                                                     *
                   3064:  ************************************************************************/
                   3065: #ifdef DEBUG
                   3066: static unsigned long nbParseName = 0;
                   3067: static unsigned long nbParseNmToken = 0;
                   3068: static unsigned long nbParseNCName = 0;
                   3069: static unsigned long nbParseNCNameComplex = 0;
                   3070: static unsigned long nbParseNameComplex = 0;
                   3071: static unsigned long nbParseStringName = 0;
                   3072: #endif
                   3073: 
                   3074: /*
                   3075:  * The two following functions are related to the change of accepted
                   3076:  * characters for Name and NmToken in the Revision 5 of XML-1.0
                   3077:  * They correspond to the modified production [4] and the new production [4a]
                   3078:  * changes in that revision. Also note that the macros used for the
                   3079:  * productions Letter, Digit, CombiningChar and Extender are not needed
                   3080:  * anymore.
                   3081:  * We still keep compatibility to pre-revision5 parsing semantic if the
                   3082:  * new XML_PARSE_OLD10 option is given to the parser.
                   3083:  */
                   3084: static int
                   3085: xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
                   3086:     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
                   3087:         /*
                   3088:         * Use the new checks of production [4] [4a] amd [5] of the
                   3089:         * Update 5 of XML-1.0
                   3090:         */
                   3091:        if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
                   3092:            (((c >= 'a') && (c <= 'z')) ||
                   3093:             ((c >= 'A') && (c <= 'Z')) ||
                   3094:             (c == '_') || (c == ':') ||
                   3095:             ((c >= 0xC0) && (c <= 0xD6)) ||
                   3096:             ((c >= 0xD8) && (c <= 0xF6)) ||
                   3097:             ((c >= 0xF8) && (c <= 0x2FF)) ||
                   3098:             ((c >= 0x370) && (c <= 0x37D)) ||
                   3099:             ((c >= 0x37F) && (c <= 0x1FFF)) ||
                   3100:             ((c >= 0x200C) && (c <= 0x200D)) ||
                   3101:             ((c >= 0x2070) && (c <= 0x218F)) ||
                   3102:             ((c >= 0x2C00) && (c <= 0x2FEF)) ||
                   3103:             ((c >= 0x3001) && (c <= 0xD7FF)) ||
                   3104:             ((c >= 0xF900) && (c <= 0xFDCF)) ||
                   3105:             ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
                   3106:             ((c >= 0x10000) && (c <= 0xEFFFF))))
                   3107:            return(1);
                   3108:     } else {
                   3109:         if (IS_LETTER(c) || (c == '_') || (c == ':'))
                   3110:            return(1);
                   3111:     }
                   3112:     return(0);
                   3113: }
                   3114: 
                   3115: static int
                   3116: xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
                   3117:     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
                   3118:         /*
                   3119:         * Use the new checks of production [4] [4a] amd [5] of the
                   3120:         * Update 5 of XML-1.0
                   3121:         */
                   3122:        if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
                   3123:            (((c >= 'a') && (c <= 'z')) ||
                   3124:             ((c >= 'A') && (c <= 'Z')) ||
                   3125:             ((c >= '0') && (c <= '9')) || /* !start */
                   3126:             (c == '_') || (c == ':') ||
                   3127:             (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
                   3128:             ((c >= 0xC0) && (c <= 0xD6)) ||
                   3129:             ((c >= 0xD8) && (c <= 0xF6)) ||
                   3130:             ((c >= 0xF8) && (c <= 0x2FF)) ||
                   3131:             ((c >= 0x300) && (c <= 0x36F)) || /* !start */
                   3132:             ((c >= 0x370) && (c <= 0x37D)) ||
                   3133:             ((c >= 0x37F) && (c <= 0x1FFF)) ||
                   3134:             ((c >= 0x200C) && (c <= 0x200D)) ||
                   3135:             ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
                   3136:             ((c >= 0x2070) && (c <= 0x218F)) ||
                   3137:             ((c >= 0x2C00) && (c <= 0x2FEF)) ||
                   3138:             ((c >= 0x3001) && (c <= 0xD7FF)) ||
                   3139:             ((c >= 0xF900) && (c <= 0xFDCF)) ||
                   3140:             ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
                   3141:             ((c >= 0x10000) && (c <= 0xEFFFF))))
                   3142:             return(1);
                   3143:     } else {
                   3144:         if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
                   3145:             (c == '.') || (c == '-') ||
                   3146:            (c == '_') || (c == ':') || 
                   3147:            (IS_COMBINING(c)) ||
                   3148:            (IS_EXTENDER(c)))
                   3149:            return(1);
                   3150:     }
                   3151:     return(0);
                   3152: }
                   3153: 
                   3154: static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
                   3155:                                           int *len, int *alloc, int normalize);
                   3156: 
                   3157: static const xmlChar *
                   3158: xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
                   3159:     int len = 0, l;
                   3160:     int c;
                   3161:     int count = 0;
                   3162: 
                   3163: #ifdef DEBUG
                   3164:     nbParseNameComplex++;
                   3165: #endif
                   3166: 
                   3167:     /*
                   3168:      * Handler for more complex cases
                   3169:      */
                   3170:     GROW;
                   3171:     c = CUR_CHAR(l);
                   3172:     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
                   3173:         /*
                   3174:         * Use the new checks of production [4] [4a] amd [5] of the
                   3175:         * Update 5 of XML-1.0
                   3176:         */
                   3177:        if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
                   3178:            (!(((c >= 'a') && (c <= 'z')) ||
                   3179:               ((c >= 'A') && (c <= 'Z')) ||
                   3180:               (c == '_') || (c == ':') ||
                   3181:               ((c >= 0xC0) && (c <= 0xD6)) ||
                   3182:               ((c >= 0xD8) && (c <= 0xF6)) ||
                   3183:               ((c >= 0xF8) && (c <= 0x2FF)) ||
                   3184:               ((c >= 0x370) && (c <= 0x37D)) ||
                   3185:               ((c >= 0x37F) && (c <= 0x1FFF)) ||
                   3186:               ((c >= 0x200C) && (c <= 0x200D)) ||
                   3187:               ((c >= 0x2070) && (c <= 0x218F)) ||
                   3188:               ((c >= 0x2C00) && (c <= 0x2FEF)) ||
                   3189:               ((c >= 0x3001) && (c <= 0xD7FF)) ||
                   3190:               ((c >= 0xF900) && (c <= 0xFDCF)) ||
                   3191:               ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
                   3192:               ((c >= 0x10000) && (c <= 0xEFFFF))))) {
                   3193:            return(NULL);
                   3194:        }
                   3195:        len += l;
                   3196:        NEXTL(l);
                   3197:        c = CUR_CHAR(l);
                   3198:        while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
                   3199:               (((c >= 'a') && (c <= 'z')) ||
                   3200:                ((c >= 'A') && (c <= 'Z')) ||
                   3201:                ((c >= '0') && (c <= '9')) || /* !start */
                   3202:                (c == '_') || (c == ':') ||
                   3203:                (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
                   3204:                ((c >= 0xC0) && (c <= 0xD6)) ||
                   3205:                ((c >= 0xD8) && (c <= 0xF6)) ||
                   3206:                ((c >= 0xF8) && (c <= 0x2FF)) ||
                   3207:                ((c >= 0x300) && (c <= 0x36F)) || /* !start */
                   3208:                ((c >= 0x370) && (c <= 0x37D)) ||
                   3209:                ((c >= 0x37F) && (c <= 0x1FFF)) ||
                   3210:                ((c >= 0x200C) && (c <= 0x200D)) ||
                   3211:                ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
                   3212:                ((c >= 0x2070) && (c <= 0x218F)) ||
                   3213:                ((c >= 0x2C00) && (c <= 0x2FEF)) ||
                   3214:                ((c >= 0x3001) && (c <= 0xD7FF)) ||
                   3215:                ((c >= 0xF900) && (c <= 0xFDCF)) ||
                   3216:                ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
                   3217:                ((c >= 0x10000) && (c <= 0xEFFFF))
                   3218:                )) {
                   3219:            if (count++ > 100) {
                   3220:                count = 0;
                   3221:                GROW;
                   3222:            }
                   3223:            len += l;
                   3224:            NEXTL(l);
                   3225:            c = CUR_CHAR(l);
                   3226:        }
                   3227:     } else {
                   3228:        if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
                   3229:            (!IS_LETTER(c) && (c != '_') &&
                   3230:             (c != ':'))) {
                   3231:            return(NULL);
                   3232:        }
                   3233:        len += l;
                   3234:        NEXTL(l);
                   3235:        c = CUR_CHAR(l);
                   3236: 
                   3237:        while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
                   3238:               ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
                   3239:                (c == '.') || (c == '-') ||
                   3240:                (c == '_') || (c == ':') || 
                   3241:                (IS_COMBINING(c)) ||
                   3242:                (IS_EXTENDER(c)))) {
                   3243:            if (count++ > 100) {
                   3244:                count = 0;
                   3245:                GROW;
                   3246:            }
                   3247:            len += l;
                   3248:            NEXTL(l);
                   3249:            c = CUR_CHAR(l);
                   3250:        }
                   3251:     }
                   3252:     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
                   3253:         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
                   3254:     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
                   3255: }
                   3256: 
                   3257: /**
                   3258:  * xmlParseName:
                   3259:  * @ctxt:  an XML parser context
                   3260:  *
                   3261:  * parse an XML name.
                   3262:  *
                   3263:  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
                   3264:  *                  CombiningChar | Extender
                   3265:  *
                   3266:  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
                   3267:  *
                   3268:  * [6] Names ::= Name (#x20 Name)*
                   3269:  *
                   3270:  * Returns the Name parsed or NULL
                   3271:  */
                   3272: 
                   3273: const xmlChar *
                   3274: xmlParseName(xmlParserCtxtPtr ctxt) {
                   3275:     const xmlChar *in;
                   3276:     const xmlChar *ret;
                   3277:     int count = 0;
                   3278: 
                   3279:     GROW;
                   3280: 
                   3281: #ifdef DEBUG
                   3282:     nbParseName++;
                   3283: #endif
                   3284: 
                   3285:     /*
                   3286:      * Accelerator for simple ASCII names
                   3287:      */
                   3288:     in = ctxt->input->cur;
                   3289:     if (((*in >= 0x61) && (*in <= 0x7A)) ||
                   3290:        ((*in >= 0x41) && (*in <= 0x5A)) ||
                   3291:        (*in == '_') || (*in == ':')) {
                   3292:        in++;
                   3293:        while (((*in >= 0x61) && (*in <= 0x7A)) ||
                   3294:               ((*in >= 0x41) && (*in <= 0x5A)) ||
                   3295:               ((*in >= 0x30) && (*in <= 0x39)) ||
                   3296:               (*in == '_') || (*in == '-') ||
                   3297:               (*in == ':') || (*in == '.'))
                   3298:            in++;
                   3299:        if ((*in > 0) && (*in < 0x80)) {
                   3300:            count = in - ctxt->input->cur;
                   3301:            ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
                   3302:            ctxt->input->cur = in;
                   3303:            ctxt->nbChars += count;
                   3304:            ctxt->input->col += count;
                   3305:            if (ret == NULL)
                   3306:                xmlErrMemory(ctxt, NULL);
                   3307:            return(ret);
                   3308:        }
                   3309:     }
                   3310:     /* accelerator for special cases */
                   3311:     return(xmlParseNameComplex(ctxt));
                   3312: }
                   3313: 
                   3314: static const xmlChar *
                   3315: xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
                   3316:     int len = 0, l;
                   3317:     int c;
                   3318:     int count = 0;
                   3319: 
                   3320: #ifdef DEBUG
                   3321:     nbParseNCNameComplex++;
                   3322: #endif
                   3323: 
                   3324:     /*
                   3325:      * Handler for more complex cases
                   3326:      */
                   3327:     GROW;
                   3328:     c = CUR_CHAR(l);
                   3329:     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
                   3330:        (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
                   3331:        return(NULL);
                   3332:     }
                   3333: 
                   3334:     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
                   3335:           (xmlIsNameChar(ctxt, c) && (c != ':'))) {
                   3336:        if (count++ > 100) {
                   3337:            count = 0;
                   3338:            GROW;
                   3339:        }
                   3340:        len += l;
                   3341:        NEXTL(l);
                   3342:        c = CUR_CHAR(l);
                   3343:     }
                   3344:     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
                   3345: }
                   3346: 
                   3347: /**
                   3348:  * xmlParseNCName:
                   3349:  * @ctxt:  an XML parser context
                   3350:  * @len:  lenght of the string parsed
                   3351:  *
                   3352:  * parse an XML name.
                   3353:  *
                   3354:  * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
                   3355:  *                      CombiningChar | Extender
                   3356:  *
                   3357:  * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
                   3358:  *
                   3359:  * Returns the Name parsed or NULL
                   3360:  */
                   3361: 
                   3362: static const xmlChar *
                   3363: xmlParseNCName(xmlParserCtxtPtr ctxt) {
                   3364:     const xmlChar *in;
                   3365:     const xmlChar *ret;
                   3366:     int count = 0;
                   3367: 
                   3368: #ifdef DEBUG
                   3369:     nbParseNCName++;
                   3370: #endif
                   3371: 
                   3372:     /*
                   3373:      * Accelerator for simple ASCII names
                   3374:      */
                   3375:     in = ctxt->input->cur;
                   3376:     if (((*in >= 0x61) && (*in <= 0x7A)) ||
                   3377:        ((*in >= 0x41) && (*in <= 0x5A)) ||
                   3378:        (*in == '_')) {
                   3379:        in++;
                   3380:        while (((*in >= 0x61) && (*in <= 0x7A)) ||
                   3381:               ((*in >= 0x41) && (*in <= 0x5A)) ||
                   3382:               ((*in >= 0x30) && (*in <= 0x39)) ||
                   3383:               (*in == '_') || (*in == '-') ||
                   3384:               (*in == '.'))
                   3385:            in++;
                   3386:        if ((*in > 0) && (*in < 0x80)) {
                   3387:            count = in - ctxt->input->cur;
                   3388:            ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
                   3389:            ctxt->input->cur = in;
                   3390:            ctxt->nbChars += count;
                   3391:            ctxt->input->col += count;
                   3392:            if (ret == NULL) {
                   3393:                xmlErrMemory(ctxt, NULL);
                   3394:            }
                   3395:            return(ret);
                   3396:        }
                   3397:     }
                   3398:     return(xmlParseNCNameComplex(ctxt));
                   3399: }
                   3400: 
                   3401: /**
                   3402:  * xmlParseNameAndCompare:
                   3403:  * @ctxt:  an XML parser context
                   3404:  *
                   3405:  * parse an XML name and compares for match
                   3406:  * (specialized for endtag parsing)
                   3407:  *
                   3408:  * Returns NULL for an illegal name, (xmlChar*) 1 for success
                   3409:  * and the name for mismatch
                   3410:  */
                   3411: 
                   3412: static const xmlChar *
                   3413: xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
                   3414:     register const xmlChar *cmp = other;
                   3415:     register const xmlChar *in;
                   3416:     const xmlChar *ret;
                   3417: 
                   3418:     GROW;
                   3419: 
                   3420:     in = ctxt->input->cur;
                   3421:     while (*in != 0 && *in == *cmp) {
                   3422:        ++in;
                   3423:        ++cmp;
                   3424:        ctxt->input->col++;
                   3425:     }
                   3426:     if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
                   3427:        /* success */
                   3428:        ctxt->input->cur = in;
                   3429:        return (const xmlChar*) 1;
                   3430:     }
                   3431:     /* failure (or end of input buffer), check with full function */
                   3432:     ret = xmlParseName (ctxt);
                   3433:     /* strings coming from the dictionnary direct compare possible */
                   3434:     if (ret == other) {
                   3435:        return (const xmlChar*) 1;
                   3436:     }
                   3437:     return ret;
                   3438: }
                   3439: 
                   3440: /**
                   3441:  * xmlParseStringName:
                   3442:  * @ctxt:  an XML parser context
                   3443:  * @str:  a pointer to the string pointer (IN/OUT)
                   3444:  *
                   3445:  * parse an XML name.
                   3446:  *
                   3447:  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
                   3448:  *                  CombiningChar | Extender
                   3449:  *
                   3450:  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
                   3451:  *
                   3452:  * [6] Names ::= Name (#x20 Name)*
                   3453:  *
                   3454:  * Returns the Name parsed or NULL. The @str pointer 
                   3455:  * is updated to the current location in the string.
                   3456:  */
                   3457: 
                   3458: static xmlChar *
                   3459: xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
                   3460:     xmlChar buf[XML_MAX_NAMELEN + 5];
                   3461:     const xmlChar *cur = *str;
                   3462:     int len = 0, l;
                   3463:     int c;
                   3464: 
                   3465: #ifdef DEBUG
                   3466:     nbParseStringName++;
                   3467: #endif
                   3468: 
                   3469:     c = CUR_SCHAR(cur, l);
                   3470:     if (!xmlIsNameStartChar(ctxt, c)) {
                   3471:        return(NULL);
                   3472:     }
                   3473: 
                   3474:     COPY_BUF(l,buf,len,c);
                   3475:     cur += l;
                   3476:     c = CUR_SCHAR(cur, l);
                   3477:     while (xmlIsNameChar(ctxt, c)) {
                   3478:        COPY_BUF(l,buf,len,c);
                   3479:        cur += l;
                   3480:        c = CUR_SCHAR(cur, l);
                   3481:        if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
                   3482:            /*
                   3483:             * Okay someone managed to make a huge name, so he's ready to pay
                   3484:             * for the processing speed.
                   3485:             */
                   3486:            xmlChar *buffer;
                   3487:            int max = len * 2;
                   3488: 
                   3489:            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
                   3490:            if (buffer == NULL) {
                   3491:                xmlErrMemory(ctxt, NULL);
                   3492:                return(NULL);
                   3493:            }
                   3494:            memcpy(buffer, buf, len);
                   3495:            while (xmlIsNameChar(ctxt, c)) {
                   3496:                if (len + 10 > max) {
                   3497:                    xmlChar *tmp;
                   3498:                    max *= 2;
                   3499:                    tmp = (xmlChar *) xmlRealloc(buffer,
                   3500:                                                    max * sizeof(xmlChar));
                   3501:                    if (tmp == NULL) {
                   3502:                        xmlErrMemory(ctxt, NULL);
                   3503:                        xmlFree(buffer);
                   3504:                        return(NULL);
                   3505:                    }
                   3506:                    buffer = tmp;
                   3507:                }
                   3508:                COPY_BUF(l,buffer,len,c);
                   3509:                cur += l;
                   3510:                c = CUR_SCHAR(cur, l);
                   3511:            }
                   3512:            buffer[len] = 0;
                   3513:            *str = cur;
                   3514:            return(buffer);
                   3515:        }
                   3516:     }
                   3517:     *str = cur;
                   3518:     return(xmlStrndup(buf, len));
                   3519: }
                   3520: 
                   3521: /**
                   3522:  * xmlParseNmtoken:
                   3523:  * @ctxt:  an XML parser context
                   3524:  *
                   3525:  * parse an XML Nmtoken.
                   3526:  *
                   3527:  * [7] Nmtoken ::= (NameChar)+
                   3528:  *
                   3529:  * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
                   3530:  *
                   3531:  * Returns the Nmtoken parsed or NULL
                   3532:  */
                   3533: 
                   3534: xmlChar *
                   3535: xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
                   3536:     xmlChar buf[XML_MAX_NAMELEN + 5];
                   3537:     int len = 0, l;
                   3538:     int c;
                   3539:     int count = 0;
                   3540: 
                   3541: #ifdef DEBUG
                   3542:     nbParseNmToken++;
                   3543: #endif
                   3544: 
                   3545:     GROW;
                   3546:     c = CUR_CHAR(l);
                   3547: 
                   3548:     while (xmlIsNameChar(ctxt, c)) {
                   3549:        if (count++ > 100) {
                   3550:            count = 0;
                   3551:            GROW;
                   3552:        }
                   3553:        COPY_BUF(l,buf,len,c);
                   3554:        NEXTL(l);
                   3555:        c = CUR_CHAR(l);
                   3556:        if (len >= XML_MAX_NAMELEN) {
                   3557:            /*
                   3558:             * Okay someone managed to make a huge token, so he's ready to pay
                   3559:             * for the processing speed.
                   3560:             */
                   3561:            xmlChar *buffer;
                   3562:            int max = len * 2;
                   3563: 
                   3564:            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
                   3565:            if (buffer == NULL) {
                   3566:                xmlErrMemory(ctxt, NULL);
                   3567:                return(NULL);
                   3568:            }
                   3569:            memcpy(buffer, buf, len);
                   3570:            while (xmlIsNameChar(ctxt, c)) {
                   3571:                if (count++ > 100) {
                   3572:                    count = 0;
                   3573:                    GROW;
                   3574:                }
                   3575:                if (len + 10 > max) {
                   3576:                    xmlChar *tmp;
                   3577: 
                   3578:                    max *= 2;
                   3579:                    tmp = (xmlChar *) xmlRealloc(buffer,
                   3580:                                                    max * sizeof(xmlChar));
                   3581:                    if (tmp == NULL) {
                   3582:                        xmlErrMemory(ctxt, NULL);
                   3583:                        xmlFree(buffer);
                   3584:                        return(NULL);
                   3585:                    }
                   3586:                    buffer = tmp;
                   3587:                }
                   3588:                COPY_BUF(l,buffer,len,c);
                   3589:                NEXTL(l);
                   3590:                c = CUR_CHAR(l);
                   3591:            }
                   3592:            buffer[len] = 0;
                   3593:            return(buffer);
                   3594:        }
                   3595:     }
                   3596:     if (len == 0)
                   3597:         return(NULL);
                   3598:     return(xmlStrndup(buf, len));
                   3599: }
                   3600: 
                   3601: /**
                   3602:  * xmlParseEntityValue:
                   3603:  * @ctxt:  an XML parser context
                   3604:  * @orig:  if non-NULL store a copy of the original entity value
                   3605:  *
                   3606:  * parse a value for ENTITY declarations
                   3607:  *
                   3608:  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
                   3609:  *                    "'" ([^%&'] | PEReference | Reference)* "'"
                   3610:  *
                   3611:  * Returns the EntityValue parsed with reference substituted or NULL
                   3612:  */
                   3613: 
                   3614: xmlChar *
                   3615: xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
                   3616:     xmlChar *buf = NULL;
                   3617:     int len = 0;
                   3618:     int size = XML_PARSER_BUFFER_SIZE;
                   3619:     int c, l;
                   3620:     xmlChar stop;
                   3621:     xmlChar *ret = NULL;
                   3622:     const xmlChar *cur = NULL;
                   3623:     xmlParserInputPtr input;
                   3624: 
                   3625:     if (RAW == '"') stop = '"';
                   3626:     else if (RAW == '\'') stop = '\'';
                   3627:     else {
                   3628:        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
                   3629:        return(NULL);
                   3630:     }
                   3631:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   3632:     if (buf == NULL) {
                   3633:        xmlErrMemory(ctxt, NULL);
                   3634:        return(NULL);
                   3635:     }
                   3636: 
                   3637:     /*
                   3638:      * The content of the entity definition is copied in a buffer.
                   3639:      */
                   3640: 
                   3641:     ctxt->instate = XML_PARSER_ENTITY_VALUE;
                   3642:     input = ctxt->input;
                   3643:     GROW;
                   3644:     NEXT;
                   3645:     c = CUR_CHAR(l);
                   3646:     /*
                   3647:      * NOTE: 4.4.5 Included in Literal
                   3648:      * When a parameter entity reference appears in a literal entity
                   3649:      * value, ... a single or double quote character in the replacement
                   3650:      * text is always treated as a normal data character and will not
                   3651:      * terminate the literal. 
                   3652:      * In practice it means we stop the loop only when back at parsing
                   3653:      * the initial entity and the quote is found
                   3654:      */
                   3655:     while ((IS_CHAR(c)) && ((c != stop) || /* checked */
                   3656:           (ctxt->input != input))) {
                   3657:        if (len + 5 >= size) {
                   3658:            xmlChar *tmp;
                   3659: 
                   3660:            size *= 2;
                   3661:            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   3662:            if (tmp == NULL) {
                   3663:                xmlErrMemory(ctxt, NULL);
                   3664:                xmlFree(buf);
                   3665:                return(NULL);
                   3666:            }
                   3667:            buf = tmp;
                   3668:        }
                   3669:        COPY_BUF(l,buf,len,c);
                   3670:        NEXTL(l);
                   3671:        /*
                   3672:         * Pop-up of finished entities.
                   3673:         */
                   3674:        while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
                   3675:            xmlPopInput(ctxt);
                   3676: 
                   3677:        GROW;
                   3678:        c = CUR_CHAR(l);
                   3679:        if (c == 0) {
                   3680:            GROW;
                   3681:            c = CUR_CHAR(l);
                   3682:        }
                   3683:     }
                   3684:     buf[len] = 0;
                   3685: 
                   3686:     /*
                   3687:      * Raise problem w.r.t. '&' and '%' being used in non-entities
                   3688:      * reference constructs. Note Charref will be handled in
                   3689:      * xmlStringDecodeEntities()
                   3690:      */
                   3691:     cur = buf;
                   3692:     while (*cur != 0) { /* non input consuming */
                   3693:        if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
                   3694:            xmlChar *name;
                   3695:            xmlChar tmp = *cur;
                   3696: 
                   3697:            cur++;
                   3698:            name = xmlParseStringName(ctxt, &cur);
                   3699:             if ((name == NULL) || (*cur != ';')) {
                   3700:                xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
                   3701:            "EntityValue: '%c' forbidden except for entities references\n",
                   3702:                                  tmp);
                   3703:            }
                   3704:            if ((tmp == '%') && (ctxt->inSubset == 1) &&
                   3705:                (ctxt->inputNr == 1)) {
                   3706:                xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
                   3707:            }
                   3708:            if (name != NULL)
                   3709:                xmlFree(name);
                   3710:            if (*cur == 0)
                   3711:                break;
                   3712:        }
                   3713:        cur++;
                   3714:     }
                   3715: 
                   3716:     /*
                   3717:      * Then PEReference entities are substituted.
                   3718:      */
                   3719:     if (c != stop) {
                   3720:        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
                   3721:        xmlFree(buf);
                   3722:     } else {
                   3723:        NEXT;
                   3724:        /*
                   3725:         * NOTE: 4.4.7 Bypassed
                   3726:         * When a general entity reference appears in the EntityValue in
                   3727:         * an entity declaration, it is bypassed and left as is.
                   3728:         * so XML_SUBSTITUTE_REF is not set here.
                   3729:         */
                   3730:        ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
                   3731:                                      0, 0, 0);
                   3732:        if (orig != NULL) 
                   3733:            *orig = buf;
                   3734:        else
                   3735:            xmlFree(buf);
                   3736:     }
                   3737:     
                   3738:     return(ret);
                   3739: }
                   3740: 
                   3741: /**
                   3742:  * xmlParseAttValueComplex:
                   3743:  * @ctxt:  an XML parser context
                   3744:  * @len:   the resulting attribute len
                   3745:  * @normalize:  wether to apply the inner normalization
                   3746:  *
                   3747:  * parse a value for an attribute, this is the fallback function
                   3748:  * of xmlParseAttValue() when the attribute parsing requires handling
                   3749:  * of non-ASCII characters, or normalization compaction.
                   3750:  *
                   3751:  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
                   3752:  */
                   3753: static xmlChar *
                   3754: xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
                   3755:     xmlChar limit = 0;
                   3756:     xmlChar *buf = NULL;
                   3757:     xmlChar *rep = NULL;
                   3758:     int len = 0;
                   3759:     int buf_size = 0;
                   3760:     int c, l, in_space = 0;
                   3761:     xmlChar *current = NULL;
                   3762:     xmlEntityPtr ent;
                   3763: 
                   3764:     if (NXT(0) == '"') {
                   3765:        ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
                   3766:        limit = '"';
                   3767:         NEXT;
                   3768:     } else if (NXT(0) == '\'') {
                   3769:        limit = '\'';
                   3770:        ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
                   3771:         NEXT;
                   3772:     } else {
                   3773:        xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
                   3774:        return(NULL);
                   3775:     }
                   3776: 
                   3777:     /*
                   3778:      * allocate a translation buffer.
                   3779:      */
                   3780:     buf_size = XML_PARSER_BUFFER_SIZE;
                   3781:     buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
                   3782:     if (buf == NULL) goto mem_error;
                   3783: 
                   3784:     /*
                   3785:      * OK loop until we reach one of the ending char or a size limit.
                   3786:      */
                   3787:     c = CUR_CHAR(l);
                   3788:     while ((NXT(0) != limit) && /* checked */
                   3789:            (IS_CHAR(c)) && (c != '<')) {
                   3790:        if (c == 0) break;
                   3791:        if (c == '&') {
                   3792:            in_space = 0;
                   3793:            if (NXT(1) == '#') {
                   3794:                int val = xmlParseCharRef(ctxt);
                   3795: 
                   3796:                if (val == '&') {
                   3797:                    if (ctxt->replaceEntities) {
                   3798:                        if (len > buf_size - 10) {
                   3799:                            growBuffer(buf, 10);
                   3800:                        }
                   3801:                        buf[len++] = '&';
                   3802:                    } else {
                   3803:                        /*
                   3804:                         * The reparsing will be done in xmlStringGetNodeList()
                   3805:                         * called by the attribute() function in SAX.c
                   3806:                         */
                   3807:                        if (len > buf_size - 10) {
                   3808:                            growBuffer(buf, 10);
                   3809:                        }
                   3810:                        buf[len++] = '&';
                   3811:                        buf[len++] = '#';
                   3812:                        buf[len++] = '3';
                   3813:                        buf[len++] = '8';
                   3814:                        buf[len++] = ';';
                   3815:                    }
                   3816:                } else if (val != 0) {
                   3817:                    if (len > buf_size - 10) {
                   3818:                        growBuffer(buf, 10);
                   3819:                    }
                   3820:                    len += xmlCopyChar(0, &buf[len], val);
                   3821:                }
                   3822:            } else {
                   3823:                ent = xmlParseEntityRef(ctxt);
                   3824:                ctxt->nbentities++;
                   3825:                if (ent != NULL)
                   3826:                    ctxt->nbentities += ent->owner;
                   3827:                if ((ent != NULL) &&
                   3828:                    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
                   3829:                    if (len > buf_size - 10) {
                   3830:                        growBuffer(buf, 10);
                   3831:                    }
                   3832:                    if ((ctxt->replaceEntities == 0) &&
                   3833:                        (ent->content[0] == '&')) {
                   3834:                        buf[len++] = '&';
                   3835:                        buf[len++] = '#';
                   3836:                        buf[len++] = '3';
                   3837:                        buf[len++] = '8';
                   3838:                        buf[len++] = ';';
                   3839:                    } else {
                   3840:                        buf[len++] = ent->content[0];
                   3841:                    }
                   3842:                } else if ((ent != NULL) && 
                   3843:                           (ctxt->replaceEntities != 0)) {
                   3844:                    if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
                   3845:                        rep = xmlStringDecodeEntities(ctxt, ent->content,
                   3846:                                                      XML_SUBSTITUTE_REF,
                   3847:                                                      0, 0, 0);
                   3848:                        if (rep != NULL) {
                   3849:                            current = rep;
                   3850:                            while (*current != 0) { /* non input consuming */
                   3851:                                 if ((*current == 0xD) || (*current == 0xA) ||
                   3852:                                     (*current == 0x9)) {
                   3853:                                     buf[len++] = 0x20;
                   3854:                                     current++;
                   3855:                                 } else
                   3856:                                     buf[len++] = *current++;
                   3857:                                if (len > buf_size - 10) {
                   3858:                                    growBuffer(buf, 10);
                   3859:                                }
                   3860:                            }
                   3861:                            xmlFree(rep);
                   3862:                            rep = NULL;
                   3863:                        }
                   3864:                    } else {
                   3865:                        if (len > buf_size - 10) {
                   3866:                            growBuffer(buf, 10);
                   3867:                        }
                   3868:                        if (ent->content != NULL)
                   3869:                            buf[len++] = ent->content[0];
                   3870:                    }
                   3871:                } else if (ent != NULL) {
                   3872:                    int i = xmlStrlen(ent->name);
                   3873:                    const xmlChar *cur = ent->name;
                   3874: 
                   3875:                    /*
                   3876:                     * This may look absurd but is needed to detect
                   3877:                     * entities problems
                   3878:                     */
                   3879:                    if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
                   3880:                        (ent->content != NULL)) {
                   3881:                        rep = xmlStringDecodeEntities(ctxt, ent->content,
                   3882:                                                  XML_SUBSTITUTE_REF, 0, 0, 0);
                   3883:                        if (rep != NULL) {
                   3884:                            xmlFree(rep);
                   3885:                            rep = NULL;
                   3886:                        }
                   3887:                    }
                   3888: 
                   3889:                    /*
                   3890:                     * Just output the reference
                   3891:                     */
                   3892:                    buf[len++] = '&';
                   3893:                    while (len > buf_size - i - 10) {
                   3894:                        growBuffer(buf, i + 10);
                   3895:                    }
                   3896:                    for (;i > 0;i--)
                   3897:                        buf[len++] = *cur++;
                   3898:                    buf[len++] = ';';
                   3899:                }
                   3900:            }
                   3901:        } else {
                   3902:            if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
                   3903:                if ((len != 0) || (!normalize)) {
                   3904:                    if ((!normalize) || (!in_space)) {
                   3905:                        COPY_BUF(l,buf,len,0x20);
                   3906:                        while (len > buf_size - 10) {
                   3907:                            growBuffer(buf, 10);
                   3908:                        }
                   3909:                    }
                   3910:                    in_space = 1;
                   3911:                }
                   3912:            } else {
                   3913:                in_space = 0;
                   3914:                COPY_BUF(l,buf,len,c);
                   3915:                if (len > buf_size - 10) {
                   3916:                    growBuffer(buf, 10);
                   3917:                }
                   3918:            }
                   3919:            NEXTL(l);
                   3920:        }
                   3921:        GROW;
                   3922:        c = CUR_CHAR(l);
                   3923:     }
                   3924:     if ((in_space) && (normalize)) {
                   3925:         while (buf[len - 1] == 0x20) len--;
                   3926:     }
                   3927:     buf[len] = 0;
                   3928:     if (RAW == '<') {
                   3929:        xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
                   3930:     } else if (RAW != limit) {
                   3931:        if ((c != 0) && (!IS_CHAR(c))) {
                   3932:            xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
                   3933:                           "invalid character in attribute value\n");
                   3934:        } else {
                   3935:            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
                   3936:                           "AttValue: ' expected\n");
                   3937:         }
                   3938:     } else
                   3939:        NEXT;
                   3940:     if (attlen != NULL) *attlen = len;
                   3941:     return(buf);
                   3942: 
                   3943: mem_error:
                   3944:     xmlErrMemory(ctxt, NULL);
                   3945:     if (buf != NULL)
                   3946:         xmlFree(buf);
                   3947:     if (rep != NULL)
                   3948:         xmlFree(rep);
                   3949:     return(NULL);
                   3950: }
                   3951: 
                   3952: /**
                   3953:  * xmlParseAttValue:
                   3954:  * @ctxt:  an XML parser context
                   3955:  *
                   3956:  * parse a value for an attribute
                   3957:  * Note: the parser won't do substitution of entities here, this
                   3958:  * will be handled later in xmlStringGetNodeList
                   3959:  *
                   3960:  * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
                   3961:  *                   "'" ([^<&'] | Reference)* "'"
                   3962:  *
                   3963:  * 3.3.3 Attribute-Value Normalization:
                   3964:  * Before the value of an attribute is passed to the application or
                   3965:  * checked for validity, the XML processor must normalize it as follows: 
                   3966:  * - a character reference is processed by appending the referenced
                   3967:  *   character to the attribute value
                   3968:  * - an entity reference is processed by recursively processing the
                   3969:  *   replacement text of the entity 
                   3970:  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
                   3971:  *   appending #x20 to the normalized value, except that only a single
                   3972:  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
                   3973:  *   parsed entity or the literal entity value of an internal parsed entity 
                   3974:  * - other characters are processed by appending them to the normalized value 
                   3975:  * If the declared value is not CDATA, then the XML processor must further
                   3976:  * process the normalized attribute value by discarding any leading and
                   3977:  * trailing space (#x20) characters, and by replacing sequences of space
                   3978:  * (#x20) characters by a single space (#x20) character.  
                   3979:  * All attributes for which no declaration has been read should be treated
                   3980:  * by a non-validating parser as if declared CDATA.
                   3981:  *
                   3982:  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
                   3983:  */
                   3984: 
                   3985: 
                   3986: xmlChar *
                   3987: xmlParseAttValue(xmlParserCtxtPtr ctxt) {
                   3988:     if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
                   3989:     return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
                   3990: }
                   3991: 
                   3992: /**
                   3993:  * xmlParseSystemLiteral:
                   3994:  * @ctxt:  an XML parser context
                   3995:  * 
                   3996:  * parse an XML Literal
                   3997:  *
                   3998:  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
                   3999:  *
                   4000:  * Returns the SystemLiteral parsed or NULL
                   4001:  */
                   4002: 
                   4003: xmlChar *
                   4004: xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
                   4005:     xmlChar *buf = NULL;
                   4006:     int len = 0;
                   4007:     int size = XML_PARSER_BUFFER_SIZE;
                   4008:     int cur, l;
                   4009:     xmlChar stop;
                   4010:     int state = ctxt->instate;
                   4011:     int count = 0;
                   4012: 
                   4013:     SHRINK;
                   4014:     if (RAW == '"') {
                   4015:         NEXT;
                   4016:        stop = '"';
                   4017:     } else if (RAW == '\'') {
                   4018:         NEXT;
                   4019:        stop = '\'';
                   4020:     } else {
                   4021:        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
                   4022:        return(NULL);
                   4023:     }
                   4024:     
                   4025:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   4026:     if (buf == NULL) {
                   4027:         xmlErrMemory(ctxt, NULL);
                   4028:        return(NULL);
                   4029:     }
                   4030:     ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
                   4031:     cur = CUR_CHAR(l);
                   4032:     while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
                   4033:        if (len + 5 >= size) {
                   4034:            xmlChar *tmp;
                   4035: 
                   4036:            size *= 2;
                   4037:            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   4038:            if (tmp == NULL) {
                   4039:                xmlFree(buf);
                   4040:                xmlErrMemory(ctxt, NULL);
                   4041:                ctxt->instate = (xmlParserInputState) state;
                   4042:                return(NULL);
                   4043:            }
                   4044:            buf = tmp;
                   4045:        }
                   4046:        count++;
                   4047:        if (count > 50) {
                   4048:            GROW;
                   4049:            count = 0;
                   4050:        }
                   4051:        COPY_BUF(l,buf,len,cur);
                   4052:        NEXTL(l);
                   4053:        cur = CUR_CHAR(l);
                   4054:        if (cur == 0) {
                   4055:            GROW;
                   4056:            SHRINK;
                   4057:            cur = CUR_CHAR(l);
                   4058:        }
                   4059:     }
                   4060:     buf[len] = 0;
                   4061:     ctxt->instate = (xmlParserInputState) state;
                   4062:     if (!IS_CHAR(cur)) {
                   4063:        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
                   4064:     } else {
                   4065:        NEXT;
                   4066:     }
                   4067:     return(buf);
                   4068: }
                   4069: 
                   4070: /**
                   4071:  * xmlParsePubidLiteral:
                   4072:  * @ctxt:  an XML parser context
                   4073:  *
                   4074:  * parse an XML public literal
                   4075:  *
                   4076:  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
                   4077:  *
                   4078:  * Returns the PubidLiteral parsed or NULL.
                   4079:  */
                   4080: 
                   4081: xmlChar *
                   4082: xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
                   4083:     xmlChar *buf = NULL;
                   4084:     int len = 0;
                   4085:     int size = XML_PARSER_BUFFER_SIZE;
                   4086:     xmlChar cur;
                   4087:     xmlChar stop;
                   4088:     int count = 0;
                   4089:     xmlParserInputState oldstate = ctxt->instate;
                   4090: 
                   4091:     SHRINK;
                   4092:     if (RAW == '"') {
                   4093:         NEXT;
                   4094:        stop = '"';
                   4095:     } else if (RAW == '\'') {
                   4096:         NEXT;
                   4097:        stop = '\'';
                   4098:     } else {
                   4099:        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
                   4100:        return(NULL);
                   4101:     }
                   4102:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   4103:     if (buf == NULL) {
                   4104:        xmlErrMemory(ctxt, NULL);
                   4105:        return(NULL);
                   4106:     }
                   4107:     ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
                   4108:     cur = CUR;
                   4109:     while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
                   4110:        if (len + 1 >= size) {
                   4111:            xmlChar *tmp;
                   4112: 
                   4113:            size *= 2;
                   4114:            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   4115:            if (tmp == NULL) {
                   4116:                xmlErrMemory(ctxt, NULL);
                   4117:                xmlFree(buf);
                   4118:                return(NULL);
                   4119:            }
                   4120:            buf = tmp;
                   4121:        }
                   4122:        buf[len++] = cur;
                   4123:        count++;
                   4124:        if (count > 50) {
                   4125:            GROW;
                   4126:            count = 0;
                   4127:        }
                   4128:        NEXT;
                   4129:        cur = CUR;
                   4130:        if (cur == 0) {
                   4131:            GROW;
                   4132:            SHRINK;
                   4133:            cur = CUR;
                   4134:        }
                   4135:     }
                   4136:     buf[len] = 0;
                   4137:     if (cur != stop) {
                   4138:        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
                   4139:     } else {
                   4140:        NEXT;
                   4141:     }
                   4142:     ctxt->instate = oldstate;
                   4143:     return(buf);
                   4144: }
                   4145: 
                   4146: static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
                   4147: 
                   4148: /*
                   4149:  * used for the test in the inner loop of the char data testing
                   4150:  */
                   4151: static const unsigned char test_char_data[256] = {
                   4152:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4153:     0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
                   4154:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4155:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4156:     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
                   4157:     0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
                   4158:     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
                   4159:     0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
                   4160:     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
                   4161:     0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
                   4162:     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
                   4163:     0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
                   4164:     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
                   4165:     0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
                   4166:     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
                   4167:     0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
                   4168:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
                   4169:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4170:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4171:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4172:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4173:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4174:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4175:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4176:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   4177:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                   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: };
                   4185: 
                   4186: /**
                   4187:  * xmlParseCharData:
                   4188:  * @ctxt:  an XML parser context
                   4189:  * @cdata:  int indicating whether we are within a CDATA section
                   4190:  *
                   4191:  * parse a CharData section.
                   4192:  * if we are within a CDATA section ']]>' marks an end of section.
                   4193:  *
                   4194:  * The right angle bracket (>) may be represented using the string "&gt;",
                   4195:  * and must, for compatibility, be escaped using "&gt;" or a character
                   4196:  * reference when it appears in the string "]]>" in content, when that
                   4197:  * string is not marking the end of a CDATA section. 
                   4198:  *
                   4199:  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
                   4200:  */
                   4201: 
                   4202: void
                   4203: xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
                   4204:     const xmlChar *in;
                   4205:     int nbchar = 0;
                   4206:     int line = ctxt->input->line;
                   4207:     int col = ctxt->input->col;
                   4208:     int ccol;
                   4209: 
                   4210:     SHRINK;
                   4211:     GROW;
                   4212:     /*
                   4213:      * Accelerated common case where input don't need to be
                   4214:      * modified before passing it to the handler.
                   4215:      */
                   4216:     if (!cdata) {
                   4217:        in = ctxt->input->cur;
                   4218:        do {
                   4219: get_more_space:
                   4220:            while (*in == 0x20) { in++; ctxt->input->col++; }
                   4221:            if (*in == 0xA) {
                   4222:                do {
                   4223:                    ctxt->input->line++; ctxt->input->col = 1;
                   4224:                    in++;
                   4225:                } while (*in == 0xA);
                   4226:                goto get_more_space;
                   4227:            }
                   4228:            if (*in == '<') {
                   4229:                nbchar = in - ctxt->input->cur;
                   4230:                if (nbchar > 0) {
                   4231:                    const xmlChar *tmp = ctxt->input->cur;
                   4232:                    ctxt->input->cur = in;
                   4233: 
                   4234:                    if ((ctxt->sax != NULL) &&
                   4235:                        (ctxt->sax->ignorableWhitespace !=
                   4236:                         ctxt->sax->characters)) {
                   4237:                        if (areBlanks(ctxt, tmp, nbchar, 1)) {
                   4238:                            if (ctxt->sax->ignorableWhitespace != NULL)
                   4239:                                ctxt->sax->ignorableWhitespace(ctxt->userData,
                   4240:                                                       tmp, nbchar);
                   4241:                        } else {
                   4242:                            if (ctxt->sax->characters != NULL)
                   4243:                                ctxt->sax->characters(ctxt->userData,
                   4244:                                                      tmp, nbchar);
                   4245:                            if (*ctxt->space == -1)
                   4246:                                *ctxt->space = -2;
                   4247:                        }
                   4248:                    } else if ((ctxt->sax != NULL) &&
                   4249:                               (ctxt->sax->characters != NULL)) {
                   4250:                        ctxt->sax->characters(ctxt->userData,
                   4251:                                              tmp, nbchar);
                   4252:                    }
                   4253:                }
                   4254:                return;
                   4255:            }
                   4256: 
                   4257: get_more:
                   4258:             ccol = ctxt->input->col;
                   4259:            while (test_char_data[*in]) {
                   4260:                in++;
                   4261:                ccol++;
                   4262:            }
                   4263:            ctxt->input->col = ccol;
                   4264:            if (*in == 0xA) {
                   4265:                do {
                   4266:                    ctxt->input->line++; ctxt->input->col = 1;
                   4267:                    in++;
                   4268:                } while (*in == 0xA);
                   4269:                goto get_more;
                   4270:            }
                   4271:            if (*in == ']') {
                   4272:                if ((in[1] == ']') && (in[2] == '>')) {
                   4273:                    xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
                   4274:                    ctxt->input->cur = in;
                   4275:                    return;
                   4276:                }
                   4277:                in++;
                   4278:                ctxt->input->col++;
                   4279:                goto get_more;
                   4280:            }
                   4281:            nbchar = in - ctxt->input->cur;
                   4282:            if (nbchar > 0) {
                   4283:                if ((ctxt->sax != NULL) &&
                   4284:                    (ctxt->sax->ignorableWhitespace !=
                   4285:                     ctxt->sax->characters) &&
                   4286:                    (IS_BLANK_CH(*ctxt->input->cur))) {
                   4287:                    const xmlChar *tmp = ctxt->input->cur;
                   4288:                    ctxt->input->cur = in;
                   4289: 
                   4290:                    if (areBlanks(ctxt, tmp, nbchar, 0)) {
                   4291:                        if (ctxt->sax->ignorableWhitespace != NULL)
                   4292:                            ctxt->sax->ignorableWhitespace(ctxt->userData,
                   4293:                                                           tmp, nbchar);
                   4294:                    } else {
                   4295:                        if (ctxt->sax->characters != NULL)
                   4296:                            ctxt->sax->characters(ctxt->userData,
                   4297:                                                  tmp, nbchar);
                   4298:                        if (*ctxt->space == -1)
                   4299:                            *ctxt->space = -2;
                   4300:                    }
                   4301:                     line = ctxt->input->line;
                   4302:                     col = ctxt->input->col;
                   4303:                } else if (ctxt->sax != NULL) {
                   4304:                    if (ctxt->sax->characters != NULL)
                   4305:                        ctxt->sax->characters(ctxt->userData,
                   4306:                                              ctxt->input->cur, nbchar);
                   4307:                     line = ctxt->input->line;
                   4308:                     col = ctxt->input->col;
                   4309:                }
                   4310:                 /* something really bad happened in the SAX callback */
                   4311:                 if (ctxt->instate != XML_PARSER_CONTENT)
                   4312:                     return;
                   4313:            }
                   4314:            ctxt->input->cur = in;
                   4315:            if (*in == 0xD) {
                   4316:                in++;
                   4317:                if (*in == 0xA) {
                   4318:                    ctxt->input->cur = in;
                   4319:                    in++;
                   4320:                    ctxt->input->line++; ctxt->input->col = 1;
                   4321:                    continue; /* while */
                   4322:                }
                   4323:                in--;
                   4324:            }
                   4325:            if (*in == '<') {
                   4326:                return;
                   4327:            }
                   4328:            if (*in == '&') {
                   4329:                return;
                   4330:            }
                   4331:            SHRINK;
                   4332:            GROW;
                   4333:            in = ctxt->input->cur;
                   4334:        } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
                   4335:        nbchar = 0;
                   4336:     }
                   4337:     ctxt->input->line = line;
                   4338:     ctxt->input->col = col;
                   4339:     xmlParseCharDataComplex(ctxt, cdata);
                   4340: }
                   4341: 
                   4342: /**
                   4343:  * xmlParseCharDataComplex:
                   4344:  * @ctxt:  an XML parser context
                   4345:  * @cdata:  int indicating whether we are within a CDATA section
                   4346:  *
                   4347:  * parse a CharData section.this is the fallback function
                   4348:  * of xmlParseCharData() when the parsing requires handling
                   4349:  * of non-ASCII characters.
                   4350:  */
                   4351: static void
                   4352: xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
                   4353:     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
                   4354:     int nbchar = 0;
                   4355:     int cur, l;
                   4356:     int count = 0;
                   4357: 
                   4358:     SHRINK;
                   4359:     GROW;
                   4360:     cur = CUR_CHAR(l);
                   4361:     while ((cur != '<') && /* checked */
                   4362:            (cur != '&') && 
                   4363:           (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
                   4364:        if ((cur == ']') && (NXT(1) == ']') &&
                   4365:            (NXT(2) == '>')) {
                   4366:            if (cdata) break;
                   4367:            else {
                   4368:                xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
                   4369:            }
                   4370:        }
                   4371:        COPY_BUF(l,buf,nbchar,cur);
                   4372:        if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
                   4373:            buf[nbchar] = 0;
                   4374: 
                   4375:            /*
                   4376:             * OK the segment is to be consumed as chars.
                   4377:             */
                   4378:            if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
                   4379:                if (areBlanks(ctxt, buf, nbchar, 0)) {
                   4380:                    if (ctxt->sax->ignorableWhitespace != NULL)
                   4381:                        ctxt->sax->ignorableWhitespace(ctxt->userData,
                   4382:                                                       buf, nbchar);
                   4383:                } else {
                   4384:                    if (ctxt->sax->characters != NULL)
                   4385:                        ctxt->sax->characters(ctxt->userData, buf, nbchar);
                   4386:                    if ((ctxt->sax->characters !=
                   4387:                         ctxt->sax->ignorableWhitespace) &&
                   4388:                        (*ctxt->space == -1))
                   4389:                        *ctxt->space = -2;
                   4390:                }
                   4391:            }
                   4392:            nbchar = 0;
                   4393:             /* something really bad happened in the SAX callback */
                   4394:             if (ctxt->instate != XML_PARSER_CONTENT)
                   4395:                 return;
                   4396:        }
                   4397:        count++;
                   4398:        if (count > 50) {
                   4399:            GROW;
                   4400:            count = 0;
                   4401:        }
                   4402:        NEXTL(l);
                   4403:        cur = CUR_CHAR(l);
                   4404:     }
                   4405:     if (nbchar != 0) {
                   4406:         buf[nbchar] = 0;
                   4407:        /*
                   4408:         * OK the segment is to be consumed as chars.
                   4409:         */
                   4410:        if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
                   4411:            if (areBlanks(ctxt, buf, nbchar, 0)) {
                   4412:                if (ctxt->sax->ignorableWhitespace != NULL)
                   4413:                    ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
                   4414:            } else {
                   4415:                if (ctxt->sax->characters != NULL)
                   4416:                    ctxt->sax->characters(ctxt->userData, buf, nbchar);
                   4417:                if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
                   4418:                    (*ctxt->space == -1))
                   4419:                    *ctxt->space = -2;
                   4420:            }
                   4421:        }
                   4422:     }
                   4423:     if ((cur != 0) && (!IS_CHAR(cur))) {
                   4424:        /* Generate the error and skip the offending character */
                   4425:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   4426:                           "PCDATA invalid Char value %d\n",
                   4427:                          cur);
                   4428:        NEXTL(l);
                   4429:     }
                   4430: }
                   4431: 
                   4432: /**
                   4433:  * xmlParseExternalID:
                   4434:  * @ctxt:  an XML parser context
                   4435:  * @publicID:  a xmlChar** receiving PubidLiteral
                   4436:  * @strict: indicate whether we should restrict parsing to only
                   4437:  *          production [75], see NOTE below
                   4438:  *
                   4439:  * Parse an External ID or a Public ID
                   4440:  *
                   4441:  * NOTE: Productions [75] and [83] interact badly since [75] can generate
                   4442:  *       'PUBLIC' S PubidLiteral S SystemLiteral
                   4443:  *
                   4444:  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
                   4445:  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
                   4446:  *
                   4447:  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
                   4448:  *
                   4449:  * Returns the function returns SystemLiteral and in the second
                   4450:  *                case publicID receives PubidLiteral, is strict is off
                   4451:  *                it is possible to return NULL and have publicID set.
                   4452:  */
                   4453: 
                   4454: xmlChar *
                   4455: xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
                   4456:     xmlChar *URI = NULL;
                   4457: 
                   4458:     SHRINK;
                   4459: 
                   4460:     *publicID = NULL;
                   4461:     if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
                   4462:         SKIP(6);
                   4463:        if (!IS_BLANK_CH(CUR)) {
                   4464:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   4465:                           "Space required after 'SYSTEM'\n");
                   4466:        }
                   4467:         SKIP_BLANKS;
                   4468:        URI = xmlParseSystemLiteral(ctxt);
                   4469:        if (URI == NULL) {
                   4470:            xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
                   4471:         }
                   4472:     } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
                   4473:         SKIP(6);
                   4474:        if (!IS_BLANK_CH(CUR)) {
                   4475:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   4476:                    "Space required after 'PUBLIC'\n");
                   4477:        }
                   4478:         SKIP_BLANKS;
                   4479:        *publicID = xmlParsePubidLiteral(ctxt);
                   4480:        if (*publicID == NULL) {
                   4481:            xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
                   4482:        }
                   4483:        if (strict) {
                   4484:            /*
                   4485:             * We don't handle [83] so "S SystemLiteral" is required.
                   4486:             */
                   4487:            if (!IS_BLANK_CH(CUR)) {
                   4488:                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   4489:                        "Space required after the Public Identifier\n");
                   4490:            }
                   4491:        } else {
                   4492:            /*
                   4493:             * We handle [83] so we return immediately, if 
                   4494:             * "S SystemLiteral" is not detected. From a purely parsing
                   4495:             * point of view that's a nice mess.
                   4496:             */
                   4497:            const xmlChar *ptr;
                   4498:            GROW;
                   4499: 
                   4500:            ptr = CUR_PTR;
                   4501:            if (!IS_BLANK_CH(*ptr)) return(NULL);
                   4502:            
                   4503:            while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
                   4504:            if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
                   4505:        }
                   4506:         SKIP_BLANKS;
                   4507:        URI = xmlParseSystemLiteral(ctxt);
                   4508:        if (URI == NULL) {
                   4509:            xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
                   4510:         }
                   4511:     }
                   4512:     return(URI);
                   4513: }
                   4514: 
                   4515: /**
                   4516:  * xmlParseCommentComplex:
                   4517:  * @ctxt:  an XML parser context
                   4518:  * @buf:  the already parsed part of the buffer
                   4519:  * @len:  number of bytes filles in the buffer
                   4520:  * @size:  allocated size of the buffer
                   4521:  *
                   4522:  * Skip an XML (SGML) comment <!-- .... -->
                   4523:  *  The spec says that "For compatibility, the string "--" (double-hyphen)
                   4524:  *  must not occur within comments. "
                   4525:  * This is the slow routine in case the accelerator for ascii didn't work
                   4526:  *
                   4527:  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
                   4528:  */
                   4529: static void
                   4530: xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, int len, int size) {
                   4531:     int q, ql;
                   4532:     int r, rl;
                   4533:     int cur, l;
                   4534:     int count = 0;
                   4535:     int inputid;
                   4536: 
                   4537:     inputid = ctxt->input->id;
                   4538: 
                   4539:     if (buf == NULL) {
                   4540:         len = 0;
                   4541:        size = XML_PARSER_BUFFER_SIZE;
                   4542:        buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   4543:        if (buf == NULL) {
                   4544:            xmlErrMemory(ctxt, NULL);
                   4545:            return;
                   4546:        }
                   4547:     }
                   4548:     GROW;      /* Assure there's enough input data */
                   4549:     q = CUR_CHAR(ql);
                   4550:     if (q == 0)
                   4551:         goto not_terminated;
                   4552:     if (!IS_CHAR(q)) {
                   4553:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   4554:                           "xmlParseComment: invalid xmlChar value %d\n",
                   4555:                          q);
                   4556:        xmlFree (buf);
                   4557:        return;
                   4558:     }
                   4559:     NEXTL(ql);
                   4560:     r = CUR_CHAR(rl);
                   4561:     if (r == 0)
                   4562:         goto not_terminated;
                   4563:     if (!IS_CHAR(r)) {
                   4564:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   4565:                           "xmlParseComment: invalid xmlChar value %d\n",
                   4566:                          q);
                   4567:        xmlFree (buf);
                   4568:        return;
                   4569:     }
                   4570:     NEXTL(rl);
                   4571:     cur = CUR_CHAR(l);
                   4572:     if (cur == 0)
                   4573:         goto not_terminated;
                   4574:     while (IS_CHAR(cur) && /* checked */
                   4575:            ((cur != '>') ||
                   4576:            (r != '-') || (q != '-'))) {
                   4577:        if ((r == '-') && (q == '-')) {
                   4578:            xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
                   4579:        }
                   4580:        if (len + 5 >= size) {
                   4581:            xmlChar *new_buf;
                   4582:            size *= 2;
                   4583:            new_buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   4584:            if (new_buf == NULL) {
                   4585:                xmlFree (buf);
                   4586:                xmlErrMemory(ctxt, NULL);
                   4587:                return;
                   4588:            }
                   4589:            buf = new_buf;
                   4590:        }
                   4591:        COPY_BUF(ql,buf,len,q);
                   4592:        q = r;
                   4593:        ql = rl;
                   4594:        r = cur;
                   4595:        rl = l;
                   4596: 
                   4597:        count++;
                   4598:        if (count > 50) {
                   4599:            GROW;
                   4600:            count = 0;
                   4601:        }
                   4602:        NEXTL(l);
                   4603:        cur = CUR_CHAR(l);
                   4604:        if (cur == 0) {
                   4605:            SHRINK;
                   4606:            GROW;
                   4607:            cur = CUR_CHAR(l);
                   4608:        }
                   4609:     }
                   4610:     buf[len] = 0;
                   4611:     if (cur == 0) {
                   4612:        xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
                   4613:                             "Comment not terminated \n<!--%.50s\n", buf);
                   4614:     } else if (!IS_CHAR(cur)) {
                   4615:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   4616:                           "xmlParseComment: invalid xmlChar value %d\n",
                   4617:                          cur);
                   4618:     } else {
                   4619:        if (inputid != ctxt->input->id) {
                   4620:            xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   4621:                "Comment doesn't start and stop in the same entity\n");
                   4622:        }
                   4623:         NEXT;
                   4624:        if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
                   4625:            (!ctxt->disableSAX))
                   4626:            ctxt->sax->comment(ctxt->userData, buf);
                   4627:     }
                   4628:     xmlFree(buf);
                   4629:     return;
                   4630: not_terminated:
                   4631:     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
                   4632:                         "Comment not terminated\n", NULL);
                   4633:     xmlFree(buf);
                   4634:     return;
                   4635: }
                   4636: 
                   4637: /**
                   4638:  * xmlParseComment:
                   4639:  * @ctxt:  an XML parser context
                   4640:  *
                   4641:  * Skip an XML (SGML) comment <!-- .... -->
                   4642:  *  The spec says that "For compatibility, the string "--" (double-hyphen)
                   4643:  *  must not occur within comments. "
                   4644:  *
                   4645:  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
                   4646:  */
                   4647: void
                   4648: xmlParseComment(xmlParserCtxtPtr ctxt) {
                   4649:     xmlChar *buf = NULL;
                   4650:     int size = XML_PARSER_BUFFER_SIZE;
                   4651:     int len = 0;
                   4652:     xmlParserInputState state;
                   4653:     const xmlChar *in;
                   4654:     int nbchar = 0, ccol;
                   4655:     int inputid;
                   4656: 
                   4657:     /*
                   4658:      * Check that there is a comment right here.
                   4659:      */
                   4660:     if ((RAW != '<') || (NXT(1) != '!') ||
                   4661:         (NXT(2) != '-') || (NXT(3) != '-')) return;
                   4662:     state = ctxt->instate;
                   4663:     ctxt->instate = XML_PARSER_COMMENT;
                   4664:     inputid = ctxt->input->id;
                   4665:     SKIP(4);
                   4666:     SHRINK;
                   4667:     GROW;
                   4668: 
                   4669:     /*
                   4670:      * Accelerated common case where input don't need to be
                   4671:      * modified before passing it to the handler.
                   4672:      */
                   4673:     in = ctxt->input->cur;
                   4674:     do {
                   4675:        if (*in == 0xA) {
                   4676:            do {
                   4677:                ctxt->input->line++; ctxt->input->col = 1;
                   4678:                in++;
                   4679:            } while (*in == 0xA);
                   4680:        }
                   4681: get_more:
                   4682:         ccol = ctxt->input->col;
                   4683:        while (((*in > '-') && (*in <= 0x7F)) ||
                   4684:               ((*in >= 0x20) && (*in < '-')) ||
                   4685:               (*in == 0x09)) {
                   4686:                    in++;
                   4687:                    ccol++;
                   4688:        }
                   4689:        ctxt->input->col = ccol;
                   4690:        if (*in == 0xA) {
                   4691:            do {
                   4692:                ctxt->input->line++; ctxt->input->col = 1;
                   4693:                in++;
                   4694:            } while (*in == 0xA);
                   4695:            goto get_more;
                   4696:        }
                   4697:        nbchar = in - ctxt->input->cur;
                   4698:        /*
                   4699:         * save current set of data
                   4700:         */
                   4701:        if (nbchar > 0) {
                   4702:            if ((ctxt->sax != NULL) &&
                   4703:                (ctxt->sax->comment != NULL)) {
                   4704:                if (buf == NULL) {
                   4705:                    if ((*in == '-') && (in[1] == '-'))
                   4706:                        size = nbchar + 1;
                   4707:                    else
                   4708:                        size = XML_PARSER_BUFFER_SIZE + nbchar;
                   4709:                    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   4710:                    if (buf == NULL) {
                   4711:                        xmlErrMemory(ctxt, NULL);
                   4712:                        ctxt->instate = state;
                   4713:                        return;
                   4714:                    }
                   4715:                    len = 0;
                   4716:                } else if (len + nbchar + 1 >= size) {
                   4717:                    xmlChar *new_buf;
                   4718:                    size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
                   4719:                    new_buf = (xmlChar *) xmlRealloc(buf,
                   4720:                                                     size * sizeof(xmlChar));
                   4721:                    if (new_buf == NULL) {
                   4722:                        xmlFree (buf);
                   4723:                        xmlErrMemory(ctxt, NULL);
                   4724:                        ctxt->instate = state;
                   4725:                        return;
                   4726:                    }
                   4727:                    buf = new_buf;
                   4728:                }
                   4729:                memcpy(&buf[len], ctxt->input->cur, nbchar);
                   4730:                len += nbchar;
                   4731:                buf[len] = 0;
                   4732:            }
                   4733:        }
                   4734:        ctxt->input->cur = in;
                   4735:        if (*in == 0xA) {
                   4736:            in++;
                   4737:            ctxt->input->line++; ctxt->input->col = 1;
                   4738:        }
                   4739:        if (*in == 0xD) {
                   4740:            in++;
                   4741:            if (*in == 0xA) {
                   4742:                ctxt->input->cur = in;
                   4743:                in++;
                   4744:                ctxt->input->line++; ctxt->input->col = 1;
                   4745:                continue; /* while */
                   4746:            }
                   4747:            in--;
                   4748:        }
                   4749:        SHRINK;
                   4750:        GROW;
                   4751:        in = ctxt->input->cur;
                   4752:        if (*in == '-') {
                   4753:            if (in[1] == '-') {
                   4754:                if (in[2] == '>') {
                   4755:                    if (ctxt->input->id != inputid) {
                   4756:                        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   4757:                        "comment doesn't start and stop in the same entity\n");
                   4758:                    }
                   4759:                    SKIP(3);
                   4760:                    if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
                   4761:                        (!ctxt->disableSAX)) {
                   4762:                        if (buf != NULL)
                   4763:                            ctxt->sax->comment(ctxt->userData, buf);
                   4764:                        else
                   4765:                            ctxt->sax->comment(ctxt->userData, BAD_CAST "");
                   4766:                    }
                   4767:                    if (buf != NULL)
                   4768:                        xmlFree(buf);
                   4769:                    ctxt->instate = state;
                   4770:                    return;
                   4771:                }
                   4772:                if (buf != NULL)
                   4773:                    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
                   4774:                                      "Comment not terminated \n<!--%.50s\n",
                   4775:                                      buf);
                   4776:                else
                   4777:                    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
                   4778:                                      "Comment not terminated \n", NULL);
                   4779:                in++;
                   4780:                ctxt->input->col++;
                   4781:            }
                   4782:            in++;
                   4783:            ctxt->input->col++;
                   4784:            goto get_more;
                   4785:        }
                   4786:     } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
                   4787:     xmlParseCommentComplex(ctxt, buf, len, size);
                   4788:     ctxt->instate = state;
                   4789:     return;
                   4790: }
                   4791: 
                   4792: 
                   4793: /**
                   4794:  * xmlParsePITarget:
                   4795:  * @ctxt:  an XML parser context
                   4796:  * 
                   4797:  * parse the name of a PI
                   4798:  *
                   4799:  * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
                   4800:  *
                   4801:  * Returns the PITarget name or NULL
                   4802:  */
                   4803: 
                   4804: const xmlChar *
                   4805: xmlParsePITarget(xmlParserCtxtPtr ctxt) {
                   4806:     const xmlChar *name;
                   4807: 
                   4808:     name = xmlParseName(ctxt);
                   4809:     if ((name != NULL) &&
                   4810:         ((name[0] == 'x') || (name[0] == 'X')) &&
                   4811:         ((name[1] == 'm') || (name[1] == 'M')) &&
                   4812:         ((name[2] == 'l') || (name[2] == 'L'))) {
                   4813:        int i;
                   4814:        if ((name[0] == 'x') && (name[1] == 'm') &&
                   4815:            (name[2] == 'l') && (name[3] == 0)) {
                   4816:            xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
                   4817:                 "XML declaration allowed only at the start of the document\n");
                   4818:            return(name);
                   4819:        } else if (name[3] == 0) {
                   4820:            xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
                   4821:            return(name);
                   4822:        }
                   4823:        for (i = 0;;i++) {
                   4824:            if (xmlW3CPIs[i] == NULL) break;
                   4825:            if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
                   4826:                return(name);
                   4827:        }
                   4828:        xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
                   4829:                      "xmlParsePITarget: invalid name prefix 'xml'\n",
                   4830:                      NULL, NULL);
                   4831:     }
                   4832:     if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
                   4833:        xmlNsErr(ctxt, XML_NS_ERR_COLON, 
                   4834:                 "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
                   4835:     }
                   4836:     return(name);
                   4837: }
                   4838: 
                   4839: #ifdef LIBXML_CATALOG_ENABLED
                   4840: /**
                   4841:  * xmlParseCatalogPI:
                   4842:  * @ctxt:  an XML parser context
                   4843:  * @catalog:  the PI value string
                   4844:  * 
                   4845:  * parse an XML Catalog Processing Instruction.
                   4846:  *
                   4847:  * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
                   4848:  *
                   4849:  * Occurs only if allowed by the user and if happening in the Misc
                   4850:  * part of the document before any doctype informations
                   4851:  * This will add the given catalog to the parsing context in order
                   4852:  * to be used if there is a resolution need further down in the document
                   4853:  */
                   4854: 
                   4855: static void
                   4856: xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
                   4857:     xmlChar *URL = NULL;
                   4858:     const xmlChar *tmp, *base;
                   4859:     xmlChar marker;
                   4860: 
                   4861:     tmp = catalog;
                   4862:     while (IS_BLANK_CH(*tmp)) tmp++;
                   4863:     if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
                   4864:        goto error;
                   4865:     tmp += 7;
                   4866:     while (IS_BLANK_CH(*tmp)) tmp++;
                   4867:     if (*tmp != '=') {
                   4868:        return;
                   4869:     }
                   4870:     tmp++;
                   4871:     while (IS_BLANK_CH(*tmp)) tmp++;
                   4872:     marker = *tmp;
                   4873:     if ((marker != '\'') && (marker != '"'))
                   4874:        goto error;
                   4875:     tmp++;
                   4876:     base = tmp;
                   4877:     while ((*tmp != 0) && (*tmp != marker)) tmp++;
                   4878:     if (*tmp == 0)
                   4879:        goto error;
                   4880:     URL = xmlStrndup(base, tmp - base);
                   4881:     tmp++;
                   4882:     while (IS_BLANK_CH(*tmp)) tmp++;
                   4883:     if (*tmp != 0)
                   4884:        goto error;
                   4885: 
                   4886:     if (URL != NULL) {
                   4887:        ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
                   4888:        xmlFree(URL);
                   4889:     }
                   4890:     return;
                   4891: 
                   4892: error:
                   4893:     xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
                   4894:                  "Catalog PI syntax error: %s\n",
                   4895:                  catalog, NULL);
                   4896:     if (URL != NULL)
                   4897:        xmlFree(URL);
                   4898: }
                   4899: #endif
                   4900: 
                   4901: /**
                   4902:  * xmlParsePI:
                   4903:  * @ctxt:  an XML parser context
                   4904:  * 
                   4905:  * parse an XML Processing Instruction.
                   4906:  *
                   4907:  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
                   4908:  *
                   4909:  * The processing is transfered to SAX once parsed.
                   4910:  */
                   4911: 
                   4912: void
                   4913: xmlParsePI(xmlParserCtxtPtr ctxt) {
                   4914:     xmlChar *buf = NULL;
                   4915:     int len = 0;
                   4916:     int size = XML_PARSER_BUFFER_SIZE;
                   4917:     int cur, l;
                   4918:     const xmlChar *target;
                   4919:     xmlParserInputState state;
                   4920:     int count = 0;
                   4921: 
                   4922:     if ((RAW == '<') && (NXT(1) == '?')) {
                   4923:        xmlParserInputPtr input = ctxt->input;
                   4924:        state = ctxt->instate;
                   4925:         ctxt->instate = XML_PARSER_PI;
                   4926:        /*
                   4927:         * this is a Processing Instruction.
                   4928:         */
                   4929:        SKIP(2);
                   4930:        SHRINK;
                   4931: 
                   4932:        /*
                   4933:         * Parse the target name and check for special support like
                   4934:         * namespace.
                   4935:         */
                   4936:         target = xmlParsePITarget(ctxt);
                   4937:        if (target != NULL) {
                   4938:            if ((RAW == '?') && (NXT(1) == '>')) {
                   4939:                if (input != ctxt->input) {
                   4940:                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   4941:            "PI declaration doesn't start and stop in the same entity\n");
                   4942:                }
                   4943:                SKIP(2);
                   4944: 
                   4945:                /*
                   4946:                 * SAX: PI detected.
                   4947:                 */
                   4948:                if ((ctxt->sax) && (!ctxt->disableSAX) &&
                   4949:                    (ctxt->sax->processingInstruction != NULL))
                   4950:                    ctxt->sax->processingInstruction(ctxt->userData,
                   4951:                                                     target, NULL);
                   4952:                ctxt->instate = state;
                   4953:                return;
                   4954:            }
                   4955:            buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   4956:            if (buf == NULL) {
                   4957:                xmlErrMemory(ctxt, NULL);
                   4958:                ctxt->instate = state;
                   4959:                return;
                   4960:            }
                   4961:            cur = CUR;
                   4962:            if (!IS_BLANK(cur)) {
                   4963:                xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
                   4964:                          "ParsePI: PI %s space expected\n", target);
                   4965:            }
                   4966:             SKIP_BLANKS;
                   4967:            cur = CUR_CHAR(l);
                   4968:            while (IS_CHAR(cur) && /* checked */
                   4969:                   ((cur != '?') || (NXT(1) != '>'))) {
                   4970:                if (len + 5 >= size) {
                   4971:                    xmlChar *tmp;
                   4972: 
                   4973:                    size *= 2;
                   4974:                    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   4975:                    if (tmp == NULL) {
                   4976:                        xmlErrMemory(ctxt, NULL);
                   4977:                        xmlFree(buf);
                   4978:                        ctxt->instate = state;
                   4979:                        return;
                   4980:                    }
                   4981:                    buf = tmp;
                   4982:                }
                   4983:                count++;
                   4984:                if (count > 50) {
                   4985:                    GROW;
                   4986:                    count = 0;
                   4987:                }
                   4988:                COPY_BUF(l,buf,len,cur);
                   4989:                NEXTL(l);
                   4990:                cur = CUR_CHAR(l);
                   4991:                if (cur == 0) {
                   4992:                    SHRINK;
                   4993:                    GROW;
                   4994:                    cur = CUR_CHAR(l);
                   4995:                }
                   4996:            }
                   4997:            buf[len] = 0;
                   4998:            if (cur != '?') {
                   4999:                xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
                   5000:                      "ParsePI: PI %s never end ...\n", target);
                   5001:            } else {
                   5002:                if (input != ctxt->input) {
                   5003:                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5004:            "PI declaration doesn't start and stop in the same entity\n");
                   5005:                }
                   5006:                SKIP(2);
                   5007: 
                   5008: #ifdef LIBXML_CATALOG_ENABLED
                   5009:                if (((state == XML_PARSER_MISC) ||
                   5010:                     (state == XML_PARSER_START)) &&
                   5011:                    (xmlStrEqual(target, XML_CATALOG_PI))) {
                   5012:                    xmlCatalogAllow allow = xmlCatalogGetDefaults();
                   5013:                    if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
                   5014:                        (allow == XML_CATA_ALLOW_ALL))
                   5015:                        xmlParseCatalogPI(ctxt, buf);
                   5016:                }
                   5017: #endif
                   5018: 
                   5019: 
                   5020:                /*
                   5021:                 * SAX: PI detected.
                   5022:                 */
                   5023:                if ((ctxt->sax) && (!ctxt->disableSAX) &&
                   5024:                    (ctxt->sax->processingInstruction != NULL))
                   5025:                    ctxt->sax->processingInstruction(ctxt->userData,
                   5026:                                                     target, buf);
                   5027:            }
                   5028:            xmlFree(buf);
                   5029:        } else {
                   5030:            xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
                   5031:        }
                   5032:        ctxt->instate = state;
                   5033:     }
                   5034: }
                   5035: 
                   5036: /**
                   5037:  * xmlParseNotationDecl:
                   5038:  * @ctxt:  an XML parser context
                   5039:  *
                   5040:  * parse a notation declaration
                   5041:  *
                   5042:  * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
                   5043:  *
                   5044:  * Hence there is actually 3 choices:
                   5045:  *     'PUBLIC' S PubidLiteral
                   5046:  *     'PUBLIC' S PubidLiteral S SystemLiteral
                   5047:  * and 'SYSTEM' S SystemLiteral
                   5048:  *
                   5049:  * See the NOTE on xmlParseExternalID().
                   5050:  */
                   5051: 
                   5052: void
                   5053: xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
                   5054:     const xmlChar *name;
                   5055:     xmlChar *Pubid;
                   5056:     xmlChar *Systemid;
                   5057:     
                   5058:     if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
                   5059:        xmlParserInputPtr input = ctxt->input;
                   5060:        SHRINK;
                   5061:        SKIP(10);
                   5062:        if (!IS_BLANK_CH(CUR)) {
                   5063:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5064:                           "Space required after '<!NOTATION'\n");
                   5065:            return;
                   5066:        }
                   5067:        SKIP_BLANKS;
                   5068: 
                   5069:         name = xmlParseName(ctxt);
                   5070:        if (name == NULL) {
                   5071:            xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
                   5072:            return;
                   5073:        }
                   5074:        if (!IS_BLANK_CH(CUR)) {
                   5075:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5076:                     "Space required after the NOTATION name'\n");
                   5077:            return;
                   5078:        }
                   5079:        if (xmlStrchr(name, ':') != NULL) {
                   5080:            xmlNsErr(ctxt, XML_NS_ERR_COLON, 
                   5081:                     "colon are forbidden from notation names '%s'\n",
                   5082:                     name, NULL, NULL);
                   5083:        }
                   5084:        SKIP_BLANKS;
                   5085: 
                   5086:        /*
                   5087:         * Parse the IDs.
                   5088:         */
                   5089:        Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
                   5090:        SKIP_BLANKS;
                   5091: 
                   5092:        if (RAW == '>') {
                   5093:            if (input != ctxt->input) {
                   5094:                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5095:        "Notation declaration doesn't start and stop in the same entity\n");
                   5096:            }
                   5097:            NEXT;
                   5098:            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   5099:                (ctxt->sax->notationDecl != NULL))
                   5100:                ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
                   5101:        } else {
                   5102:            xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
                   5103:        }
                   5104:        if (Systemid != NULL) xmlFree(Systemid);
                   5105:        if (Pubid != NULL) xmlFree(Pubid);
                   5106:     }
                   5107: }
                   5108: 
                   5109: /**
                   5110:  * xmlParseEntityDecl:
                   5111:  * @ctxt:  an XML parser context
                   5112:  *
                   5113:  * parse <!ENTITY declarations
                   5114:  *
                   5115:  * [70] EntityDecl ::= GEDecl | PEDecl
                   5116:  *
                   5117:  * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
                   5118:  *
                   5119:  * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
                   5120:  *
                   5121:  * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
                   5122:  *
                   5123:  * [74] PEDef ::= EntityValue | ExternalID
                   5124:  *
                   5125:  * [76] NDataDecl ::= S 'NDATA' S Name
                   5126:  *
                   5127:  * [ VC: Notation Declared ]
                   5128:  * The Name must match the declared name of a notation.
                   5129:  */
                   5130: 
                   5131: void
                   5132: xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
                   5133:     const xmlChar *name = NULL;
                   5134:     xmlChar *value = NULL;
                   5135:     xmlChar *URI = NULL, *literal = NULL;
                   5136:     const xmlChar *ndata = NULL;
                   5137:     int isParameter = 0;
                   5138:     xmlChar *orig = NULL;
                   5139:     int skipped;
                   5140:     
                   5141:     /* GROW; done in the caller */
                   5142:     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
                   5143:        xmlParserInputPtr input = ctxt->input;
                   5144:        SHRINK;
                   5145:        SKIP(8);
                   5146:        skipped = SKIP_BLANKS;
                   5147:        if (skipped == 0) {
                   5148:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5149:                           "Space required after '<!ENTITY'\n");
                   5150:        }
                   5151: 
                   5152:        if (RAW == '%') {
                   5153:            NEXT;
                   5154:            skipped = SKIP_BLANKS;
                   5155:            if (skipped == 0) {
                   5156:                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5157:                               "Space required after '%'\n");
                   5158:            }
                   5159:            isParameter = 1;
                   5160:        }
                   5161: 
                   5162:         name = xmlParseName(ctxt);
                   5163:        if (name == NULL) {
                   5164:            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   5165:                           "xmlParseEntityDecl: no name\n");
                   5166:             return;
                   5167:        }
                   5168:        if (xmlStrchr(name, ':') != NULL) {
                   5169:            xmlNsErr(ctxt, XML_NS_ERR_COLON, 
                   5170:                     "colon are forbidden from entities names '%s'\n",
                   5171:                     name, NULL, NULL);
                   5172:        }
                   5173:         skipped = SKIP_BLANKS;
                   5174:        if (skipped == 0) {
                   5175:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5176:                           "Space required after the entity name\n");
                   5177:        }
                   5178: 
                   5179:        ctxt->instate = XML_PARSER_ENTITY_DECL;
                   5180:        /*
                   5181:         * handle the various case of definitions...
                   5182:         */
                   5183:        if (isParameter) {
                   5184:            if ((RAW == '"') || (RAW == '\'')) {
                   5185:                value = xmlParseEntityValue(ctxt, &orig);
                   5186:                if (value) {
                   5187:                    if ((ctxt->sax != NULL) &&
                   5188:                        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
                   5189:                        ctxt->sax->entityDecl(ctxt->userData, name,
                   5190:                                    XML_INTERNAL_PARAMETER_ENTITY,
                   5191:                                    NULL, NULL, value);
                   5192:                }
                   5193:            } else {
                   5194:                URI = xmlParseExternalID(ctxt, &literal, 1);
                   5195:                if ((URI == NULL) && (literal == NULL)) {
                   5196:                    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
                   5197:                }
                   5198:                if (URI) {
                   5199:                    xmlURIPtr uri;
                   5200: 
                   5201:                    uri = xmlParseURI((const char *) URI);
                   5202:                    if (uri == NULL) {
                   5203:                        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
                   5204:                                     "Invalid URI: %s\n", URI);
                   5205:                        /*
                   5206:                         * This really ought to be a well formedness error
                   5207:                         * but the XML Core WG decided otherwise c.f. issue
                   5208:                         * E26 of the XML erratas.
                   5209:                         */
                   5210:                    } else {
                   5211:                        if (uri->fragment != NULL) {
                   5212:                            /*
                   5213:                             * Okay this is foolish to block those but not
                   5214:                             * invalid URIs.
                   5215:                             */
                   5216:                            xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
                   5217:                        } else {
                   5218:                            if ((ctxt->sax != NULL) &&
                   5219:                                (!ctxt->disableSAX) &&
                   5220:                                (ctxt->sax->entityDecl != NULL))
                   5221:                                ctxt->sax->entityDecl(ctxt->userData, name,
                   5222:                                            XML_EXTERNAL_PARAMETER_ENTITY,
                   5223:                                            literal, URI, NULL);
                   5224:                        }
                   5225:                        xmlFreeURI(uri);
                   5226:                    }
                   5227:                }
                   5228:            }
                   5229:        } else {
                   5230:            if ((RAW == '"') || (RAW == '\'')) {
                   5231:                value = xmlParseEntityValue(ctxt, &orig);
                   5232:                if ((ctxt->sax != NULL) &&
                   5233:                    (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
                   5234:                    ctxt->sax->entityDecl(ctxt->userData, name,
                   5235:                                XML_INTERNAL_GENERAL_ENTITY,
                   5236:                                NULL, NULL, value);
                   5237:                /*
                   5238:                 * For expat compatibility in SAX mode.
                   5239:                 */
                   5240:                if ((ctxt->myDoc == NULL) ||
                   5241:                    (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
                   5242:                    if (ctxt->myDoc == NULL) {
                   5243:                        ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
                   5244:                        if (ctxt->myDoc == NULL) {
                   5245:                            xmlErrMemory(ctxt, "New Doc failed");
                   5246:                            return;
                   5247:                        }
                   5248:                        ctxt->myDoc->properties = XML_DOC_INTERNAL;
                   5249:                    }
                   5250:                    if (ctxt->myDoc->intSubset == NULL)
                   5251:                        ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
                   5252:                                            BAD_CAST "fake", NULL, NULL);
                   5253: 
                   5254:                    xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
                   5255:                                      NULL, NULL, value);
                   5256:                }
                   5257:            } else {
                   5258:                URI = xmlParseExternalID(ctxt, &literal, 1);
                   5259:                if ((URI == NULL) && (literal == NULL)) {
                   5260:                    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
                   5261:                }
                   5262:                if (URI) {
                   5263:                    xmlURIPtr uri;
                   5264: 
                   5265:                    uri = xmlParseURI((const char *)URI);
                   5266:                    if (uri == NULL) {
                   5267:                        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
                   5268:                                     "Invalid URI: %s\n", URI);
                   5269:                        /*
                   5270:                         * This really ought to be a well formedness error
                   5271:                         * but the XML Core WG decided otherwise c.f. issue
                   5272:                         * E26 of the XML erratas.
                   5273:                         */
                   5274:                    } else {
                   5275:                        if (uri->fragment != NULL) {
                   5276:                            /*
                   5277:                             * Okay this is foolish to block those but not
                   5278:                             * invalid URIs.
                   5279:                             */
                   5280:                            xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
                   5281:                        }
                   5282:                        xmlFreeURI(uri);
                   5283:                    }
                   5284:                }
                   5285:                if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
                   5286:                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5287:                                   "Space required before 'NDATA'\n");
                   5288:                }
                   5289:                SKIP_BLANKS;
                   5290:                if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
                   5291:                    SKIP(5);
                   5292:                    if (!IS_BLANK_CH(CUR)) {
                   5293:                        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5294:                                       "Space required after 'NDATA'\n");
                   5295:                    }
                   5296:                    SKIP_BLANKS;
                   5297:                    ndata = xmlParseName(ctxt);
                   5298:                    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   5299:                        (ctxt->sax->unparsedEntityDecl != NULL))
                   5300:                        ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
                   5301:                                    literal, URI, ndata);
                   5302:                } else {
                   5303:                    if ((ctxt->sax != NULL) &&
                   5304:                        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
                   5305:                        ctxt->sax->entityDecl(ctxt->userData, name,
                   5306:                                    XML_EXTERNAL_GENERAL_PARSED_ENTITY,
                   5307:                                    literal, URI, NULL);
                   5308:                    /*
                   5309:                     * For expat compatibility in SAX mode.
                   5310:                     * assuming the entity repalcement was asked for
                   5311:                     */
                   5312:                    if ((ctxt->replaceEntities != 0) &&
                   5313:                        ((ctxt->myDoc == NULL) ||
                   5314:                        (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
                   5315:                        if (ctxt->myDoc == NULL) {
                   5316:                            ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
                   5317:                            if (ctxt->myDoc == NULL) {
                   5318:                                xmlErrMemory(ctxt, "New Doc failed");
                   5319:                                return;
                   5320:                            }
                   5321:                            ctxt->myDoc->properties = XML_DOC_INTERNAL;
                   5322:                        }
                   5323: 
                   5324:                        if (ctxt->myDoc->intSubset == NULL)
                   5325:                            ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
                   5326:                                                BAD_CAST "fake", NULL, NULL);
                   5327:                        xmlSAX2EntityDecl(ctxt, name,
                   5328:                                          XML_EXTERNAL_GENERAL_PARSED_ENTITY,
                   5329:                                          literal, URI, NULL);
                   5330:                    }
                   5331:                }
                   5332:            }
                   5333:        }
                   5334:        SKIP_BLANKS;
                   5335:        if (RAW != '>') {
                   5336:            xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
                   5337:                    "xmlParseEntityDecl: entity %s not terminated\n", name);
                   5338:        } else {
                   5339:            if (input != ctxt->input) {
                   5340:                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   5341:        "Entity declaration doesn't start and stop in the same entity\n");
                   5342:            }
                   5343:            NEXT;
                   5344:        }
                   5345:        if (orig != NULL) {
                   5346:            /*
                   5347:             * Ugly mechanism to save the raw entity value.
                   5348:             */
                   5349:            xmlEntityPtr cur = NULL;
                   5350: 
                   5351:            if (isParameter) {
                   5352:                if ((ctxt->sax != NULL) &&
                   5353:                    (ctxt->sax->getParameterEntity != NULL))
                   5354:                    cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
                   5355:            } else {
                   5356:                if ((ctxt->sax != NULL) &&
                   5357:                    (ctxt->sax->getEntity != NULL))
                   5358:                    cur = ctxt->sax->getEntity(ctxt->userData, name);
                   5359:                if ((cur == NULL) && (ctxt->userData==ctxt)) {
                   5360:                    cur = xmlSAX2GetEntity(ctxt, name);
                   5361:                }
                   5362:            }
                   5363:             if (cur != NULL) {
                   5364:                if (cur->orig != NULL)
                   5365:                    xmlFree(orig);
                   5366:                else
                   5367:                    cur->orig = orig;
                   5368:            } else
                   5369:                xmlFree(orig);
                   5370:        }
                   5371:        if (value != NULL) xmlFree(value);
                   5372:        if (URI != NULL) xmlFree(URI);
                   5373:        if (literal != NULL) xmlFree(literal);
                   5374:     }
                   5375: }
                   5376: 
                   5377: /**
                   5378:  * xmlParseDefaultDecl:
                   5379:  * @ctxt:  an XML parser context
                   5380:  * @value:  Receive a possible fixed default value for the attribute
                   5381:  *
                   5382:  * Parse an attribute default declaration
                   5383:  *
                   5384:  * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
                   5385:  *
                   5386:  * [ VC: Required Attribute ]
                   5387:  * if the default declaration is the keyword #REQUIRED, then the
                   5388:  * attribute must be specified for all elements of the type in the
                   5389:  * attribute-list declaration.
                   5390:  *
                   5391:  * [ VC: Attribute Default Legal ]
                   5392:  * The declared default value must meet the lexical constraints of
                   5393:  * the declared attribute type c.f. xmlValidateAttributeDecl()
                   5394:  *
                   5395:  * [ VC: Fixed Attribute Default ]
                   5396:  * if an attribute has a default value declared with the #FIXED
                   5397:  * keyword, instances of that attribute must match the default value. 
                   5398:  *
                   5399:  * [ WFC: No < in Attribute Values ]
                   5400:  * handled in xmlParseAttValue()
                   5401:  *
                   5402:  * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
                   5403:  *          or XML_ATTRIBUTE_FIXED. 
                   5404:  */
                   5405: 
                   5406: int
                   5407: xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
                   5408:     int val;
                   5409:     xmlChar *ret;
                   5410: 
                   5411:     *value = NULL;
                   5412:     if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
                   5413:        SKIP(9);
                   5414:        return(XML_ATTRIBUTE_REQUIRED);
                   5415:     }
                   5416:     if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
                   5417:        SKIP(8);
                   5418:        return(XML_ATTRIBUTE_IMPLIED);
                   5419:     }
                   5420:     val = XML_ATTRIBUTE_NONE;
                   5421:     if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
                   5422:        SKIP(6);
                   5423:        val = XML_ATTRIBUTE_FIXED;
                   5424:        if (!IS_BLANK_CH(CUR)) {
                   5425:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5426:                           "Space required after '#FIXED'\n");
                   5427:        }
                   5428:        SKIP_BLANKS;
                   5429:     }
                   5430:     ret = xmlParseAttValue(ctxt);
                   5431:     ctxt->instate = XML_PARSER_DTD;
                   5432:     if (ret == NULL) {
                   5433:        xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
                   5434:                       "Attribute default value declaration error\n");
                   5435:     } else
                   5436:         *value = ret;
                   5437:     return(val);
                   5438: }
                   5439: 
                   5440: /**
                   5441:  * xmlParseNotationType:
                   5442:  * @ctxt:  an XML parser context
                   5443:  *
                   5444:  * parse an Notation attribute type.
                   5445:  *
                   5446:  * Note: the leading 'NOTATION' S part has already being parsed...
                   5447:  *
                   5448:  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
                   5449:  *
                   5450:  * [ VC: Notation Attributes ]
                   5451:  * Values of this type must match one of the notation names included
                   5452:  * in the declaration; all notation names in the declaration must be declared. 
                   5453:  *
                   5454:  * Returns: the notation attribute tree built while parsing
                   5455:  */
                   5456: 
                   5457: xmlEnumerationPtr
                   5458: xmlParseNotationType(xmlParserCtxtPtr ctxt) {
                   5459:     const xmlChar *name;
                   5460:     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
                   5461: 
                   5462:     if (RAW != '(') {
                   5463:        xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
                   5464:        return(NULL);
                   5465:     }
                   5466:     SHRINK;
                   5467:     do {
                   5468:         NEXT;
                   5469:        SKIP_BLANKS;
                   5470:         name = xmlParseName(ctxt);
                   5471:        if (name == NULL) {
                   5472:            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   5473:                           "Name expected in NOTATION declaration\n");
                   5474:             xmlFreeEnumeration(ret);
                   5475:            return(NULL);
                   5476:        }
                   5477:        tmp = ret;
                   5478:        while (tmp != NULL) {
                   5479:            if (xmlStrEqual(name, tmp->name)) {
                   5480:                xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
                   5481:          "standalone: attribute notation value token %s duplicated\n",
                   5482:                                 name, NULL);
                   5483:                if (!xmlDictOwns(ctxt->dict, name))
                   5484:                    xmlFree((xmlChar *) name);
                   5485:                break;
                   5486:            }
                   5487:            tmp = tmp->next;
                   5488:        }
                   5489:        if (tmp == NULL) {
                   5490:            cur = xmlCreateEnumeration(name);
                   5491:            if (cur == NULL) {
                   5492:                 xmlFreeEnumeration(ret);
                   5493:                 return(NULL);
                   5494:             }
                   5495:            if (last == NULL) ret = last = cur;
                   5496:            else {
                   5497:                last->next = cur;
                   5498:                last = cur;
                   5499:            }
                   5500:        }
                   5501:        SKIP_BLANKS;
                   5502:     } while (RAW == '|');
                   5503:     if (RAW != ')') {
                   5504:        xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
                   5505:         xmlFreeEnumeration(ret);
                   5506:        return(NULL);
                   5507:     }
                   5508:     NEXT;
                   5509:     return(ret);
                   5510: }
                   5511: 
                   5512: /**
                   5513:  * xmlParseEnumerationType:
                   5514:  * @ctxt:  an XML parser context
                   5515:  *
                   5516:  * parse an Enumeration attribute type.
                   5517:  *
                   5518:  * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
                   5519:  *
                   5520:  * [ VC: Enumeration ]
                   5521:  * Values of this type must match one of the Nmtoken tokens in
                   5522:  * the declaration
                   5523:  *
                   5524:  * Returns: the enumeration attribute tree built while parsing
                   5525:  */
                   5526: 
                   5527: xmlEnumerationPtr
                   5528: xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
                   5529:     xmlChar *name;
                   5530:     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
                   5531: 
                   5532:     if (RAW != '(') {
                   5533:        xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
                   5534:        return(NULL);
                   5535:     }
                   5536:     SHRINK;
                   5537:     do {
                   5538:         NEXT;
                   5539:        SKIP_BLANKS;
                   5540:         name = xmlParseNmtoken(ctxt);
                   5541:        if (name == NULL) {
                   5542:            xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
                   5543:            return(ret);
                   5544:        }
                   5545:        tmp = ret;
                   5546:        while (tmp != NULL) {
                   5547:            if (xmlStrEqual(name, tmp->name)) {
                   5548:                xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
                   5549:          "standalone: attribute enumeration value token %s duplicated\n",
                   5550:                                 name, NULL);
                   5551:                if (!xmlDictOwns(ctxt->dict, name))
                   5552:                    xmlFree(name);
                   5553:                break;
                   5554:            }
                   5555:            tmp = tmp->next;
                   5556:        }
                   5557:        if (tmp == NULL) {
                   5558:            cur = xmlCreateEnumeration(name);
                   5559:            if (!xmlDictOwns(ctxt->dict, name))
                   5560:                xmlFree(name);
                   5561:            if (cur == NULL) {
                   5562:                 xmlFreeEnumeration(ret);
                   5563:                 return(NULL);
                   5564:             }
                   5565:            if (last == NULL) ret = last = cur;
                   5566:            else {
                   5567:                last->next = cur;
                   5568:                last = cur;
                   5569:            }
                   5570:        }
                   5571:        SKIP_BLANKS;
                   5572:     } while (RAW == '|');
                   5573:     if (RAW != ')') {
                   5574:        xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
                   5575:        return(ret);
                   5576:     }
                   5577:     NEXT;
                   5578:     return(ret);
                   5579: }
                   5580: 
                   5581: /**
                   5582:  * xmlParseEnumeratedType:
                   5583:  * @ctxt:  an XML parser context
                   5584:  * @tree:  the enumeration tree built while parsing
                   5585:  *
                   5586:  * parse an Enumerated attribute type.
                   5587:  *
                   5588:  * [57] EnumeratedType ::= NotationType | Enumeration
                   5589:  *
                   5590:  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
                   5591:  *
                   5592:  *
                   5593:  * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
                   5594:  */
                   5595: 
                   5596: int
                   5597: xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
                   5598:     if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
                   5599:        SKIP(8);
                   5600:        if (!IS_BLANK_CH(CUR)) {
                   5601:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5602:                           "Space required after 'NOTATION'\n");
                   5603:            return(0);
                   5604:        }
                   5605:         SKIP_BLANKS;
                   5606:        *tree = xmlParseNotationType(ctxt);
                   5607:        if (*tree == NULL) return(0);
                   5608:        return(XML_ATTRIBUTE_NOTATION);
                   5609:     }
                   5610:     *tree = xmlParseEnumerationType(ctxt);
                   5611:     if (*tree == NULL) return(0);
                   5612:     return(XML_ATTRIBUTE_ENUMERATION);
                   5613: }
                   5614: 
                   5615: /**
                   5616:  * xmlParseAttributeType:
                   5617:  * @ctxt:  an XML parser context
                   5618:  * @tree:  the enumeration tree built while parsing
                   5619:  *
                   5620:  * parse the Attribute list def for an element
                   5621:  *
                   5622:  * [54] AttType ::= StringType | TokenizedType | EnumeratedType
                   5623:  *
                   5624:  * [55] StringType ::= 'CDATA'
                   5625:  *
                   5626:  * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
                   5627:  *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
                   5628:  *
                   5629:  * Validity constraints for attribute values syntax are checked in
                   5630:  * xmlValidateAttributeValue()
                   5631:  *
                   5632:  * [ VC: ID ]
                   5633:  * Values of type ID must match the Name production. A name must not
                   5634:  * appear more than once in an XML document as a value of this type;
                   5635:  * i.e., ID values must uniquely identify the elements which bear them.
                   5636:  *
                   5637:  * [ VC: One ID per Element Type ]
                   5638:  * No element type may have more than one ID attribute specified.
                   5639:  *
                   5640:  * [ VC: ID Attribute Default ]
                   5641:  * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
                   5642:  *
                   5643:  * [ VC: IDREF ]
                   5644:  * Values of type IDREF must match the Name production, and values
                   5645:  * of type IDREFS must match Names; each IDREF Name must match the value
                   5646:  * of an ID attribute on some element in the XML document; i.e. IDREF
                   5647:  * values must match the value of some ID attribute.
                   5648:  *
                   5649:  * [ VC: Entity Name ]
                   5650:  * Values of type ENTITY must match the Name production, values
                   5651:  * of type ENTITIES must match Names; each Entity Name must match the
                   5652:  * name of an unparsed entity declared in the DTD.  
                   5653:  *
                   5654:  * [ VC: Name Token ]
                   5655:  * Values of type NMTOKEN must match the Nmtoken production; values
                   5656:  * of type NMTOKENS must match Nmtokens. 
                   5657:  *
                   5658:  * Returns the attribute type
                   5659:  */
                   5660: int 
                   5661: xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
                   5662:     SHRINK;
                   5663:     if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
                   5664:        SKIP(5);
                   5665:        return(XML_ATTRIBUTE_CDATA);
                   5666:      } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
                   5667:        SKIP(6);
                   5668:        return(XML_ATTRIBUTE_IDREFS);
                   5669:      } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
                   5670:        SKIP(5);
                   5671:        return(XML_ATTRIBUTE_IDREF);
                   5672:      } else if ((RAW == 'I') && (NXT(1) == 'D')) {
                   5673:         SKIP(2);
                   5674:        return(XML_ATTRIBUTE_ID);
                   5675:      } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
                   5676:        SKIP(6);
                   5677:        return(XML_ATTRIBUTE_ENTITY);
                   5678:      } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
                   5679:        SKIP(8);
                   5680:        return(XML_ATTRIBUTE_ENTITIES);
                   5681:      } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
                   5682:        SKIP(8);
                   5683:        return(XML_ATTRIBUTE_NMTOKENS);
                   5684:      } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
                   5685:        SKIP(7);
                   5686:        return(XML_ATTRIBUTE_NMTOKEN);
                   5687:      }
                   5688:      return(xmlParseEnumeratedType(ctxt, tree));
                   5689: }
                   5690: 
                   5691: /**
                   5692:  * xmlParseAttributeListDecl:
                   5693:  * @ctxt:  an XML parser context
                   5694:  *
                   5695:  * : parse the Attribute list def for an element
                   5696:  *
                   5697:  * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
                   5698:  *
                   5699:  * [53] AttDef ::= S Name S AttType S DefaultDecl
                   5700:  *
                   5701:  */
                   5702: void
                   5703: xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
                   5704:     const xmlChar *elemName;
                   5705:     const xmlChar *attrName;
                   5706:     xmlEnumerationPtr tree;
                   5707: 
                   5708:     if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
                   5709:        xmlParserInputPtr input = ctxt->input;
                   5710: 
                   5711:        SKIP(9);
                   5712:        if (!IS_BLANK_CH(CUR)) {
                   5713:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5714:                                 "Space required after '<!ATTLIST'\n");
                   5715:        }
                   5716:         SKIP_BLANKS;
                   5717:         elemName = xmlParseName(ctxt);
                   5718:        if (elemName == NULL) {
                   5719:            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   5720:                           "ATTLIST: no name for Element\n");
                   5721:            return;
                   5722:        }
                   5723:        SKIP_BLANKS;
                   5724:        GROW;
                   5725:        while (RAW != '>') {
                   5726:            const xmlChar *check = CUR_PTR;
                   5727:            int type;
                   5728:            int def;
                   5729:            xmlChar *defaultValue = NULL;
                   5730: 
                   5731:            GROW;
                   5732:             tree = NULL;
                   5733:            attrName = xmlParseName(ctxt);
                   5734:            if (attrName == NULL) {
                   5735:                xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   5736:                               "ATTLIST: no name for Attribute\n");
                   5737:                break;
                   5738:            }
                   5739:            GROW;
                   5740:            if (!IS_BLANK_CH(CUR)) {
                   5741:                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5742:                        "Space required after the attribute name\n");
                   5743:                break;
                   5744:            }
                   5745:            SKIP_BLANKS;
                   5746: 
                   5747:            type = xmlParseAttributeType(ctxt, &tree);
                   5748:            if (type <= 0) {
                   5749:                break;
                   5750:            }
                   5751: 
                   5752:            GROW;
                   5753:            if (!IS_BLANK_CH(CUR)) {
                   5754:                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5755:                               "Space required after the attribute type\n");
                   5756:                if (tree != NULL)
                   5757:                    xmlFreeEnumeration(tree);
                   5758:                break;
                   5759:            }
                   5760:            SKIP_BLANKS;
                   5761: 
                   5762:            def = xmlParseDefaultDecl(ctxt, &defaultValue);
                   5763:            if (def <= 0) {
                   5764:                 if (defaultValue != NULL)
                   5765:                    xmlFree(defaultValue);
                   5766:                if (tree != NULL)
                   5767:                    xmlFreeEnumeration(tree);
                   5768:                break;
                   5769:            }
                   5770:            if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
                   5771:                xmlAttrNormalizeSpace(defaultValue, defaultValue);
                   5772: 
                   5773:            GROW;
                   5774:             if (RAW != '>') {
                   5775:                if (!IS_BLANK_CH(CUR)) {
                   5776:                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   5777:                        "Space required after the attribute default value\n");
                   5778:                    if (defaultValue != NULL)
                   5779:                        xmlFree(defaultValue);
                   5780:                    if (tree != NULL)
                   5781:                        xmlFreeEnumeration(tree);
                   5782:                    break;
                   5783:                }
                   5784:                SKIP_BLANKS;
                   5785:            }
                   5786:            if (check == CUR_PTR) {
                   5787:                xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   5788:                            "in xmlParseAttributeListDecl\n");
                   5789:                if (defaultValue != NULL)
                   5790:                    xmlFree(defaultValue);
                   5791:                if (tree != NULL)
                   5792:                    xmlFreeEnumeration(tree);
                   5793:                break;
                   5794:            }
                   5795:            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   5796:                (ctxt->sax->attributeDecl != NULL))
                   5797:                ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
                   5798:                                type, def, defaultValue, tree);
                   5799:            else if (tree != NULL)
                   5800:                xmlFreeEnumeration(tree);
                   5801: 
                   5802:            if ((ctxt->sax2) && (defaultValue != NULL) &&
                   5803:                (def != XML_ATTRIBUTE_IMPLIED) && 
                   5804:                (def != XML_ATTRIBUTE_REQUIRED)) {
                   5805:                xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
                   5806:            }
                   5807:            if (ctxt->sax2) {
                   5808:                xmlAddSpecialAttr(ctxt, elemName, attrName, type);
                   5809:            }
                   5810:            if (defaultValue != NULL)
                   5811:                xmlFree(defaultValue);
                   5812:            GROW;
                   5813:        }
                   5814:        if (RAW == '>') {
                   5815:            if (input != ctxt->input) {
                   5816:                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   5817:     "Attribute list declaration doesn't start and stop in the same entity\n",
                   5818:                                  NULL, NULL);
                   5819:            }
                   5820:            NEXT;
                   5821:        }
                   5822:     }
                   5823: }
                   5824: 
                   5825: /**
                   5826:  * xmlParseElementMixedContentDecl:
                   5827:  * @ctxt:  an XML parser context
                   5828:  * @inputchk:  the input used for the current entity, needed for boundary checks
                   5829:  *
                   5830:  * parse the declaration for a Mixed Element content
                   5831:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
                   5832:  * 
                   5833:  * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
                   5834:  *                '(' S? '#PCDATA' S? ')'
                   5835:  *
                   5836:  * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
                   5837:  *
                   5838:  * [ VC: No Duplicate Types ]
                   5839:  * The same name must not appear more than once in a single
                   5840:  * mixed-content declaration. 
                   5841:  *
                   5842:  * returns: the list of the xmlElementContentPtr describing the element choices
                   5843:  */
                   5844: xmlElementContentPtr
                   5845: xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
                   5846:     xmlElementContentPtr ret = NULL, cur = NULL, n;
                   5847:     const xmlChar *elem = NULL;
                   5848: 
                   5849:     GROW;
                   5850:     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
                   5851:        SKIP(7);
                   5852:        SKIP_BLANKS;
                   5853:        SHRINK;
                   5854:        if (RAW == ')') {
                   5855:            if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
                   5856:                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   5857: "Element content declaration doesn't start and stop in the same entity\n",
                   5858:                                  NULL, NULL);
                   5859:            }
                   5860:            NEXT;
                   5861:            ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
                   5862:            if (ret == NULL)
                   5863:                return(NULL);
                   5864:            if (RAW == '*') {
                   5865:                ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   5866:                NEXT;
                   5867:            }
                   5868:            return(ret);
                   5869:        }
                   5870:        if ((RAW == '(') || (RAW == '|')) {
                   5871:            ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
                   5872:            if (ret == NULL) return(NULL);
                   5873:        }
                   5874:        while (RAW == '|') {
                   5875:            NEXT;
                   5876:            if (elem == NULL) {
                   5877:                ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
                   5878:                if (ret == NULL) return(NULL);
                   5879:                ret->c1 = cur;
                   5880:                if (cur != NULL)
                   5881:                    cur->parent = ret;
                   5882:                cur = ret;
                   5883:            } else {
                   5884:                n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
                   5885:                if (n == NULL) return(NULL);
                   5886:                n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
                   5887:                if (n->c1 != NULL)
                   5888:                    n->c1->parent = n;
                   5889:                cur->c2 = n;
                   5890:                if (n != NULL)
                   5891:                    n->parent = cur;
                   5892:                cur = n;
                   5893:            }
                   5894:            SKIP_BLANKS;
                   5895:            elem = xmlParseName(ctxt);
                   5896:            if (elem == NULL) {
                   5897:                xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   5898:                        "xmlParseElementMixedContentDecl : Name expected\n");
                   5899:                xmlFreeDocElementContent(ctxt->myDoc, cur);
                   5900:                return(NULL);
                   5901:            }
                   5902:            SKIP_BLANKS;
                   5903:            GROW;
                   5904:        }
                   5905:        if ((RAW == ')') && (NXT(1) == '*')) {
                   5906:            if (elem != NULL) {
                   5907:                cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
                   5908:                                               XML_ELEMENT_CONTENT_ELEMENT);
                   5909:                if (cur->c2 != NULL)
                   5910:                    cur->c2->parent = cur;
                   5911:             }
                   5912:             if (ret != NULL)
                   5913:                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   5914:            if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
                   5915:                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   5916: "Element content declaration doesn't start and stop in the same entity\n",
                   5917:                                 NULL, NULL);
                   5918:            }
                   5919:            SKIP(2);
                   5920:        } else {
                   5921:            xmlFreeDocElementContent(ctxt->myDoc, ret);
                   5922:            xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
                   5923:            return(NULL);
                   5924:        }
                   5925: 
                   5926:     } else {
                   5927:        xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
                   5928:     }
                   5929:     return(ret);
                   5930: }
                   5931: 
                   5932: /**
                   5933:  * xmlParseElementChildrenContentDeclPriv:
                   5934:  * @ctxt:  an XML parser context
                   5935:  * @inputchk:  the input used for the current entity, needed for boundary checks
                   5936:  * @depth: the level of recursion
                   5937:  *
                   5938:  * parse the declaration for a Mixed Element content
                   5939:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
                   5940:  * 
                   5941:  *
                   5942:  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
                   5943:  *
                   5944:  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
                   5945:  *
                   5946:  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
                   5947:  *
                   5948:  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
                   5949:  *
                   5950:  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
                   5951:  * TODO Parameter-entity replacement text must be properly nested
                   5952:  *     with parenthesized groups. That is to say, if either of the
                   5953:  *     opening or closing parentheses in a choice, seq, or Mixed
                   5954:  *     construct is contained in the replacement text for a parameter
                   5955:  *     entity, both must be contained in the same replacement text. For
                   5956:  *     interoperability, if a parameter-entity reference appears in a
                   5957:  *     choice, seq, or Mixed construct, its replacement text should not
                   5958:  *     be empty, and neither the first nor last non-blank character of
                   5959:  *     the replacement text should be a connector (| or ,).
                   5960:  *
                   5961:  * Returns the tree of xmlElementContentPtr describing the element 
                   5962:  *          hierarchy.
                   5963:  */
                   5964: static xmlElementContentPtr
                   5965: xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
                   5966:                                        int depth) {
                   5967:     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
                   5968:     const xmlChar *elem;
                   5969:     xmlChar type = 0;
                   5970: 
                   5971:     if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
                   5972:         (depth >  2048)) {
                   5973:         xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
                   5974: "xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
                   5975:                           depth);
                   5976:        return(NULL);
                   5977:     }
                   5978:     SKIP_BLANKS;
                   5979:     GROW;
                   5980:     if (RAW == '(') {
                   5981:        int inputid = ctxt->input->id;
                   5982: 
                   5983:         /* Recurse on first child */
                   5984:        NEXT;
                   5985:        SKIP_BLANKS;
                   5986:         cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
                   5987:                                                            depth + 1);
                   5988:        SKIP_BLANKS;
                   5989:        GROW;
                   5990:     } else {
                   5991:        elem = xmlParseName(ctxt);
                   5992:        if (elem == NULL) {
                   5993:            xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
                   5994:            return(NULL);
                   5995:        }
                   5996:         cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
                   5997:        if (cur == NULL) {
                   5998:            xmlErrMemory(ctxt, NULL);
                   5999:            return(NULL);
                   6000:        }
                   6001:        GROW;
                   6002:        if (RAW == '?') {
                   6003:            cur->ocur = XML_ELEMENT_CONTENT_OPT;
                   6004:            NEXT;
                   6005:        } else if (RAW == '*') {
                   6006:            cur->ocur = XML_ELEMENT_CONTENT_MULT;
                   6007:            NEXT;
                   6008:        } else if (RAW == '+') {
                   6009:            cur->ocur = XML_ELEMENT_CONTENT_PLUS;
                   6010:            NEXT;
                   6011:        } else {
                   6012:            cur->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6013:        }
                   6014:        GROW;
                   6015:     }
                   6016:     SKIP_BLANKS;
                   6017:     SHRINK;
                   6018:     while (RAW != ')') {
                   6019:         /*
                   6020:         * Each loop we parse one separator and one element.
                   6021:         */
                   6022:         if (RAW == ',') {
                   6023:            if (type == 0) type = CUR;
                   6024: 
                   6025:            /*
                   6026:             * Detect "Name | Name , Name" error
                   6027:             */
                   6028:            else if (type != CUR) {
                   6029:                xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
                   6030:                    "xmlParseElementChildrenContentDecl : '%c' expected\n",
                   6031:                                  type);
                   6032:                if ((last != NULL) && (last != ret))
                   6033:                    xmlFreeDocElementContent(ctxt->myDoc, last);
                   6034:                if (ret != NULL)
                   6035:                    xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6036:                return(NULL);
                   6037:            }
                   6038:            NEXT;
                   6039: 
                   6040:            op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
                   6041:            if (op == NULL) {
                   6042:                if ((last != NULL) && (last != ret))
                   6043:                    xmlFreeDocElementContent(ctxt->myDoc, last);
                   6044:                xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6045:                return(NULL);
                   6046:            }
                   6047:            if (last == NULL) {
                   6048:                op->c1 = ret;
                   6049:                if (ret != NULL)
                   6050:                    ret->parent = op;
                   6051:                ret = cur = op;
                   6052:            } else {
                   6053:                cur->c2 = op;
                   6054:                if (op != NULL)
                   6055:                    op->parent = cur;
                   6056:                op->c1 = last;
                   6057:                if (last != NULL)
                   6058:                    last->parent = op;
                   6059:                cur =op;
                   6060:                last = NULL;
                   6061:            }
                   6062:        } else if (RAW == '|') {
                   6063:            if (type == 0) type = CUR;
                   6064: 
                   6065:            /*
                   6066:             * Detect "Name , Name | Name" error
                   6067:             */
                   6068:            else if (type != CUR) {
                   6069:                xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
                   6070:                    "xmlParseElementChildrenContentDecl : '%c' expected\n",
                   6071:                                  type);
                   6072:                if ((last != NULL) && (last != ret))
                   6073:                    xmlFreeDocElementContent(ctxt->myDoc, last);
                   6074:                if (ret != NULL)
                   6075:                    xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6076:                return(NULL);
                   6077:            }
                   6078:            NEXT;
                   6079: 
                   6080:            op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
                   6081:            if (op == NULL) {
                   6082:                if ((last != NULL) && (last != ret))
                   6083:                    xmlFreeDocElementContent(ctxt->myDoc, last);
                   6084:                if (ret != NULL)
                   6085:                    xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6086:                return(NULL);
                   6087:            }
                   6088:            if (last == NULL) {
                   6089:                op->c1 = ret;
                   6090:                if (ret != NULL)
                   6091:                    ret->parent = op;
                   6092:                ret = cur = op;
                   6093:            } else {
                   6094:                cur->c2 = op;
                   6095:                if (op != NULL)
                   6096:                    op->parent = cur;
                   6097:                op->c1 = last;
                   6098:                if (last != NULL)
                   6099:                    last->parent = op;
                   6100:                cur =op;
                   6101:                last = NULL;
                   6102:            }
                   6103:        } else {
                   6104:            xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
                   6105:            if ((last != NULL) && (last != ret))
                   6106:                xmlFreeDocElementContent(ctxt->myDoc, last);
                   6107:            if (ret != NULL)
                   6108:                xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6109:            return(NULL);
                   6110:        }
                   6111:        GROW;
                   6112:        SKIP_BLANKS;
                   6113:        GROW;
                   6114:        if (RAW == '(') {
                   6115:            int inputid = ctxt->input->id;
                   6116:            /* Recurse on second child */
                   6117:            NEXT;
                   6118:            SKIP_BLANKS;
                   6119:            last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
                   6120:                                                           depth + 1);
                   6121:            SKIP_BLANKS;
                   6122:        } else {
                   6123:            elem = xmlParseName(ctxt);
                   6124:            if (elem == NULL) {
                   6125:                xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
                   6126:                if (ret != NULL)
                   6127:                    xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6128:                return(NULL);
                   6129:            }
                   6130:            last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
                   6131:            if (last == NULL) {
                   6132:                if (ret != NULL)
                   6133:                    xmlFreeDocElementContent(ctxt->myDoc, ret);
                   6134:                return(NULL);
                   6135:            }
                   6136:            if (RAW == '?') {
                   6137:                last->ocur = XML_ELEMENT_CONTENT_OPT;
                   6138:                NEXT;
                   6139:            } else if (RAW == '*') {
                   6140:                last->ocur = XML_ELEMENT_CONTENT_MULT;
                   6141:                NEXT;
                   6142:            } else if (RAW == '+') {
                   6143:                last->ocur = XML_ELEMENT_CONTENT_PLUS;
                   6144:                NEXT;
                   6145:            } else {
                   6146:                last->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6147:            }
                   6148:        }
                   6149:        SKIP_BLANKS;
                   6150:        GROW;
                   6151:     }
                   6152:     if ((cur != NULL) && (last != NULL)) {
                   6153:         cur->c2 = last;
                   6154:        if (last != NULL)
                   6155:            last->parent = cur;
                   6156:     }
                   6157:     if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
                   6158:        xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   6159: "Element content declaration doesn't start and stop in the same entity\n",
                   6160:                         NULL, NULL);
                   6161:     }
                   6162:     NEXT;
                   6163:     if (RAW == '?') {
                   6164:        if (ret != NULL) {
                   6165:            if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
                   6166:                (ret->ocur == XML_ELEMENT_CONTENT_MULT))
                   6167:                ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   6168:            else
                   6169:                ret->ocur = XML_ELEMENT_CONTENT_OPT;
                   6170:        }
                   6171:        NEXT;
                   6172:     } else if (RAW == '*') {
                   6173:        if (ret != NULL) {
                   6174:            ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   6175:            cur = ret;
                   6176:            /*
                   6177:             * Some normalization:
                   6178:             * (a | b* | c?)* == (a | b | c)*
                   6179:             */
                   6180:            while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
                   6181:                if ((cur->c1 != NULL) &&
                   6182:                    ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
                   6183:                     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
                   6184:                    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6185:                if ((cur->c2 != NULL) &&
                   6186:                    ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
                   6187:                     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
                   6188:                    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6189:                cur = cur->c2;
                   6190:            }
                   6191:        }
                   6192:        NEXT;
                   6193:     } else if (RAW == '+') {
                   6194:        if (ret != NULL) {
                   6195:            int found = 0;
                   6196: 
                   6197:            if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
                   6198:                (ret->ocur == XML_ELEMENT_CONTENT_MULT))
                   6199:                ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   6200:            else
                   6201:                ret->ocur = XML_ELEMENT_CONTENT_PLUS;
                   6202:            /*
                   6203:             * Some normalization:
                   6204:             * (a | b*)+ == (a | b)*
                   6205:             * (a | b?)+ == (a | b)*
                   6206:             */
                   6207:            while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
                   6208:                if ((cur->c1 != NULL) &&
                   6209:                    ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
                   6210:                     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
                   6211:                    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6212:                    found = 1;
                   6213:                }
                   6214:                if ((cur->c2 != NULL) &&
                   6215:                    ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
                   6216:                     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
                   6217:                    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
                   6218:                    found = 1;
                   6219:                }
                   6220:                cur = cur->c2;
                   6221:            }
                   6222:            if (found)
                   6223:                ret->ocur = XML_ELEMENT_CONTENT_MULT;
                   6224:        }
                   6225:        NEXT;
                   6226:     }
                   6227:     return(ret);
                   6228: }
                   6229: 
                   6230: /**
                   6231:  * xmlParseElementChildrenContentDecl:
                   6232:  * @ctxt:  an XML parser context
                   6233:  * @inputchk:  the input used for the current entity, needed for boundary checks
                   6234:  *
                   6235:  * parse the declaration for a Mixed Element content
                   6236:  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
                   6237:  *
                   6238:  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
                   6239:  *
                   6240:  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
                   6241:  *
                   6242:  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
                   6243:  *
                   6244:  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
                   6245:  *
                   6246:  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
                   6247:  * TODO Parameter-entity replacement text must be properly nested
                   6248:  *     with parenthesized groups. That is to say, if either of the
                   6249:  *     opening or closing parentheses in a choice, seq, or Mixed
                   6250:  *     construct is contained in the replacement text for a parameter
                   6251:  *     entity, both must be contained in the same replacement text. For
                   6252:  *     interoperability, if a parameter-entity reference appears in a
                   6253:  *     choice, seq, or Mixed construct, its replacement text should not
                   6254:  *     be empty, and neither the first nor last non-blank character of
                   6255:  *     the replacement text should be a connector (| or ,).
                   6256:  *
                   6257:  * Returns the tree of xmlElementContentPtr describing the element
                   6258:  *          hierarchy.
                   6259:  */
                   6260: xmlElementContentPtr
                   6261: xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
                   6262:     /* stub left for API/ABI compat */
                   6263:     return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
                   6264: }
                   6265: 
                   6266: /**
                   6267:  * xmlParseElementContentDecl:
                   6268:  * @ctxt:  an XML parser context
                   6269:  * @name:  the name of the element being defined.
                   6270:  * @result:  the Element Content pointer will be stored here if any
                   6271:  *
                   6272:  * parse the declaration for an Element content either Mixed or Children,
                   6273:  * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
                   6274:  * 
                   6275:  * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
                   6276:  *
                   6277:  * returns: the type of element content XML_ELEMENT_TYPE_xxx
                   6278:  */
                   6279: 
                   6280: int
                   6281: xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
                   6282:                            xmlElementContentPtr *result) {
                   6283: 
                   6284:     xmlElementContentPtr tree = NULL;
                   6285:     int inputid = ctxt->input->id;
                   6286:     int res;
                   6287: 
                   6288:     *result = NULL;
                   6289: 
                   6290:     if (RAW != '(') {
                   6291:        xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
                   6292:                "xmlParseElementContentDecl : %s '(' expected\n", name);
                   6293:        return(-1);
                   6294:     }
                   6295:     NEXT;
                   6296:     GROW;
                   6297:     SKIP_BLANKS;
                   6298:     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
                   6299:         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
                   6300:        res = XML_ELEMENT_TYPE_MIXED;
                   6301:     } else {
                   6302:         tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
                   6303:        res = XML_ELEMENT_TYPE_ELEMENT;
                   6304:     }
                   6305:     SKIP_BLANKS;
                   6306:     *result = tree;
                   6307:     return(res);
                   6308: }
                   6309: 
                   6310: /**
                   6311:  * xmlParseElementDecl:
                   6312:  * @ctxt:  an XML parser context
                   6313:  *
                   6314:  * parse an Element declaration.
                   6315:  *
                   6316:  * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
                   6317:  *
                   6318:  * [ VC: Unique Element Type Declaration ]
                   6319:  * No element type may be declared more than once
                   6320:  *
                   6321:  * Returns the type of the element, or -1 in case of error
                   6322:  */
                   6323: int
                   6324: xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
                   6325:     const xmlChar *name;
                   6326:     int ret = -1;
                   6327:     xmlElementContentPtr content  = NULL;
                   6328: 
                   6329:     /* GROW; done in the caller */
                   6330:     if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
                   6331:        xmlParserInputPtr input = ctxt->input;
                   6332: 
                   6333:        SKIP(9);
                   6334:        if (!IS_BLANK_CH(CUR)) {
                   6335:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   6336:                           "Space required after 'ELEMENT'\n");
                   6337:        }
                   6338:         SKIP_BLANKS;
                   6339:         name = xmlParseName(ctxt);
                   6340:        if (name == NULL) {
                   6341:            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   6342:                           "xmlParseElementDecl: no name for Element\n");
                   6343:            return(-1);
                   6344:        }
                   6345:        while ((RAW == 0) && (ctxt->inputNr > 1))
                   6346:            xmlPopInput(ctxt);
                   6347:        if (!IS_BLANK_CH(CUR)) {
                   6348:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   6349:                           "Space required after the element name\n");
                   6350:        }
                   6351:         SKIP_BLANKS;
                   6352:        if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
                   6353:            SKIP(5);
                   6354:            /*
                   6355:             * Element must always be empty.
                   6356:             */
                   6357:            ret = XML_ELEMENT_TYPE_EMPTY;
                   6358:        } else if ((RAW == 'A') && (NXT(1) == 'N') &&
                   6359:                   (NXT(2) == 'Y')) {
                   6360:            SKIP(3);
                   6361:            /*
                   6362:             * Element is a generic container.
                   6363:             */
                   6364:            ret = XML_ELEMENT_TYPE_ANY;
                   6365:        } else if (RAW == '(') {
                   6366:            ret = xmlParseElementContentDecl(ctxt, name, &content);
                   6367:        } else {
                   6368:            /*
                   6369:             * [ WFC: PEs in Internal Subset ] error handling.
                   6370:             */
                   6371:            if ((RAW == '%') && (ctxt->external == 0) &&
                   6372:                (ctxt->inputNr == 1)) {
                   6373:                xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
                   6374:          "PEReference: forbidden within markup decl in internal subset\n");
                   6375:            } else {
                   6376:                xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
                   6377:                      "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
                   6378:             }
                   6379:            return(-1);
                   6380:        }
                   6381: 
                   6382:        SKIP_BLANKS;
                   6383:        /*
                   6384:         * Pop-up of finished entities.
                   6385:         */
                   6386:        while ((RAW == 0) && (ctxt->inputNr > 1))
                   6387:            xmlPopInput(ctxt);
                   6388:        SKIP_BLANKS;
                   6389: 
                   6390:        if (RAW != '>') {
                   6391:            xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
                   6392:            if (content != NULL) {
                   6393:                xmlFreeDocElementContent(ctxt->myDoc, content);
                   6394:            }
                   6395:        } else {
                   6396:            if (input != ctxt->input) {
                   6397:                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   6398:     "Element declaration doesn't start and stop in the same entity\n");
                   6399:            }
                   6400:                
                   6401:            NEXT;
                   6402:            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   6403:                (ctxt->sax->elementDecl != NULL)) {
                   6404:                if (content != NULL)
                   6405:                    content->parent = NULL;
                   6406:                ctxt->sax->elementDecl(ctxt->userData, name, ret,
                   6407:                                       content);
                   6408:                if ((content != NULL) && (content->parent == NULL)) {
                   6409:                    /*
                   6410:                     * this is a trick: if xmlAddElementDecl is called,
                   6411:                     * instead of copying the full tree it is plugged directly
                   6412:                     * if called from the parser. Avoid duplicating the 
                   6413:                     * interfaces or change the API/ABI
                   6414:                     */
                   6415:                    xmlFreeDocElementContent(ctxt->myDoc, content);
                   6416:                }
                   6417:            } else if (content != NULL) {
                   6418:                xmlFreeDocElementContent(ctxt->myDoc, content);
                   6419:            }
                   6420:        }
                   6421:     }
                   6422:     return(ret);
                   6423: }
                   6424: 
                   6425: /**
                   6426:  * xmlParseConditionalSections
                   6427:  * @ctxt:  an XML parser context
                   6428:  *
                   6429:  * [61] conditionalSect ::= includeSect | ignoreSect 
                   6430:  * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>' 
                   6431:  * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
                   6432:  * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
                   6433:  * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
                   6434:  */
                   6435: 
                   6436: static void
                   6437: xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
                   6438:     int id = ctxt->input->id;
                   6439: 
                   6440:     SKIP(3);
                   6441:     SKIP_BLANKS;
                   6442:     if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
                   6443:        SKIP(7);
                   6444:        SKIP_BLANKS;
                   6445:        if (RAW != '[') {
                   6446:            xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
                   6447:        } else {
                   6448:            if (ctxt->input->id != id) {
                   6449:                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   6450:            "All markup of the conditional section is not in the same entity\n",
                   6451:                                     NULL, NULL);
                   6452:            }
                   6453:            NEXT;
                   6454:        }
                   6455:        if (xmlParserDebugEntities) {
                   6456:            if ((ctxt->input != NULL) && (ctxt->input->filename))
                   6457:                xmlGenericError(xmlGenericErrorContext,
                   6458:                        "%s(%d): ", ctxt->input->filename,
                   6459:                        ctxt->input->line);
                   6460:            xmlGenericError(xmlGenericErrorContext,
                   6461:                    "Entering INCLUDE Conditional Section\n");
                   6462:        }
                   6463: 
                   6464:        while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
                   6465:               (NXT(2) != '>'))) {
                   6466:            const xmlChar *check = CUR_PTR;
                   6467:            unsigned int cons = ctxt->input->consumed;
                   6468: 
                   6469:            if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
                   6470:                xmlParseConditionalSections(ctxt);
                   6471:            } else if (IS_BLANK_CH(CUR)) {
                   6472:                NEXT;
                   6473:            } else if (RAW == '%') {
                   6474:                xmlParsePEReference(ctxt);
                   6475:            } else
                   6476:                xmlParseMarkupDecl(ctxt);
                   6477: 
                   6478:            /*
                   6479:             * Pop-up of finished entities.
                   6480:             */
                   6481:            while ((RAW == 0) && (ctxt->inputNr > 1))
                   6482:                xmlPopInput(ctxt);
                   6483: 
                   6484:            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
                   6485:                xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
                   6486:                break;
                   6487:            }
                   6488:        }
                   6489:        if (xmlParserDebugEntities) {
                   6490:            if ((ctxt->input != NULL) && (ctxt->input->filename))
                   6491:                xmlGenericError(xmlGenericErrorContext,
                   6492:                        "%s(%d): ", ctxt->input->filename,
                   6493:                        ctxt->input->line);
                   6494:            xmlGenericError(xmlGenericErrorContext,
                   6495:                    "Leaving INCLUDE Conditional Section\n");
                   6496:        }
                   6497: 
                   6498:     } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
                   6499:        int state;
                   6500:        xmlParserInputState instate;
                   6501:        int depth = 0;
                   6502: 
                   6503:        SKIP(6);
                   6504:        SKIP_BLANKS;
                   6505:        if (RAW != '[') {
                   6506:            xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
                   6507:        } else {
                   6508:            if (ctxt->input->id != id) {
                   6509:                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   6510:            "All markup of the conditional section is not in the same entity\n",
                   6511:                                     NULL, NULL);
                   6512:            }
                   6513:            NEXT;
                   6514:        }
                   6515:        if (xmlParserDebugEntities) {
                   6516:            if ((ctxt->input != NULL) && (ctxt->input->filename))
                   6517:                xmlGenericError(xmlGenericErrorContext,
                   6518:                        "%s(%d): ", ctxt->input->filename,
                   6519:                        ctxt->input->line);
                   6520:            xmlGenericError(xmlGenericErrorContext,
                   6521:                    "Entering IGNORE Conditional Section\n");
                   6522:        }
                   6523: 
                   6524:        /*
                   6525:         * Parse up to the end of the conditional section
                   6526:         * But disable SAX event generating DTD building in the meantime
                   6527:         */
                   6528:        state = ctxt->disableSAX;
                   6529:        instate = ctxt->instate;
                   6530:        if (ctxt->recovery == 0) ctxt->disableSAX = 1;
                   6531:        ctxt->instate = XML_PARSER_IGNORE;
                   6532: 
                   6533:        while ((depth >= 0) && (RAW != 0)) {
                   6534:          if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
                   6535:            depth++;
                   6536:            SKIP(3);
                   6537:            continue;
                   6538:          }
                   6539:          if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
                   6540:            if (--depth >= 0) SKIP(3);
                   6541:            continue;
                   6542:          }
                   6543:          NEXT;
                   6544:          continue;
                   6545:        }
                   6546: 
                   6547:        ctxt->disableSAX = state;
                   6548:        ctxt->instate = instate;
                   6549: 
                   6550:        if (xmlParserDebugEntities) {
                   6551:            if ((ctxt->input != NULL) && (ctxt->input->filename))
                   6552:                xmlGenericError(xmlGenericErrorContext,
                   6553:                        "%s(%d): ", ctxt->input->filename,
                   6554:                        ctxt->input->line);
                   6555:            xmlGenericError(xmlGenericErrorContext,
                   6556:                    "Leaving IGNORE Conditional Section\n");
                   6557:        }
                   6558: 
                   6559:     } else {
                   6560:        xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
                   6561:     }
                   6562: 
                   6563:     if (RAW == 0)
                   6564:         SHRINK;
                   6565: 
                   6566:     if (RAW == 0) {
                   6567:        xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
                   6568:     } else {
                   6569:        if (ctxt->input->id != id) {
                   6570:            xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
                   6571:        "All markup of the conditional section is not in the same entity\n",
                   6572:                                 NULL, NULL);
                   6573:        }
                   6574:         SKIP(3);
                   6575:     }
                   6576: }
                   6577: 
                   6578: /**
                   6579:  * xmlParseMarkupDecl:
                   6580:  * @ctxt:  an XML parser context
                   6581:  * 
                   6582:  * parse Markup declarations
                   6583:  *
                   6584:  * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
                   6585:  *                     NotationDecl | PI | Comment
                   6586:  *
                   6587:  * [ VC: Proper Declaration/PE Nesting ]
                   6588:  * Parameter-entity replacement text must be properly nested with
                   6589:  * markup declarations. That is to say, if either the first character
                   6590:  * or the last character of a markup declaration (markupdecl above) is
                   6591:  * contained in the replacement text for a parameter-entity reference,
                   6592:  * both must be contained in the same replacement text.
                   6593:  *
                   6594:  * [ WFC: PEs in Internal Subset ]
                   6595:  * In the internal DTD subset, parameter-entity references can occur
                   6596:  * only where markup declarations can occur, not within markup declarations.
                   6597:  * (This does not apply to references that occur in external parameter
                   6598:  * entities or to the external subset.) 
                   6599:  */
                   6600: void
                   6601: xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
                   6602:     GROW;
                   6603:     if (CUR == '<') {
                   6604:         if (NXT(1) == '!') {
                   6605:            switch (NXT(2)) {
                   6606:                case 'E':
                   6607:                    if (NXT(3) == 'L')
                   6608:                        xmlParseElementDecl(ctxt);
                   6609:                    else if (NXT(3) == 'N')
                   6610:                        xmlParseEntityDecl(ctxt);
                   6611:                    break;
                   6612:                case 'A':
                   6613:                    xmlParseAttributeListDecl(ctxt);
                   6614:                    break;
                   6615:                case 'N':
                   6616:                    xmlParseNotationDecl(ctxt);
                   6617:                    break;
                   6618:                case '-':
                   6619:                    xmlParseComment(ctxt);
                   6620:                    break;
                   6621:                default:
                   6622:                    /* there is an error but it will be detected later */
                   6623:                    break;
                   6624:            }
                   6625:        } else if (NXT(1) == '?') {
                   6626:            xmlParsePI(ctxt);
                   6627:        }
                   6628:     }
                   6629:     /*
                   6630:      * This is only for internal subset. On external entities,
                   6631:      * the replacement is done before parsing stage
                   6632:      */
                   6633:     if ((ctxt->external == 0) && (ctxt->inputNr == 1))
                   6634:        xmlParsePEReference(ctxt);
                   6635: 
                   6636:     /*
                   6637:      * Conditional sections are allowed from entities included
                   6638:      * by PE References in the internal subset.
                   6639:      */
                   6640:     if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
                   6641:         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
                   6642:            xmlParseConditionalSections(ctxt);
                   6643:        }
                   6644:     }
                   6645: 
                   6646:     ctxt->instate = XML_PARSER_DTD;
                   6647: }
                   6648: 
                   6649: /**
                   6650:  * xmlParseTextDecl:
                   6651:  * @ctxt:  an XML parser context
                   6652:  *
                   6653:  * parse an XML declaration header for external entities
                   6654:  *
                   6655:  * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
                   6656:  */
                   6657: 
                   6658: void
                   6659: xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
                   6660:     xmlChar *version;
                   6661:     const xmlChar *encoding;
                   6662: 
                   6663:     /*
                   6664:      * We know that '<?xml' is here.
                   6665:      */
                   6666:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
                   6667:        SKIP(5);
                   6668:     } else {
                   6669:        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
                   6670:        return;
                   6671:     }
                   6672: 
                   6673:     if (!IS_BLANK_CH(CUR)) {
                   6674:        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   6675:                       "Space needed after '<?xml'\n");
                   6676:     }
                   6677:     SKIP_BLANKS;
                   6678: 
                   6679:     /*
                   6680:      * We may have the VersionInfo here.
                   6681:      */
                   6682:     version = xmlParseVersionInfo(ctxt);
                   6683:     if (version == NULL)
                   6684:        version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   6685:     else {
                   6686:        if (!IS_BLANK_CH(CUR)) {
                   6687:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   6688:                           "Space needed here\n");
                   6689:        }
                   6690:     }
                   6691:     ctxt->input->version = version;
                   6692: 
                   6693:     /*
                   6694:      * We must have the encoding declaration
                   6695:      */
                   6696:     encoding = xmlParseEncodingDecl(ctxt);
                   6697:     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   6698:        /*
                   6699:         * The XML REC instructs us to stop parsing right here
                   6700:         */
                   6701:         return;
                   6702:     }
                   6703:     if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
                   6704:        xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
                   6705:                       "Missing encoding in text declaration\n");
                   6706:     }
                   6707: 
                   6708:     SKIP_BLANKS;
                   6709:     if ((RAW == '?') && (NXT(1) == '>')) {
                   6710:         SKIP(2);
                   6711:     } else if (RAW == '>') {
                   6712:         /* Deprecated old WD ... */
                   6713:        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
                   6714:        NEXT;
                   6715:     } else {
                   6716:        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
                   6717:        MOVETO_ENDTAG(CUR_PTR);
                   6718:        NEXT;
                   6719:     }
                   6720: }
                   6721: 
                   6722: /**
                   6723:  * xmlParseExternalSubset:
                   6724:  * @ctxt:  an XML parser context
                   6725:  * @ExternalID: the external identifier
                   6726:  * @SystemID: the system identifier (or URL)
                   6727:  * 
                   6728:  * parse Markup declarations from an external subset
                   6729:  *
                   6730:  * [30] extSubset ::= textDecl? extSubsetDecl
                   6731:  *
                   6732:  * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
                   6733:  */
                   6734: void
                   6735: xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
                   6736:                        const xmlChar *SystemID) {
                   6737:     xmlDetectSAX2(ctxt);
                   6738:     GROW;
                   6739: 
                   6740:     if ((ctxt->encoding == NULL) &&
                   6741:         (ctxt->input->end - ctxt->input->cur >= 4)) {
                   6742:         xmlChar start[4];
                   6743:        xmlCharEncoding enc;
                   6744: 
                   6745:        start[0] = RAW;
                   6746:        start[1] = NXT(1);
                   6747:        start[2] = NXT(2);
                   6748:        start[3] = NXT(3);
                   6749:        enc = xmlDetectCharEncoding(start, 4);
                   6750:        if (enc != XML_CHAR_ENCODING_NONE)
                   6751:            xmlSwitchEncoding(ctxt, enc);
                   6752:     }
                   6753: 
                   6754:     if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
                   6755:        xmlParseTextDecl(ctxt);
                   6756:        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   6757:            /*
                   6758:             * The XML REC instructs us to stop parsing right here
                   6759:             */
                   6760:            ctxt->instate = XML_PARSER_EOF;
                   6761:            return;
                   6762:        }
                   6763:     }
                   6764:     if (ctxt->myDoc == NULL) {
                   6765:         ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
                   6766:        if (ctxt->myDoc == NULL) {
                   6767:            xmlErrMemory(ctxt, "New Doc failed");
                   6768:            return;
                   6769:        }
                   6770:        ctxt->myDoc->properties = XML_DOC_INTERNAL;
                   6771:     }
                   6772:     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
                   6773:         xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
                   6774: 
                   6775:     ctxt->instate = XML_PARSER_DTD;
                   6776:     ctxt->external = 1;
                   6777:     while (((RAW == '<') && (NXT(1) == '?')) ||
                   6778:            ((RAW == '<') && (NXT(1) == '!')) ||
                   6779:           (RAW == '%') || IS_BLANK_CH(CUR)) {
                   6780:        const xmlChar *check = CUR_PTR;
                   6781:        unsigned int cons = ctxt->input->consumed;
                   6782: 
                   6783:        GROW;
                   6784:         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
                   6785:            xmlParseConditionalSections(ctxt);
                   6786:        } else if (IS_BLANK_CH(CUR)) {
                   6787:            NEXT;
                   6788:        } else if (RAW == '%') {
                   6789:             xmlParsePEReference(ctxt);
                   6790:        } else
                   6791:            xmlParseMarkupDecl(ctxt);
                   6792: 
                   6793:        /*
                   6794:         * Pop-up of finished entities.
                   6795:         */
                   6796:        while ((RAW == 0) && (ctxt->inputNr > 1))
                   6797:            xmlPopInput(ctxt);
                   6798: 
                   6799:        if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
                   6800:            xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
                   6801:            break;
                   6802:        }
                   6803:     }
                   6804:     
                   6805:     if (RAW != 0) {
                   6806:        xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
                   6807:     }
                   6808: 
                   6809: }
                   6810: 
                   6811: /**
                   6812:  * xmlParseReference:
                   6813:  * @ctxt:  an XML parser context
                   6814:  *
                   6815:  * parse and handle entity references in content, depending on the SAX
                   6816:  * interface, this may end-up in a call to character() if this is a
                   6817:  * CharRef, a predefined entity, if there is no reference() callback.
                   6818:  * or if the parser was asked to switch to that mode.
                   6819:  *
                   6820:  * [67] Reference ::= EntityRef | CharRef
                   6821:  */
                   6822: void
                   6823: xmlParseReference(xmlParserCtxtPtr ctxt) {
                   6824:     xmlEntityPtr ent;
                   6825:     xmlChar *val;
                   6826:     int was_checked;
                   6827:     xmlNodePtr list = NULL;
                   6828:     xmlParserErrors ret = XML_ERR_OK;
                   6829: 
                   6830: 
                   6831:     if (RAW != '&')
                   6832:         return;
                   6833: 
                   6834:     /*
                   6835:      * Simple case of a CharRef
                   6836:      */
                   6837:     if (NXT(1) == '#') {
                   6838:        int i = 0;
                   6839:        xmlChar out[10];
                   6840:        int hex = NXT(2);
                   6841:        int value = xmlParseCharRef(ctxt);
                   6842: 
                   6843:        if (value == 0)
                   6844:            return;
                   6845:        if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
                   6846:            /*
                   6847:             * So we are using non-UTF-8 buffers
                   6848:             * Check that the char fit on 8bits, if not
                   6849:             * generate a CharRef.
                   6850:             */
                   6851:            if (value <= 0xFF) {
                   6852:                out[0] = value;
                   6853:                out[1] = 0;
                   6854:                if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
                   6855:                    (!ctxt->disableSAX))
                   6856:                    ctxt->sax->characters(ctxt->userData, out, 1);
                   6857:            } else {
                   6858:                if ((hex == 'x') || (hex == 'X'))
                   6859:                    snprintf((char *)out, sizeof(out), "#x%X", value);
                   6860:                else
                   6861:                    snprintf((char *)out, sizeof(out), "#%d", value);
                   6862:                if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
                   6863:                    (!ctxt->disableSAX))
                   6864:                    ctxt->sax->reference(ctxt->userData, out);
                   6865:            }
                   6866:        } else {
                   6867:            /*
                   6868:             * Just encode the value in UTF-8
                   6869:             */
                   6870:            COPY_BUF(0 ,out, i, value);
                   6871:            out[i] = 0;
                   6872:            if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
                   6873:                (!ctxt->disableSAX))
                   6874:                ctxt->sax->characters(ctxt->userData, out, i);
                   6875:        }
                   6876:        return;
                   6877:     }
                   6878: 
                   6879:     /*
                   6880:      * We are seeing an entity reference
                   6881:      */
                   6882:     ent = xmlParseEntityRef(ctxt);
                   6883:     if (ent == NULL) return;
                   6884:     if (!ctxt->wellFormed)
                   6885:        return;
                   6886:     was_checked = ent->checked;
                   6887: 
                   6888:     /* special case of predefined entities */
                   6889:     if ((ent->name == NULL) ||
                   6890:         (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
                   6891:        val = ent->content;
                   6892:        if (val == NULL) return;
                   6893:        /*
                   6894:         * inline the entity.
                   6895:         */
                   6896:        if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
                   6897:            (!ctxt->disableSAX))
                   6898:            ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
                   6899:        return;
                   6900:     }
                   6901: 
                   6902:     /*
                   6903:      * The first reference to the entity trigger a parsing phase
                   6904:      * where the ent->children is filled with the result from
                   6905:      * the parsing.
                   6906:      */
                   6907:     if (ent->checked == 0) {
                   6908:        unsigned long oldnbent = ctxt->nbentities;
                   6909: 
                   6910:        /*
                   6911:         * This is a bit hackish but this seems the best
                   6912:         * way to make sure both SAX and DOM entity support
                   6913:         * behaves okay.
                   6914:         */
                   6915:        void *user_data;
                   6916:        if (ctxt->userData == ctxt)
                   6917:            user_data = NULL;
                   6918:        else
                   6919:            user_data = ctxt->userData;
                   6920: 
                   6921:        /*
                   6922:         * Check that this entity is well formed
                   6923:         * 4.3.2: An internal general parsed entity is well-formed
                   6924:         * if its replacement text matches the production labeled
                   6925:         * content.
                   6926:         */
                   6927:        if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
                   6928:            ctxt->depth++;
                   6929:            ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
                   6930:                                                      user_data, &list);
                   6931:            ctxt->depth--;
                   6932: 
                   6933:        } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
                   6934:            ctxt->depth++;
                   6935:            ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
                   6936:                                           user_data, ctxt->depth, ent->URI,
                   6937:                                           ent->ExternalID, &list);
                   6938:            ctxt->depth--;
                   6939:        } else {
                   6940:            ret = XML_ERR_ENTITY_PE_INTERNAL;
                   6941:            xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
                   6942:                         "invalid entity type found\n", NULL);
                   6943:        }
                   6944: 
                   6945:        /*
                   6946:         * Store the number of entities needing parsing for this entity
                   6947:         * content and do checkings
                   6948:         */
                   6949:        ent->checked = ctxt->nbentities - oldnbent;
                   6950:        if (ret == XML_ERR_ENTITY_LOOP) {
                   6951:            xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
                   6952:            xmlFreeNodeList(list);
                   6953:            return;
                   6954:        }
                   6955:        if (xmlParserEntityCheck(ctxt, 0, ent)) {
                   6956:            xmlFreeNodeList(list);
                   6957:            return;
                   6958:        }
                   6959: 
                   6960:        if ((ret == XML_ERR_OK) && (list != NULL)) {
                   6961:            if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
                   6962:             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
                   6963:                (ent->children == NULL)) {
                   6964:                ent->children = list;
                   6965:                if (ctxt->replaceEntities) {
                   6966:                    /*
                   6967:                     * Prune it directly in the generated document
                   6968:                     * except for single text nodes.
                   6969:                     */
                   6970:                    if (((list->type == XML_TEXT_NODE) &&
                   6971:                         (list->next == NULL)) ||
                   6972:                        (ctxt->parseMode == XML_PARSE_READER)) {
                   6973:                        list->parent = (xmlNodePtr) ent;
                   6974:                        list = NULL;
                   6975:                        ent->owner = 1;
                   6976:                    } else {
                   6977:                        ent->owner = 0;
                   6978:                        while (list != NULL) {
                   6979:                            list->parent = (xmlNodePtr) ctxt->node;
                   6980:                            list->doc = ctxt->myDoc;
                   6981:                            if (list->next == NULL)
                   6982:                                ent->last = list;
                   6983:                            list = list->next;
                   6984:                        }
                   6985:                        list = ent->children;
                   6986: #ifdef LIBXML_LEGACY_ENABLED
                   6987:                        if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
                   6988:                          xmlAddEntityReference(ent, list, NULL);
                   6989: #endif /* LIBXML_LEGACY_ENABLED */
                   6990:                    }
                   6991:                } else {
                   6992:                    ent->owner = 1;
                   6993:                    while (list != NULL) {
                   6994:                        list->parent = (xmlNodePtr) ent;
                   6995:                        if (list->next == NULL)
                   6996:                            ent->last = list;
                   6997:                        list = list->next;
                   6998:                    }
                   6999:                }
                   7000:            } else {
                   7001:                xmlFreeNodeList(list);
                   7002:                list = NULL;
                   7003:            }
                   7004:        } else if ((ret != XML_ERR_OK) &&
                   7005:                   (ret != XML_WAR_UNDECLARED_ENTITY)) {
                   7006:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   7007:                     "Entity '%s' failed to parse\n", ent->name);
                   7008:        } else if (list != NULL) {
                   7009:            xmlFreeNodeList(list);
                   7010:            list = NULL;
                   7011:        }
                   7012:        if (ent->checked == 0)
                   7013:            ent->checked = 1;
                   7014:     } else if (ent->checked != 1) {
                   7015:        ctxt->nbentities += ent->checked;
                   7016:     }
                   7017: 
                   7018:     /*
                   7019:      * Now that the entity content has been gathered
                   7020:      * provide it to the application, this can take different forms based
                   7021:      * on the parsing modes.
                   7022:      */
                   7023:     if (ent->children == NULL) {
                   7024:        /*
                   7025:         * Probably running in SAX mode and the callbacks don't
                   7026:         * build the entity content. So unless we already went
                   7027:         * though parsing for first checking go though the entity
                   7028:         * content to generate callbacks associated to the entity
                   7029:         */
                   7030:        if (was_checked != 0) {
                   7031:            void *user_data;
                   7032:            /*
                   7033:             * This is a bit hackish but this seems the best
                   7034:             * way to make sure both SAX and DOM entity support
                   7035:             * behaves okay.
                   7036:             */
                   7037:            if (ctxt->userData == ctxt)
                   7038:                user_data = NULL;
                   7039:            else
                   7040:                user_data = ctxt->userData;
                   7041: 
                   7042:            if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
                   7043:                ctxt->depth++;
                   7044:                ret = xmlParseBalancedChunkMemoryInternal(ctxt,
                   7045:                                   ent->content, user_data, NULL);
                   7046:                ctxt->depth--;
                   7047:            } else if (ent->etype ==
                   7048:                       XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
                   7049:                ctxt->depth++;
                   7050:                ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
                   7051:                           ctxt->sax, user_data, ctxt->depth,
                   7052:                           ent->URI, ent->ExternalID, NULL);
                   7053:                ctxt->depth--;
                   7054:            } else {
                   7055:                ret = XML_ERR_ENTITY_PE_INTERNAL;
                   7056:                xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
                   7057:                             "invalid entity type found\n", NULL);
                   7058:            }
                   7059:            if (ret == XML_ERR_ENTITY_LOOP) {
                   7060:                xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
                   7061:                return;
                   7062:            }
                   7063:        }
                   7064:        if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
                   7065:            (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
                   7066:            /*
                   7067:             * Entity reference callback comes second, it's somewhat
                   7068:             * superfluous but a compatibility to historical behaviour
                   7069:             */
                   7070:            ctxt->sax->reference(ctxt->userData, ent->name);
                   7071:        }
                   7072:        return;
                   7073:     }
                   7074: 
                   7075:     /*
                   7076:      * If we didn't get any children for the entity being built
                   7077:      */
                   7078:     if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
                   7079:        (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
                   7080:        /*
                   7081:         * Create a node.
                   7082:         */
                   7083:        ctxt->sax->reference(ctxt->userData, ent->name);
                   7084:        return;
                   7085:     }
                   7086: 
                   7087:     if ((ctxt->replaceEntities) || (ent->children == NULL))  {
                   7088:        /*
                   7089:         * There is a problem on the handling of _private for entities
                   7090:         * (bug 155816): Should we copy the content of the field from
                   7091:         * the entity (possibly overwriting some value set by the user
                   7092:         * when a copy is created), should we leave it alone, or should
                   7093:         * we try to take care of different situations?  The problem
                   7094:         * is exacerbated by the usage of this field by the xmlReader.
                   7095:         * To fix this bug, we look at _private on the created node
                   7096:         * and, if it's NULL, we copy in whatever was in the entity.
                   7097:         * If it's not NULL we leave it alone.  This is somewhat of a
                   7098:         * hack - maybe we should have further tests to determine
                   7099:         * what to do.
                   7100:         */
                   7101:        if ((ctxt->node != NULL) && (ent->children != NULL)) {
                   7102:            /*
                   7103:             * Seems we are generating the DOM content, do
                   7104:             * a simple tree copy for all references except the first
                   7105:             * In the first occurrence list contains the replacement.
                   7106:             * progressive == 2 means we are operating on the Reader
                   7107:             * and since nodes are discarded we must copy all the time.
                   7108:             */
                   7109:            if (((list == NULL) && (ent->owner == 0)) ||
                   7110:                (ctxt->parseMode == XML_PARSE_READER)) {
                   7111:                xmlNodePtr nw = NULL, cur, firstChild = NULL;
                   7112: 
                   7113:                /*
                   7114:                 * when operating on a reader, the entities definitions
                   7115:                 * are always owning the entities subtree.
                   7116:                if (ctxt->parseMode == XML_PARSE_READER)
                   7117:                    ent->owner = 1;
                   7118:                 */
                   7119: 
                   7120:                cur = ent->children;
                   7121:                while (cur != NULL) {
                   7122:                    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
                   7123:                    if (nw != NULL) {
                   7124:                        if (nw->_private == NULL)
                   7125:                            nw->_private = cur->_private;
                   7126:                        if (firstChild == NULL){
                   7127:                            firstChild = nw;
                   7128:                        }
                   7129:                        nw = xmlAddChild(ctxt->node, nw);
                   7130:                    }
                   7131:                    if (cur == ent->last) {
                   7132:                        /*
                   7133:                         * needed to detect some strange empty
                   7134:                         * node cases in the reader tests
                   7135:                         */
                   7136:                        if ((ctxt->parseMode == XML_PARSE_READER) &&
                   7137:                            (nw != NULL) &&
                   7138:                            (nw->type == XML_ELEMENT_NODE) &&
                   7139:                            (nw->children == NULL))
                   7140:                            nw->extra = 1;
                   7141: 
                   7142:                        break;
                   7143:                    }
                   7144:                    cur = cur->next;
                   7145:                }
                   7146: #ifdef LIBXML_LEGACY_ENABLED
                   7147:                if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
                   7148:                  xmlAddEntityReference(ent, firstChild, nw);
                   7149: #endif /* LIBXML_LEGACY_ENABLED */
                   7150:            } else if (list == NULL) {
                   7151:                xmlNodePtr nw = NULL, cur, next, last,
                   7152:                           firstChild = NULL;
                   7153:                /*
                   7154:                 * Copy the entity child list and make it the new
                   7155:                 * entity child list. The goal is to make sure any
                   7156:                 * ID or REF referenced will be the one from the
                   7157:                 * document content and not the entity copy.
                   7158:                 */
                   7159:                cur = ent->children;
                   7160:                ent->children = NULL;
                   7161:                last = ent->last;
                   7162:                ent->last = NULL;
                   7163:                while (cur != NULL) {
                   7164:                    next = cur->next;
                   7165:                    cur->next = NULL;
                   7166:                    cur->parent = NULL;
                   7167:                    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
                   7168:                    if (nw != NULL) {
                   7169:                        if (nw->_private == NULL)
                   7170:                            nw->_private = cur->_private;
                   7171:                        if (firstChild == NULL){
                   7172:                            firstChild = cur;
                   7173:                        }
                   7174:                        xmlAddChild((xmlNodePtr) ent, nw);
                   7175:                        xmlAddChild(ctxt->node, cur);
                   7176:                    }
                   7177:                    if (cur == last)
                   7178:                        break;
                   7179:                    cur = next;
                   7180:                }
                   7181:                if (ent->owner == 0)
                   7182:                    ent->owner = 1;
                   7183: #ifdef LIBXML_LEGACY_ENABLED
                   7184:                if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
                   7185:                  xmlAddEntityReference(ent, firstChild, nw);
                   7186: #endif /* LIBXML_LEGACY_ENABLED */
                   7187:            } else {
                   7188:                const xmlChar *nbktext;
                   7189: 
                   7190:                /*
                   7191:                 * the name change is to avoid coalescing of the
                   7192:                 * node with a possible previous text one which
                   7193:                 * would make ent->children a dangling pointer
                   7194:                 */
                   7195:                nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
                   7196:                                        -1);
                   7197:                if (ent->children->type == XML_TEXT_NODE)
                   7198:                    ent->children->name = nbktext;
                   7199:                if ((ent->last != ent->children) &&
                   7200:                    (ent->last->type == XML_TEXT_NODE))
                   7201:                    ent->last->name = nbktext;
                   7202:                xmlAddChildList(ctxt->node, ent->children);
                   7203:            }
                   7204: 
                   7205:            /*
                   7206:             * This is to avoid a nasty side effect, see
                   7207:             * characters() in SAX.c
                   7208:             */
                   7209:            ctxt->nodemem = 0;
                   7210:            ctxt->nodelen = 0;
                   7211:            return;
                   7212:        }
                   7213:     }
                   7214: }
                   7215: 
                   7216: /**
                   7217:  * xmlParseEntityRef:
                   7218:  * @ctxt:  an XML parser context
                   7219:  *
                   7220:  * parse ENTITY references declarations
                   7221:  *
                   7222:  * [68] EntityRef ::= '&' Name ';'
                   7223:  *
                   7224:  * [ WFC: Entity Declared ]
                   7225:  * In a document without any DTD, a document with only an internal DTD
                   7226:  * subset which contains no parameter entity references, or a document
                   7227:  * with "standalone='yes'", the Name given in the entity reference
                   7228:  * must match that in an entity declaration, except that well-formed
                   7229:  * documents need not declare any of the following entities: amp, lt,
                   7230:  * gt, apos, quot.  The declaration of a parameter entity must precede
                   7231:  * any reference to it.  Similarly, the declaration of a general entity
                   7232:  * must precede any reference to it which appears in a default value in an
                   7233:  * attribute-list declaration. Note that if entities are declared in the
                   7234:  * external subset or in external parameter entities, a non-validating
                   7235:  * processor is not obligated to read and process their declarations;
                   7236:  * for such documents, the rule that an entity must be declared is a
                   7237:  * well-formedness constraint only if standalone='yes'.
                   7238:  *
                   7239:  * [ WFC: Parsed Entity ]
                   7240:  * An entity reference must not contain the name of an unparsed entity
                   7241:  *
                   7242:  * Returns the xmlEntityPtr if found, or NULL otherwise.
                   7243:  */
                   7244: xmlEntityPtr
                   7245: xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
                   7246:     const xmlChar *name;
                   7247:     xmlEntityPtr ent = NULL;
                   7248: 
                   7249:     GROW;
                   7250: 
                   7251:     if (RAW != '&')
                   7252:         return(NULL);
                   7253:     NEXT;
                   7254:     name = xmlParseName(ctxt);
                   7255:     if (name == NULL) {
                   7256:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   7257:                       "xmlParseEntityRef: no name\n");
                   7258:         return(NULL);
                   7259:     }
                   7260:     if (RAW != ';') {
                   7261:        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
                   7262:        return(NULL);
                   7263:     }
                   7264:     NEXT;
                   7265: 
                   7266:     /*
                   7267:      * Predefined entites override any extra definition
                   7268:      */
                   7269:     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
                   7270:         ent = xmlGetPredefinedEntity(name);
                   7271:         if (ent != NULL)
                   7272:             return(ent);
                   7273:     }
                   7274: 
                   7275:     /*
                   7276:      * Increate the number of entity references parsed
                   7277:      */
                   7278:     ctxt->nbentities++;
                   7279: 
                   7280:     /*
                   7281:      * Ask first SAX for entity resolution, otherwise try the
                   7282:      * entities which may have stored in the parser context.
                   7283:      */
                   7284:     if (ctxt->sax != NULL) {
                   7285:        if (ctxt->sax->getEntity != NULL)
                   7286:            ent = ctxt->sax->getEntity(ctxt->userData, name);
                   7287:        if ((ctxt->wellFormed == 1 ) && (ent == NULL) && 
                   7288:            (ctxt->options & XML_PARSE_OLDSAX))
                   7289:            ent = xmlGetPredefinedEntity(name);
                   7290:        if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
                   7291:            (ctxt->userData==ctxt)) {
                   7292:            ent = xmlSAX2GetEntity(ctxt, name);
                   7293:        }
                   7294:     }
                   7295:     /*
                   7296:      * [ WFC: Entity Declared ]
                   7297:      * In a document without any DTD, a document with only an
                   7298:      * internal DTD subset which contains no parameter entity
                   7299:      * references, or a document with "standalone='yes'", the
                   7300:      * Name given in the entity reference must match that in an
                   7301:      * entity declaration, except that well-formed documents
                   7302:      * need not declare any of the following entities: amp, lt,
                   7303:      * gt, apos, quot.
                   7304:      * The declaration of a parameter entity must precede any
                   7305:      * reference to it.
                   7306:      * Similarly, the declaration of a general entity must
                   7307:      * precede any reference to it which appears in a default
                   7308:      * value in an attribute-list declaration. Note that if
                   7309:      * entities are declared in the external subset or in
                   7310:      * external parameter entities, a non-validating processor
                   7311:      * is not obligated to read and process their declarations;
                   7312:      * for such documents, the rule that an entity must be
                   7313:      * declared is a well-formedness constraint only if
                   7314:      * standalone='yes'.
                   7315:      */
                   7316:     if (ent == NULL) {
                   7317:        if ((ctxt->standalone == 1) ||
                   7318:            ((ctxt->hasExternalSubset == 0) &&
                   7319:             (ctxt->hasPErefs == 0))) {
                   7320:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   7321:                     "Entity '%s' not defined\n", name);
                   7322:        } else {
                   7323:            xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7324:                     "Entity '%s' not defined\n", name);
                   7325:            if ((ctxt->inSubset == 0) &&
                   7326:                (ctxt->sax != NULL) &&
                   7327:                (ctxt->sax->reference != NULL)) {
                   7328:                ctxt->sax->reference(ctxt->userData, name);
                   7329:            }
                   7330:        }
                   7331:        ctxt->valid = 0;
                   7332:     }
                   7333: 
                   7334:     /*
                   7335:      * [ WFC: Parsed Entity ]
                   7336:      * An entity reference must not contain the name of an
                   7337:      * unparsed entity
                   7338:      */
                   7339:     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
                   7340:        xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
                   7341:                 "Entity reference to unparsed entity %s\n", name);
                   7342:     }
                   7343: 
                   7344:     /*
                   7345:      * [ WFC: No External Entity References ]
                   7346:      * Attribute values cannot contain direct or indirect
                   7347:      * entity references to external entities.
                   7348:      */
                   7349:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   7350:             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
                   7351:        xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
                   7352:             "Attribute references external entity '%s'\n", name);
                   7353:     }
                   7354:     /*
                   7355:      * [ WFC: No < in Attribute Values ]
                   7356:      * The replacement text of any entity referred to directly or
                   7357:      * indirectly in an attribute value (other than "&lt;") must
                   7358:      * not contain a <. 
                   7359:      */
                   7360:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   7361:             (ent != NULL) && (ent->content != NULL) &&
                   7362:             (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
                   7363:             (xmlStrchr(ent->content, '<'))) {
                   7364:        xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
                   7365:     "'<' in entity '%s' is not allowed in attributes values\n", name);
                   7366:     }
                   7367: 
                   7368:     /*
                   7369:      * Internal check, no parameter entities here ...
                   7370:      */
                   7371:     else {
                   7372:        switch (ent->etype) {
                   7373:            case XML_INTERNAL_PARAMETER_ENTITY:
                   7374:            case XML_EXTERNAL_PARAMETER_ENTITY:
                   7375:            xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
                   7376:             "Attempt to reference the parameter entity '%s'\n",
                   7377:                              name);
                   7378:            break;
                   7379:            default:
                   7380:            break;
                   7381:        }
                   7382:     }
                   7383: 
                   7384:     /*
                   7385:      * [ WFC: No Recursion ]
                   7386:      * A parsed entity must not contain a recursive reference
                   7387:      * to itself, either directly or indirectly. 
                   7388:      * Done somewhere else
                   7389:      */
                   7390:     return(ent);
                   7391: }
                   7392: 
                   7393: /**
                   7394:  * xmlParseStringEntityRef:
                   7395:  * @ctxt:  an XML parser context
                   7396:  * @str:  a pointer to an index in the string
                   7397:  *
                   7398:  * parse ENTITY references declarations, but this version parses it from
                   7399:  * a string value.
                   7400:  *
                   7401:  * [68] EntityRef ::= '&' Name ';'
                   7402:  *
                   7403:  * [ WFC: Entity Declared ]
                   7404:  * In a document without any DTD, a document with only an internal DTD
                   7405:  * subset which contains no parameter entity references, or a document
                   7406:  * with "standalone='yes'", the Name given in the entity reference
                   7407:  * must match that in an entity declaration, except that well-formed
                   7408:  * documents need not declare any of the following entities: amp, lt,
                   7409:  * gt, apos, quot.  The declaration of a parameter entity must precede
                   7410:  * any reference to it.  Similarly, the declaration of a general entity
                   7411:  * must precede any reference to it which appears in a default value in an
                   7412:  * attribute-list declaration. Note that if entities are declared in the
                   7413:  * external subset or in external parameter entities, a non-validating
                   7414:  * processor is not obligated to read and process their declarations;
                   7415:  * for such documents, the rule that an entity must be declared is a
                   7416:  * well-formedness constraint only if standalone='yes'.
                   7417:  *
                   7418:  * [ WFC: Parsed Entity ]
                   7419:  * An entity reference must not contain the name of an unparsed entity
                   7420:  *
                   7421:  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
                   7422:  * is updated to the current location in the string.
                   7423:  */
                   7424: static xmlEntityPtr
                   7425: xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
                   7426:     xmlChar *name;
                   7427:     const xmlChar *ptr;
                   7428:     xmlChar cur;
                   7429:     xmlEntityPtr ent = NULL;
                   7430: 
                   7431:     if ((str == NULL) || (*str == NULL))
                   7432:         return(NULL);
                   7433:     ptr = *str;
                   7434:     cur = *ptr;
                   7435:     if (cur != '&')
                   7436:        return(NULL);
                   7437: 
                   7438:     ptr++;
                   7439:     name = xmlParseStringName(ctxt, &ptr);
                   7440:     if (name == NULL) {
                   7441:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   7442:                       "xmlParseStringEntityRef: no name\n");
                   7443:        *str = ptr;
                   7444:        return(NULL);
                   7445:     }
                   7446:     if (*ptr != ';') {
                   7447:        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
                   7448:         xmlFree(name);
                   7449:        *str = ptr;
                   7450:        return(NULL);
                   7451:     }
                   7452:     ptr++;
                   7453: 
                   7454: 
                   7455:     /*
                   7456:      * Predefined entites override any extra definition
                   7457:      */
                   7458:     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
                   7459:         ent = xmlGetPredefinedEntity(name);
                   7460:         if (ent != NULL) {
                   7461:             xmlFree(name);
                   7462:             *str = ptr;
                   7463:             return(ent);
                   7464:         }
                   7465:     }
                   7466: 
                   7467:     /*
                   7468:      * Increate the number of entity references parsed
                   7469:      */
                   7470:     ctxt->nbentities++;
                   7471: 
                   7472:     /*
                   7473:      * Ask first SAX for entity resolution, otherwise try the
                   7474:      * entities which may have stored in the parser context.
                   7475:      */
                   7476:     if (ctxt->sax != NULL) {
                   7477:        if (ctxt->sax->getEntity != NULL)
                   7478:            ent = ctxt->sax->getEntity(ctxt->userData, name);
                   7479:        if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
                   7480:            ent = xmlGetPredefinedEntity(name);
                   7481:        if ((ent == NULL) && (ctxt->userData==ctxt)) {
                   7482:            ent = xmlSAX2GetEntity(ctxt, name);
                   7483:        }
                   7484:     }
                   7485: 
                   7486:     /*
                   7487:      * [ WFC: Entity Declared ]
                   7488:      * In a document without any DTD, a document with only an
                   7489:      * internal DTD subset which contains no parameter entity
                   7490:      * references, or a document with "standalone='yes'", the
                   7491:      * Name given in the entity reference must match that in an
                   7492:      * entity declaration, except that well-formed documents
                   7493:      * need not declare any of the following entities: amp, lt,
                   7494:      * gt, apos, quot.
                   7495:      * The declaration of a parameter entity must precede any
                   7496:      * reference to it.
                   7497:      * Similarly, the declaration of a general entity must
                   7498:      * precede any reference to it which appears in a default
                   7499:      * value in an attribute-list declaration. Note that if
                   7500:      * entities are declared in the external subset or in
                   7501:      * external parameter entities, a non-validating processor
                   7502:      * is not obligated to read and process their declarations;
                   7503:      * for such documents, the rule that an entity must be
                   7504:      * declared is a well-formedness constraint only if
                   7505:      * standalone='yes'. 
                   7506:      */
                   7507:     if (ent == NULL) {
                   7508:        if ((ctxt->standalone == 1) ||
                   7509:            ((ctxt->hasExternalSubset == 0) &&
                   7510:             (ctxt->hasPErefs == 0))) {
                   7511:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   7512:                     "Entity '%s' not defined\n", name);
                   7513:        } else {
                   7514:            xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7515:                          "Entity '%s' not defined\n",
                   7516:                          name);
                   7517:        }
                   7518:        /* TODO ? check regressions ctxt->valid = 0; */
                   7519:     }
                   7520: 
                   7521:     /*
                   7522:      * [ WFC: Parsed Entity ]
                   7523:      * An entity reference must not contain the name of an
                   7524:      * unparsed entity
                   7525:      */
                   7526:     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
                   7527:        xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
                   7528:                 "Entity reference to unparsed entity %s\n", name);
                   7529:     }
                   7530: 
                   7531:     /*
                   7532:      * [ WFC: No External Entity References ]
                   7533:      * Attribute values cannot contain direct or indirect
                   7534:      * entity references to external entities.
                   7535:      */
                   7536:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   7537:             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
                   7538:        xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
                   7539:         "Attribute references external entity '%s'\n", name);
                   7540:     }
                   7541:     /*
                   7542:      * [ WFC: No < in Attribute Values ]
                   7543:      * The replacement text of any entity referred to directly or
                   7544:      * indirectly in an attribute value (other than "&lt;") must
                   7545:      * not contain a <.
                   7546:      */
                   7547:     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
                   7548:             (ent != NULL) && (ent->content != NULL) &&
                   7549:             (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
                   7550:             (xmlStrchr(ent->content, '<'))) {
                   7551:        xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
                   7552:      "'<' in entity '%s' is not allowed in attributes values\n",
                   7553:                          name);
                   7554:     }
                   7555: 
                   7556:     /*
                   7557:      * Internal check, no parameter entities here ...
                   7558:      */
                   7559:     else {
                   7560:        switch (ent->etype) {
                   7561:            case XML_INTERNAL_PARAMETER_ENTITY:
                   7562:            case XML_EXTERNAL_PARAMETER_ENTITY:
                   7563:                xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
                   7564:             "Attempt to reference the parameter entity '%s'\n",
                   7565:                                  name);
                   7566:            break;
                   7567:            default:
                   7568:            break;
                   7569:        }
                   7570:     }
                   7571: 
                   7572:     /*
                   7573:      * [ WFC: No Recursion ]
                   7574:      * A parsed entity must not contain a recursive reference
                   7575:      * to itself, either directly or indirectly.
                   7576:      * Done somewhere else
                   7577:      */
                   7578: 
                   7579:     xmlFree(name);
                   7580:     *str = ptr;
                   7581:     return(ent);
                   7582: }
                   7583: 
                   7584: /**
                   7585:  * xmlParsePEReference:
                   7586:  * @ctxt:  an XML parser context
                   7587:  *
                   7588:  * parse PEReference declarations
                   7589:  * The entity content is handled directly by pushing it's content as
                   7590:  * a new input stream.
                   7591:  *
                   7592:  * [69] PEReference ::= '%' Name ';'
                   7593:  *
                   7594:  * [ WFC: No Recursion ]
                   7595:  * A parsed entity must not contain a recursive
                   7596:  * reference to itself, either directly or indirectly. 
                   7597:  *
                   7598:  * [ WFC: Entity Declared ]
                   7599:  * In a document without any DTD, a document with only an internal DTD
                   7600:  * subset which contains no parameter entity references, or a document
                   7601:  * with "standalone='yes'", ...  ... The declaration of a parameter
                   7602:  * entity must precede any reference to it...
                   7603:  *
                   7604:  * [ VC: Entity Declared ]
                   7605:  * In a document with an external subset or external parameter entities
                   7606:  * with "standalone='no'", ...  ... The declaration of a parameter entity
                   7607:  * must precede any reference to it...
                   7608:  *
                   7609:  * [ WFC: In DTD ]
                   7610:  * Parameter-entity references may only appear in the DTD.
                   7611:  * NOTE: misleading but this is handled.
                   7612:  */
                   7613: void
                   7614: xmlParsePEReference(xmlParserCtxtPtr ctxt)
                   7615: {
                   7616:     const xmlChar *name;
                   7617:     xmlEntityPtr entity = NULL;
                   7618:     xmlParserInputPtr input;
                   7619: 
                   7620:     if (RAW != '%')
                   7621:         return;
                   7622:     NEXT;
                   7623:     name = xmlParseName(ctxt);
                   7624:     if (name == NULL) {
                   7625:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   7626:                       "xmlParsePEReference: no name\n");
                   7627:        return;
                   7628:     }
                   7629:     if (RAW != ';') {
                   7630:        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
                   7631:         return;
                   7632:     }
                   7633: 
                   7634:     NEXT;
                   7635: 
                   7636:     /*
                   7637:      * Increate the number of entity references parsed
                   7638:      */
                   7639:     ctxt->nbentities++;
                   7640: 
                   7641:     /*
                   7642:      * Request the entity from SAX
                   7643:      */
                   7644:     if ((ctxt->sax != NULL) &&
                   7645:        (ctxt->sax->getParameterEntity != NULL))
                   7646:        entity = ctxt->sax->getParameterEntity(ctxt->userData,
                   7647:                                               name);
                   7648:     if (entity == NULL) {
                   7649:        /*
                   7650:         * [ WFC: Entity Declared ]
                   7651:         * In a document without any DTD, a document with only an
                   7652:         * internal DTD subset which contains no parameter entity
                   7653:         * references, or a document with "standalone='yes'", ...
                   7654:         * ... The declaration of a parameter entity must precede
                   7655:         * any reference to it...
                   7656:         */
                   7657:        if ((ctxt->standalone == 1) ||
                   7658:            ((ctxt->hasExternalSubset == 0) &&
                   7659:             (ctxt->hasPErefs == 0))) {
                   7660:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   7661:                              "PEReference: %%%s; not found\n",
                   7662:                              name);
                   7663:        } else {
                   7664:            /*
                   7665:             * [ VC: Entity Declared ]
                   7666:             * In a document with an external subset or external
                   7667:             * parameter entities with "standalone='no'", ...
                   7668:             * ... The declaration of a parameter entity must
                   7669:             * precede any reference to it...
                   7670:             */
                   7671:            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7672:                          "PEReference: %%%s; not found\n",
                   7673:                          name, NULL);
                   7674:            ctxt->valid = 0;
                   7675:        }
                   7676:     } else {
                   7677:        /*
                   7678:         * Internal checking in case the entity quest barfed
                   7679:         */
                   7680:        if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
                   7681:            (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
                   7682:            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7683:                  "Internal: %%%s; is not a parameter entity\n",
                   7684:                          name, NULL);
                   7685:        } else if (ctxt->input->free != deallocblankswrapper) {
                   7686:            input = xmlNewBlanksWrapperInputStream(ctxt, entity);
                   7687:            if (xmlPushInput(ctxt, input) < 0)
                   7688:                return;
                   7689:        } else {
                   7690:            /*
                   7691:             * TODO !!!
                   7692:             * handle the extra spaces added before and after
                   7693:             * c.f. http://www.w3.org/TR/REC-xml#as-PE
                   7694:             */
                   7695:            input = xmlNewEntityInputStream(ctxt, entity);
                   7696:            if (xmlPushInput(ctxt, input) < 0)
                   7697:                return;
                   7698:            if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
                   7699:                (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
                   7700:                (IS_BLANK_CH(NXT(5)))) {
                   7701:                xmlParseTextDecl(ctxt);
                   7702:                if (ctxt->errNo ==
                   7703:                    XML_ERR_UNSUPPORTED_ENCODING) {
                   7704:                    /*
                   7705:                     * The XML REC instructs us to stop parsing
                   7706:                     * right here
                   7707:                     */
                   7708:                    ctxt->instate = XML_PARSER_EOF;
                   7709:                    return;
                   7710:                }
                   7711:            }
                   7712:        }
                   7713:     }
                   7714:     ctxt->hasPErefs = 1;
                   7715: }
                   7716: 
                   7717: /**
                   7718:  * xmlLoadEntityContent:
                   7719:  * @ctxt:  an XML parser context
                   7720:  * @entity: an unloaded system entity
                   7721:  *
                   7722:  * Load the original content of the given system entity from the
                   7723:  * ExternalID/SystemID given. This is to be used for Included in Literal
                   7724:  * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
                   7725:  *
                   7726:  * Returns 0 in case of success and -1 in case of failure
                   7727:  */
                   7728: static int
                   7729: xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
                   7730:     xmlParserInputPtr input;
                   7731:     xmlBufferPtr buf;
                   7732:     int l, c;
                   7733:     int count = 0;
                   7734: 
                   7735:     if ((ctxt == NULL) || (entity == NULL) ||
                   7736:         ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
                   7737:         (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
                   7738:        (entity->content != NULL)) {
                   7739:        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   7740:                    "xmlLoadEntityContent parameter error");
                   7741:         return(-1);
                   7742:     }
                   7743: 
                   7744:     if (xmlParserDebugEntities)
                   7745:        xmlGenericError(xmlGenericErrorContext,
                   7746:                "Reading %s entity content input\n", entity->name);
                   7747: 
                   7748:     buf = xmlBufferCreate();
                   7749:     if (buf == NULL) {
                   7750:        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   7751:                    "xmlLoadEntityContent parameter error");
                   7752:         return(-1);
                   7753:     }
                   7754: 
                   7755:     input = xmlNewEntityInputStream(ctxt, entity);
                   7756:     if (input == NULL) {
                   7757:        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   7758:                    "xmlLoadEntityContent input error");
                   7759:        xmlBufferFree(buf);
                   7760:         return(-1);
                   7761:     }
                   7762: 
                   7763:     /*
                   7764:      * Push the entity as the current input, read char by char
                   7765:      * saving to the buffer until the end of the entity or an error
                   7766:      */
                   7767:     if (xmlPushInput(ctxt, input) < 0) {
                   7768:         xmlBufferFree(buf);
                   7769:        return(-1);
                   7770:     }
                   7771: 
                   7772:     GROW;
                   7773:     c = CUR_CHAR(l);
                   7774:     while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
                   7775:            (IS_CHAR(c))) {
                   7776:         xmlBufferAdd(buf, ctxt->input->cur, l);
                   7777:        if (count++ > 100) {
                   7778:            count = 0;
                   7779:            GROW;
                   7780:        }
                   7781:        NEXTL(l);
                   7782:        c = CUR_CHAR(l);
                   7783:     }
                   7784: 
                   7785:     if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
                   7786:         xmlPopInput(ctxt);
                   7787:     } else if (!IS_CHAR(c)) {
                   7788:         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
                   7789:                           "xmlLoadEntityContent: invalid char value %d\n",
                   7790:                          c);
                   7791:        xmlBufferFree(buf);
                   7792:        return(-1);
                   7793:     }
                   7794:     entity->content = buf->content;
                   7795:     buf->content = NULL;
                   7796:     xmlBufferFree(buf);
                   7797: 
                   7798:     return(0);
                   7799: }
                   7800: 
                   7801: /**
                   7802:  * xmlParseStringPEReference:
                   7803:  * @ctxt:  an XML parser context
                   7804:  * @str:  a pointer to an index in the string
                   7805:  *
                   7806:  * parse PEReference declarations
                   7807:  *
                   7808:  * [69] PEReference ::= '%' Name ';'
                   7809:  *
                   7810:  * [ WFC: No Recursion ]
                   7811:  * A parsed entity must not contain a recursive
                   7812:  * reference to itself, either directly or indirectly.
                   7813:  *
                   7814:  * [ WFC: Entity Declared ]
                   7815:  * In a document without any DTD, a document with only an internal DTD
                   7816:  * subset which contains no parameter entity references, or a document
                   7817:  * with "standalone='yes'", ...  ... The declaration of a parameter
                   7818:  * entity must precede any reference to it...
                   7819:  *
                   7820:  * [ VC: Entity Declared ]
                   7821:  * In a document with an external subset or external parameter entities
                   7822:  * with "standalone='no'", ...  ... The declaration of a parameter entity
                   7823:  * must precede any reference to it...
                   7824:  *
                   7825:  * [ WFC: In DTD ]
                   7826:  * Parameter-entity references may only appear in the DTD.
                   7827:  * NOTE: misleading but this is handled.
                   7828:  *
                   7829:  * Returns the string of the entity content.
                   7830:  *         str is updated to the current value of the index
                   7831:  */
                   7832: static xmlEntityPtr
                   7833: xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
                   7834:     const xmlChar *ptr;
                   7835:     xmlChar cur;
                   7836:     xmlChar *name;
                   7837:     xmlEntityPtr entity = NULL;
                   7838: 
                   7839:     if ((str == NULL) || (*str == NULL)) return(NULL);
                   7840:     ptr = *str;
                   7841:     cur = *ptr;
                   7842:     if (cur != '%')
                   7843:         return(NULL);
                   7844:     ptr++;
                   7845:     name = xmlParseStringName(ctxt, &ptr);
                   7846:     if (name == NULL) {
                   7847:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   7848:                       "xmlParseStringPEReference: no name\n");
                   7849:        *str = ptr;
                   7850:        return(NULL);
                   7851:     }
                   7852:     cur = *ptr;
                   7853:     if (cur != ';') {
                   7854:        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
                   7855:        xmlFree(name);
                   7856:        *str = ptr;
                   7857:        return(NULL);
                   7858:     }
                   7859:     ptr++;
                   7860: 
                   7861:     /*
                   7862:      * Increate the number of entity references parsed
                   7863:      */
                   7864:     ctxt->nbentities++;
                   7865: 
                   7866:     /*
                   7867:      * Request the entity from SAX
                   7868:      */
                   7869:     if ((ctxt->sax != NULL) &&
                   7870:        (ctxt->sax->getParameterEntity != NULL))
                   7871:        entity = ctxt->sax->getParameterEntity(ctxt->userData,
                   7872:                                               name);
                   7873:     if (entity == NULL) {
                   7874:        /*
                   7875:         * [ WFC: Entity Declared ]
                   7876:         * In a document without any DTD, a document with only an
                   7877:         * internal DTD subset which contains no parameter entity
                   7878:         * references, or a document with "standalone='yes'", ...
                   7879:         * ... The declaration of a parameter entity must precede
                   7880:         * any reference to it...
                   7881:         */
                   7882:        if ((ctxt->standalone == 1) ||
                   7883:            ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
                   7884:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
                   7885:                 "PEReference: %%%s; not found\n", name);
                   7886:        } else {
                   7887:            /*
                   7888:             * [ VC: Entity Declared ]
                   7889:             * In a document with an external subset or external
                   7890:             * parameter entities with "standalone='no'", ...
                   7891:             * ... The declaration of a parameter entity must
                   7892:             * precede any reference to it...
                   7893:             */
                   7894:            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7895:                          "PEReference: %%%s; not found\n",
                   7896:                          name, NULL);
                   7897:            ctxt->valid = 0;
                   7898:        }
                   7899:     } else {
                   7900:        /*
                   7901:         * Internal checking in case the entity quest barfed
                   7902:         */
                   7903:        if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
                   7904:            (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
                   7905:            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                   7906:                          "%%%s; is not a parameter entity\n",
                   7907:                          name, NULL);
                   7908:        }
                   7909:     }
                   7910:     ctxt->hasPErefs = 1;
                   7911:     xmlFree(name);
                   7912:     *str = ptr;
                   7913:     return(entity);
                   7914: }
                   7915: 
                   7916: /**
                   7917:  * xmlParseDocTypeDecl:
                   7918:  * @ctxt:  an XML parser context
                   7919:  *
                   7920:  * parse a DOCTYPE declaration
                   7921:  *
                   7922:  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? 
                   7923:  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
                   7924:  *
                   7925:  * [ VC: Root Element Type ]
                   7926:  * The Name in the document type declaration must match the element
                   7927:  * type of the root element. 
                   7928:  */
                   7929: 
                   7930: void
                   7931: xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
                   7932:     const xmlChar *name = NULL;
                   7933:     xmlChar *ExternalID = NULL;
                   7934:     xmlChar *URI = NULL;
                   7935: 
                   7936:     /*
                   7937:      * We know that '<!DOCTYPE' has been detected.
                   7938:      */
                   7939:     SKIP(9);
                   7940: 
                   7941:     SKIP_BLANKS;
                   7942: 
                   7943:     /*
                   7944:      * Parse the DOCTYPE name.
                   7945:      */
                   7946:     name = xmlParseName(ctxt);
                   7947:     if (name == NULL) {
                   7948:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   7949:                       "xmlParseDocTypeDecl : no DOCTYPE name !\n");
                   7950:     }
                   7951:     ctxt->intSubName = name;
                   7952: 
                   7953:     SKIP_BLANKS;
                   7954: 
                   7955:     /*
                   7956:      * Check for SystemID and ExternalID
                   7957:      */
                   7958:     URI = xmlParseExternalID(ctxt, &ExternalID, 1);
                   7959: 
                   7960:     if ((URI != NULL) || (ExternalID != NULL)) {
                   7961:         ctxt->hasExternalSubset = 1;
                   7962:     }
                   7963:     ctxt->extSubURI = URI;
                   7964:     ctxt->extSubSystem = ExternalID;
                   7965: 
                   7966:     SKIP_BLANKS;
                   7967: 
                   7968:     /*
                   7969:      * Create and update the internal subset.
                   7970:      */
                   7971:     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
                   7972:        (!ctxt->disableSAX))
                   7973:        ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
                   7974: 
                   7975:     /*
                   7976:      * Is there any internal subset declarations ?
                   7977:      * they are handled separately in xmlParseInternalSubset()
                   7978:      */
                   7979:     if (RAW == '[')
                   7980:        return;
                   7981: 
                   7982:     /*
                   7983:      * We should be at the end of the DOCTYPE declaration.
                   7984:      */
                   7985:     if (RAW != '>') {
                   7986:        xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
                   7987:     }
                   7988:     NEXT;
                   7989: }
                   7990: 
                   7991: /**
                   7992:  * xmlParseInternalSubset:
                   7993:  * @ctxt:  an XML parser context
                   7994:  *
                   7995:  * parse the internal subset declaration
                   7996:  *
                   7997:  * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
                   7998:  */
                   7999: 
                   8000: static void
                   8001: xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
                   8002:     /*
                   8003:      * Is there any DTD definition ?
                   8004:      */
                   8005:     if (RAW == '[') {
                   8006:         ctxt->instate = XML_PARSER_DTD;
                   8007:         NEXT;
                   8008:        /*
                   8009:         * Parse the succession of Markup declarations and 
                   8010:         * PEReferences.
                   8011:         * Subsequence (markupdecl | PEReference | S)*
                   8012:         */
                   8013:        while (RAW != ']') {
                   8014:            const xmlChar *check = CUR_PTR;
                   8015:            unsigned int cons = ctxt->input->consumed;
                   8016: 
                   8017:            SKIP_BLANKS;
                   8018:            xmlParseMarkupDecl(ctxt);
                   8019:            xmlParsePEReference(ctxt);
                   8020: 
                   8021:            /*
                   8022:             * Pop-up of finished entities.
                   8023:             */
                   8024:            while ((RAW == 0) && (ctxt->inputNr > 1))
                   8025:                xmlPopInput(ctxt);
                   8026: 
                   8027:            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
                   8028:                xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   8029:             "xmlParseInternalSubset: error detected in Markup declaration\n");
                   8030:                break;
                   8031:            }
                   8032:        }
                   8033:        if (RAW == ']') { 
                   8034:            NEXT;
                   8035:            SKIP_BLANKS;
                   8036:        }
                   8037:     }
                   8038: 
                   8039:     /*
                   8040:      * We should be at the end of the DOCTYPE declaration.
                   8041:      */
                   8042:     if (RAW != '>') {
                   8043:        xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
                   8044:     }
                   8045:     NEXT;
                   8046: }
                   8047: 
                   8048: #ifdef LIBXML_SAX1_ENABLED
                   8049: /**
                   8050:  * xmlParseAttribute:
                   8051:  * @ctxt:  an XML parser context
                   8052:  * @value:  a xmlChar ** used to store the value of the attribute
                   8053:  *
                   8054:  * parse an attribute
                   8055:  *
                   8056:  * [41] Attribute ::= Name Eq AttValue
                   8057:  *
                   8058:  * [ WFC: No External Entity References ]
                   8059:  * Attribute values cannot contain direct or indirect entity references
                   8060:  * to external entities.
                   8061:  *
                   8062:  * [ WFC: No < in Attribute Values ]
                   8063:  * The replacement text of any entity referred to directly or indirectly in
                   8064:  * an attribute value (other than "&lt;") must not contain a <. 
                   8065:  * 
                   8066:  * [ VC: Attribute Value Type ]
                   8067:  * The attribute must have been declared; the value must be of the type
                   8068:  * declared for it.
                   8069:  *
                   8070:  * [25] Eq ::= S? '=' S?
                   8071:  *
                   8072:  * With namespace:
                   8073:  *
                   8074:  * [NS 11] Attribute ::= QName Eq AttValue
                   8075:  *
                   8076:  * Also the case QName == xmlns:??? is handled independently as a namespace
                   8077:  * definition.
                   8078:  *
                   8079:  * Returns the attribute name, and the value in *value.
                   8080:  */
                   8081: 
                   8082: const xmlChar *
                   8083: xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
                   8084:     const xmlChar *name;
                   8085:     xmlChar *val;
                   8086: 
                   8087:     *value = NULL;
                   8088:     GROW;
                   8089:     name = xmlParseName(ctxt);
                   8090:     if (name == NULL) {
                   8091:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   8092:                       "error parsing attribute name\n");
                   8093:         return(NULL);
                   8094:     }
                   8095: 
                   8096:     /*
                   8097:      * read the value
                   8098:      */
                   8099:     SKIP_BLANKS;
                   8100:     if (RAW == '=') {
                   8101:         NEXT;
                   8102:        SKIP_BLANKS;
                   8103:        val = xmlParseAttValue(ctxt);
                   8104:        ctxt->instate = XML_PARSER_CONTENT;
                   8105:     } else {
                   8106:        xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
                   8107:               "Specification mandate value for attribute %s\n", name);
                   8108:        return(NULL);
                   8109:     }
                   8110: 
                   8111:     /*
                   8112:      * Check that xml:lang conforms to the specification
                   8113:      * No more registered as an error, just generate a warning now
                   8114:      * since this was deprecated in XML second edition
                   8115:      */
                   8116:     if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
                   8117:        if (!xmlCheckLanguageID(val)) {
                   8118:            xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
                   8119:                          "Malformed value for xml:lang : %s\n",
                   8120:                          val, NULL);
                   8121:        }
                   8122:     }
                   8123: 
                   8124:     /*
                   8125:      * Check that xml:space conforms to the specification
                   8126:      */
                   8127:     if (xmlStrEqual(name, BAD_CAST "xml:space")) {
                   8128:        if (xmlStrEqual(val, BAD_CAST "default"))
                   8129:            *(ctxt->space) = 0;
                   8130:        else if (xmlStrEqual(val, BAD_CAST "preserve"))
                   8131:            *(ctxt->space) = 1;
                   8132:        else {
                   8133:                xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
                   8134: "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
                   8135:                                  val, NULL);
                   8136:        }
                   8137:     }
                   8138: 
                   8139:     *value = val;
                   8140:     return(name);
                   8141: }
                   8142: 
                   8143: /**
                   8144:  * xmlParseStartTag:
                   8145:  * @ctxt:  an XML parser context
                   8146:  * 
                   8147:  * parse a start of tag either for rule element or
                   8148:  * EmptyElement. In both case we don't parse the tag closing chars.
                   8149:  *
                   8150:  * [40] STag ::= '<' Name (S Attribute)* S? '>'
                   8151:  *
                   8152:  * [ WFC: Unique Att Spec ]
                   8153:  * No attribute name may appear more than once in the same start-tag or
                   8154:  * empty-element tag. 
                   8155:  *
                   8156:  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
                   8157:  *
                   8158:  * [ WFC: Unique Att Spec ]
                   8159:  * No attribute name may appear more than once in the same start-tag or
                   8160:  * empty-element tag. 
                   8161:  *
                   8162:  * With namespace:
                   8163:  *
                   8164:  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
                   8165:  *
                   8166:  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
                   8167:  *
                   8168:  * Returns the element name parsed
                   8169:  */
                   8170: 
                   8171: const xmlChar *
                   8172: xmlParseStartTag(xmlParserCtxtPtr ctxt) {
                   8173:     const xmlChar *name;
                   8174:     const xmlChar *attname;
                   8175:     xmlChar *attvalue;
                   8176:     const xmlChar **atts = ctxt->atts;
                   8177:     int nbatts = 0;
                   8178:     int maxatts = ctxt->maxatts;
                   8179:     int i;
                   8180: 
                   8181:     if (RAW != '<') return(NULL);
                   8182:     NEXT1;
                   8183: 
                   8184:     name = xmlParseName(ctxt);
                   8185:     if (name == NULL) {
                   8186:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   8187:             "xmlParseStartTag: invalid element name\n");
                   8188:         return(NULL);
                   8189:     }
                   8190: 
                   8191:     /*
                   8192:      * Now parse the attributes, it ends up with the ending
                   8193:      *
                   8194:      * (S Attribute)* S?
                   8195:      */
                   8196:     SKIP_BLANKS;
                   8197:     GROW;
                   8198: 
                   8199:     while ((RAW != '>') && 
                   8200:           ((RAW != '/') || (NXT(1) != '>')) &&
                   8201:           (IS_BYTE_CHAR(RAW))) {
                   8202:        const xmlChar *q = CUR_PTR;
                   8203:        unsigned int cons = ctxt->input->consumed;
                   8204: 
                   8205:        attname = xmlParseAttribute(ctxt, &attvalue);
                   8206:         if ((attname != NULL) && (attvalue != NULL)) {
                   8207:            /*
                   8208:             * [ WFC: Unique Att Spec ]
                   8209:             * No attribute name may appear more than once in the same
                   8210:             * start-tag or empty-element tag. 
                   8211:             */
                   8212:            for (i = 0; i < nbatts;i += 2) {
                   8213:                if (xmlStrEqual(atts[i], attname)) {
                   8214:                    xmlErrAttributeDup(ctxt, NULL, attname);
                   8215:                    xmlFree(attvalue);
                   8216:                    goto failed;
                   8217:                }
                   8218:            }
                   8219:            /*
                   8220:             * Add the pair to atts
                   8221:             */
                   8222:            if (atts == NULL) {
                   8223:                maxatts = 22; /* allow for 10 attrs by default */
                   8224:                atts = (const xmlChar **)
                   8225:                       xmlMalloc(maxatts * sizeof(xmlChar *));
                   8226:                if (atts == NULL) {
                   8227:                    xmlErrMemory(ctxt, NULL);
                   8228:                    if (attvalue != NULL)
                   8229:                        xmlFree(attvalue);
                   8230:                    goto failed;
                   8231:                }
                   8232:                ctxt->atts = atts;
                   8233:                ctxt->maxatts = maxatts;
                   8234:            } else if (nbatts + 4 > maxatts) {
                   8235:                const xmlChar **n;
                   8236: 
                   8237:                maxatts *= 2;
                   8238:                n = (const xmlChar **) xmlRealloc((void *) atts,
                   8239:                                             maxatts * sizeof(const xmlChar *));
                   8240:                if (n == NULL) {
                   8241:                    xmlErrMemory(ctxt, NULL);
                   8242:                    if (attvalue != NULL)
                   8243:                        xmlFree(attvalue);
                   8244:                    goto failed;
                   8245:                }
                   8246:                atts = n;
                   8247:                ctxt->atts = atts;
                   8248:                ctxt->maxatts = maxatts;
                   8249:            }
                   8250:            atts[nbatts++] = attname;
                   8251:            atts[nbatts++] = attvalue;
                   8252:            atts[nbatts] = NULL;
                   8253:            atts[nbatts + 1] = NULL;
                   8254:        } else {
                   8255:            if (attvalue != NULL)
                   8256:                xmlFree(attvalue);
                   8257:        }
                   8258: 
                   8259: failed:     
                   8260: 
                   8261:        GROW
                   8262:        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
                   8263:            break;
                   8264:        if (!IS_BLANK_CH(RAW)) {
                   8265:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   8266:                           "attributes construct error\n");
                   8267:        }
                   8268:        SKIP_BLANKS;
                   8269:         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
                   8270:             (attname == NULL) && (attvalue == NULL)) {
                   8271:            xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
                   8272:                           "xmlParseStartTag: problem parsing attributes\n");
                   8273:            break;
                   8274:        }
                   8275:        SHRINK;
                   8276:         GROW;
                   8277:     }
                   8278: 
                   8279:     /*
                   8280:      * SAX: Start of Element !
                   8281:      */
                   8282:     if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
                   8283:        (!ctxt->disableSAX)) {
                   8284:        if (nbatts > 0)
                   8285:            ctxt->sax->startElement(ctxt->userData, name, atts);
                   8286:        else
                   8287:            ctxt->sax->startElement(ctxt->userData, name, NULL);
                   8288:     }
                   8289: 
                   8290:     if (atts != NULL) {
                   8291:         /* Free only the content strings */
                   8292:         for (i = 1;i < nbatts;i+=2)
                   8293:            if (atts[i] != NULL)
                   8294:               xmlFree((xmlChar *) atts[i]);
                   8295:     }
                   8296:     return(name);
                   8297: }
                   8298: 
                   8299: /**
                   8300:  * xmlParseEndTag1:
                   8301:  * @ctxt:  an XML parser context
                   8302:  * @line:  line of the start tag
                   8303:  * @nsNr:  number of namespaces on the start tag
                   8304:  *
                   8305:  * parse an end of tag
                   8306:  *
                   8307:  * [42] ETag ::= '</' Name S? '>'
                   8308:  *
                   8309:  * With namespace
                   8310:  *
                   8311:  * [NS 9] ETag ::= '</' QName S? '>'
                   8312:  */
                   8313: 
                   8314: static void
                   8315: xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
                   8316:     const xmlChar *name;
                   8317: 
                   8318:     GROW;
                   8319:     if ((RAW != '<') || (NXT(1) != '/')) {
                   8320:        xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
                   8321:                       "xmlParseEndTag: '</' not found\n");
                   8322:        return;
                   8323:     }
                   8324:     SKIP(2);
                   8325: 
                   8326:     name = xmlParseNameAndCompare(ctxt,ctxt->name);
                   8327: 
                   8328:     /*
                   8329:      * We should definitely be at the ending "S? '>'" part
                   8330:      */
                   8331:     GROW;
                   8332:     SKIP_BLANKS;
                   8333:     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
                   8334:        xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
                   8335:     } else
                   8336:        NEXT1;
                   8337: 
                   8338:     /*
                   8339:      * [ WFC: Element Type Match ]
                   8340:      * The Name in an element's end-tag must match the element type in the
                   8341:      * start-tag. 
                   8342:      *
                   8343:      */
                   8344:     if (name != (xmlChar*)1) {
                   8345:         if (name == NULL) name = BAD_CAST "unparseable";
                   8346:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
                   8347:                     "Opening and ending tag mismatch: %s line %d and %s\n",
                   8348:                                ctxt->name, line, name);
                   8349:     }
                   8350: 
                   8351:     /*
                   8352:      * SAX: End of Tag
                   8353:      */
                   8354:     if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
                   8355:        (!ctxt->disableSAX))
                   8356:         ctxt->sax->endElement(ctxt->userData, ctxt->name);
                   8357: 
                   8358:     namePop(ctxt);
                   8359:     spacePop(ctxt);
                   8360:     return;
                   8361: }
                   8362: 
                   8363: /**
                   8364:  * xmlParseEndTag:
                   8365:  * @ctxt:  an XML parser context
                   8366:  *
                   8367:  * parse an end of tag
                   8368:  *
                   8369:  * [42] ETag ::= '</' Name S? '>'
                   8370:  *
                   8371:  * With namespace
                   8372:  *
                   8373:  * [NS 9] ETag ::= '</' QName S? '>'
                   8374:  */
                   8375: 
                   8376: void
                   8377: xmlParseEndTag(xmlParserCtxtPtr ctxt) {
                   8378:     xmlParseEndTag1(ctxt, 0);
                   8379: }
                   8380: #endif /* LIBXML_SAX1_ENABLED */
                   8381: 
                   8382: /************************************************************************
                   8383:  *                                                                     *
                   8384:  *                   SAX 2 specific operations                         *
                   8385:  *                                                                     *
                   8386:  ************************************************************************/
                   8387: 
                   8388: /*
                   8389:  * xmlGetNamespace:
                   8390:  * @ctxt:  an XML parser context
                   8391:  * @prefix:  the prefix to lookup
                   8392:  *
                   8393:  * Lookup the namespace name for the @prefix (which ca be NULL)
                   8394:  * The prefix must come from the @ctxt->dict dictionnary
                   8395:  *
                   8396:  * Returns the namespace name or NULL if not bound
                   8397:  */
                   8398: static const xmlChar *
                   8399: xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
                   8400:     int i;
                   8401: 
                   8402:     if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
                   8403:     for (i = ctxt->nsNr - 2;i >= 0;i-=2)
                   8404:         if (ctxt->nsTab[i] == prefix) {
                   8405:            if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
                   8406:                return(NULL);
                   8407:            return(ctxt->nsTab[i + 1]);
                   8408:        }
                   8409:     return(NULL);
                   8410: }
                   8411: 
                   8412: /**
                   8413:  * xmlParseQName:
                   8414:  * @ctxt:  an XML parser context
                   8415:  * @prefix:  pointer to store the prefix part
                   8416:  *
                   8417:  * parse an XML Namespace QName
                   8418:  *
                   8419:  * [6]  QName  ::= (Prefix ':')? LocalPart
                   8420:  * [7]  Prefix  ::= NCName
                   8421:  * [8]  LocalPart  ::= NCName
                   8422:  *
                   8423:  * Returns the Name parsed or NULL
                   8424:  */
                   8425: 
                   8426: static const xmlChar *
                   8427: xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
                   8428:     const xmlChar *l, *p;
                   8429: 
                   8430:     GROW;
                   8431: 
                   8432:     l = xmlParseNCName(ctxt);
                   8433:     if (l == NULL) {
                   8434:         if (CUR == ':') {
                   8435:            l = xmlParseName(ctxt);
                   8436:            if (l != NULL) {
                   8437:                xmlNsErr(ctxt, XML_NS_ERR_QNAME, 
                   8438:                         "Failed to parse QName '%s'\n", l, NULL, NULL);
                   8439:                *prefix = NULL;
                   8440:                return(l);
                   8441:            }
                   8442:        }
                   8443:         return(NULL);
                   8444:     }
                   8445:     if (CUR == ':') {
                   8446:         NEXT;
                   8447:        p = l;
                   8448:        l = xmlParseNCName(ctxt);
                   8449:        if (l == NULL) {
                   8450:            xmlChar *tmp;
                   8451: 
                   8452:             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
                   8453:                     "Failed to parse QName '%s:'\n", p, NULL, NULL);
                   8454:            l = xmlParseNmtoken(ctxt);
                   8455:            if (l == NULL)
                   8456:                tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
                   8457:            else {
                   8458:                tmp = xmlBuildQName(l, p, NULL, 0);
                   8459:                xmlFree((char *)l);
                   8460:            }
                   8461:            p = xmlDictLookup(ctxt->dict, tmp, -1);
                   8462:            if (tmp != NULL) xmlFree(tmp);
                   8463:            *prefix = NULL;
                   8464:            return(p);
                   8465:        }
                   8466:        if (CUR == ':') {
                   8467:            xmlChar *tmp;
                   8468: 
                   8469:             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
                   8470:                     "Failed to parse QName '%s:%s:'\n", p, l, NULL);
                   8471:            NEXT;
                   8472:            tmp = (xmlChar *) xmlParseName(ctxt);
                   8473:            if (tmp != NULL) {
                   8474:                tmp = xmlBuildQName(tmp, l, NULL, 0);
                   8475:                l = xmlDictLookup(ctxt->dict, tmp, -1);
                   8476:                if (tmp != NULL) xmlFree(tmp);
                   8477:                *prefix = p;
                   8478:                return(l);
                   8479:            }
                   8480:            tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
                   8481:            l = xmlDictLookup(ctxt->dict, tmp, -1);
                   8482:            if (tmp != NULL) xmlFree(tmp);
                   8483:            *prefix = p;
                   8484:            return(l);
                   8485:        }
                   8486:        *prefix = p;
                   8487:     } else
                   8488:         *prefix = NULL;
                   8489:     return(l);
                   8490: }
                   8491: 
                   8492: /**
                   8493:  * xmlParseQNameAndCompare:
                   8494:  * @ctxt:  an XML parser context
                   8495:  * @name:  the localname
                   8496:  * @prefix:  the prefix, if any.
                   8497:  *
                   8498:  * parse an XML name and compares for match
                   8499:  * (specialized for endtag parsing)
                   8500:  *
                   8501:  * Returns NULL for an illegal name, (xmlChar*) 1 for success
                   8502:  * and the name for mismatch
                   8503:  */
                   8504: 
                   8505: static const xmlChar *
                   8506: xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
                   8507:                         xmlChar const *prefix) {
                   8508:     const xmlChar *cmp;
                   8509:     const xmlChar *in;
                   8510:     const xmlChar *ret;
                   8511:     const xmlChar *prefix2;
                   8512: 
                   8513:     if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
                   8514: 
                   8515:     GROW;
                   8516:     in = ctxt->input->cur;
                   8517: 
                   8518:     cmp = prefix;
                   8519:     while (*in != 0 && *in == *cmp) {
                   8520:        ++in;
                   8521:        ++cmp;
                   8522:     }
                   8523:     if ((*cmp == 0) && (*in == ':')) {
                   8524:         in++;
                   8525:        cmp = name;
                   8526:        while (*in != 0 && *in == *cmp) {
                   8527:            ++in;
                   8528:            ++cmp;
                   8529:        }
                   8530:        if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
                   8531:            /* success */
                   8532:            ctxt->input->cur = in;
                   8533:            return((const xmlChar*) 1);
                   8534:        }
                   8535:     }
                   8536:     /*
                   8537:      * all strings coms from the dictionary, equality can be done directly
                   8538:      */
                   8539:     ret = xmlParseQName (ctxt, &prefix2);
                   8540:     if ((ret == name) && (prefix == prefix2))
                   8541:        return((const xmlChar*) 1);
                   8542:     return ret;
                   8543: }
                   8544: 
                   8545: /**
                   8546:  * xmlParseAttValueInternal:
                   8547:  * @ctxt:  an XML parser context
                   8548:  * @len:  attribute len result
                   8549:  * @alloc:  whether the attribute was reallocated as a new string
                   8550:  * @normalize:  if 1 then further non-CDATA normalization must be done
                   8551:  *
                   8552:  * parse a value for an attribute.
                   8553:  * NOTE: if no normalization is needed, the routine will return pointers
                   8554:  *       directly from the data buffer.
                   8555:  *
                   8556:  * 3.3.3 Attribute-Value Normalization:
                   8557:  * Before the value of an attribute is passed to the application or
                   8558:  * checked for validity, the XML processor must normalize it as follows: 
                   8559:  * - a character reference is processed by appending the referenced
                   8560:  *   character to the attribute value
                   8561:  * - an entity reference is processed by recursively processing the
                   8562:  *   replacement text of the entity 
                   8563:  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
                   8564:  *   appending #x20 to the normalized value, except that only a single
                   8565:  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
                   8566:  *   parsed entity or the literal entity value of an internal parsed entity 
                   8567:  * - other characters are processed by appending them to the normalized value 
                   8568:  * If the declared value is not CDATA, then the XML processor must further
                   8569:  * process the normalized attribute value by discarding any leading and
                   8570:  * trailing space (#x20) characters, and by replacing sequences of space
                   8571:  * (#x20) characters by a single space (#x20) character.  
                   8572:  * All attributes for which no declaration has been read should be treated
                   8573:  * by a non-validating parser as if declared CDATA.
                   8574:  *
                   8575:  * Returns the AttValue parsed or NULL. The value has to be freed by the
                   8576:  *     caller if it was copied, this can be detected by val[*len] == 0.
                   8577:  */
                   8578: 
                   8579: static xmlChar *
                   8580: xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
                   8581:                          int normalize)
                   8582: {
                   8583:     xmlChar limit = 0;
                   8584:     const xmlChar *in = NULL, *start, *end, *last;
                   8585:     xmlChar *ret = NULL;
                   8586: 
                   8587:     GROW;
                   8588:     in = (xmlChar *) CUR_PTR;
                   8589:     if (*in != '"' && *in != '\'') {
                   8590:         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
                   8591:         return (NULL);
                   8592:     }
                   8593:     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
                   8594: 
                   8595:     /*
                   8596:      * try to handle in this routine the most common case where no
                   8597:      * allocation of a new string is required and where content is
                   8598:      * pure ASCII.
                   8599:      */
                   8600:     limit = *in++;
                   8601:     end = ctxt->input->end;
                   8602:     start = in;
                   8603:     if (in >= end) {
                   8604:         const xmlChar *oldbase = ctxt->input->base;
                   8605:        GROW;
                   8606:        if (oldbase != ctxt->input->base) {
                   8607:            long delta = ctxt->input->base - oldbase;
                   8608:            start = start + delta;
                   8609:            in = in + delta;
                   8610:        }
                   8611:        end = ctxt->input->end;
                   8612:     }
                   8613:     if (normalize) {
                   8614:         /*
                   8615:         * Skip any leading spaces
                   8616:         */
                   8617:        while ((in < end) && (*in != limit) && 
                   8618:               ((*in == 0x20) || (*in == 0x9) ||
                   8619:                (*in == 0xA) || (*in == 0xD))) {
                   8620:            in++;
                   8621:            start = in;
                   8622:            if (in >= end) {
                   8623:                const xmlChar *oldbase = ctxt->input->base;
                   8624:                GROW;
                   8625:                if (oldbase != ctxt->input->base) {
                   8626:                    long delta = ctxt->input->base - oldbase;
                   8627:                    start = start + delta;
                   8628:                    in = in + delta;
                   8629:                }
                   8630:                end = ctxt->input->end;
                   8631:            }
                   8632:        }
                   8633:        while ((in < end) && (*in != limit) && (*in >= 0x20) &&
                   8634:               (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
                   8635:            if ((*in++ == 0x20) && (*in == 0x20)) break;
                   8636:            if (in >= end) {
                   8637:                const xmlChar *oldbase = ctxt->input->base;
                   8638:                GROW;
                   8639:                if (oldbase != ctxt->input->base) {
                   8640:                    long delta = ctxt->input->base - oldbase;
                   8641:                    start = start + delta;
                   8642:                    in = in + delta;
                   8643:                }
                   8644:                end = ctxt->input->end;
                   8645:            }
                   8646:        }
                   8647:        last = in;
                   8648:        /*
                   8649:         * skip the trailing blanks
                   8650:         */
                   8651:        while ((last[-1] == 0x20) && (last > start)) last--;
                   8652:        while ((in < end) && (*in != limit) && 
                   8653:               ((*in == 0x20) || (*in == 0x9) ||
                   8654:                (*in == 0xA) || (*in == 0xD))) {
                   8655:            in++;
                   8656:            if (in >= end) {
                   8657:                const xmlChar *oldbase = ctxt->input->base;
                   8658:                GROW;
                   8659:                if (oldbase != ctxt->input->base) {
                   8660:                    long delta = ctxt->input->base - oldbase;
                   8661:                    start = start + delta;
                   8662:                    in = in + delta;
                   8663:                    last = last + delta;
                   8664:                }
                   8665:                end = ctxt->input->end;
                   8666:            }
                   8667:        }
                   8668:        if (*in != limit) goto need_complex;
                   8669:     } else {
                   8670:        while ((in < end) && (*in != limit) && (*in >= 0x20) &&
                   8671:               (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
                   8672:            in++;
                   8673:            if (in >= end) {
                   8674:                const xmlChar *oldbase = ctxt->input->base;
                   8675:                GROW;
                   8676:                if (oldbase != ctxt->input->base) {
                   8677:                    long delta = ctxt->input->base - oldbase;
                   8678:                    start = start + delta;
                   8679:                    in = in + delta;
                   8680:                }
                   8681:                end = ctxt->input->end;
                   8682:            }
                   8683:        }
                   8684:        last = in;
                   8685:        if (*in != limit) goto need_complex;
                   8686:     }
                   8687:     in++;
                   8688:     if (len != NULL) {
                   8689:         *len = last - start;
                   8690:         ret = (xmlChar *) start;
                   8691:     } else {
                   8692:         if (alloc) *alloc = 1;
                   8693:         ret = xmlStrndup(start, last - start);
                   8694:     }
                   8695:     CUR_PTR = in;
                   8696:     if (alloc) *alloc = 0;
                   8697:     return ret;
                   8698: need_complex:
                   8699:     if (alloc) *alloc = 1;
                   8700:     return xmlParseAttValueComplex(ctxt, len, normalize);
                   8701: }
                   8702: 
                   8703: /**
                   8704:  * xmlParseAttribute2:
                   8705:  * @ctxt:  an XML parser context
                   8706:  * @pref:  the element prefix
                   8707:  * @elem:  the element name
                   8708:  * @prefix:  a xmlChar ** used to store the value of the attribute prefix
                   8709:  * @value:  a xmlChar ** used to store the value of the attribute
                   8710:  * @len:  an int * to save the length of the attribute
                   8711:  * @alloc:  an int * to indicate if the attribute was allocated
                   8712:  *
                   8713:  * parse an attribute in the new SAX2 framework.
                   8714:  *
                   8715:  * Returns the attribute name, and the value in *value, .
                   8716:  */
                   8717: 
                   8718: static const xmlChar *
                   8719: xmlParseAttribute2(xmlParserCtxtPtr ctxt,
                   8720:                    const xmlChar * pref, const xmlChar * elem,
                   8721:                    const xmlChar ** prefix, xmlChar ** value,
                   8722:                    int *len, int *alloc)
                   8723: {
                   8724:     const xmlChar *name;
                   8725:     xmlChar *val, *internal_val = NULL;
                   8726:     int normalize = 0;
                   8727: 
                   8728:     *value = NULL;
                   8729:     GROW;
                   8730:     name = xmlParseQName(ctxt, prefix);
                   8731:     if (name == NULL) {
                   8732:         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   8733:                        "error parsing attribute name\n");
                   8734:         return (NULL);
                   8735:     }
                   8736: 
                   8737:     /*
                   8738:      * get the type if needed
                   8739:      */
                   8740:     if (ctxt->attsSpecial != NULL) {
                   8741:         int type;
                   8742: 
                   8743:         type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
                   8744:                                             pref, elem, *prefix, name);
                   8745:         if (type != 0)
                   8746:             normalize = 1;
                   8747:     }
                   8748: 
                   8749:     /*
                   8750:      * read the value
                   8751:      */
                   8752:     SKIP_BLANKS;
                   8753:     if (RAW == '=') {
                   8754:         NEXT;
                   8755:         SKIP_BLANKS;
                   8756:         val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
                   8757:        if (normalize) {
                   8758:            /*
                   8759:             * Sometimes a second normalisation pass for spaces is needed
                   8760:             * but that only happens if charrefs or entities refernces
                   8761:             * have been used in the attribute value, i.e. the attribute
                   8762:             * value have been extracted in an allocated string already.
                   8763:             */
                   8764:            if (*alloc) {
                   8765:                const xmlChar *val2;
                   8766: 
                   8767:                val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
                   8768:                if ((val2 != NULL) && (val2 != val)) {
                   8769:                    xmlFree(val);
                   8770:                    val = (xmlChar *) val2;
                   8771:                }
                   8772:            }
                   8773:        }
                   8774:         ctxt->instate = XML_PARSER_CONTENT;
                   8775:     } else {
                   8776:         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
                   8777:                           "Specification mandate value for attribute %s\n",
                   8778:                           name);
                   8779:         return (NULL);
                   8780:     }
                   8781: 
                   8782:     if (*prefix == ctxt->str_xml) {
                   8783:         /*
                   8784:          * Check that xml:lang conforms to the specification
                   8785:          * No more registered as an error, just generate a warning now
                   8786:          * since this was deprecated in XML second edition
                   8787:          */
                   8788:         if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
                   8789:             internal_val = xmlStrndup(val, *len);
                   8790:             if (!xmlCheckLanguageID(internal_val)) {
                   8791:                 xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
                   8792:                               "Malformed value for xml:lang : %s\n",
                   8793:                               internal_val, NULL);
                   8794:             }
                   8795:         }
                   8796: 
                   8797:         /*
                   8798:          * Check that xml:space conforms to the specification
                   8799:          */
                   8800:         if (xmlStrEqual(name, BAD_CAST "space")) {
                   8801:             internal_val = xmlStrndup(val, *len);
                   8802:             if (xmlStrEqual(internal_val, BAD_CAST "default"))
                   8803:                 *(ctxt->space) = 0;
                   8804:             else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
                   8805:                 *(ctxt->space) = 1;
                   8806:             else {
                   8807:                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
                   8808:                               "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
                   8809:                               internal_val, NULL);
                   8810:             }
                   8811:         }
                   8812:         if (internal_val) {
                   8813:             xmlFree(internal_val);
                   8814:         }
                   8815:     }
                   8816: 
                   8817:     *value = val;
                   8818:     return (name);
                   8819: }
                   8820: /**
                   8821:  * xmlParseStartTag2:
                   8822:  * @ctxt:  an XML parser context
                   8823:  * 
                   8824:  * parse a start of tag either for rule element or
                   8825:  * EmptyElement. In both case we don't parse the tag closing chars.
                   8826:  * This routine is called when running SAX2 parsing
                   8827:  *
                   8828:  * [40] STag ::= '<' Name (S Attribute)* S? '>'
                   8829:  *
                   8830:  * [ WFC: Unique Att Spec ]
                   8831:  * No attribute name may appear more than once in the same start-tag or
                   8832:  * empty-element tag. 
                   8833:  *
                   8834:  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
                   8835:  *
                   8836:  * [ WFC: Unique Att Spec ]
                   8837:  * No attribute name may appear more than once in the same start-tag or
                   8838:  * empty-element tag. 
                   8839:  *
                   8840:  * With namespace:
                   8841:  *
                   8842:  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
                   8843:  *
                   8844:  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
                   8845:  *
                   8846:  * Returns the element name parsed
                   8847:  */
                   8848: 
                   8849: static const xmlChar *
                   8850: xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
                   8851:                   const xmlChar **URI, int *tlen) {
                   8852:     const xmlChar *localname;
                   8853:     const xmlChar *prefix;
                   8854:     const xmlChar *attname;
                   8855:     const xmlChar *aprefix;
                   8856:     const xmlChar *nsname;
                   8857:     xmlChar *attvalue;
                   8858:     const xmlChar **atts = ctxt->atts;
                   8859:     int maxatts = ctxt->maxatts;
                   8860:     int nratts, nbatts, nbdef;
                   8861:     int i, j, nbNs, attval, oldline, oldcol;
                   8862:     const xmlChar *base;
                   8863:     unsigned long cur;
                   8864:     int nsNr = ctxt->nsNr;
                   8865: 
                   8866:     if (RAW != '<') return(NULL);
                   8867:     NEXT1;
                   8868: 
                   8869:     /*
                   8870:      * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
                   8871:      *       point since the attribute values may be stored as pointers to
                   8872:      *       the buffer and calling SHRINK would destroy them !
                   8873:      *       The Shrinking is only possible once the full set of attribute
                   8874:      *       callbacks have been done.
                   8875:      */
                   8876: reparse:
                   8877:     SHRINK;
                   8878:     base = ctxt->input->base;
                   8879:     cur = ctxt->input->cur - ctxt->input->base;
                   8880:     oldline = ctxt->input->line;
                   8881:     oldcol = ctxt->input->col;
                   8882:     nbatts = 0;
                   8883:     nratts = 0;
                   8884:     nbdef = 0;
                   8885:     nbNs = 0;
                   8886:     attval = 0;
                   8887:     /* Forget any namespaces added during an earlier parse of this element. */
                   8888:     ctxt->nsNr = nsNr;
                   8889: 
                   8890:     localname = xmlParseQName(ctxt, &prefix);
                   8891:     if (localname == NULL) {
                   8892:        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                   8893:                       "StartTag: invalid element name\n");
                   8894:         return(NULL);
                   8895:     }
                   8896:     *tlen = ctxt->input->cur - ctxt->input->base - cur;
                   8897: 
                   8898:     /*
                   8899:      * Now parse the attributes, it ends up with the ending
                   8900:      *
                   8901:      * (S Attribute)* S?
                   8902:      */
                   8903:     SKIP_BLANKS;
                   8904:     GROW;
                   8905:     if (ctxt->input->base != base) goto base_changed;
                   8906: 
                   8907:     while ((RAW != '>') && 
                   8908:           ((RAW != '/') || (NXT(1) != '>')) &&
                   8909:           (IS_BYTE_CHAR(RAW))) {
                   8910:        const xmlChar *q = CUR_PTR;
                   8911:        unsigned int cons = ctxt->input->consumed;
                   8912:        int len = -1, alloc = 0;
                   8913: 
                   8914:        attname = xmlParseAttribute2(ctxt, prefix, localname,
                   8915:                                     &aprefix, &attvalue, &len, &alloc);
                   8916:        if (ctxt->input->base != base) {
                   8917:            if ((attvalue != NULL) && (alloc != 0))
                   8918:                xmlFree(attvalue);
                   8919:            attvalue = NULL;
                   8920:            goto base_changed;
                   8921:        }
                   8922:         if ((attname != NULL) && (attvalue != NULL)) {
                   8923:            if (len < 0) len = xmlStrlen(attvalue);
                   8924:             if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
                   8925:                const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
                   8926:                xmlURIPtr uri;
                   8927: 
                   8928:                 if (*URL != 0) {
                   8929:                    uri = xmlParseURI((const char *) URL);
                   8930:                    if (uri == NULL) {
                   8931:                        xmlNsErr(ctxt, XML_WAR_NS_URI,
                   8932:                                 "xmlns: '%s' is not a valid URI\n",
                   8933:                                           URL, NULL, NULL);
                   8934:                    } else {
                   8935:                        if (uri->scheme == NULL) {
                   8936:                            xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
                   8937:                                      "xmlns: URI %s is not absolute\n",
                   8938:                                      URL, NULL, NULL);
                   8939:                        }
                   8940:                        xmlFreeURI(uri);
                   8941:                    }
                   8942:                    if (URL == ctxt->str_xml_ns) {
                   8943:                        if (attname != ctxt->str_xml) {
                   8944:                            xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   8945:                         "xml namespace URI cannot be the default namespace\n",
                   8946:                                     NULL, NULL, NULL);
                   8947:                        }
                   8948:                        goto skip_default_ns;
                   8949:                    }
                   8950:                    if ((len == 29) &&
                   8951:                        (xmlStrEqual(URL,
                   8952:                                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
                   8953:                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   8954:                             "reuse of the xmlns namespace name is forbidden\n",
                   8955:                                 NULL, NULL, NULL);
                   8956:                        goto skip_default_ns;
                   8957:                    }
                   8958:                }
                   8959:                /*
                   8960:                 * check that it's not a defined namespace
                   8961:                 */
                   8962:                for (j = 1;j <= nbNs;j++)
                   8963:                    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
                   8964:                        break;
                   8965:                if (j <= nbNs)
                   8966:                    xmlErrAttributeDup(ctxt, NULL, attname);
                   8967:                else
                   8968:                    if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
                   8969: skip_default_ns:
                   8970:                if (alloc != 0) xmlFree(attvalue);
                   8971:                SKIP_BLANKS;
                   8972:                continue;
                   8973:            }
                   8974:             if (aprefix == ctxt->str_xmlns) {
                   8975:                const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
                   8976:                xmlURIPtr uri;
                   8977: 
                   8978:                 if (attname == ctxt->str_xml) {
                   8979:                    if (URL != ctxt->str_xml_ns) {
                   8980:                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   8981:                                 "xml namespace prefix mapped to wrong URI\n",
                   8982:                                 NULL, NULL, NULL);
                   8983:                    }
                   8984:                    /*
                   8985:                     * Do not keep a namespace definition node
                   8986:                     */
                   8987:                    goto skip_ns;
                   8988:                }
                   8989:                 if (URL == ctxt->str_xml_ns) {
                   8990:                    if (attname != ctxt->str_xml) {
                   8991:                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   8992:                                 "xml namespace URI mapped to wrong prefix\n",
                   8993:                                 NULL, NULL, NULL);
                   8994:                    }
                   8995:                    goto skip_ns;
                   8996:                }
                   8997:                 if (attname == ctxt->str_xmlns) {
                   8998:                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   8999:                             "redefinition of the xmlns prefix is forbidden\n",
                   9000:                             NULL, NULL, NULL);
                   9001:                    goto skip_ns;
                   9002:                }
                   9003:                if ((len == 29) &&
                   9004:                    (xmlStrEqual(URL,
                   9005:                                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
                   9006:                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   9007:                             "reuse of the xmlns namespace name is forbidden\n",
                   9008:                             NULL, NULL, NULL);
                   9009:                    goto skip_ns;
                   9010:                }
                   9011:                if ((URL == NULL) || (URL[0] == 0)) {
                   9012:                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                   9013:                             "xmlns:%s: Empty XML namespace is not allowed\n",
                   9014:                                  attname, NULL, NULL);
                   9015:                    goto skip_ns;
                   9016:                } else {
                   9017:                    uri = xmlParseURI((const char *) URL);
                   9018:                    if (uri == NULL) {
                   9019:                        xmlNsErr(ctxt, XML_WAR_NS_URI,
                   9020:                             "xmlns:%s: '%s' is not a valid URI\n",
                   9021:                                           attname, URL, NULL);
                   9022:                    } else {
                   9023:                        if ((ctxt->pedantic) && (uri->scheme == NULL)) {
                   9024:                            xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
                   9025:                                      "xmlns:%s: URI %s is not absolute\n",
                   9026:                                      attname, URL, NULL);
                   9027:                        }
                   9028:                        xmlFreeURI(uri);
                   9029:                    }
                   9030:                }
                   9031: 
                   9032:                /*
                   9033:                 * check that it's not a defined namespace
                   9034:                 */
                   9035:                for (j = 1;j <= nbNs;j++)
                   9036:                    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
                   9037:                        break;
                   9038:                if (j <= nbNs)
                   9039:                    xmlErrAttributeDup(ctxt, aprefix, attname);
                   9040:                else
                   9041:                    if (nsPush(ctxt, attname, URL) > 0) nbNs++;
                   9042: skip_ns:
                   9043:                if (alloc != 0) xmlFree(attvalue);
                   9044:                SKIP_BLANKS;
                   9045:                if (ctxt->input->base != base) goto base_changed;
                   9046:                continue;
                   9047:            }
                   9048: 
                   9049:            /*
                   9050:             * Add the pair to atts
                   9051:             */
                   9052:            if ((atts == NULL) || (nbatts + 5 > maxatts)) {
                   9053:                if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
                   9054:                    if (attvalue[len] == 0)
                   9055:                        xmlFree(attvalue);
                   9056:                    goto failed;
                   9057:                }
                   9058:                maxatts = ctxt->maxatts;
                   9059:                atts = ctxt->atts;
                   9060:            }
                   9061:            ctxt->attallocs[nratts++] = alloc;
                   9062:            atts[nbatts++] = attname;
                   9063:            atts[nbatts++] = aprefix;
                   9064:            atts[nbatts++] = NULL; /* the URI will be fetched later */
                   9065:            atts[nbatts++] = attvalue;
                   9066:            attvalue += len;
                   9067:            atts[nbatts++] = attvalue;
                   9068:            /*
                   9069:             * tag if some deallocation is needed
                   9070:             */
                   9071:            if (alloc != 0) attval = 1;
                   9072:        } else {
                   9073:            if ((attvalue != NULL) && (attvalue[len] == 0))
                   9074:                xmlFree(attvalue);
                   9075:        }
                   9076: 
                   9077: failed:
                   9078: 
                   9079:        GROW
                   9080:        if (ctxt->input->base != base) goto base_changed;
                   9081:        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
                   9082:            break;
                   9083:        if (!IS_BLANK_CH(RAW)) {
                   9084:            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   9085:                           "attributes construct error\n");
                   9086:            break;
                   9087:        }
                   9088:        SKIP_BLANKS;
                   9089:         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
                   9090:             (attname == NULL) && (attvalue == NULL)) {
                   9091:            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   9092:                 "xmlParseStartTag: problem parsing attributes\n");
                   9093:            break;
                   9094:        }
                   9095:         GROW;
                   9096:        if (ctxt->input->base != base) goto base_changed;
                   9097:     }
                   9098: 
                   9099:     /*
                   9100:      * The attributes defaulting
                   9101:      */
                   9102:     if (ctxt->attsDefault != NULL) {
                   9103:         xmlDefAttrsPtr defaults;
                   9104: 
                   9105:        defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
                   9106:        if (defaults != NULL) {
                   9107:            for (i = 0;i < defaults->nbAttrs;i++) {
                   9108:                attname = defaults->values[5 * i];
                   9109:                aprefix = defaults->values[5 * i + 1];
                   9110: 
                   9111:                 /*
                   9112:                 * special work for namespaces defaulted defs
                   9113:                 */
                   9114:                if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
                   9115:                    /*
                   9116:                     * check that it's not a defined namespace
                   9117:                     */
                   9118:                    for (j = 1;j <= nbNs;j++)
                   9119:                        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
                   9120:                            break;
                   9121:                    if (j <= nbNs) continue;
                   9122: 
                   9123:                    nsname = xmlGetNamespace(ctxt, NULL);
                   9124:                    if (nsname != defaults->values[5 * i + 2]) {
                   9125:                        if (nsPush(ctxt, NULL,
                   9126:                                   defaults->values[5 * i + 2]) > 0)
                   9127:                            nbNs++;
                   9128:                    }
                   9129:                } else if (aprefix == ctxt->str_xmlns) {
                   9130:                    /*
                   9131:                     * check that it's not a defined namespace
                   9132:                     */
                   9133:                    for (j = 1;j <= nbNs;j++)
                   9134:                        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
                   9135:                            break;
                   9136:                    if (j <= nbNs) continue;
                   9137: 
                   9138:                    nsname = xmlGetNamespace(ctxt, attname);
                   9139:                    if (nsname != defaults->values[2]) {
                   9140:                        if (nsPush(ctxt, attname,
                   9141:                                   defaults->values[5 * i + 2]) > 0)
                   9142:                            nbNs++;
                   9143:                    }
                   9144:                } else {
                   9145:                    /*
                   9146:                     * check that it's not a defined attribute
                   9147:                     */
                   9148:                    for (j = 0;j < nbatts;j+=5) {
                   9149:                        if ((attname == atts[j]) && (aprefix == atts[j+1]))
                   9150:                            break;
                   9151:                    }
                   9152:                    if (j < nbatts) continue;
                   9153: 
                   9154:                    if ((atts == NULL) || (nbatts + 5 > maxatts)) {
                   9155:                        if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
                   9156:                            return(NULL);
                   9157:                        }
                   9158:                        maxatts = ctxt->maxatts;
                   9159:                        atts = ctxt->atts;
                   9160:                    }
                   9161:                    atts[nbatts++] = attname;
                   9162:                    atts[nbatts++] = aprefix;
                   9163:                    if (aprefix == NULL)
                   9164:                        atts[nbatts++] = NULL;
                   9165:                    else
                   9166:                        atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
                   9167:                    atts[nbatts++] = defaults->values[5 * i + 2];
                   9168:                    atts[nbatts++] = defaults->values[5 * i + 3];
                   9169:                    if ((ctxt->standalone == 1) &&
                   9170:                        (defaults->values[5 * i + 4] != NULL)) {
                   9171:                        xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED, 
                   9172:          "standalone: attribute %s on %s defaulted from external subset\n",
                   9173:                                         attname, localname);
                   9174:                    }
                   9175:                    nbdef++;
                   9176:                }
                   9177:            }
                   9178:        }
                   9179:     }
                   9180: 
                   9181:     /*
                   9182:      * The attributes checkings
                   9183:      */
                   9184:     for (i = 0; i < nbatts;i += 5) {
                   9185:         /*
                   9186:        * The default namespace does not apply to attribute names.
                   9187:        */
                   9188:        if (atts[i + 1] != NULL) {
                   9189:            nsname = xmlGetNamespace(ctxt, atts[i + 1]);
                   9190:            if (nsname == NULL) {
                   9191:                xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
                   9192:                    "Namespace prefix %s for %s on %s is not defined\n",
                   9193:                    atts[i + 1], atts[i], localname);
                   9194:            }
                   9195:            atts[i + 2] = nsname;
                   9196:        } else
                   9197:            nsname = NULL;
                   9198:        /*
                   9199:         * [ WFC: Unique Att Spec ]
                   9200:         * No attribute name may appear more than once in the same
                   9201:         * start-tag or empty-element tag. 
                   9202:         * As extended by the Namespace in XML REC.
                   9203:         */
                   9204:         for (j = 0; j < i;j += 5) {
                   9205:            if (atts[i] == atts[j]) {
                   9206:                if (atts[i+1] == atts[j+1]) {
                   9207:                    xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
                   9208:                    break;
                   9209:                }
                   9210:                if ((nsname != NULL) && (atts[j + 2] == nsname)) {
                   9211:                    xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
                   9212:                             "Namespaced Attribute %s in '%s' redefined\n",
                   9213:                             atts[i], nsname, NULL);
                   9214:                    break;
                   9215:                }
                   9216:            }
                   9217:        }
                   9218:     }
                   9219: 
                   9220:     nsname = xmlGetNamespace(ctxt, prefix);
                   9221:     if ((prefix != NULL) && (nsname == NULL)) {
                   9222:        xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
                   9223:                 "Namespace prefix %s on %s is not defined\n",
                   9224:                 prefix, localname, NULL);
                   9225:     }
                   9226:     *pref = prefix;
                   9227:     *URI = nsname;
                   9228: 
                   9229:     /*
                   9230:      * SAX: Start of Element !
                   9231:      */
                   9232:     if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
                   9233:        (!ctxt->disableSAX)) {
                   9234:        if (nbNs > 0)
                   9235:            ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
                   9236:                          nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
                   9237:                          nbatts / 5, nbdef, atts);
                   9238:        else
                   9239:            ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
                   9240:                          nsname, 0, NULL, nbatts / 5, nbdef, atts);
                   9241:     }
                   9242: 
                   9243:     /*
                   9244:      * Free up attribute allocated strings if needed
                   9245:      */
                   9246:     if (attval != 0) {
                   9247:        for (i = 3,j = 0; j < nratts;i += 5,j++)
                   9248:            if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
                   9249:                xmlFree((xmlChar *) atts[i]);
                   9250:     }
                   9251: 
                   9252:     return(localname);
                   9253: 
                   9254: base_changed:
                   9255:     /*
                   9256:      * the attribute strings are valid iif the base didn't changed
                   9257:      */
                   9258:     if (attval != 0) {
                   9259:        for (i = 3,j = 0; j < nratts;i += 5,j++)
                   9260:            if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
                   9261:                xmlFree((xmlChar *) atts[i]);
                   9262:     }
                   9263:     ctxt->input->cur = ctxt->input->base + cur;
                   9264:     ctxt->input->line = oldline;
                   9265:     ctxt->input->col = oldcol;
                   9266:     if (ctxt->wellFormed == 1) {
                   9267:        goto reparse;
                   9268:     }
                   9269:     return(NULL);
                   9270: }
                   9271: 
                   9272: /**
                   9273:  * xmlParseEndTag2:
                   9274:  * @ctxt:  an XML parser context
                   9275:  * @line:  line of the start tag
                   9276:  * @nsNr:  number of namespaces on the start tag
                   9277:  *
                   9278:  * parse an end of tag
                   9279:  *
                   9280:  * [42] ETag ::= '</' Name S? '>'
                   9281:  *
                   9282:  * With namespace
                   9283:  *
                   9284:  * [NS 9] ETag ::= '</' QName S? '>'
                   9285:  */
                   9286: 
                   9287: static void
                   9288: xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
                   9289:                 const xmlChar *URI, int line, int nsNr, int tlen) {
                   9290:     const xmlChar *name;
                   9291: 
                   9292:     GROW;
                   9293:     if ((RAW != '<') || (NXT(1) != '/')) {
                   9294:        xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
                   9295:        return;
                   9296:     }
                   9297:     SKIP(2);
                   9298: 
                   9299:     if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
                   9300:         if (ctxt->input->cur[tlen] == '>') {
                   9301:            ctxt->input->cur += tlen + 1;
                   9302:            goto done;
                   9303:        }
                   9304:        ctxt->input->cur += tlen;
                   9305:        name = (xmlChar*)1;
                   9306:     } else {
                   9307:        if (prefix == NULL)
                   9308:            name = xmlParseNameAndCompare(ctxt, ctxt->name);
                   9309:        else
                   9310:            name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
                   9311:     }
                   9312: 
                   9313:     /*
                   9314:      * We should definitely be at the ending "S? '>'" part
                   9315:      */
                   9316:     GROW;
                   9317:     SKIP_BLANKS;
                   9318:     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
                   9319:        xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
                   9320:     } else
                   9321:        NEXT1;
                   9322: 
                   9323:     /*
                   9324:      * [ WFC: Element Type Match ]
                   9325:      * The Name in an element's end-tag must match the element type in the
                   9326:      * start-tag. 
                   9327:      *
                   9328:      */
                   9329:     if (name != (xmlChar*)1) {
                   9330:         if (name == NULL) name = BAD_CAST "unparseable";
                   9331:         if ((line == 0) && (ctxt->node != NULL))
                   9332:             line = ctxt->node->line;
                   9333:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
                   9334:                     "Opening and ending tag mismatch: %s line %d and %s\n",
                   9335:                                ctxt->name, line, name);
                   9336:     }
                   9337: 
                   9338:     /*
                   9339:      * SAX: End of Tag
                   9340:      */
                   9341: done:
                   9342:     if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
                   9343:        (!ctxt->disableSAX))
                   9344:        ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
                   9345: 
                   9346:     spacePop(ctxt);
                   9347:     if (nsNr != 0)
                   9348:        nsPop(ctxt, nsNr);
                   9349:     return;
                   9350: }
                   9351: 
                   9352: /**
                   9353:  * xmlParseCDSect:
                   9354:  * @ctxt:  an XML parser context
                   9355:  * 
                   9356:  * Parse escaped pure raw content.
                   9357:  *
                   9358:  * [18] CDSect ::= CDStart CData CDEnd
                   9359:  *
                   9360:  * [19] CDStart ::= '<![CDATA['
                   9361:  *
                   9362:  * [20] Data ::= (Char* - (Char* ']]>' Char*))
                   9363:  *
                   9364:  * [21] CDEnd ::= ']]>'
                   9365:  */
                   9366: void
                   9367: xmlParseCDSect(xmlParserCtxtPtr ctxt) {
                   9368:     xmlChar *buf = NULL;
                   9369:     int len = 0;
                   9370:     int size = XML_PARSER_BUFFER_SIZE;
                   9371:     int r, rl;
                   9372:     int        s, sl;
                   9373:     int cur, l;
                   9374:     int count = 0;
                   9375: 
                   9376:     /* Check 2.6.0 was NXT(0) not RAW */
                   9377:     if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
                   9378:        SKIP(9);
                   9379:     } else
                   9380:         return;
                   9381: 
                   9382:     ctxt->instate = XML_PARSER_CDATA_SECTION;
                   9383:     r = CUR_CHAR(rl);
                   9384:     if (!IS_CHAR(r)) {
                   9385:        xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
                   9386:        ctxt->instate = XML_PARSER_CONTENT;
                   9387:         return;
                   9388:     }
                   9389:     NEXTL(rl);
                   9390:     s = CUR_CHAR(sl);
                   9391:     if (!IS_CHAR(s)) {
                   9392:        xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
                   9393:        ctxt->instate = XML_PARSER_CONTENT;
                   9394:         return;
                   9395:     }
                   9396:     NEXTL(sl);
                   9397:     cur = CUR_CHAR(l);
                   9398:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   9399:     if (buf == NULL) {
                   9400:        xmlErrMemory(ctxt, NULL);
                   9401:        return;
                   9402:     }
                   9403:     while (IS_CHAR(cur) &&
                   9404:            ((r != ']') || (s != ']') || (cur != '>'))) {
                   9405:        if (len + 5 >= size) {
                   9406:            xmlChar *tmp;
                   9407: 
                   9408:            size *= 2;
                   9409:            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   9410:            if (tmp == NULL) {
                   9411:                xmlFree(buf);
                   9412:                xmlErrMemory(ctxt, NULL);
                   9413:                return;
                   9414:            }
                   9415:            buf = tmp;
                   9416:        }
                   9417:        COPY_BUF(rl,buf,len,r);
                   9418:        r = s;
                   9419:        rl = sl;
                   9420:        s = cur;
                   9421:        sl = l;
                   9422:        count++;
                   9423:        if (count > 50) {
                   9424:            GROW;
                   9425:            count = 0;
                   9426:        }
                   9427:        NEXTL(l);
                   9428:        cur = CUR_CHAR(l);
                   9429:     }
                   9430:     buf[len] = 0;
                   9431:     ctxt->instate = XML_PARSER_CONTENT;
                   9432:     if (cur != '>') {
                   9433:        xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
                   9434:                             "CData section not finished\n%.50s\n", buf);
                   9435:        xmlFree(buf);
                   9436:         return;
                   9437:     }
                   9438:     NEXTL(l);
                   9439: 
                   9440:     /*
                   9441:      * OK the buffer is to be consumed as cdata.
                   9442:      */
                   9443:     if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
                   9444:        if (ctxt->sax->cdataBlock != NULL)
                   9445:            ctxt->sax->cdataBlock(ctxt->userData, buf, len);
                   9446:        else if (ctxt->sax->characters != NULL)
                   9447:            ctxt->sax->characters(ctxt->userData, buf, len);
                   9448:     }
                   9449:     xmlFree(buf);
                   9450: }
                   9451: 
                   9452: /**
                   9453:  * xmlParseContent:
                   9454:  * @ctxt:  an XML parser context
                   9455:  *
                   9456:  * Parse a content:
                   9457:  *
                   9458:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   9459:  */
                   9460: 
                   9461: void
                   9462: xmlParseContent(xmlParserCtxtPtr ctxt) {
                   9463:     GROW;
                   9464:     while ((RAW != 0) &&
                   9465:           ((RAW != '<') || (NXT(1) != '/')) &&
                   9466:           (ctxt->instate != XML_PARSER_EOF)) {
                   9467:        const xmlChar *test = CUR_PTR;
                   9468:        unsigned int cons = ctxt->input->consumed;
                   9469:        const xmlChar *cur = ctxt->input->cur;
                   9470: 
                   9471:        /*
                   9472:         * First case : a Processing Instruction.
                   9473:         */
                   9474:        if ((*cur == '<') && (cur[1] == '?')) {
                   9475:            xmlParsePI(ctxt);
                   9476:        }
                   9477: 
                   9478:        /*
                   9479:         * Second case : a CDSection
                   9480:         */
                   9481:        /* 2.6.0 test was *cur not RAW */
                   9482:        else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
                   9483:            xmlParseCDSect(ctxt);
                   9484:        }
                   9485: 
                   9486:        /*
                   9487:         * Third case :  a comment
                   9488:         */
                   9489:        else if ((*cur == '<') && (NXT(1) == '!') &&
                   9490:                 (NXT(2) == '-') && (NXT(3) == '-')) {
                   9491:            xmlParseComment(ctxt);
                   9492:            ctxt->instate = XML_PARSER_CONTENT;
                   9493:        }
                   9494: 
                   9495:        /*
                   9496:         * Fourth case :  a sub-element.
                   9497:         */
                   9498:        else if (*cur == '<') {
                   9499:            xmlParseElement(ctxt);
                   9500:        }
                   9501: 
                   9502:        /*
                   9503:         * Fifth case : a reference. If if has not been resolved,
                   9504:         *    parsing returns it's Name, create the node 
                   9505:         */
                   9506: 
                   9507:        else if (*cur == '&') {
                   9508:            xmlParseReference(ctxt);
                   9509:        }
                   9510: 
                   9511:        /*
                   9512:         * Last case, text. Note that References are handled directly.
                   9513:         */
                   9514:        else {
                   9515:            xmlParseCharData(ctxt, 0);
                   9516:        }
                   9517: 
                   9518:        GROW;
                   9519:        /*
                   9520:         * Pop-up of finished entities.
                   9521:         */
                   9522:        while ((RAW == 0) && (ctxt->inputNr > 1))
                   9523:            xmlPopInput(ctxt);
                   9524:        SHRINK;
                   9525: 
                   9526:        if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
                   9527:            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   9528:                        "detected an error in element content\n");
                   9529:            ctxt->instate = XML_PARSER_EOF;
                   9530:             break;
                   9531:        }
                   9532:     }
                   9533: }
                   9534: 
                   9535: /**
                   9536:  * xmlParseElement:
                   9537:  * @ctxt:  an XML parser context
                   9538:  *
                   9539:  * parse an XML element, this is highly recursive
                   9540:  *
                   9541:  * [39] element ::= EmptyElemTag | STag content ETag
                   9542:  *
                   9543:  * [ WFC: Element Type Match ]
                   9544:  * The Name in an element's end-tag must match the element type in the
                   9545:  * start-tag. 
                   9546:  *
                   9547:  */
                   9548: 
                   9549: void
                   9550: xmlParseElement(xmlParserCtxtPtr ctxt) {
                   9551:     const xmlChar *name;
                   9552:     const xmlChar *prefix = NULL;
                   9553:     const xmlChar *URI = NULL;
                   9554:     xmlParserNodeInfo node_info;
                   9555:     int line, tlen;
                   9556:     xmlNodePtr ret;
                   9557:     int nsNr = ctxt->nsNr;
                   9558: 
                   9559:     if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
                   9560:         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                   9561:        xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
                   9562:                 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
                   9563:                          xmlParserMaxDepth);
                   9564:        ctxt->instate = XML_PARSER_EOF;
                   9565:        return;
                   9566:     }
                   9567: 
                   9568:     /* Capture start position */
                   9569:     if (ctxt->record_info) {
                   9570:         node_info.begin_pos = ctxt->input->consumed +
                   9571:                           (CUR_PTR - ctxt->input->base);
                   9572:        node_info.begin_line = ctxt->input->line;
                   9573:     }
                   9574: 
                   9575:     if (ctxt->spaceNr == 0)
                   9576:        spacePush(ctxt, -1);
                   9577:     else if (*ctxt->space == -2)
                   9578:        spacePush(ctxt, -1);
                   9579:     else
                   9580:        spacePush(ctxt, *ctxt->space);
                   9581: 
                   9582:     line = ctxt->input->line;
                   9583: #ifdef LIBXML_SAX1_ENABLED
                   9584:     if (ctxt->sax2)
                   9585: #endif /* LIBXML_SAX1_ENABLED */
                   9586:         name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
                   9587: #ifdef LIBXML_SAX1_ENABLED
                   9588:     else
                   9589:        name = xmlParseStartTag(ctxt);
                   9590: #endif /* LIBXML_SAX1_ENABLED */
                   9591:     if (name == NULL) {
                   9592:        spacePop(ctxt);
                   9593:         return;
                   9594:     }
                   9595:     namePush(ctxt, name);
                   9596:     ret = ctxt->node;
                   9597: 
                   9598: #ifdef LIBXML_VALID_ENABLED
                   9599:     /*
                   9600:      * [ VC: Root Element Type ]
                   9601:      * The Name in the document type declaration must match the element
                   9602:      * type of the root element. 
                   9603:      */
                   9604:     if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
                   9605:         ctxt->node && (ctxt->node == ctxt->myDoc->children))
                   9606:         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
                   9607: #endif /* LIBXML_VALID_ENABLED */
                   9608: 
                   9609:     /*
                   9610:      * Check for an Empty Element.
                   9611:      */
                   9612:     if ((RAW == '/') && (NXT(1) == '>')) {
                   9613:         SKIP(2);
                   9614:        if (ctxt->sax2) {
                   9615:            if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
                   9616:                (!ctxt->disableSAX))
                   9617:                ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
                   9618: #ifdef LIBXML_SAX1_ENABLED
                   9619:        } else {
                   9620:            if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
                   9621:                (!ctxt->disableSAX))
                   9622:                ctxt->sax->endElement(ctxt->userData, name);
                   9623: #endif /* LIBXML_SAX1_ENABLED */
                   9624:        }
                   9625:        namePop(ctxt);
                   9626:        spacePop(ctxt);
                   9627:        if (nsNr != ctxt->nsNr)
                   9628:            nsPop(ctxt, ctxt->nsNr - nsNr);
                   9629:        if ( ret != NULL && ctxt->record_info ) {
                   9630:           node_info.end_pos = ctxt->input->consumed +
                   9631:                              (CUR_PTR - ctxt->input->base);
                   9632:           node_info.end_line = ctxt->input->line;
                   9633:           node_info.node = ret;
                   9634:           xmlParserAddNodeInfo(ctxt, &node_info);
                   9635:        }
                   9636:        return;
                   9637:     }
                   9638:     if (RAW == '>') {
                   9639:         NEXT1;
                   9640:     } else {
                   9641:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
                   9642:                     "Couldn't find end of Start Tag %s line %d\n",
                   9643:                                name, line, NULL);
                   9644: 
                   9645:        /*
                   9646:         * end of parsing of this node.
                   9647:         */
                   9648:        nodePop(ctxt);
                   9649:        namePop(ctxt);
                   9650:        spacePop(ctxt);
                   9651:        if (nsNr != ctxt->nsNr)
                   9652:            nsPop(ctxt, ctxt->nsNr - nsNr);
                   9653: 
                   9654:        /*
                   9655:         * Capture end position and add node
                   9656:         */
                   9657:        if ( ret != NULL && ctxt->record_info ) {
                   9658:           node_info.end_pos = ctxt->input->consumed +
                   9659:                              (CUR_PTR - ctxt->input->base);
                   9660:           node_info.end_line = ctxt->input->line;
                   9661:           node_info.node = ret;
                   9662:           xmlParserAddNodeInfo(ctxt, &node_info);
                   9663:        }
                   9664:        return;
                   9665:     }
                   9666: 
                   9667:     /*
                   9668:      * Parse the content of the element:
                   9669:      */
                   9670:     xmlParseContent(ctxt);
                   9671:     if (!IS_BYTE_CHAR(RAW)) {
                   9672:         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
                   9673:         "Premature end of data in tag %s line %d\n",
                   9674:                                name, line, NULL);
                   9675: 
                   9676:        /*
                   9677:         * end of parsing of this node.
                   9678:         */
                   9679:        nodePop(ctxt);
                   9680:        namePop(ctxt);
                   9681:        spacePop(ctxt);
                   9682:        if (nsNr != ctxt->nsNr)
                   9683:            nsPop(ctxt, ctxt->nsNr - nsNr);
                   9684:        return;
                   9685:     }
                   9686: 
                   9687:     /*
                   9688:      * parse the end of tag: '</' should be here.
                   9689:      */
                   9690:     if (ctxt->sax2) {
                   9691:        xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
                   9692:        namePop(ctxt);
                   9693:     }
                   9694: #ifdef LIBXML_SAX1_ENABLED
                   9695:       else
                   9696:        xmlParseEndTag1(ctxt, line);
                   9697: #endif /* LIBXML_SAX1_ENABLED */
                   9698: 
                   9699:     /*
                   9700:      * Capture end position and add node
                   9701:      */
                   9702:     if ( ret != NULL && ctxt->record_info ) {
                   9703:        node_info.end_pos = ctxt->input->consumed +
                   9704:                           (CUR_PTR - ctxt->input->base);
                   9705:        node_info.end_line = ctxt->input->line;
                   9706:        node_info.node = ret;
                   9707:        xmlParserAddNodeInfo(ctxt, &node_info);
                   9708:     }
                   9709: }
                   9710: 
                   9711: /**
                   9712:  * xmlParseVersionNum:
                   9713:  * @ctxt:  an XML parser context
                   9714:  *
                   9715:  * parse the XML version value.
                   9716:  *
                   9717:  * [26] VersionNum ::= '1.' [0-9]+
                   9718:  *
                   9719:  * In practice allow [0-9].[0-9]+ at that level
                   9720:  *
                   9721:  * Returns the string giving the XML version number, or NULL
                   9722:  */
                   9723: xmlChar *
                   9724: xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
                   9725:     xmlChar *buf = NULL;
                   9726:     int len = 0;
                   9727:     int size = 10;
                   9728:     xmlChar cur;
                   9729: 
                   9730:     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   9731:     if (buf == NULL) {
                   9732:        xmlErrMemory(ctxt, NULL);
                   9733:        return(NULL);
                   9734:     }
                   9735:     cur = CUR;
                   9736:     if (!((cur >= '0') && (cur <= '9'))) {
                   9737:        xmlFree(buf);
                   9738:        return(NULL);
                   9739:     }
                   9740:     buf[len++] = cur;
                   9741:     NEXT;
                   9742:     cur=CUR;
                   9743:     if (cur != '.') {
                   9744:        xmlFree(buf);
                   9745:        return(NULL);
                   9746:     }
                   9747:     buf[len++] = cur;
                   9748:     NEXT;
                   9749:     cur=CUR;
                   9750:     while ((cur >= '0') && (cur <= '9')) {
                   9751:        if (len + 1 >= size) {
                   9752:            xmlChar *tmp;
                   9753: 
                   9754:            size *= 2;
                   9755:            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   9756:            if (tmp == NULL) {
                   9757:                xmlFree(buf);
                   9758:                xmlErrMemory(ctxt, NULL);
                   9759:                return(NULL);
                   9760:            }
                   9761:            buf = tmp;
                   9762:        }
                   9763:        buf[len++] = cur;
                   9764:        NEXT;
                   9765:        cur=CUR;
                   9766:     }
                   9767:     buf[len] = 0;
                   9768:     return(buf);
                   9769: }
                   9770: 
                   9771: /**
                   9772:  * xmlParseVersionInfo:
                   9773:  * @ctxt:  an XML parser context
                   9774:  *
                   9775:  * parse the XML version.
                   9776:  *
                   9777:  * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
                   9778:  *
                   9779:  * [25] Eq ::= S? '=' S?
                   9780:  *
                   9781:  * Returns the version string, e.g. "1.0"
                   9782:  */
                   9783: 
                   9784: xmlChar *
                   9785: xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
                   9786:     xmlChar *version = NULL;
                   9787: 
                   9788:     if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
                   9789:        SKIP(7);
                   9790:        SKIP_BLANKS;
                   9791:        if (RAW != '=') {
                   9792:            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
                   9793:            return(NULL);
                   9794:         }
                   9795:        NEXT;
                   9796:        SKIP_BLANKS;
                   9797:        if (RAW == '"') {
                   9798:            NEXT;
                   9799:            version = xmlParseVersionNum(ctxt);
                   9800:            if (RAW != '"') {
                   9801:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   9802:            } else
                   9803:                NEXT;
                   9804:        } else if (RAW == '\''){
                   9805:            NEXT;
                   9806:            version = xmlParseVersionNum(ctxt);
                   9807:            if (RAW != '\'') {
                   9808:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   9809:            } else
                   9810:                NEXT;
                   9811:        } else {
                   9812:            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
                   9813:        }
                   9814:     }
                   9815:     return(version);
                   9816: }
                   9817: 
                   9818: /**
                   9819:  * xmlParseEncName:
                   9820:  * @ctxt:  an XML parser context
                   9821:  *
                   9822:  * parse the XML encoding name
                   9823:  *
                   9824:  * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
                   9825:  *
                   9826:  * Returns the encoding name value or NULL
                   9827:  */
                   9828: xmlChar *
                   9829: xmlParseEncName(xmlParserCtxtPtr ctxt) {
                   9830:     xmlChar *buf = NULL;
                   9831:     int len = 0;
                   9832:     int size = 10;
                   9833:     xmlChar cur;
                   9834: 
                   9835:     cur = CUR;
                   9836:     if (((cur >= 'a') && (cur <= 'z')) ||
                   9837:         ((cur >= 'A') && (cur <= 'Z'))) {
                   9838:        buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
                   9839:        if (buf == NULL) {
                   9840:            xmlErrMemory(ctxt, NULL);
                   9841:            return(NULL);
                   9842:        }
                   9843: 
                   9844:        buf[len++] = cur;
                   9845:        NEXT;
                   9846:        cur = CUR;
                   9847:        while (((cur >= 'a') && (cur <= 'z')) ||
                   9848:               ((cur >= 'A') && (cur <= 'Z')) ||
                   9849:               ((cur >= '0') && (cur <= '9')) ||
                   9850:               (cur == '.') || (cur == '_') ||
                   9851:               (cur == '-')) {
                   9852:            if (len + 1 >= size) {
                   9853:                xmlChar *tmp;
                   9854: 
                   9855:                size *= 2;
                   9856:                tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
                   9857:                if (tmp == NULL) {
                   9858:                    xmlErrMemory(ctxt, NULL);
                   9859:                    xmlFree(buf);
                   9860:                    return(NULL);
                   9861:                }
                   9862:                buf = tmp;
                   9863:            }
                   9864:            buf[len++] = cur;
                   9865:            NEXT;
                   9866:            cur = CUR;
                   9867:            if (cur == 0) {
                   9868:                SHRINK;
                   9869:                GROW;
                   9870:                cur = CUR;
                   9871:            }
                   9872:         }
                   9873:        buf[len] = 0;
                   9874:     } else {
                   9875:        xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
                   9876:     }
                   9877:     return(buf);
                   9878: }
                   9879: 
                   9880: /**
                   9881:  * xmlParseEncodingDecl:
                   9882:  * @ctxt:  an XML parser context
                   9883:  * 
                   9884:  * parse the XML encoding declaration
                   9885:  *
                   9886:  * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
                   9887:  *
                   9888:  * this setups the conversion filters.
                   9889:  *
                   9890:  * Returns the encoding value or NULL
                   9891:  */
                   9892: 
                   9893: const xmlChar *
                   9894: xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
                   9895:     xmlChar *encoding = NULL;
                   9896: 
                   9897:     SKIP_BLANKS;
                   9898:     if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
                   9899:        SKIP(8);
                   9900:        SKIP_BLANKS;
                   9901:        if (RAW != '=') {
                   9902:            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
                   9903:            return(NULL);
                   9904:         }
                   9905:        NEXT;
                   9906:        SKIP_BLANKS;
                   9907:        if (RAW == '"') {
                   9908:            NEXT;
                   9909:            encoding = xmlParseEncName(ctxt);
                   9910:            if (RAW != '"') {
                   9911:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   9912:            } else
                   9913:                NEXT;
                   9914:        } else if (RAW == '\''){
                   9915:            NEXT;
                   9916:            encoding = xmlParseEncName(ctxt);
                   9917:            if (RAW != '\'') {
                   9918:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   9919:            } else
                   9920:                NEXT;
                   9921:        } else {
                   9922:            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
                   9923:        }
                   9924:        /*
                   9925:         * UTF-16 encoding stwich has already taken place at this stage,
                   9926:         * more over the little-endian/big-endian selection is already done
                   9927:         */
                   9928:         if ((encoding != NULL) &&
                   9929:            ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
                   9930:             (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
                   9931:            /*
                   9932:             * If no encoding was passed to the parser, that we are
                   9933:             * using UTF-16 and no decoder is present i.e. the 
                   9934:             * document is apparently UTF-8 compatible, then raise an
                   9935:             * encoding mismatch fatal error
                   9936:             */
                   9937:            if ((ctxt->encoding == NULL) &&
                   9938:                (ctxt->input->buf != NULL) &&
                   9939:                (ctxt->input->buf->encoder == NULL)) {
                   9940:                xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
                   9941:                  "Document labelled UTF-16 but has UTF-8 content\n");
                   9942:            }
                   9943:            if (ctxt->encoding != NULL)
                   9944:                xmlFree((xmlChar *) ctxt->encoding);
                   9945:            ctxt->encoding = encoding;
                   9946:        }
                   9947:        /*
                   9948:         * UTF-8 encoding is handled natively
                   9949:         */
                   9950:         else if ((encoding != NULL) &&
                   9951:            ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
                   9952:             (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
                   9953:            if (ctxt->encoding != NULL)
                   9954:                xmlFree((xmlChar *) ctxt->encoding);
                   9955:            ctxt->encoding = encoding;
                   9956:        }
                   9957:        else if (encoding != NULL) {
                   9958:            xmlCharEncodingHandlerPtr handler;
                   9959: 
                   9960:            if (ctxt->input->encoding != NULL)
                   9961:                xmlFree((xmlChar *) ctxt->input->encoding);
                   9962:            ctxt->input->encoding = encoding;
                   9963: 
                   9964:             handler = xmlFindCharEncodingHandler((const char *) encoding);
                   9965:            if (handler != NULL) {
                   9966:                xmlSwitchToEncoding(ctxt, handler);
                   9967:            } else {
                   9968:                xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
                   9969:                        "Unsupported encoding %s\n", encoding);
                   9970:                return(NULL);
                   9971:            }
                   9972:        }
                   9973:     }
                   9974:     return(encoding);
                   9975: }
                   9976: 
                   9977: /**
                   9978:  * xmlParseSDDecl:
                   9979:  * @ctxt:  an XML parser context
                   9980:  *
                   9981:  * parse the XML standalone declaration
                   9982:  *
                   9983:  * [32] SDDecl ::= S 'standalone' Eq
                   9984:  *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"')) 
                   9985:  *
                   9986:  * [ VC: Standalone Document Declaration ]
                   9987:  * TODO The standalone document declaration must have the value "no"
                   9988:  * if any external markup declarations contain declarations of:
                   9989:  *  - attributes with default values, if elements to which these
                   9990:  *    attributes apply appear in the document without specifications
                   9991:  *    of values for these attributes, or
                   9992:  *  - entities (other than amp, lt, gt, apos, quot), if references
                   9993:  *    to those entities appear in the document, or
                   9994:  *  - attributes with values subject to normalization, where the
                   9995:  *    attribute appears in the document with a value which will change
                   9996:  *    as a result of normalization, or
                   9997:  *  - element types with element content, if white space occurs directly
                   9998:  *    within any instance of those types.
                   9999:  *
                   10000:  * Returns:
                   10001:  *   1 if standalone="yes"
                   10002:  *   0 if standalone="no"
                   10003:  *  -2 if standalone attribute is missing or invalid
                   10004:  *       (A standalone value of -2 means that the XML declaration was found,
                   10005:  *        but no value was specified for the standalone attribute).
                   10006:  */
                   10007: 
                   10008: int
                   10009: xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
                   10010:     int standalone = -2;
                   10011: 
                   10012:     SKIP_BLANKS;
                   10013:     if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
                   10014:        SKIP(10);
                   10015:         SKIP_BLANKS;
                   10016:        if (RAW != '=') {
                   10017:            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
                   10018:            return(standalone);
                   10019:         }
                   10020:        NEXT;
                   10021:        SKIP_BLANKS;
                   10022:         if (RAW == '\''){
                   10023:            NEXT;
                   10024:            if ((RAW == 'n') && (NXT(1) == 'o')) {
                   10025:                standalone = 0;
                   10026:                 SKIP(2);
                   10027:            } else if ((RAW == 'y') && (NXT(1) == 'e') &&
                   10028:                       (NXT(2) == 's')) {
                   10029:                standalone = 1;
                   10030:                SKIP(3);
                   10031:             } else {
                   10032:                xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
                   10033:            }
                   10034:            if (RAW != '\'') {
                   10035:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   10036:            } else
                   10037:                NEXT;
                   10038:        } else if (RAW == '"'){
                   10039:            NEXT;
                   10040:            if ((RAW == 'n') && (NXT(1) == 'o')) {
                   10041:                standalone = 0;
                   10042:                SKIP(2);
                   10043:            } else if ((RAW == 'y') && (NXT(1) == 'e') &&
                   10044:                       (NXT(2) == 's')) {
                   10045:                standalone = 1;
                   10046:                 SKIP(3);
                   10047:             } else {
                   10048:                xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
                   10049:            }
                   10050:            if (RAW != '"') {
                   10051:                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
                   10052:            } else
                   10053:                NEXT;
                   10054:        } else {
                   10055:            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
                   10056:         }
                   10057:     }
                   10058:     return(standalone);
                   10059: }
                   10060: 
                   10061: /**
                   10062:  * xmlParseXMLDecl:
                   10063:  * @ctxt:  an XML parser context
                   10064:  * 
                   10065:  * parse an XML declaration header
                   10066:  *
                   10067:  * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
                   10068:  */
                   10069: 
                   10070: void
                   10071: xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
                   10072:     xmlChar *version;
                   10073: 
                   10074:     /*
                   10075:      * This value for standalone indicates that the document has an
                   10076:      * XML declaration but it does not have a standalone attribute.
                   10077:      * It will be overwritten later if a standalone attribute is found.
                   10078:      */
                   10079:     ctxt->input->standalone = -2;
                   10080: 
                   10081:     /*
                   10082:      * We know that '<?xml' is here.
                   10083:      */
                   10084:     SKIP(5);
                   10085: 
                   10086:     if (!IS_BLANK_CH(RAW)) {
                   10087:        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                   10088:                       "Blank needed after '<?xml'\n");
                   10089:     }
                   10090:     SKIP_BLANKS;
                   10091: 
                   10092:     /*
                   10093:      * We must have the VersionInfo here.
                   10094:      */
                   10095:     version = xmlParseVersionInfo(ctxt);
                   10096:     if (version == NULL) {
                   10097:        xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
                   10098:     } else {
                   10099:        if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
                   10100:            /*
                   10101:             * Changed here for XML-1.0 5th edition
                   10102:             */
                   10103:            if (ctxt->options & XML_PARSE_OLD10) {
                   10104:                xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
                   10105:                                  "Unsupported version '%s'\n",
                   10106:                                  version);
                   10107:            } else {
                   10108:                if ((version[0] == '1') && ((version[1] == '.'))) {
                   10109:                    xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
                   10110:                                  "Unsupported version '%s'\n",
                   10111:                                  version, NULL);
                   10112:                } else {
                   10113:                    xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
                   10114:                                      "Unsupported version '%s'\n",
                   10115:                                      version);
                   10116:                }
                   10117:            }
                   10118:        }
                   10119:        if (ctxt->version != NULL)
                   10120:            xmlFree((void *) ctxt->version);
                   10121:        ctxt->version = version;
                   10122:     }
                   10123: 
                   10124:     /*
                   10125:      * We may have the encoding declaration
                   10126:      */
                   10127:     if (!IS_BLANK_CH(RAW)) {
                   10128:         if ((RAW == '?') && (NXT(1) == '>')) {
                   10129:            SKIP(2);
                   10130:            return;
                   10131:        }
                   10132:        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
                   10133:     }
                   10134:     xmlParseEncodingDecl(ctxt);
                   10135:     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   10136:        /*
                   10137:         * The XML REC instructs us to stop parsing right here
                   10138:         */
                   10139:         return;
                   10140:     }
                   10141: 
                   10142:     /*
                   10143:      * We may have the standalone status.
                   10144:      */
                   10145:     if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
                   10146:         if ((RAW == '?') && (NXT(1) == '>')) {
                   10147:            SKIP(2);
                   10148:            return;
                   10149:        }
                   10150:        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
                   10151:     }
                   10152: 
                   10153:     /*
                   10154:      * We can grow the input buffer freely at that point
                   10155:      */
                   10156:     GROW;
                   10157: 
                   10158:     SKIP_BLANKS;
                   10159:     ctxt->input->standalone = xmlParseSDDecl(ctxt);
                   10160: 
                   10161:     SKIP_BLANKS;
                   10162:     if ((RAW == '?') && (NXT(1) == '>')) {
                   10163:         SKIP(2);
                   10164:     } else if (RAW == '>') {
                   10165:         /* Deprecated old WD ... */
                   10166:        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
                   10167:        NEXT;
                   10168:     } else {
                   10169:        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
                   10170:        MOVETO_ENDTAG(CUR_PTR);
                   10171:        NEXT;
                   10172:     }
                   10173: }
                   10174: 
                   10175: /**
                   10176:  * xmlParseMisc:
                   10177:  * @ctxt:  an XML parser context
                   10178:  * 
                   10179:  * parse an XML Misc* optional field.
                   10180:  *
                   10181:  * [27] Misc ::= Comment | PI |  S
                   10182:  */
                   10183: 
                   10184: void
                   10185: xmlParseMisc(xmlParserCtxtPtr ctxt) {
                   10186:     while (((RAW == '<') && (NXT(1) == '?')) ||
                   10187:            (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
                   10188:            IS_BLANK_CH(CUR)) {
                   10189:         if ((RAW == '<') && (NXT(1) == '?')) {
                   10190:            xmlParsePI(ctxt);
                   10191:        } else if (IS_BLANK_CH(CUR)) {
                   10192:            NEXT;
                   10193:        } else
                   10194:            xmlParseComment(ctxt);
                   10195:     }
                   10196: }
                   10197: 
                   10198: /**
                   10199:  * xmlParseDocument:
                   10200:  * @ctxt:  an XML parser context
                   10201:  * 
                   10202:  * parse an XML document (and build a tree if using the standard SAX
                   10203:  * interface).
                   10204:  *
                   10205:  * [1] document ::= prolog element Misc*
                   10206:  *
                   10207:  * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
                   10208:  *
                   10209:  * Returns 0, -1 in case of error. the parser context is augmented
                   10210:  *                as a result of the parsing.
                   10211:  */
                   10212: 
                   10213: int
                   10214: xmlParseDocument(xmlParserCtxtPtr ctxt) {
                   10215:     xmlChar start[4];
                   10216:     xmlCharEncoding enc;
                   10217: 
                   10218:     xmlInitParser();
                   10219: 
                   10220:     if ((ctxt == NULL) || (ctxt->input == NULL))
                   10221:         return(-1);
                   10222: 
                   10223:     GROW;
                   10224: 
                   10225:     /*
                   10226:      * SAX: detecting the level.
                   10227:      */
                   10228:     xmlDetectSAX2(ctxt);
                   10229: 
                   10230:     /*
                   10231:      * SAX: beginning of the document processing.
                   10232:      */
                   10233:     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   10234:         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
                   10235: 
                   10236:     if ((ctxt->encoding == NULL) &&
                   10237:         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
                   10238:        /* 
                   10239:         * Get the 4 first bytes and decode the charset
                   10240:         * if enc != XML_CHAR_ENCODING_NONE
                   10241:         * plug some encoding conversion routines.
                   10242:         */
                   10243:        start[0] = RAW;
                   10244:        start[1] = NXT(1);
                   10245:        start[2] = NXT(2);
                   10246:        start[3] = NXT(3);
                   10247:        enc = xmlDetectCharEncoding(&start[0], 4);
                   10248:        if (enc != XML_CHAR_ENCODING_NONE) {
                   10249:            xmlSwitchEncoding(ctxt, enc);
                   10250:        }
                   10251:     }
                   10252: 
                   10253: 
                   10254:     if (CUR == 0) {
                   10255:        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
                   10256:     }
                   10257: 
                   10258:     /*
                   10259:      * Check for the XMLDecl in the Prolog.
                   10260:      * do not GROW here to avoid the detected encoder to decode more
                   10261:      * than just the first line, unless the amount of data is really
                   10262:      * too small to hold "<?xml version="1.0" encoding="foo"
                   10263:      */
                   10264:     if ((ctxt->input->end - ctxt->input->cur) < 35) {
                   10265:        GROW;
                   10266:     }
                   10267:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
                   10268: 
                   10269:        /*
                   10270:         * Note that we will switch encoding on the fly.
                   10271:         */
                   10272:        xmlParseXMLDecl(ctxt);
                   10273:        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   10274:            /*
                   10275:             * The XML REC instructs us to stop parsing right here
                   10276:             */
                   10277:            return(-1);
                   10278:        }
                   10279:        ctxt->standalone = ctxt->input->standalone;
                   10280:        SKIP_BLANKS;
                   10281:     } else {
                   10282:        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   10283:     }
                   10284:     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
                   10285:         ctxt->sax->startDocument(ctxt->userData);
                   10286: 
                   10287:     /*
                   10288:      * The Misc part of the Prolog
                   10289:      */
                   10290:     GROW;
                   10291:     xmlParseMisc(ctxt);
                   10292: 
                   10293:     /*
                   10294:      * Then possibly doc type declaration(s) and more Misc
                   10295:      * (doctypedecl Misc*)?
                   10296:      */
                   10297:     GROW;
                   10298:     if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
                   10299: 
                   10300:        ctxt->inSubset = 1;
                   10301:        xmlParseDocTypeDecl(ctxt);
                   10302:        if (RAW == '[') {
                   10303:            ctxt->instate = XML_PARSER_DTD;
                   10304:            xmlParseInternalSubset(ctxt);
                   10305:        }
                   10306: 
                   10307:        /*
                   10308:         * Create and update the external subset.
                   10309:         */
                   10310:        ctxt->inSubset = 2;
                   10311:        if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
                   10312:            (!ctxt->disableSAX))
                   10313:            ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
                   10314:                                      ctxt->extSubSystem, ctxt->extSubURI);
                   10315:        ctxt->inSubset = 0;
                   10316: 
                   10317:         xmlCleanSpecialAttr(ctxt);
                   10318: 
                   10319:        ctxt->instate = XML_PARSER_PROLOG;
                   10320:        xmlParseMisc(ctxt);
                   10321:     }
                   10322: 
                   10323:     /*
                   10324:      * Time to start parsing the tree itself
                   10325:      */
                   10326:     GROW;
                   10327:     if (RAW != '<') {
                   10328:        xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
                   10329:                       "Start tag expected, '<' not found\n");
                   10330:     } else {
                   10331:        ctxt->instate = XML_PARSER_CONTENT;
                   10332:        xmlParseElement(ctxt);
                   10333:        ctxt->instate = XML_PARSER_EPILOG;
                   10334: 
                   10335: 
                   10336:        /*
                   10337:         * The Misc part at the end
                   10338:         */
                   10339:        xmlParseMisc(ctxt);
                   10340: 
                   10341:        if (RAW != 0) {
                   10342:            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
                   10343:        }
                   10344:        ctxt->instate = XML_PARSER_EOF;
                   10345:     }
                   10346: 
                   10347:     /*
                   10348:      * SAX: end of the document processing.
                   10349:      */
                   10350:     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   10351:         ctxt->sax->endDocument(ctxt->userData);
                   10352: 
                   10353:     /*
                   10354:      * Remove locally kept entity definitions if the tree was not built
                   10355:      */
                   10356:     if ((ctxt->myDoc != NULL) &&
                   10357:        (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
                   10358:        xmlFreeDoc(ctxt->myDoc);
                   10359:        ctxt->myDoc = NULL;
                   10360:     }
                   10361: 
                   10362:     if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
                   10363:         ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
                   10364:        if (ctxt->valid)
                   10365:            ctxt->myDoc->properties |= XML_DOC_DTDVALID;
                   10366:        if (ctxt->nsWellFormed)
                   10367:            ctxt->myDoc->properties |= XML_DOC_NSVALID;
                   10368:        if (ctxt->options & XML_PARSE_OLD10)
                   10369:            ctxt->myDoc->properties |= XML_DOC_OLD10;
                   10370:     }
                   10371:     if (! ctxt->wellFormed) {
                   10372:        ctxt->valid = 0;
                   10373:        return(-1);
                   10374:     }
                   10375:     return(0);
                   10376: }
                   10377: 
                   10378: /**
                   10379:  * xmlParseExtParsedEnt:
                   10380:  * @ctxt:  an XML parser context
                   10381:  * 
                   10382:  * parse a general parsed entity
                   10383:  * An external general parsed entity is well-formed if it matches the
                   10384:  * production labeled extParsedEnt.
                   10385:  *
                   10386:  * [78] extParsedEnt ::= TextDecl? content
                   10387:  *
                   10388:  * Returns 0, -1 in case of error. the parser context is augmented
                   10389:  *                as a result of the parsing.
                   10390:  */
                   10391: 
                   10392: int
                   10393: xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
                   10394:     xmlChar start[4];
                   10395:     xmlCharEncoding enc;
                   10396: 
                   10397:     if ((ctxt == NULL) || (ctxt->input == NULL))
                   10398:         return(-1);
                   10399: 
                   10400:     xmlDefaultSAXHandlerInit();
                   10401: 
                   10402:     xmlDetectSAX2(ctxt);
                   10403: 
                   10404:     GROW;
                   10405: 
                   10406:     /*
                   10407:      * SAX: beginning of the document processing.
                   10408:      */
                   10409:     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   10410:         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
                   10411: 
                   10412:     /* 
                   10413:      * Get the 4 first bytes and decode the charset
                   10414:      * if enc != XML_CHAR_ENCODING_NONE
                   10415:      * plug some encoding conversion routines.
                   10416:      */
                   10417:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
                   10418:        start[0] = RAW;
                   10419:        start[1] = NXT(1);
                   10420:        start[2] = NXT(2);
                   10421:        start[3] = NXT(3);
                   10422:        enc = xmlDetectCharEncoding(start, 4);
                   10423:        if (enc != XML_CHAR_ENCODING_NONE) {
                   10424:            xmlSwitchEncoding(ctxt, enc);
                   10425:        }
                   10426:     }
                   10427: 
                   10428: 
                   10429:     if (CUR == 0) {
                   10430:        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
                   10431:     }
                   10432: 
                   10433:     /*
                   10434:      * Check for the XMLDecl in the Prolog.
                   10435:      */
                   10436:     GROW;
                   10437:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
                   10438: 
                   10439:        /*
                   10440:         * Note that we will switch encoding on the fly.
                   10441:         */
                   10442:        xmlParseXMLDecl(ctxt);
                   10443:        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   10444:            /*
                   10445:             * The XML REC instructs us to stop parsing right here
                   10446:             */
                   10447:            return(-1);
                   10448:        }
                   10449:        SKIP_BLANKS;
                   10450:     } else {
                   10451:        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   10452:     }
                   10453:     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
                   10454:         ctxt->sax->startDocument(ctxt->userData);
                   10455: 
                   10456:     /*
                   10457:      * Doing validity checking on chunk doesn't make sense
                   10458:      */
                   10459:     ctxt->instate = XML_PARSER_CONTENT;
                   10460:     ctxt->validate = 0;
                   10461:     ctxt->loadsubset = 0;
                   10462:     ctxt->depth = 0;
                   10463: 
                   10464:     xmlParseContent(ctxt);
                   10465:    
                   10466:     if ((RAW == '<') && (NXT(1) == '/')) {
                   10467:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   10468:     } else if (RAW != 0) {
                   10469:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   10470:     }
                   10471: 
                   10472:     /*
                   10473:      * SAX: end of the document processing.
                   10474:      */
                   10475:     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   10476:         ctxt->sax->endDocument(ctxt->userData);
                   10477: 
                   10478:     if (! ctxt->wellFormed) return(-1);
                   10479:     return(0);
                   10480: }
                   10481: 
                   10482: #ifdef LIBXML_PUSH_ENABLED
                   10483: /************************************************************************
                   10484:  *                                                                     *
                   10485:  *             Progressive parsing interfaces                          *
                   10486:  *                                                                     *
                   10487:  ************************************************************************/
                   10488: 
                   10489: /**
                   10490:  * xmlParseLookupSequence:
                   10491:  * @ctxt:  an XML parser context
                   10492:  * @first:  the first char to lookup
                   10493:  * @next:  the next char to lookup or zero
                   10494:  * @third:  the next char to lookup or zero
                   10495:  *
                   10496:  * Try to find if a sequence (first, next, third) or  just (first next) or
                   10497:  * (first) is available in the input stream.
                   10498:  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
                   10499:  * to avoid rescanning sequences of bytes, it DOES change the state of the
                   10500:  * parser, do not use liberally.
                   10501:  *
                   10502:  * Returns the index to the current parsing point if the full sequence
                   10503:  *      is available, -1 otherwise.
                   10504:  */
                   10505: static int
                   10506: xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
                   10507:                        xmlChar next, xmlChar third) {
                   10508:     int base, len;
                   10509:     xmlParserInputPtr in;
                   10510:     const xmlChar *buf;
                   10511: 
                   10512:     in = ctxt->input;
                   10513:     if (in == NULL) return(-1);
                   10514:     base = in->cur - in->base;
                   10515:     if (base < 0) return(-1);
                   10516:     if (ctxt->checkIndex > base)
                   10517:         base = ctxt->checkIndex;
                   10518:     if (in->buf == NULL) {
                   10519:        buf = in->base;
                   10520:        len = in->length;
                   10521:     } else {
                   10522:        buf = in->buf->buffer->content;
                   10523:        len = in->buf->buffer->use;
                   10524:     }
                   10525:     /* take into account the sequence length */
                   10526:     if (third) len -= 2;
                   10527:     else if (next) len --;
                   10528:     for (;base < len;base++) {
                   10529:         if (buf[base] == first) {
                   10530:            if (third != 0) {
                   10531:                if ((buf[base + 1] != next) ||
                   10532:                    (buf[base + 2] != third)) continue;
                   10533:            } else if (next != 0) {
                   10534:                if (buf[base + 1] != next) continue;
                   10535:            }
                   10536:            ctxt->checkIndex = 0;
                   10537: #ifdef DEBUG_PUSH
                   10538:            if (next == 0)
                   10539:                xmlGenericError(xmlGenericErrorContext,
                   10540:                        "PP: lookup '%c' found at %d\n",
                   10541:                        first, base);
                   10542:            else if (third == 0)
                   10543:                xmlGenericError(xmlGenericErrorContext,
                   10544:                        "PP: lookup '%c%c' found at %d\n",
                   10545:                        first, next, base);
                   10546:            else 
                   10547:                xmlGenericError(xmlGenericErrorContext,
                   10548:                        "PP: lookup '%c%c%c' found at %d\n",
                   10549:                        first, next, third, base);
                   10550: #endif
                   10551:            return(base - (in->cur - in->base));
                   10552:        }
                   10553:     }
                   10554:     ctxt->checkIndex = base;
                   10555: #ifdef DEBUG_PUSH
                   10556:     if (next == 0)
                   10557:        xmlGenericError(xmlGenericErrorContext,
                   10558:                "PP: lookup '%c' failed\n", first);
                   10559:     else if (third == 0)
                   10560:        xmlGenericError(xmlGenericErrorContext,
                   10561:                "PP: lookup '%c%c' failed\n", first, next);
                   10562:     else       
                   10563:        xmlGenericError(xmlGenericErrorContext,
                   10564:                "PP: lookup '%c%c%c' failed\n", first, next, third);
                   10565: #endif
                   10566:     return(-1);
                   10567: }
                   10568: 
                   10569: /**
                   10570:  * xmlParseGetLasts:
                   10571:  * @ctxt:  an XML parser context
                   10572:  * @lastlt:  pointer to store the last '<' from the input
                   10573:  * @lastgt:  pointer to store the last '>' from the input
                   10574:  *
                   10575:  * Lookup the last < and > in the current chunk
                   10576:  */
                   10577: static void
                   10578: xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
                   10579:                  const xmlChar **lastgt) {
                   10580:     const xmlChar *tmp;
                   10581: 
                   10582:     if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
                   10583:        xmlGenericError(xmlGenericErrorContext,
                   10584:                    "Internal error: xmlParseGetLasts\n");
                   10585:        return;
                   10586:     }
                   10587:     if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
                   10588:         tmp = ctxt->input->end;
                   10589:        tmp--;
                   10590:        while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
                   10591:        if (tmp < ctxt->input->base) {
                   10592:            *lastlt = NULL;
                   10593:            *lastgt = NULL;
                   10594:        } else {
                   10595:            *lastlt = tmp;
                   10596:            tmp++;
                   10597:            while ((tmp < ctxt->input->end) && (*tmp != '>')) {
                   10598:                if (*tmp == '\'') {
                   10599:                    tmp++;
                   10600:                    while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
                   10601:                    if (tmp < ctxt->input->end) tmp++;
                   10602:                } else if (*tmp == '"') {
                   10603:                    tmp++;
                   10604:                    while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
                   10605:                    if (tmp < ctxt->input->end) tmp++;
                   10606:                } else
                   10607:                    tmp++;
                   10608:            }
                   10609:            if (tmp < ctxt->input->end)
                   10610:                *lastgt = tmp;
                   10611:            else {
                   10612:                tmp = *lastlt;
                   10613:                tmp--;
                   10614:                while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
                   10615:                if (tmp >= ctxt->input->base)
                   10616:                    *lastgt = tmp;
                   10617:                else
                   10618:                    *lastgt = NULL;
                   10619:            }
                   10620:        }
                   10621:     } else {
                   10622:         *lastlt = NULL;
                   10623:        *lastgt = NULL;
                   10624:     }
                   10625: }
                   10626: /**
                   10627:  * xmlCheckCdataPush:
                   10628:  * @cur: pointer to the bock of characters
                   10629:  * @len: length of the block in bytes
                   10630:  *
                   10631:  * Check that the block of characters is okay as SCdata content [20]
                   10632:  *
                   10633:  * Returns the number of bytes to pass if okay, a negative index where an
                   10634:  *         UTF-8 error occured otherwise
                   10635:  */
                   10636: static int
                   10637: xmlCheckCdataPush(const xmlChar *utf, int len) {
                   10638:     int ix;
                   10639:     unsigned char c;
                   10640:     int codepoint;
                   10641: 
                   10642:     if ((utf == NULL) || (len <= 0))
                   10643:         return(0);
                   10644:     
                   10645:     for (ix = 0; ix < len;) {      /* string is 0-terminated */
                   10646:         c = utf[ix];
                   10647:         if ((c & 0x80) == 0x00) {      /* 1-byte code, starts with 10 */
                   10648:            if (c >= 0x20)
                   10649:                ix++;
                   10650:            else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
                   10651:                ix++;
                   10652:            else
                   10653:                return(-ix);
                   10654:        } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
                   10655:            if (ix + 2 > len) return(ix);
                   10656:            if ((utf[ix+1] & 0xc0 ) != 0x80)
                   10657:                return(-ix);
                   10658:            codepoint = (utf[ix] & 0x1f) << 6;
                   10659:            codepoint |= utf[ix+1] & 0x3f;
                   10660:            if (!xmlIsCharQ(codepoint))
                   10661:                return(-ix);
                   10662:            ix += 2;
                   10663:        } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
                   10664:            if (ix + 3 > len) return(ix);
                   10665:            if (((utf[ix+1] & 0xc0) != 0x80) ||
                   10666:                ((utf[ix+2] & 0xc0) != 0x80))
                   10667:                    return(-ix);
                   10668:            codepoint = (utf[ix] & 0xf) << 12;
                   10669:            codepoint |= (utf[ix+1] & 0x3f) << 6;
                   10670:            codepoint |= utf[ix+2] & 0x3f;
                   10671:            if (!xmlIsCharQ(codepoint))
                   10672:                return(-ix);
                   10673:            ix += 3;
                   10674:        } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
                   10675:            if (ix + 4 > len) return(ix);
                   10676:            if (((utf[ix+1] & 0xc0) != 0x80) ||
                   10677:                ((utf[ix+2] & 0xc0) != 0x80) ||
                   10678:                ((utf[ix+3] & 0xc0) != 0x80))
                   10679:                    return(-ix);
                   10680:            codepoint = (utf[ix] & 0x7) << 18;
                   10681:            codepoint |= (utf[ix+1] & 0x3f) << 12;
                   10682:            codepoint |= (utf[ix+2] & 0x3f) << 6;
                   10683:            codepoint |= utf[ix+3] & 0x3f;
                   10684:            if (!xmlIsCharQ(codepoint))
                   10685:                return(-ix);
                   10686:            ix += 4;
                   10687:        } else                          /* unknown encoding */
                   10688:            return(-ix);
                   10689:       }
                   10690:       return(ix);
                   10691: }
                   10692: 
                   10693: /**
                   10694:  * xmlParseTryOrFinish:
                   10695:  * @ctxt:  an XML parser context
                   10696:  * @terminate:  last chunk indicator
                   10697:  *
                   10698:  * Try to progress on parsing
                   10699:  *
                   10700:  * Returns zero if no parsing was possible
                   10701:  */
                   10702: static int
                   10703: xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                   10704:     int ret = 0;
                   10705:     int avail, tlen;
                   10706:     xmlChar cur, next;
                   10707:     const xmlChar *lastlt, *lastgt;
                   10708: 
                   10709:     if (ctxt->input == NULL)
                   10710:         return(0);
                   10711: 
                   10712: #ifdef DEBUG_PUSH
                   10713:     switch (ctxt->instate) {
                   10714:        case XML_PARSER_EOF:
                   10715:            xmlGenericError(xmlGenericErrorContext,
                   10716:                    "PP: try EOF\n"); break;
                   10717:        case XML_PARSER_START:
                   10718:            xmlGenericError(xmlGenericErrorContext,
                   10719:                    "PP: try START\n"); break;
                   10720:        case XML_PARSER_MISC:
                   10721:            xmlGenericError(xmlGenericErrorContext,
                   10722:                    "PP: try MISC\n");break;
                   10723:        case XML_PARSER_COMMENT:
                   10724:            xmlGenericError(xmlGenericErrorContext,
                   10725:                    "PP: try COMMENT\n");break;
                   10726:        case XML_PARSER_PROLOG:
                   10727:            xmlGenericError(xmlGenericErrorContext,
                   10728:                    "PP: try PROLOG\n");break;
                   10729:        case XML_PARSER_START_TAG:
                   10730:            xmlGenericError(xmlGenericErrorContext,
                   10731:                    "PP: try START_TAG\n");break;
                   10732:        case XML_PARSER_CONTENT:
                   10733:            xmlGenericError(xmlGenericErrorContext,
                   10734:                    "PP: try CONTENT\n");break;
                   10735:        case XML_PARSER_CDATA_SECTION:
                   10736:            xmlGenericError(xmlGenericErrorContext,
                   10737:                    "PP: try CDATA_SECTION\n");break;
                   10738:        case XML_PARSER_END_TAG:
                   10739:            xmlGenericError(xmlGenericErrorContext,
                   10740:                    "PP: try END_TAG\n");break;
                   10741:        case XML_PARSER_ENTITY_DECL:
                   10742:            xmlGenericError(xmlGenericErrorContext,
                   10743:                    "PP: try ENTITY_DECL\n");break;
                   10744:        case XML_PARSER_ENTITY_VALUE:
                   10745:            xmlGenericError(xmlGenericErrorContext,
                   10746:                    "PP: try ENTITY_VALUE\n");break;
                   10747:        case XML_PARSER_ATTRIBUTE_VALUE:
                   10748:            xmlGenericError(xmlGenericErrorContext,
                   10749:                    "PP: try ATTRIBUTE_VALUE\n");break;
                   10750:        case XML_PARSER_DTD:
                   10751:            xmlGenericError(xmlGenericErrorContext,
                   10752:                    "PP: try DTD\n");break;
                   10753:        case XML_PARSER_EPILOG:
                   10754:            xmlGenericError(xmlGenericErrorContext,
                   10755:                    "PP: try EPILOG\n");break;
                   10756:        case XML_PARSER_PI:
                   10757:            xmlGenericError(xmlGenericErrorContext,
                   10758:                    "PP: try PI\n");break;
                   10759:         case XML_PARSER_IGNORE:
                   10760:             xmlGenericError(xmlGenericErrorContext,
                   10761:                    "PP: try IGNORE\n");break;
                   10762:     }
                   10763: #endif
                   10764: 
                   10765:     if ((ctxt->input != NULL) &&
                   10766:         (ctxt->input->cur - ctxt->input->base > 4096)) {
                   10767:        xmlSHRINK(ctxt);
                   10768:        ctxt->checkIndex = 0;
                   10769:     }
                   10770:     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
                   10771: 
                   10772:     while (1) {
                   10773:        if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
                   10774:            return(0);
                   10775: 
                   10776:         
                   10777:        /*
                   10778:         * Pop-up of finished entities.
                   10779:         */
                   10780:        while ((RAW == 0) && (ctxt->inputNr > 1))
                   10781:            xmlPopInput(ctxt);
                   10782: 
                   10783:        if (ctxt->input == NULL) break;
                   10784:        if (ctxt->input->buf == NULL)
                   10785:            avail = ctxt->input->length -
                   10786:                    (ctxt->input->cur - ctxt->input->base);
                   10787:        else {
                   10788:            /*
                   10789:             * If we are operating on converted input, try to flush
                   10790:             * remainng chars to avoid them stalling in the non-converted
                   10791:             * buffer.
                   10792:             */
                   10793:            if ((ctxt->input->buf->raw != NULL) &&
                   10794:                (ctxt->input->buf->raw->use > 0)) {
                   10795:                int base = ctxt->input->base -
                   10796:                           ctxt->input->buf->buffer->content;
                   10797:                int current = ctxt->input->cur - ctxt->input->base;
                   10798: 
                   10799:                xmlParserInputBufferPush(ctxt->input->buf, 0, "");
                   10800:                ctxt->input->base = ctxt->input->buf->buffer->content + base;
                   10801:                ctxt->input->cur = ctxt->input->base + current;
                   10802:                ctxt->input->end =
                   10803:                    &ctxt->input->buf->buffer->content[
                   10804:                                       ctxt->input->buf->buffer->use];
                   10805:            }
                   10806:            avail = ctxt->input->buf->buffer->use -
                   10807:                    (ctxt->input->cur - ctxt->input->base);
                   10808:        }
                   10809:         if (avail < 1)
                   10810:            goto done;
                   10811:         switch (ctxt->instate) {
                   10812:             case XML_PARSER_EOF:
                   10813:                /*
                   10814:                 * Document parsing is done !
                   10815:                 */
                   10816:                goto done;
                   10817:             case XML_PARSER_START:
                   10818:                if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
                   10819:                    xmlChar start[4];
                   10820:                    xmlCharEncoding enc;
                   10821: 
                   10822:                    /*
                   10823:                     * Very first chars read from the document flow.
                   10824:                     */
                   10825:                    if (avail < 4)
                   10826:                        goto done;
                   10827: 
                   10828:                    /* 
                   10829:                     * Get the 4 first bytes and decode the charset
                   10830:                     * if enc != XML_CHAR_ENCODING_NONE
                   10831:                     * plug some encoding conversion routines,
                   10832:                     * else xmlSwitchEncoding will set to (default)
                   10833:                     * UTF8.
                   10834:                     */
                   10835:                    start[0] = RAW;
                   10836:                    start[1] = NXT(1);
                   10837:                    start[2] = NXT(2);
                   10838:                    start[3] = NXT(3);
                   10839:                    enc = xmlDetectCharEncoding(start, 4);
                   10840:                    xmlSwitchEncoding(ctxt, enc);
                   10841:                    break;
                   10842:                }
                   10843: 
                   10844:                if (avail < 2)
                   10845:                    goto done;
                   10846:                cur = ctxt->input->cur[0];
                   10847:                next = ctxt->input->cur[1];
                   10848:                if (cur == 0) {
                   10849:                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   10850:                        ctxt->sax->setDocumentLocator(ctxt->userData,
                   10851:                                                      &xmlDefaultSAXLocator);
                   10852:                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
                   10853:                    ctxt->instate = XML_PARSER_EOF;
                   10854: #ifdef DEBUG_PUSH
                   10855:                    xmlGenericError(xmlGenericErrorContext,
                   10856:                            "PP: entering EOF\n");
                   10857: #endif
                   10858:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   10859:                        ctxt->sax->endDocument(ctxt->userData);
                   10860:                    goto done;
                   10861:                }
                   10862:                if ((cur == '<') && (next == '?')) {
                   10863:                    /* PI or XML decl */
                   10864:                    if (avail < 5) return(ret);
                   10865:                    if ((!terminate) &&
                   10866:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
                   10867:                        return(ret);
                   10868:                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   10869:                        ctxt->sax->setDocumentLocator(ctxt->userData,
                   10870:                                                      &xmlDefaultSAXLocator);
                   10871:                    if ((ctxt->input->cur[2] == 'x') &&
                   10872:                        (ctxt->input->cur[3] == 'm') &&
                   10873:                        (ctxt->input->cur[4] == 'l') &&
                   10874:                        (IS_BLANK_CH(ctxt->input->cur[5]))) {
                   10875:                        ret += 5;
                   10876: #ifdef DEBUG_PUSH
                   10877:                        xmlGenericError(xmlGenericErrorContext,
                   10878:                                "PP: Parsing XML Decl\n");
                   10879: #endif
                   10880:                        xmlParseXMLDecl(ctxt);
                   10881:                        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
                   10882:                            /*
                   10883:                             * The XML REC instructs us to stop parsing right
                   10884:                             * here
                   10885:                             */
                   10886:                            ctxt->instate = XML_PARSER_EOF;
                   10887:                            return(0);
                   10888:                        }
                   10889:                        ctxt->standalone = ctxt->input->standalone;
                   10890:                        if ((ctxt->encoding == NULL) &&
                   10891:                            (ctxt->input->encoding != NULL))
                   10892:                            ctxt->encoding = xmlStrdup(ctxt->input->encoding);
                   10893:                        if ((ctxt->sax) && (ctxt->sax->startDocument) &&
                   10894:                            (!ctxt->disableSAX))
                   10895:                            ctxt->sax->startDocument(ctxt->userData);
                   10896:                        ctxt->instate = XML_PARSER_MISC;
                   10897: #ifdef DEBUG_PUSH
                   10898:                        xmlGenericError(xmlGenericErrorContext,
                   10899:                                "PP: entering MISC\n");
                   10900: #endif
                   10901:                    } else {
                   10902:                        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   10903:                        if ((ctxt->sax) && (ctxt->sax->startDocument) &&
                   10904:                            (!ctxt->disableSAX))
                   10905:                            ctxt->sax->startDocument(ctxt->userData);
                   10906:                        ctxt->instate = XML_PARSER_MISC;
                   10907: #ifdef DEBUG_PUSH
                   10908:                        xmlGenericError(xmlGenericErrorContext,
                   10909:                                "PP: entering MISC\n");
                   10910: #endif
                   10911:                    }
                   10912:                } else {
                   10913:                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
                   10914:                        ctxt->sax->setDocumentLocator(ctxt->userData,
                   10915:                                                      &xmlDefaultSAXLocator);
                   10916:                    ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
                   10917:                    if (ctxt->version == NULL) {
                   10918:                        xmlErrMemory(ctxt, NULL);
                   10919:                        break;
                   10920:                    }
                   10921:                    if ((ctxt->sax) && (ctxt->sax->startDocument) &&
                   10922:                        (!ctxt->disableSAX))
                   10923:                        ctxt->sax->startDocument(ctxt->userData);
                   10924:                    ctxt->instate = XML_PARSER_MISC;
                   10925: #ifdef DEBUG_PUSH
                   10926:                    xmlGenericError(xmlGenericErrorContext,
                   10927:                            "PP: entering MISC\n");
                   10928: #endif
                   10929:                }
                   10930:                break;
                   10931:             case XML_PARSER_START_TAG: {
                   10932:                const xmlChar *name;
                   10933:                const xmlChar *prefix = NULL;
                   10934:                const xmlChar *URI = NULL;
                   10935:                int nsNr = ctxt->nsNr;
                   10936: 
                   10937:                if ((avail < 2) && (ctxt->inputNr == 1))
                   10938:                    goto done;
                   10939:                cur = ctxt->input->cur[0];
                   10940:                if (cur != '<') {
                   10941:                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
                   10942:                    ctxt->instate = XML_PARSER_EOF;
                   10943:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   10944:                        ctxt->sax->endDocument(ctxt->userData);
                   10945:                    goto done;
                   10946:                }
                   10947:                if (!terminate) {
                   10948:                    if (ctxt->progressive) {
                   10949:                        /* > can be found unescaped in attribute values */
                   10950:                        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
                   10951:                            goto done;
                   10952:                    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
                   10953:                        goto done;
                   10954:                    }
                   10955:                }
                   10956:                if (ctxt->spaceNr == 0)
                   10957:                    spacePush(ctxt, -1);
                   10958:                else if (*ctxt->space == -2)
                   10959:                    spacePush(ctxt, -1);
                   10960:                else
                   10961:                    spacePush(ctxt, *ctxt->space);
                   10962: #ifdef LIBXML_SAX1_ENABLED
                   10963:                if (ctxt->sax2)
                   10964: #endif /* LIBXML_SAX1_ENABLED */
                   10965:                    name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
                   10966: #ifdef LIBXML_SAX1_ENABLED
                   10967:                else
                   10968:                    name = xmlParseStartTag(ctxt);
                   10969: #endif /* LIBXML_SAX1_ENABLED */
                   10970:                if (name == NULL) {
                   10971:                    spacePop(ctxt);
                   10972:                    ctxt->instate = XML_PARSER_EOF;
                   10973:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   10974:                        ctxt->sax->endDocument(ctxt->userData);
                   10975:                    goto done;
                   10976:                }
                   10977: #ifdef LIBXML_VALID_ENABLED
                   10978:                /*
                   10979:                 * [ VC: Root Element Type ]
                   10980:                 * The Name in the document type declaration must match
                   10981:                 * the element type of the root element. 
                   10982:                 */
                   10983:                if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
                   10984:                    ctxt->node && (ctxt->node == ctxt->myDoc->children))
                   10985:                    ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
                   10986: #endif /* LIBXML_VALID_ENABLED */
                   10987: 
                   10988:                /*
                   10989:                 * Check for an Empty Element.
                   10990:                 */
                   10991:                if ((RAW == '/') && (NXT(1) == '>')) {
                   10992:                    SKIP(2);
                   10993: 
                   10994:                    if (ctxt->sax2) {
                   10995:                        if ((ctxt->sax != NULL) &&
                   10996:                            (ctxt->sax->endElementNs != NULL) &&
                   10997:                            (!ctxt->disableSAX))
                   10998:                            ctxt->sax->endElementNs(ctxt->userData, name,
                   10999:                                                    prefix, URI);
                   11000:                        if (ctxt->nsNr - nsNr > 0)
                   11001:                            nsPop(ctxt, ctxt->nsNr - nsNr);
                   11002: #ifdef LIBXML_SAX1_ENABLED
                   11003:                    } else {
                   11004:                        if ((ctxt->sax != NULL) &&
                   11005:                            (ctxt->sax->endElement != NULL) &&
                   11006:                            (!ctxt->disableSAX))
                   11007:                            ctxt->sax->endElement(ctxt->userData, name);
                   11008: #endif /* LIBXML_SAX1_ENABLED */
                   11009:                    }
                   11010:                    spacePop(ctxt);
                   11011:                    if (ctxt->nameNr == 0) {
                   11012:                        ctxt->instate = XML_PARSER_EPILOG;
                   11013:                    } else {
                   11014:                        ctxt->instate = XML_PARSER_CONTENT;
                   11015:                    }
                   11016:                    break;
                   11017:                }
                   11018:                if (RAW == '>') {
                   11019:                    NEXT;
                   11020:                } else {
                   11021:                    xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
                   11022:                                         "Couldn't find end of Start Tag %s\n",
                   11023:                                         name);
                   11024:                    nodePop(ctxt);
                   11025:                    spacePop(ctxt);
                   11026:                }
                   11027:                if (ctxt->sax2)
                   11028:                    nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
                   11029: #ifdef LIBXML_SAX1_ENABLED
                   11030:                else
                   11031:                    namePush(ctxt, name);
                   11032: #endif /* LIBXML_SAX1_ENABLED */
                   11033: 
                   11034:                ctxt->instate = XML_PARSER_CONTENT;
                   11035:                 break;
                   11036:            }
                   11037:             case XML_PARSER_CONTENT: {
                   11038:                const xmlChar *test;
                   11039:                unsigned int cons;
                   11040:                if ((avail < 2) && (ctxt->inputNr == 1))
                   11041:                    goto done;
                   11042:                cur = ctxt->input->cur[0];
                   11043:                next = ctxt->input->cur[1];
                   11044: 
                   11045:                test = CUR_PTR;
                   11046:                cons = ctxt->input->consumed;
                   11047:                if ((cur == '<') && (next == '/')) {
                   11048:                    ctxt->instate = XML_PARSER_END_TAG;
                   11049:                    break;
                   11050:                } else if ((cur == '<') && (next == '?')) {
                   11051:                    if ((!terminate) &&
                   11052:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
                   11053:                        goto done;
                   11054:                    xmlParsePI(ctxt);
                   11055:                } else if ((cur == '<') && (next != '!')) {
                   11056:                    ctxt->instate = XML_PARSER_START_TAG;
                   11057:                    break;
                   11058:                } else if ((cur == '<') && (next == '!') &&
                   11059:                           (ctxt->input->cur[2] == '-') &&
                   11060:                           (ctxt->input->cur[3] == '-')) {
                   11061:                    int term;
                   11062: 
                   11063:                    if (avail < 4)
                   11064:                        goto done;
                   11065:                    ctxt->input->cur += 4;
                   11066:                    term = xmlParseLookupSequence(ctxt, '-', '-', '>');
                   11067:                    ctxt->input->cur -= 4;
                   11068:                    if ((!terminate) && (term < 0))
                   11069:                        goto done;
                   11070:                    xmlParseComment(ctxt);
                   11071:                    ctxt->instate = XML_PARSER_CONTENT;
                   11072:                } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
                   11073:                    (ctxt->input->cur[2] == '[') &&
                   11074:                    (ctxt->input->cur[3] == 'C') &&
                   11075:                    (ctxt->input->cur[4] == 'D') &&
                   11076:                    (ctxt->input->cur[5] == 'A') &&
                   11077:                    (ctxt->input->cur[6] == 'T') &&
                   11078:                    (ctxt->input->cur[7] == 'A') &&
                   11079:                    (ctxt->input->cur[8] == '[')) {
                   11080:                    SKIP(9);
                   11081:                    ctxt->instate = XML_PARSER_CDATA_SECTION;
                   11082:                    break;
                   11083:                } else if ((cur == '<') && (next == '!') &&
                   11084:                           (avail < 9)) {
                   11085:                    goto done;
                   11086:                } else if (cur == '&') {
                   11087:                    if ((!terminate) &&
                   11088:                        (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
                   11089:                        goto done;
                   11090:                    xmlParseReference(ctxt);
                   11091:                } else {
                   11092:                    /* TODO Avoid the extra copy, handle directly !!! */
                   11093:                    /*
                   11094:                     * Goal of the following test is:
                   11095:                     *  - minimize calls to the SAX 'character' callback
                   11096:                     *    when they are mergeable
                   11097:                     *  - handle an problem for isBlank when we only parse
                   11098:                     *    a sequence of blank chars and the next one is
                   11099:                     *    not available to check against '<' presence.
                   11100:                     *  - tries to homogenize the differences in SAX
                   11101:                     *    callbacks between the push and pull versions
                   11102:                     *    of the parser.
                   11103:                     */
                   11104:                    if ((ctxt->inputNr == 1) &&
                   11105:                        (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
                   11106:                        if (!terminate) {
                   11107:                            if (ctxt->progressive) {
                   11108:                                if ((lastlt == NULL) ||
                   11109:                                    (ctxt->input->cur > lastlt))
                   11110:                                    goto done;
                   11111:                            } else if (xmlParseLookupSequence(ctxt,
                   11112:                                                              '<', 0, 0) < 0) {
                   11113:                                goto done;
                   11114:                            }
                   11115:                        }
                   11116:                     }
                   11117:                    ctxt->checkIndex = 0;
                   11118:                    xmlParseCharData(ctxt, 0);
                   11119:                }
                   11120:                /*
                   11121:                 * Pop-up of finished entities.
                   11122:                 */
                   11123:                while ((RAW == 0) && (ctxt->inputNr > 1))
                   11124:                    xmlPopInput(ctxt);
                   11125:                if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
                   11126:                    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                   11127:                                "detected an error in element content\n");
                   11128:                    ctxt->instate = XML_PARSER_EOF;
                   11129:                    break;
                   11130:                }
                   11131:                break;
                   11132:            }
                   11133:             case XML_PARSER_END_TAG:
                   11134:                if (avail < 2)
                   11135:                    goto done;
                   11136:                if (!terminate) {
                   11137:                    if (ctxt->progressive) {
                   11138:                        /* > can be found unescaped in attribute values */
                   11139:                        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
                   11140:                            goto done;
                   11141:                    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
                   11142:                        goto done;
                   11143:                    }
                   11144:                }
                   11145:                if (ctxt->sax2) {
                   11146:                    xmlParseEndTag2(ctxt,
                   11147:                           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
                   11148:                           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
                   11149:                       (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
                   11150:                    nameNsPop(ctxt);
                   11151:                }
                   11152: #ifdef LIBXML_SAX1_ENABLED
                   11153:                  else
                   11154:                    xmlParseEndTag1(ctxt, 0);
                   11155: #endif /* LIBXML_SAX1_ENABLED */
                   11156:                if (ctxt->nameNr == 0) {
                   11157:                    ctxt->instate = XML_PARSER_EPILOG;
                   11158:                } else {
                   11159:                    ctxt->instate = XML_PARSER_CONTENT;
                   11160:                }
                   11161:                break;
                   11162:             case XML_PARSER_CDATA_SECTION: {
                   11163:                /*
                   11164:                 * The Push mode need to have the SAX callback for 
                   11165:                 * cdataBlock merge back contiguous callbacks.
                   11166:                 */
                   11167:                int base;
                   11168: 
                   11169:                base = xmlParseLookupSequence(ctxt, ']', ']', '>');
                   11170:                if (base < 0) {
                   11171:                    if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
                   11172:                        int tmp;
                   11173: 
                   11174:                        tmp = xmlCheckCdataPush(ctxt->input->cur, 
                   11175:                                                XML_PARSER_BIG_BUFFER_SIZE);
                   11176:                        if (tmp < 0) {
                   11177:                            tmp = -tmp;
                   11178:                            ctxt->input->cur += tmp;
                   11179:                            goto encoding_error;
                   11180:                        }
                   11181:                        if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
                   11182:                            if (ctxt->sax->cdataBlock != NULL)
                   11183:                                ctxt->sax->cdataBlock(ctxt->userData,
                   11184:                                                      ctxt->input->cur, tmp);
                   11185:                            else if (ctxt->sax->characters != NULL)
                   11186:                                ctxt->sax->characters(ctxt->userData,
                   11187:                                                      ctxt->input->cur, tmp);
                   11188:                        }
                   11189:                        SKIPL(tmp);
                   11190:                        ctxt->checkIndex = 0;
                   11191:                    }
                   11192:                    goto done;
                   11193:                } else {
                   11194:                    int tmp;
                   11195: 
                   11196:                    tmp = xmlCheckCdataPush(ctxt->input->cur, base);
                   11197:                    if ((tmp < 0) || (tmp != base)) {
                   11198:                        tmp = -tmp;
                   11199:                        ctxt->input->cur += tmp;
                   11200:                        goto encoding_error;
                   11201:                    }
                   11202:                    if ((ctxt->sax != NULL) && (base == 0) &&
                   11203:                        (ctxt->sax->cdataBlock != NULL) &&
                   11204:                        (!ctxt->disableSAX)) {
                   11205:                        /*
                   11206:                         * Special case to provide identical behaviour
                   11207:                         * between pull and push parsers on enpty CDATA
                   11208:                         * sections
                   11209:                         */
                   11210:                         if ((ctxt->input->cur - ctxt->input->base >= 9) &&
                   11211:                             (!strncmp((const char *)&ctxt->input->cur[-9],
                   11212:                                       "<![CDATA[", 9)))
                   11213:                             ctxt->sax->cdataBlock(ctxt->userData,
                   11214:                                                   BAD_CAST "", 0);
                   11215:                    } else if ((ctxt->sax != NULL) && (base > 0) &&
                   11216:                        (!ctxt->disableSAX)) {
                   11217:                        if (ctxt->sax->cdataBlock != NULL)
                   11218:                            ctxt->sax->cdataBlock(ctxt->userData,
                   11219:                                                  ctxt->input->cur, base);
                   11220:                        else if (ctxt->sax->characters != NULL)
                   11221:                            ctxt->sax->characters(ctxt->userData,
                   11222:                                                  ctxt->input->cur, base);
                   11223:                    }
                   11224:                    SKIPL(base + 3);
                   11225:                    ctxt->checkIndex = 0;
                   11226:                    ctxt->instate = XML_PARSER_CONTENT;
                   11227: #ifdef DEBUG_PUSH
                   11228:                    xmlGenericError(xmlGenericErrorContext,
                   11229:                            "PP: entering CONTENT\n");
                   11230: #endif
                   11231:                }
                   11232:                break;
                   11233:            }
                   11234:             case XML_PARSER_MISC:
                   11235:                SKIP_BLANKS;
                   11236:                if (ctxt->input->buf == NULL)
                   11237:                    avail = ctxt->input->length -
                   11238:                            (ctxt->input->cur - ctxt->input->base);
                   11239:                else
                   11240:                    avail = ctxt->input->buf->buffer->use -
                   11241:                            (ctxt->input->cur - ctxt->input->base);
                   11242:                if (avail < 2)
                   11243:                    goto done;
                   11244:                cur = ctxt->input->cur[0];
                   11245:                next = ctxt->input->cur[1];
                   11246:                if ((cur == '<') && (next == '?')) {
                   11247:                    if ((!terminate) &&
                   11248:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
                   11249:                        goto done;
                   11250: #ifdef DEBUG_PUSH
                   11251:                    xmlGenericError(xmlGenericErrorContext,
                   11252:                            "PP: Parsing PI\n");
                   11253: #endif
                   11254:                    xmlParsePI(ctxt);
                   11255:                    ctxt->checkIndex = 0;
                   11256:                } else if ((cur == '<') && (next == '!') &&
                   11257:                    (ctxt->input->cur[2] == '-') &&
                   11258:                    (ctxt->input->cur[3] == '-')) {
                   11259:                    if ((!terminate) &&
                   11260:                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
                   11261:                        goto done;
                   11262: #ifdef DEBUG_PUSH
                   11263:                    xmlGenericError(xmlGenericErrorContext,
                   11264:                            "PP: Parsing Comment\n");
                   11265: #endif
                   11266:                    xmlParseComment(ctxt);
                   11267:                    ctxt->instate = XML_PARSER_MISC;
                   11268:                    ctxt->checkIndex = 0;
                   11269:                } else if ((cur == '<') && (next == '!') &&
                   11270:                    (ctxt->input->cur[2] == 'D') &&
                   11271:                    (ctxt->input->cur[3] == 'O') &&
                   11272:                    (ctxt->input->cur[4] == 'C') &&
                   11273:                    (ctxt->input->cur[5] == 'T') &&
                   11274:                    (ctxt->input->cur[6] == 'Y') &&
                   11275:                    (ctxt->input->cur[7] == 'P') &&
                   11276:                    (ctxt->input->cur[8] == 'E')) {
                   11277:                    if ((!terminate) &&
                   11278:                        (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
                   11279:                        goto done;
                   11280: #ifdef DEBUG_PUSH
                   11281:                    xmlGenericError(xmlGenericErrorContext,
                   11282:                            "PP: Parsing internal subset\n");
                   11283: #endif
                   11284:                    ctxt->inSubset = 1;
                   11285:                    xmlParseDocTypeDecl(ctxt);
                   11286:                    if (RAW == '[') {
                   11287:                        ctxt->instate = XML_PARSER_DTD;
                   11288: #ifdef DEBUG_PUSH
                   11289:                        xmlGenericError(xmlGenericErrorContext,
                   11290:                                "PP: entering DTD\n");
                   11291: #endif
                   11292:                    } else {
                   11293:                        /*
                   11294:                         * Create and update the external subset.
                   11295:                         */
                   11296:                        ctxt->inSubset = 2;
                   11297:                        if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   11298:                            (ctxt->sax->externalSubset != NULL))
                   11299:                            ctxt->sax->externalSubset(ctxt->userData,
                   11300:                                    ctxt->intSubName, ctxt->extSubSystem,
                   11301:                                    ctxt->extSubURI);
                   11302:                        ctxt->inSubset = 0;
                   11303:                        xmlCleanSpecialAttr(ctxt);
                   11304:                        ctxt->instate = XML_PARSER_PROLOG;
                   11305: #ifdef DEBUG_PUSH
                   11306:                        xmlGenericError(xmlGenericErrorContext,
                   11307:                                "PP: entering PROLOG\n");
                   11308: #endif
                   11309:                    }
                   11310:                } else if ((cur == '<') && (next == '!') &&
                   11311:                           (avail < 9)) {
                   11312:                    goto done;
                   11313:                } else {
                   11314:                    ctxt->instate = XML_PARSER_START_TAG;
                   11315:                    ctxt->progressive = 1;
                   11316:                    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
                   11317: #ifdef DEBUG_PUSH
                   11318:                    xmlGenericError(xmlGenericErrorContext,
                   11319:                            "PP: entering START_TAG\n");
                   11320: #endif
                   11321:                }
                   11322:                break;
                   11323:             case XML_PARSER_PROLOG:
                   11324:                SKIP_BLANKS;
                   11325:                if (ctxt->input->buf == NULL)
                   11326:                    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
                   11327:                else
                   11328:                    avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
                   11329:                if (avail < 2) 
                   11330:                    goto done;
                   11331:                cur = ctxt->input->cur[0];
                   11332:                next = ctxt->input->cur[1];
                   11333:                if ((cur == '<') && (next == '?')) {
                   11334:                    if ((!terminate) &&
                   11335:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
                   11336:                        goto done;
                   11337: #ifdef DEBUG_PUSH
                   11338:                    xmlGenericError(xmlGenericErrorContext,
                   11339:                            "PP: Parsing PI\n");
                   11340: #endif
                   11341:                    xmlParsePI(ctxt);
                   11342:                } else if ((cur == '<') && (next == '!') &&
                   11343:                    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
                   11344:                    if ((!terminate) &&
                   11345:                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
                   11346:                        goto done;
                   11347: #ifdef DEBUG_PUSH
                   11348:                    xmlGenericError(xmlGenericErrorContext,
                   11349:                            "PP: Parsing Comment\n");
                   11350: #endif
                   11351:                    xmlParseComment(ctxt);
                   11352:                    ctxt->instate = XML_PARSER_PROLOG;
                   11353:                } else if ((cur == '<') && (next == '!') &&
                   11354:                           (avail < 4)) {
                   11355:                    goto done;
                   11356:                } else {
                   11357:                    ctxt->instate = XML_PARSER_START_TAG;
                   11358:                    if (ctxt->progressive == 0)
                   11359:                        ctxt->progressive = 1;
                   11360:                    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
                   11361: #ifdef DEBUG_PUSH
                   11362:                    xmlGenericError(xmlGenericErrorContext,
                   11363:                            "PP: entering START_TAG\n");
                   11364: #endif
                   11365:                }
                   11366:                break;
                   11367:             case XML_PARSER_EPILOG:
                   11368:                SKIP_BLANKS;
                   11369:                if (ctxt->input->buf == NULL)
                   11370:                    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
                   11371:                else
                   11372:                    avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
                   11373:                if (avail < 2)
                   11374:                    goto done;
                   11375:                cur = ctxt->input->cur[0];
                   11376:                next = ctxt->input->cur[1];
                   11377:                if ((cur == '<') && (next == '?')) {
                   11378:                    if ((!terminate) &&
                   11379:                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
                   11380:                        goto done;
                   11381: #ifdef DEBUG_PUSH
                   11382:                    xmlGenericError(xmlGenericErrorContext,
                   11383:                            "PP: Parsing PI\n");
                   11384: #endif
                   11385:                    xmlParsePI(ctxt);
                   11386:                    ctxt->instate = XML_PARSER_EPILOG;
                   11387:                } else if ((cur == '<') && (next == '!') &&
                   11388:                    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
                   11389:                    if ((!terminate) &&
                   11390:                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
                   11391:                        goto done;
                   11392: #ifdef DEBUG_PUSH
                   11393:                    xmlGenericError(xmlGenericErrorContext,
                   11394:                            "PP: Parsing Comment\n");
                   11395: #endif
                   11396:                    xmlParseComment(ctxt);
                   11397:                    ctxt->instate = XML_PARSER_EPILOG;
                   11398:                } else if ((cur == '<') && (next == '!') &&
                   11399:                           (avail < 4)) {
                   11400:                    goto done;
                   11401:                } else {
                   11402:                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
                   11403:                    ctxt->instate = XML_PARSER_EOF;
                   11404: #ifdef DEBUG_PUSH
                   11405:                    xmlGenericError(xmlGenericErrorContext,
                   11406:                            "PP: entering EOF\n");
                   11407: #endif
                   11408:                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   11409:                        ctxt->sax->endDocument(ctxt->userData);
                   11410:                    goto done;
                   11411:                }
                   11412:                break;
                   11413:             case XML_PARSER_DTD: {
                   11414:                /*
                   11415:                 * Sorry but progressive parsing of the internal subset
                   11416:                 * is not expected to be supported. We first check that
                   11417:                 * the full content of the internal subset is available and
                   11418:                 * the parsing is launched only at that point.
                   11419:                 * Internal subset ends up with "']' S? '>'" in an unescaped
                   11420:                 * section and not in a ']]>' sequence which are conditional
                   11421:                 * sections (whoever argued to keep that crap in XML deserve
                   11422:                 * a place in hell !).
                   11423:                 */
                   11424:                int base, i;
                   11425:                xmlChar *buf;
                   11426:                xmlChar quote = 0;
                   11427: 
                   11428:                base = ctxt->input->cur - ctxt->input->base;
                   11429:                if (base < 0) return(0);
                   11430:                if (ctxt->checkIndex > base)
                   11431:                    base = ctxt->checkIndex;
                   11432:                buf = ctxt->input->buf->buffer->content;
                   11433:                for (;(unsigned int) base < ctxt->input->buf->buffer->use;
                   11434:                     base++) {
                   11435:                    if (quote != 0) {
                   11436:                        if (buf[base] == quote)
                   11437:                            quote = 0;
                   11438:                        continue;    
                   11439:                    }
                   11440:                    if ((quote == 0) && (buf[base] == '<')) {
                   11441:                        int found  = 0;
                   11442:                        /* special handling of comments */
                   11443:                        if (((unsigned int) base + 4 <
                   11444:                             ctxt->input->buf->buffer->use) &&
                   11445:                            (buf[base + 1] == '!') &&
                   11446:                            (buf[base + 2] == '-') &&
                   11447:                            (buf[base + 3] == '-')) {
                   11448:                            for (;(unsigned int) base + 3 <
                   11449:                                  ctxt->input->buf->buffer->use; base++) {
                   11450:                                if ((buf[base] == '-') &&
                   11451:                                    (buf[base + 1] == '-') &&
                   11452:                                    (buf[base + 2] == '>')) {
                   11453:                                    found = 1;
                   11454:                                    base += 2;
                   11455:                                    break;
                   11456:                                }
                   11457:                            }
                   11458:                            if (!found) {
                   11459: #if 0
                   11460:                                fprintf(stderr, "unfinished comment\n");
                   11461: #endif
                   11462:                                break; /* for */
                   11463:                            }
                   11464:                            continue;
                   11465:                        }
                   11466:                    }
                   11467:                    if (buf[base] == '"') {
                   11468:                        quote = '"';
                   11469:                        continue;
                   11470:                    }
                   11471:                    if (buf[base] == '\'') {
                   11472:                        quote = '\'';
                   11473:                        continue;
                   11474:                    }
                   11475:                    if (buf[base] == ']') {
                   11476: #if 0
                   11477:                        fprintf(stderr, "%c%c%c%c: ", buf[base],
                   11478:                                buf[base + 1], buf[base + 2], buf[base + 3]);
                   11479: #endif
                   11480:                        if ((unsigned int) base +1 >=
                   11481:                            ctxt->input->buf->buffer->use)
                   11482:                            break;
                   11483:                        if (buf[base + 1] == ']') {
                   11484:                            /* conditional crap, skip both ']' ! */
                   11485:                            base++;
                   11486:                            continue;
                   11487:                        }
                   11488:                        for (i = 1;
                   11489:                     (unsigned int) base + i < ctxt->input->buf->buffer->use;
                   11490:                             i++) {
                   11491:                            if (buf[base + i] == '>') {
                   11492: #if 0
                   11493:                                fprintf(stderr, "found\n");
                   11494: #endif
                   11495:                                goto found_end_int_subset;
                   11496:                            }
                   11497:                            if (!IS_BLANK_CH(buf[base + i])) {
                   11498: #if 0
                   11499:                                fprintf(stderr, "not found\n");
                   11500: #endif
                   11501:                                goto not_end_of_int_subset;
                   11502:                            }
                   11503:                        }
                   11504: #if 0
                   11505:                        fprintf(stderr, "end of stream\n");
                   11506: #endif
                   11507:                        break;
                   11508:                         
                   11509:                    }
                   11510: not_end_of_int_subset:
                   11511:                     continue; /* for */
                   11512:                }
                   11513:                /*
                   11514:                 * We didn't found the end of the Internal subset
                   11515:                 */
                   11516: #ifdef DEBUG_PUSH
                   11517:                if (next == 0)
                   11518:                    xmlGenericError(xmlGenericErrorContext,
                   11519:                            "PP: lookup of int subset end filed\n");
                   11520: #endif
                   11521:                goto done;
                   11522: 
                   11523: found_end_int_subset:
                   11524:                xmlParseInternalSubset(ctxt);
                   11525:                ctxt->inSubset = 2;
                   11526:                if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                   11527:                    (ctxt->sax->externalSubset != NULL))
                   11528:                    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
                   11529:                            ctxt->extSubSystem, ctxt->extSubURI);
                   11530:                ctxt->inSubset = 0;
                   11531:                xmlCleanSpecialAttr(ctxt);
                   11532:                ctxt->instate = XML_PARSER_PROLOG;
                   11533:                ctxt->checkIndex = 0;
                   11534: #ifdef DEBUG_PUSH
                   11535:                xmlGenericError(xmlGenericErrorContext,
                   11536:                        "PP: entering PROLOG\n");
                   11537: #endif
                   11538:                 break;
                   11539:            }
                   11540:             case XML_PARSER_COMMENT:
                   11541:                xmlGenericError(xmlGenericErrorContext,
                   11542:                        "PP: internal error, state == COMMENT\n");
                   11543:                ctxt->instate = XML_PARSER_CONTENT;
                   11544: #ifdef DEBUG_PUSH
                   11545:                xmlGenericError(xmlGenericErrorContext,
                   11546:                        "PP: entering CONTENT\n");
                   11547: #endif
                   11548:                break;
                   11549:             case XML_PARSER_IGNORE:
                   11550:                xmlGenericError(xmlGenericErrorContext,
                   11551:                        "PP: internal error, state == IGNORE");
                   11552:                ctxt->instate = XML_PARSER_DTD;
                   11553: #ifdef DEBUG_PUSH
                   11554:                xmlGenericError(xmlGenericErrorContext,
                   11555:                        "PP: entering DTD\n");
                   11556: #endif
                   11557:                break;
                   11558:             case XML_PARSER_PI:
                   11559:                xmlGenericError(xmlGenericErrorContext,
                   11560:                        "PP: internal error, state == PI\n");
                   11561:                ctxt->instate = XML_PARSER_CONTENT;
                   11562: #ifdef DEBUG_PUSH
                   11563:                xmlGenericError(xmlGenericErrorContext,
                   11564:                        "PP: entering CONTENT\n");
                   11565: #endif
                   11566:                break;
                   11567:             case XML_PARSER_ENTITY_DECL:
                   11568:                xmlGenericError(xmlGenericErrorContext,
                   11569:                        "PP: internal error, state == ENTITY_DECL\n");
                   11570:                ctxt->instate = XML_PARSER_DTD;
                   11571: #ifdef DEBUG_PUSH
                   11572:                xmlGenericError(xmlGenericErrorContext,
                   11573:                        "PP: entering DTD\n");
                   11574: #endif
                   11575:                break;
                   11576:             case XML_PARSER_ENTITY_VALUE:
                   11577:                xmlGenericError(xmlGenericErrorContext,
                   11578:                        "PP: internal error, state == ENTITY_VALUE\n");
                   11579:                ctxt->instate = XML_PARSER_CONTENT;
                   11580: #ifdef DEBUG_PUSH
                   11581:                xmlGenericError(xmlGenericErrorContext,
                   11582:                        "PP: entering DTD\n");
                   11583: #endif
                   11584:                break;
                   11585:             case XML_PARSER_ATTRIBUTE_VALUE:
                   11586:                xmlGenericError(xmlGenericErrorContext,
                   11587:                        "PP: internal error, state == ATTRIBUTE_VALUE\n");
                   11588:                ctxt->instate = XML_PARSER_START_TAG;
                   11589: #ifdef DEBUG_PUSH
                   11590:                xmlGenericError(xmlGenericErrorContext,
                   11591:                        "PP: entering START_TAG\n");
                   11592: #endif
                   11593:                break;
                   11594:             case XML_PARSER_SYSTEM_LITERAL:
                   11595:                xmlGenericError(xmlGenericErrorContext,
                   11596:                        "PP: internal error, state == SYSTEM_LITERAL\n");
                   11597:                ctxt->instate = XML_PARSER_START_TAG;
                   11598: #ifdef DEBUG_PUSH
                   11599:                xmlGenericError(xmlGenericErrorContext,
                   11600:                        "PP: entering START_TAG\n");
                   11601: #endif
                   11602:                break;
                   11603:             case XML_PARSER_PUBLIC_LITERAL:
                   11604:                xmlGenericError(xmlGenericErrorContext,
                   11605:                        "PP: internal error, state == PUBLIC_LITERAL\n");
                   11606:                ctxt->instate = XML_PARSER_START_TAG;
                   11607: #ifdef DEBUG_PUSH
                   11608:                xmlGenericError(xmlGenericErrorContext,
                   11609:                        "PP: entering START_TAG\n");
                   11610: #endif
                   11611:                break;
                   11612:        }
                   11613:     }
                   11614: done:    
                   11615: #ifdef DEBUG_PUSH
                   11616:     xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
                   11617: #endif
                   11618:     return(ret);
                   11619: encoding_error:
                   11620:     {
                   11621:         char buffer[150];
                   11622: 
                   11623:        snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
                   11624:                        ctxt->input->cur[0], ctxt->input->cur[1],
                   11625:                        ctxt->input->cur[2], ctxt->input->cur[3]);
                   11626:        __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
                   11627:                     "Input is not proper UTF-8, indicate encoding !\n%s",
                   11628:                     BAD_CAST buffer, NULL);
                   11629:     }
                   11630:     return(0);
                   11631: }
                   11632: 
                   11633: /**
                   11634:  * xmlParseChunk:
                   11635:  * @ctxt:  an XML parser context
                   11636:  * @chunk:  an char array
                   11637:  * @size:  the size in byte of the chunk
                   11638:  * @terminate:  last chunk indicator
                   11639:  *
                   11640:  * Parse a Chunk of memory
                   11641:  *
                   11642:  * Returns zero if no error, the xmlParserErrors otherwise.
                   11643:  */
                   11644: int
                   11645: xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
                   11646:               int terminate) {
                   11647:     int end_in_lf = 0;
                   11648:     int remain = 0;
                   11649: 
                   11650:     if (ctxt == NULL)
                   11651:         return(XML_ERR_INTERNAL_ERROR);
                   11652:     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
                   11653:         return(ctxt->errNo);
                   11654:     if (ctxt->instate == XML_PARSER_START)
                   11655:         xmlDetectSAX2(ctxt);
                   11656:     if ((size > 0) && (chunk != NULL) && (!terminate) &&
                   11657:         (chunk[size - 1] == '\r')) {
                   11658:        end_in_lf = 1;
                   11659:        size--;
                   11660:     }
                   11661: 
                   11662: xmldecl_done:
                   11663: 
                   11664:     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
                   11665:         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
                   11666:        int base = ctxt->input->base - ctxt->input->buf->buffer->content;
                   11667:        int cur = ctxt->input->cur - ctxt->input->base;
                   11668:        int res;
                   11669: 
                   11670:         /*
                   11671:          * Specific handling if we autodetected an encoding, we should not
                   11672:          * push more than the first line ... which depend on the encoding
                   11673:          * And only push the rest once the final encoding was detected
                   11674:          */
                   11675:         if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
                   11676:             (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
                   11677:             unsigned int len = 45;
                   11678: 
                   11679:             if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
                   11680:                                BAD_CAST "UTF-16")) ||
                   11681:                 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
                   11682:                                BAD_CAST "UTF16")))
                   11683:                 len = 90;
                   11684:             else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
                   11685:                                     BAD_CAST "UCS-4")) ||
                   11686:                      (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
                   11687:                                     BAD_CAST "UCS4")))
                   11688:                 len = 180;
                   11689: 
                   11690:             if (ctxt->input->buf->rawconsumed < len)
                   11691:                 len -= ctxt->input->buf->rawconsumed;
                   11692: 
                   11693:             /*
                   11694:              * Change size for reading the initial declaration only
                   11695:              * if size is greater than len. Otherwise, memmove in xmlBufferAdd
                   11696:              * will blindly copy extra bytes from memory.
                   11697:              */
                   11698:             if ((unsigned int) size > len) {
                   11699:                 remain = size - len;
                   11700:                 size = len;
                   11701:             } else {
                   11702:                 remain = 0;
                   11703:             }
                   11704:         }
                   11705:        res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
                   11706:        if (res < 0) {
                   11707:            ctxt->errNo = XML_PARSER_EOF;
                   11708:            ctxt->disableSAX = 1;
                   11709:            return (XML_PARSER_EOF);
                   11710:        }
                   11711:        ctxt->input->base = ctxt->input->buf->buffer->content + base;
                   11712:        ctxt->input->cur = ctxt->input->base + cur;
                   11713:        ctxt->input->end =
                   11714:            &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
                   11715: #ifdef DEBUG_PUSH
                   11716:        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
                   11717: #endif
                   11718: 
                   11719:     } else if (ctxt->instate != XML_PARSER_EOF) {
                   11720:        if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
                   11721:            xmlParserInputBufferPtr in = ctxt->input->buf;
                   11722:            if ((in->encoder != NULL) && (in->buffer != NULL) &&
                   11723:                    (in->raw != NULL)) {
                   11724:                int nbchars;
                   11725: 
                   11726:                nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
                   11727:                if (nbchars < 0) {
                   11728:                    /* TODO 2.6.0 */
                   11729:                    xmlGenericError(xmlGenericErrorContext,
                   11730:                                    "xmlParseChunk: encoder error\n");
                   11731:                    return(XML_ERR_INVALID_ENCODING);
                   11732:                }
                   11733:            }
                   11734:        }
                   11735:     }
                   11736:     if (remain != 0)
                   11737:         xmlParseTryOrFinish(ctxt, 0);
                   11738:     else
                   11739:         xmlParseTryOrFinish(ctxt, terminate);
                   11740:     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
                   11741:         return(ctxt->errNo);
                   11742: 
                   11743:     if (remain != 0) {
                   11744:         chunk += size;
                   11745:         size = remain;
                   11746:         remain = 0;
                   11747:         goto xmldecl_done;
                   11748:     }
                   11749:     if ((end_in_lf == 1) && (ctxt->input != NULL) &&
                   11750:         (ctxt->input->buf != NULL)) {
                   11751:        xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
                   11752:     }
                   11753:     if (terminate) {
                   11754:        /*
                   11755:         * Check for termination
                   11756:         */
                   11757:        int avail = 0;
                   11758: 
                   11759:        if (ctxt->input != NULL) {
                   11760:            if (ctxt->input->buf == NULL)
                   11761:                avail = ctxt->input->length -
                   11762:                        (ctxt->input->cur - ctxt->input->base);
                   11763:            else
                   11764:                avail = ctxt->input->buf->buffer->use -
                   11765:                        (ctxt->input->cur - ctxt->input->base);
                   11766:        }
                   11767:                            
                   11768:        if ((ctxt->instate != XML_PARSER_EOF) &&
                   11769:            (ctxt->instate != XML_PARSER_EPILOG)) {
                   11770:            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
                   11771:        } 
                   11772:        if ((ctxt->instate == XML_PARSER_EPILOG) && (avail > 0)) {
                   11773:            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
                   11774:        }
                   11775:        if (ctxt->instate != XML_PARSER_EOF) {
                   11776:            if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                   11777:                ctxt->sax->endDocument(ctxt->userData);
                   11778:        }
                   11779:        ctxt->instate = XML_PARSER_EOF;
                   11780:     }
                   11781:     return((xmlParserErrors) ctxt->errNo);           
                   11782: }
                   11783: 
                   11784: /************************************************************************
                   11785:  *                                                                     *
                   11786:  *             I/O front end functions to the parser                   *
                   11787:  *                                                                     *
                   11788:  ************************************************************************/
                   11789: 
                   11790: /**
                   11791:  * xmlCreatePushParserCtxt:
                   11792:  * @sax:  a SAX handler
                   11793:  * @user_data:  The user data returned on SAX callbacks
                   11794:  * @chunk:  a pointer to an array of chars
                   11795:  * @size:  number of chars in the array
                   11796:  * @filename:  an optional file name or URI
                   11797:  *
                   11798:  * Create a parser context for using the XML parser in push mode.
                   11799:  * If @buffer and @size are non-NULL, the data is used to detect
                   11800:  * the encoding.  The remaining characters will be parsed so they
                   11801:  * don't need to be fed in again through xmlParseChunk.
                   11802:  * To allow content encoding detection, @size should be >= 4
                   11803:  * The value of @filename is used for fetching external entities
                   11804:  * and error/warning reports.
                   11805:  *
                   11806:  * Returns the new parser context or NULL
                   11807:  */
                   11808: 
                   11809: xmlParserCtxtPtr
                   11810: xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data, 
                   11811:                         const char *chunk, int size, const char *filename) {
                   11812:     xmlParserCtxtPtr ctxt;
                   11813:     xmlParserInputPtr inputStream;
                   11814:     xmlParserInputBufferPtr buf;
                   11815:     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
                   11816: 
                   11817:     /*
                   11818:      * plug some encoding conversion routines
                   11819:      */
                   11820:     if ((chunk != NULL) && (size >= 4))
                   11821:        enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
                   11822: 
                   11823:     buf = xmlAllocParserInputBuffer(enc);
                   11824:     if (buf == NULL) return(NULL);
                   11825: 
                   11826:     ctxt = xmlNewParserCtxt();
                   11827:     if (ctxt == NULL) {
                   11828:         xmlErrMemory(NULL, "creating parser: out of memory\n");
                   11829:        xmlFreeParserInputBuffer(buf);
                   11830:        return(NULL);
                   11831:     }
                   11832:     ctxt->dictNames = 1;
                   11833:     ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
                   11834:     if (ctxt->pushTab == NULL) {
                   11835:         xmlErrMemory(ctxt, NULL);
                   11836:        xmlFreeParserInputBuffer(buf);
                   11837:        xmlFreeParserCtxt(ctxt);
                   11838:        return(NULL);
                   11839:     }
                   11840:     if (sax != NULL) {
                   11841: #ifdef LIBXML_SAX1_ENABLED
                   11842:        if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
                   11843: #endif /* LIBXML_SAX1_ENABLED */
                   11844:            xmlFree(ctxt->sax);
                   11845:        ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
                   11846:        if (ctxt->sax == NULL) {
                   11847:            xmlErrMemory(ctxt, NULL);
                   11848:            xmlFreeParserInputBuffer(buf);
                   11849:            xmlFreeParserCtxt(ctxt);
                   11850:            return(NULL);
                   11851:        }
                   11852:        memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
                   11853:        if (sax->initialized == XML_SAX2_MAGIC)
                   11854:            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
                   11855:        else
                   11856:            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
                   11857:        if (user_data != NULL)
                   11858:            ctxt->userData = user_data;
                   11859:     }  
                   11860:     if (filename == NULL) {
                   11861:        ctxt->directory = NULL;
                   11862:     } else {
                   11863:         ctxt->directory = xmlParserGetDirectory(filename);
                   11864:     }
                   11865: 
                   11866:     inputStream = xmlNewInputStream(ctxt);
                   11867:     if (inputStream == NULL) {
                   11868:        xmlFreeParserCtxt(ctxt);
                   11869:        xmlFreeParserInputBuffer(buf);
                   11870:        return(NULL);
                   11871:     }
                   11872: 
                   11873:     if (filename == NULL)
                   11874:        inputStream->filename = NULL;
                   11875:     else {
                   11876:        inputStream->filename = (char *)
                   11877:            xmlCanonicPath((const xmlChar *) filename);
                   11878:        if (inputStream->filename == NULL) {
                   11879:            xmlFreeParserCtxt(ctxt);
                   11880:            xmlFreeParserInputBuffer(buf);
                   11881:            return(NULL);
                   11882:        }
                   11883:     }
                   11884:     inputStream->buf = buf;
                   11885:     inputStream->base = inputStream->buf->buffer->content;
                   11886:     inputStream->cur = inputStream->buf->buffer->content;
                   11887:     inputStream->end = 
                   11888:        &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
                   11889: 
                   11890:     inputPush(ctxt, inputStream);
                   11891: 
                   11892:     /*
                   11893:      * If the caller didn't provide an initial 'chunk' for determining
                   11894:      * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
                   11895:      * that it can be automatically determined later
                   11896:      */
                   11897:     if ((size == 0) || (chunk == NULL)) {
                   11898:        ctxt->charset = XML_CHAR_ENCODING_NONE;
                   11899:     } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
                   11900:        int base = ctxt->input->base - ctxt->input->buf->buffer->content;
                   11901:        int cur = ctxt->input->cur - ctxt->input->base;
                   11902: 
                   11903:        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);              
                   11904: 
                   11905:        ctxt->input->base = ctxt->input->buf->buffer->content + base;
                   11906:        ctxt->input->cur = ctxt->input->base + cur;
                   11907:        ctxt->input->end =
                   11908:            &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
                   11909: #ifdef DEBUG_PUSH
                   11910:        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
                   11911: #endif
                   11912:     }
                   11913: 
                   11914:     if (enc != XML_CHAR_ENCODING_NONE) {
                   11915:         xmlSwitchEncoding(ctxt, enc);
                   11916:     }
                   11917: 
                   11918:     return(ctxt);
                   11919: }
                   11920: #endif /* LIBXML_PUSH_ENABLED */
                   11921: 
                   11922: /**
                   11923:  * xmlStopParser:
                   11924:  * @ctxt:  an XML parser context
                   11925:  *
                   11926:  * Blocks further parser processing
                   11927:  */
                   11928: void           
                   11929: xmlStopParser(xmlParserCtxtPtr ctxt) {
                   11930:     if (ctxt == NULL)
                   11931:         return;
                   11932:     ctxt->instate = XML_PARSER_EOF;
                   11933:     ctxt->disableSAX = 1;
                   11934:     if (ctxt->input != NULL) {
                   11935:        ctxt->input->cur = BAD_CAST"";
                   11936:        ctxt->input->base = ctxt->input->cur;
                   11937:     }
                   11938: }
                   11939: 
                   11940: /**
                   11941:  * xmlCreateIOParserCtxt:
                   11942:  * @sax:  a SAX handler
                   11943:  * @user_data:  The user data returned on SAX callbacks
                   11944:  * @ioread:  an I/O read function
                   11945:  * @ioclose:  an I/O close function
                   11946:  * @ioctx:  an I/O handler
                   11947:  * @enc:  the charset encoding if known
                   11948:  *
                   11949:  * Create a parser context for using the XML parser with an existing
                   11950:  * I/O stream
                   11951:  *
                   11952:  * Returns the new parser context or NULL
                   11953:  */
                   11954: xmlParserCtxtPtr
                   11955: xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
                   11956:        xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
                   11957:        void *ioctx, xmlCharEncoding enc) {
                   11958:     xmlParserCtxtPtr ctxt;
                   11959:     xmlParserInputPtr inputStream;
                   11960:     xmlParserInputBufferPtr buf;
                   11961:     
                   11962:     if (ioread == NULL) return(NULL);
                   11963: 
                   11964:     buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
                   11965:     if (buf == NULL) return(NULL);
                   11966: 
                   11967:     ctxt = xmlNewParserCtxt();
                   11968:     if (ctxt == NULL) {
                   11969:        xmlFreeParserInputBuffer(buf);
                   11970:        return(NULL);
                   11971:     }
                   11972:     if (sax != NULL) {
                   11973: #ifdef LIBXML_SAX1_ENABLED
                   11974:        if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
                   11975: #endif /* LIBXML_SAX1_ENABLED */
                   11976:            xmlFree(ctxt->sax);
                   11977:        ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
                   11978:        if (ctxt->sax == NULL) {
                   11979:            xmlErrMemory(ctxt, NULL);
                   11980:            xmlFreeParserCtxt(ctxt);
                   11981:            return(NULL);
                   11982:        }
                   11983:        memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
                   11984:        if (sax->initialized == XML_SAX2_MAGIC)
                   11985:            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
                   11986:        else
                   11987:            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
                   11988:        if (user_data != NULL)
                   11989:            ctxt->userData = user_data;
                   11990:     }  
                   11991: 
                   11992:     inputStream = xmlNewIOInputStream(ctxt, buf, enc);
                   11993:     if (inputStream == NULL) {
                   11994:        xmlFreeParserCtxt(ctxt);
                   11995:        return(NULL);
                   11996:     }
                   11997:     inputPush(ctxt, inputStream);
                   11998: 
                   11999:     return(ctxt);
                   12000: }
                   12001: 
                   12002: #ifdef LIBXML_VALID_ENABLED
                   12003: /************************************************************************
                   12004:  *                                                                     *
                   12005:  *             Front ends when parsing a DTD                           *
                   12006:  *                                                                     *
                   12007:  ************************************************************************/
                   12008: 
                   12009: /**
                   12010:  * xmlIOParseDTD:
                   12011:  * @sax:  the SAX handler block or NULL
                   12012:  * @input:  an Input Buffer
                   12013:  * @enc:  the charset encoding if known
                   12014:  *
                   12015:  * Load and parse a DTD
                   12016:  * 
                   12017:  * Returns the resulting xmlDtdPtr or NULL in case of error.
                   12018:  * @input will be freed by the function in any case.
                   12019:  */
                   12020: 
                   12021: xmlDtdPtr
                   12022: xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
                   12023:              xmlCharEncoding enc) {
                   12024:     xmlDtdPtr ret = NULL;
                   12025:     xmlParserCtxtPtr ctxt;
                   12026:     xmlParserInputPtr pinput = NULL;
                   12027:     xmlChar start[4];
                   12028: 
                   12029:     if (input == NULL)
                   12030:        return(NULL);
                   12031: 
                   12032:     ctxt = xmlNewParserCtxt();
                   12033:     if (ctxt == NULL) {
                   12034:         xmlFreeParserInputBuffer(input);
                   12035:        return(NULL);
                   12036:     }
                   12037: 
                   12038:     /*
                   12039:      * Set-up the SAX context
                   12040:      */
                   12041:     if (sax != NULL) { 
                   12042:        if (ctxt->sax != NULL)
                   12043:            xmlFree(ctxt->sax);
                   12044:         ctxt->sax = sax;
                   12045:         ctxt->userData = ctxt;
                   12046:     }
                   12047:     xmlDetectSAX2(ctxt);
                   12048: 
                   12049:     /*
                   12050:      * generate a parser input from the I/O handler
                   12051:      */
                   12052: 
                   12053:     pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   12054:     if (pinput == NULL) {
                   12055:         if (sax != NULL) ctxt->sax = NULL;
                   12056:         xmlFreeParserInputBuffer(input);
                   12057:        xmlFreeParserCtxt(ctxt);
                   12058:        return(NULL);
                   12059:     }
                   12060: 
                   12061:     /*
                   12062:      * plug some encoding conversion routines here.
                   12063:      */
                   12064:     if (xmlPushInput(ctxt, pinput) < 0) {
                   12065:         if (sax != NULL) ctxt->sax = NULL;
                   12066:        xmlFreeParserCtxt(ctxt);
                   12067:        return(NULL);
                   12068:     }
                   12069:     if (enc != XML_CHAR_ENCODING_NONE) {
                   12070:         xmlSwitchEncoding(ctxt, enc);
                   12071:     }
                   12072: 
                   12073:     pinput->filename = NULL;
                   12074:     pinput->line = 1;
                   12075:     pinput->col = 1;
                   12076:     pinput->base = ctxt->input->cur;
                   12077:     pinput->cur = ctxt->input->cur;
                   12078:     pinput->free = NULL;
                   12079: 
                   12080:     /*
                   12081:      * let's parse that entity knowing it's an external subset.
                   12082:      */
                   12083:     ctxt->inSubset = 2;
                   12084:     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
                   12085:     if (ctxt->myDoc == NULL) {
                   12086:        xmlErrMemory(ctxt, "New Doc failed");
                   12087:        return(NULL);
                   12088:     }
                   12089:     ctxt->myDoc->properties = XML_DOC_INTERNAL;
                   12090:     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
                   12091:                                       BAD_CAST "none", BAD_CAST "none");
                   12092: 
                   12093:     if ((enc == XML_CHAR_ENCODING_NONE) &&
                   12094:         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
                   12095:        /* 
                   12096:         * Get the 4 first bytes and decode the charset
                   12097:         * if enc != XML_CHAR_ENCODING_NONE
                   12098:         * plug some encoding conversion routines.
                   12099:         */
                   12100:        start[0] = RAW;
                   12101:        start[1] = NXT(1);
                   12102:        start[2] = NXT(2);
                   12103:        start[3] = NXT(3);
                   12104:        enc = xmlDetectCharEncoding(start, 4);
                   12105:        if (enc != XML_CHAR_ENCODING_NONE) {
                   12106:            xmlSwitchEncoding(ctxt, enc);
                   12107:        }
                   12108:     }
                   12109: 
                   12110:     xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
                   12111: 
                   12112:     if (ctxt->myDoc != NULL) {
                   12113:        if (ctxt->wellFormed) {
                   12114:            ret = ctxt->myDoc->extSubset;
                   12115:            ctxt->myDoc->extSubset = NULL;
                   12116:            if (ret != NULL) {
                   12117:                xmlNodePtr tmp;
                   12118: 
                   12119:                ret->doc = NULL;
                   12120:                tmp = ret->children;
                   12121:                while (tmp != NULL) {
                   12122:                    tmp->doc = NULL;
                   12123:                    tmp = tmp->next;
                   12124:                }
                   12125:            }
                   12126:        } else {
                   12127:            ret = NULL;
                   12128:        }
                   12129:         xmlFreeDoc(ctxt->myDoc);
                   12130:         ctxt->myDoc = NULL;
                   12131:     }
                   12132:     if (sax != NULL) ctxt->sax = NULL;
                   12133:     xmlFreeParserCtxt(ctxt);
                   12134:     
                   12135:     return(ret);
                   12136: }
                   12137: 
                   12138: /**
                   12139:  * xmlSAXParseDTD:
                   12140:  * @sax:  the SAX handler block
                   12141:  * @ExternalID:  a NAME* containing the External ID of the DTD
                   12142:  * @SystemID:  a NAME* containing the URL to the DTD
                   12143:  *
                   12144:  * Load and parse an external subset.
                   12145:  * 
                   12146:  * Returns the resulting xmlDtdPtr or NULL in case of error.
                   12147:  */
                   12148: 
                   12149: xmlDtdPtr
                   12150: xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
                   12151:                           const xmlChar *SystemID) {
                   12152:     xmlDtdPtr ret = NULL;
                   12153:     xmlParserCtxtPtr ctxt;
                   12154:     xmlParserInputPtr input = NULL;
                   12155:     xmlCharEncoding enc;
                   12156:     xmlChar* systemIdCanonic;
                   12157: 
                   12158:     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
                   12159: 
                   12160:     ctxt = xmlNewParserCtxt();
                   12161:     if (ctxt == NULL) {
                   12162:        return(NULL);
                   12163:     }
                   12164: 
                   12165:     /*
                   12166:      * Set-up the SAX context
                   12167:      */
                   12168:     if (sax != NULL) { 
                   12169:        if (ctxt->sax != NULL)
                   12170:            xmlFree(ctxt->sax);
                   12171:         ctxt->sax = sax;
                   12172:         ctxt->userData = ctxt;
                   12173:     }
                   12174:     
                   12175:     /*
                   12176:      * Canonicalise the system ID
                   12177:      */
                   12178:     systemIdCanonic = xmlCanonicPath(SystemID);
                   12179:     if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
                   12180:        xmlFreeParserCtxt(ctxt);
                   12181:        return(NULL);
                   12182:     }
                   12183: 
                   12184:     /*
                   12185:      * Ask the Entity resolver to load the damn thing
                   12186:      */
                   12187: 
                   12188:     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
                   12189:        input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
                   12190:                                         systemIdCanonic);
                   12191:     if (input == NULL) {
                   12192:         if (sax != NULL) ctxt->sax = NULL;
                   12193:        xmlFreeParserCtxt(ctxt);
                   12194:        if (systemIdCanonic != NULL)
                   12195:            xmlFree(systemIdCanonic);
                   12196:        return(NULL);
                   12197:     }
                   12198: 
                   12199:     /*
                   12200:      * plug some encoding conversion routines here.
                   12201:      */
                   12202:     if (xmlPushInput(ctxt, input) < 0) {
                   12203:         if (sax != NULL) ctxt->sax = NULL;
                   12204:        xmlFreeParserCtxt(ctxt);
                   12205:        if (systemIdCanonic != NULL)
                   12206:            xmlFree(systemIdCanonic);
                   12207:        return(NULL);
                   12208:     }
                   12209:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
                   12210:        enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
                   12211:        xmlSwitchEncoding(ctxt, enc);
                   12212:     }
                   12213: 
                   12214:     if (input->filename == NULL)
                   12215:        input->filename = (char *) systemIdCanonic;
                   12216:     else
                   12217:        xmlFree(systemIdCanonic);
                   12218:     input->line = 1;
                   12219:     input->col = 1;
                   12220:     input->base = ctxt->input->cur;
                   12221:     input->cur = ctxt->input->cur;
                   12222:     input->free = NULL;
                   12223: 
                   12224:     /*
                   12225:      * let's parse that entity knowing it's an external subset.
                   12226:      */
                   12227:     ctxt->inSubset = 2;
                   12228:     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
                   12229:     if (ctxt->myDoc == NULL) {
                   12230:        xmlErrMemory(ctxt, "New Doc failed");
                   12231:         if (sax != NULL) ctxt->sax = NULL;
                   12232:        xmlFreeParserCtxt(ctxt);
                   12233:        return(NULL);
                   12234:     }
                   12235:     ctxt->myDoc->properties = XML_DOC_INTERNAL;
                   12236:     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
                   12237:                                       ExternalID, SystemID);
                   12238:     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
                   12239: 
                   12240:     if (ctxt->myDoc != NULL) {
                   12241:        if (ctxt->wellFormed) {
                   12242:            ret = ctxt->myDoc->extSubset;
                   12243:            ctxt->myDoc->extSubset = NULL;
                   12244:            if (ret != NULL) {
                   12245:                xmlNodePtr tmp;
                   12246: 
                   12247:                ret->doc = NULL;
                   12248:                tmp = ret->children;
                   12249:                while (tmp != NULL) {
                   12250:                    tmp->doc = NULL;
                   12251:                    tmp = tmp->next;
                   12252:                }
                   12253:            }
                   12254:        } else {
                   12255:            ret = NULL;
                   12256:        }
                   12257:         xmlFreeDoc(ctxt->myDoc);
                   12258:         ctxt->myDoc = NULL;
                   12259:     }
                   12260:     if (sax != NULL) ctxt->sax = NULL;
                   12261:     xmlFreeParserCtxt(ctxt);
                   12262: 
                   12263:     return(ret);
                   12264: }
                   12265: 
                   12266: 
                   12267: /**
                   12268:  * xmlParseDTD:
                   12269:  * @ExternalID:  a NAME* containing the External ID of the DTD
                   12270:  * @SystemID:  a NAME* containing the URL to the DTD
                   12271:  *
                   12272:  * Load and parse an external subset.
                   12273:  *
                   12274:  * Returns the resulting xmlDtdPtr or NULL in case of error.
                   12275:  */
                   12276: 
                   12277: xmlDtdPtr
                   12278: xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
                   12279:     return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
                   12280: }
                   12281: #endif /* LIBXML_VALID_ENABLED */
                   12282: 
                   12283: /************************************************************************
                   12284:  *                                                                     *
                   12285:  *             Front ends when parsing an Entity                       *
                   12286:  *                                                                     *
                   12287:  ************************************************************************/
                   12288: 
                   12289: /**
                   12290:  * xmlParseCtxtExternalEntity:
                   12291:  * @ctx:  the existing parsing context
                   12292:  * @URL:  the URL for the entity to load
                   12293:  * @ID:  the System ID for the entity to load
                   12294:  * @lst:  the return value for the set of parsed nodes
                   12295:  *
                   12296:  * Parse an external general entity within an existing parsing context
                   12297:  * An external general parsed entity is well-formed if it matches the
                   12298:  * production labeled extParsedEnt.
                   12299:  *
                   12300:  * [78] extParsedEnt ::= TextDecl? content
                   12301:  *
                   12302:  * Returns 0 if the entity is well formed, -1 in case of args problem and
                   12303:  *    the parser error code otherwise
                   12304:  */
                   12305: 
                   12306: int
                   12307: xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
                   12308:                       const xmlChar *ID, xmlNodePtr *lst) {
                   12309:     xmlParserCtxtPtr ctxt;
                   12310:     xmlDocPtr newDoc;
                   12311:     xmlNodePtr newRoot;
                   12312:     xmlSAXHandlerPtr oldsax = NULL;
                   12313:     int ret = 0;
                   12314:     xmlChar start[4];
                   12315:     xmlCharEncoding enc;
                   12316: 
                   12317:     if (ctx == NULL) return(-1);
                   12318: 
                   12319:     if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
                   12320:         (ctx->depth > 1024)) {
                   12321:        return(XML_ERR_ENTITY_LOOP);
                   12322:     }
                   12323: 
                   12324:     if (lst != NULL)
                   12325:         *lst = NULL;
                   12326:     if ((URL == NULL) && (ID == NULL))
                   12327:        return(-1);
                   12328:     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
                   12329:        return(-1);
                   12330: 
                   12331:     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
                   12332:     if (ctxt == NULL) {
                   12333:        return(-1);
                   12334:     }
                   12335: 
                   12336:     oldsax = ctxt->sax;
                   12337:     ctxt->sax = ctx->sax;
                   12338:     xmlDetectSAX2(ctxt);
                   12339:     newDoc = xmlNewDoc(BAD_CAST "1.0");
                   12340:     if (newDoc == NULL) {
                   12341:        xmlFreeParserCtxt(ctxt);
                   12342:        return(-1);
                   12343:     }
                   12344:     newDoc->properties = XML_DOC_INTERNAL;
                   12345:     if (ctx->myDoc->dict) {
                   12346:        newDoc->dict = ctx->myDoc->dict;
                   12347:        xmlDictReference(newDoc->dict);
                   12348:     }
                   12349:     if (ctx->myDoc != NULL) {
                   12350:        newDoc->intSubset = ctx->myDoc->intSubset;
                   12351:        newDoc->extSubset = ctx->myDoc->extSubset;
                   12352:     }
                   12353:     if (ctx->myDoc->URL != NULL) {
                   12354:        newDoc->URL = xmlStrdup(ctx->myDoc->URL);
                   12355:     }
                   12356:     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
                   12357:     if (newRoot == NULL) {
                   12358:        ctxt->sax = oldsax;
                   12359:        xmlFreeParserCtxt(ctxt);
                   12360:        newDoc->intSubset = NULL;
                   12361:        newDoc->extSubset = NULL;
                   12362:         xmlFreeDoc(newDoc);
                   12363:        return(-1);
                   12364:     }
                   12365:     xmlAddChild((xmlNodePtr) newDoc, newRoot);
                   12366:     nodePush(ctxt, newDoc->children);
                   12367:     if (ctx->myDoc == NULL) {
                   12368:        ctxt->myDoc = newDoc;
                   12369:     } else {
                   12370:        ctxt->myDoc = ctx->myDoc;
                   12371:        newDoc->children->doc = ctx->myDoc;
                   12372:     }
                   12373: 
                   12374:     /*
                   12375:      * Get the 4 first bytes and decode the charset
                   12376:      * if enc != XML_CHAR_ENCODING_NONE
                   12377:      * plug some encoding conversion routines.
                   12378:      */
                   12379:     GROW
                   12380:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
                   12381:        start[0] = RAW;
                   12382:        start[1] = NXT(1);
                   12383:        start[2] = NXT(2);
                   12384:        start[3] = NXT(3);
                   12385:        enc = xmlDetectCharEncoding(start, 4);
                   12386:        if (enc != XML_CHAR_ENCODING_NONE) {
                   12387:            xmlSwitchEncoding(ctxt, enc);
                   12388:        }
                   12389:     }
                   12390: 
                   12391:     /*
                   12392:      * Parse a possible text declaration first
                   12393:      */
                   12394:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
                   12395:        xmlParseTextDecl(ctxt);
                   12396:        /*
                   12397:         * An XML-1.0 document can't reference an entity not XML-1.0
                   12398:         */
                   12399:        if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
                   12400:            (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
                   12401:            xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH, 
                   12402:                           "Version mismatch between document and entity\n");
                   12403:        }
                   12404:     }
                   12405: 
                   12406:     /*
                   12407:      * Doing validity checking on chunk doesn't make sense
                   12408:      */
                   12409:     ctxt->instate = XML_PARSER_CONTENT;
                   12410:     ctxt->validate = ctx->validate;
                   12411:     ctxt->valid = ctx->valid;
                   12412:     ctxt->loadsubset = ctx->loadsubset;
                   12413:     ctxt->depth = ctx->depth + 1;
                   12414:     ctxt->replaceEntities = ctx->replaceEntities;
                   12415:     if (ctxt->validate) {
                   12416:        ctxt->vctxt.error = ctx->vctxt.error;
                   12417:        ctxt->vctxt.warning = ctx->vctxt.warning;
                   12418:     } else {
                   12419:        ctxt->vctxt.error = NULL;
                   12420:        ctxt->vctxt.warning = NULL;
                   12421:     }
                   12422:     ctxt->vctxt.nodeTab = NULL;
                   12423:     ctxt->vctxt.nodeNr = 0;
                   12424:     ctxt->vctxt.nodeMax = 0;
                   12425:     ctxt->vctxt.node = NULL;
                   12426:     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
                   12427:     ctxt->dict = ctx->dict;
                   12428:     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
                   12429:     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
                   12430:     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
                   12431:     ctxt->dictNames = ctx->dictNames;
                   12432:     ctxt->attsDefault = ctx->attsDefault;
                   12433:     ctxt->attsSpecial = ctx->attsSpecial;
                   12434:     ctxt->linenumbers = ctx->linenumbers;
                   12435: 
                   12436:     xmlParseContent(ctxt);
                   12437: 
                   12438:     ctx->validate = ctxt->validate;
                   12439:     ctx->valid = ctxt->valid;
                   12440:     if ((RAW == '<') && (NXT(1) == '/')) {
                   12441:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12442:     } else if (RAW != 0) {
                   12443:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   12444:     }
                   12445:     if (ctxt->node != newDoc->children) {
                   12446:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12447:     }
                   12448: 
                   12449:     if (!ctxt->wellFormed) {
                   12450:         if (ctxt->errNo == 0)
                   12451:            ret = 1;
                   12452:        else
                   12453:            ret = ctxt->errNo;
                   12454:     } else {
                   12455:        if (lst != NULL) {
                   12456:            xmlNodePtr cur;
                   12457: 
                   12458:            /*
                   12459:             * Return the newly created nodeset after unlinking it from
                   12460:             * they pseudo parent.
                   12461:             */
                   12462:            cur = newDoc->children->children;
                   12463:            *lst = cur;
                   12464:            while (cur != NULL) {
                   12465:                cur->parent = NULL;
                   12466:                cur = cur->next;
                   12467:            }
                   12468:             newDoc->children->children = NULL;
                   12469:        }
                   12470:        ret = 0;
                   12471:     }
                   12472:     ctxt->sax = oldsax;
                   12473:     ctxt->dict = NULL;
                   12474:     ctxt->attsDefault = NULL;
                   12475:     ctxt->attsSpecial = NULL;
                   12476:     xmlFreeParserCtxt(ctxt);
                   12477:     newDoc->intSubset = NULL;
                   12478:     newDoc->extSubset = NULL;
                   12479:     xmlFreeDoc(newDoc);
                   12480: 
                   12481:     return(ret);
                   12482: }
                   12483: 
                   12484: /**
                   12485:  * xmlParseExternalEntityPrivate:
                   12486:  * @doc:  the document the chunk pertains to
                   12487:  * @oldctxt:  the previous parser context if available
                   12488:  * @sax:  the SAX handler bloc (possibly NULL)
                   12489:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
                   12490:  * @depth:  Used for loop detection, use 0
                   12491:  * @URL:  the URL for the entity to load
                   12492:  * @ID:  the System ID for the entity to load
                   12493:  * @list:  the return value for the set of parsed nodes
                   12494:  *
                   12495:  * Private version of xmlParseExternalEntity()
                   12496:  *
                   12497:  * Returns 0 if the entity is well formed, -1 in case of args problem and
                   12498:  *    the parser error code otherwise
                   12499:  */
                   12500: 
                   12501: static xmlParserErrors
                   12502: xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
                   12503:                      xmlSAXHandlerPtr sax,
                   12504:                      void *user_data, int depth, const xmlChar *URL,
                   12505:                      const xmlChar *ID, xmlNodePtr *list) {
                   12506:     xmlParserCtxtPtr ctxt;
                   12507:     xmlDocPtr newDoc;
                   12508:     xmlNodePtr newRoot;
                   12509:     xmlSAXHandlerPtr oldsax = NULL;
                   12510:     xmlParserErrors ret = XML_ERR_OK;
                   12511:     xmlChar start[4];
                   12512:     xmlCharEncoding enc;
                   12513: 
                   12514:     if (((depth > 40) &&
                   12515:        ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
                   12516:        (depth > 1024)) {
                   12517:        return(XML_ERR_ENTITY_LOOP);
                   12518:     }
                   12519: 
                   12520:     if (list != NULL)
                   12521:         *list = NULL;
                   12522:     if ((URL == NULL) && (ID == NULL))
                   12523:        return(XML_ERR_INTERNAL_ERROR);
                   12524:     if (doc == NULL)
                   12525:        return(XML_ERR_INTERNAL_ERROR);
                   12526: 
                   12527: 
                   12528:     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
                   12529:     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
                   12530:     ctxt->userData = ctxt;
                   12531:     if (oldctxt != NULL) {
                   12532:        ctxt->_private = oldctxt->_private;
                   12533:        ctxt->loadsubset = oldctxt->loadsubset;
                   12534:        ctxt->validate = oldctxt->validate;
                   12535:        ctxt->external = oldctxt->external;
                   12536:        ctxt->record_info = oldctxt->record_info;
                   12537:        ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
                   12538:        ctxt->node_seq.length = oldctxt->node_seq.length;
                   12539:        ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
                   12540:     } else {
                   12541:        /*
                   12542:         * Doing validity checking on chunk without context
                   12543:         * doesn't make sense
                   12544:         */
                   12545:        ctxt->_private = NULL;
                   12546:        ctxt->validate = 0;
                   12547:        ctxt->external = 2;
                   12548:        ctxt->loadsubset = 0;
                   12549:     }
                   12550:     if (sax != NULL) {
                   12551:        oldsax = ctxt->sax;
                   12552:         ctxt->sax = sax;
                   12553:        if (user_data != NULL)
                   12554:            ctxt->userData = user_data;
                   12555:     }
                   12556:     xmlDetectSAX2(ctxt);
                   12557:     newDoc = xmlNewDoc(BAD_CAST "1.0");
                   12558:     if (newDoc == NULL) {
                   12559:        ctxt->node_seq.maximum = 0;
                   12560:        ctxt->node_seq.length = 0;
                   12561:        ctxt->node_seq.buffer = NULL;
                   12562:        xmlFreeParserCtxt(ctxt);
                   12563:        return(XML_ERR_INTERNAL_ERROR);
                   12564:     }
                   12565:     newDoc->properties = XML_DOC_INTERNAL;
                   12566:     newDoc->intSubset = doc->intSubset;
                   12567:     newDoc->extSubset = doc->extSubset;
                   12568:     newDoc->dict = doc->dict;
                   12569:     xmlDictReference(newDoc->dict);
                   12570: 
                   12571:     if (doc->URL != NULL) {
                   12572:        newDoc->URL = xmlStrdup(doc->URL);
                   12573:     }
                   12574:     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
                   12575:     if (newRoot == NULL) {
                   12576:        if (sax != NULL)
                   12577:            ctxt->sax = oldsax;
                   12578:        ctxt->node_seq.maximum = 0;
                   12579:        ctxt->node_seq.length = 0;
                   12580:        ctxt->node_seq.buffer = NULL;
                   12581:        xmlFreeParserCtxt(ctxt);
                   12582:        newDoc->intSubset = NULL;
                   12583:        newDoc->extSubset = NULL;
                   12584:         xmlFreeDoc(newDoc);
                   12585:        return(XML_ERR_INTERNAL_ERROR);
                   12586:     }
                   12587:     xmlAddChild((xmlNodePtr) newDoc, newRoot);
                   12588:     nodePush(ctxt, newDoc->children);
                   12589:     ctxt->myDoc = doc;
                   12590:     newRoot->doc = doc;
                   12591: 
                   12592:     /*
                   12593:      * Get the 4 first bytes and decode the charset
                   12594:      * if enc != XML_CHAR_ENCODING_NONE
                   12595:      * plug some encoding conversion routines.
                   12596:      */
                   12597:     GROW;
                   12598:     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
                   12599:        start[0] = RAW;
                   12600:        start[1] = NXT(1);
                   12601:        start[2] = NXT(2);
                   12602:        start[3] = NXT(3);
                   12603:        enc = xmlDetectCharEncoding(start, 4);
                   12604:        if (enc != XML_CHAR_ENCODING_NONE) {
                   12605:            xmlSwitchEncoding(ctxt, enc);
                   12606:        }
                   12607:     }
                   12608: 
                   12609:     /*
                   12610:      * Parse a possible text declaration first
                   12611:      */
                   12612:     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
                   12613:        xmlParseTextDecl(ctxt);
                   12614:     }
                   12615: 
                   12616:     ctxt->instate = XML_PARSER_CONTENT;
                   12617:     ctxt->depth = depth;
                   12618: 
                   12619:     xmlParseContent(ctxt);
                   12620: 
                   12621:     if ((RAW == '<') && (NXT(1) == '/')) {
                   12622:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12623:     } else if (RAW != 0) {
                   12624:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   12625:     }
                   12626:     if (ctxt->node != newDoc->children) {
                   12627:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12628:     }
                   12629: 
                   12630:     if (!ctxt->wellFormed) {
                   12631:         if (ctxt->errNo == 0)
                   12632:            ret = XML_ERR_INTERNAL_ERROR;
                   12633:        else
                   12634:            ret = (xmlParserErrors)ctxt->errNo;
                   12635:     } else {
                   12636:        if (list != NULL) {
                   12637:            xmlNodePtr cur;
                   12638: 
                   12639:            /*
                   12640:             * Return the newly created nodeset after unlinking it from
                   12641:             * they pseudo parent.
                   12642:             */
                   12643:            cur = newDoc->children->children;
                   12644:            *list = cur;
                   12645:            while (cur != NULL) {
                   12646:                cur->parent = NULL;
                   12647:                cur = cur->next;
                   12648:            }
                   12649:             newDoc->children->children = NULL;
                   12650:        }
                   12651:        ret = XML_ERR_OK;
                   12652:     }
                   12653: 
                   12654:     /*
                   12655:      * Record in the parent context the number of entities replacement
                   12656:      * done when parsing that reference.
                   12657:      */
                   12658:     if (oldctxt != NULL)
                   12659:         oldctxt->nbentities += ctxt->nbentities;
                   12660: 
                   12661:     /*
                   12662:      * Also record the size of the entity parsed
                   12663:      */
                   12664:     if (ctxt->input != NULL) {
                   12665:        oldctxt->sizeentities += ctxt->input->consumed;
                   12666:        oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
                   12667:     }
                   12668:     /*
                   12669:      * And record the last error if any
                   12670:      */
                   12671:     if (ctxt->lastError.code != XML_ERR_OK)
                   12672:         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
                   12673: 
                   12674:     if (sax != NULL) 
                   12675:        ctxt->sax = oldsax;
                   12676:     oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
                   12677:     oldctxt->node_seq.length = ctxt->node_seq.length;
                   12678:     oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
                   12679:     ctxt->node_seq.maximum = 0;
                   12680:     ctxt->node_seq.length = 0;
                   12681:     ctxt->node_seq.buffer = NULL;
                   12682:     xmlFreeParserCtxt(ctxt);
                   12683:     newDoc->intSubset = NULL;
                   12684:     newDoc->extSubset = NULL;
                   12685:     xmlFreeDoc(newDoc);
                   12686: 
                   12687:     return(ret);
                   12688: }
                   12689: 
                   12690: #ifdef LIBXML_SAX1_ENABLED
                   12691: /**
                   12692:  * xmlParseExternalEntity:
                   12693:  * @doc:  the document the chunk pertains to
                   12694:  * @sax:  the SAX handler bloc (possibly NULL)
                   12695:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
                   12696:  * @depth:  Used for loop detection, use 0
                   12697:  * @URL:  the URL for the entity to load
                   12698:  * @ID:  the System ID for the entity to load
                   12699:  * @lst:  the return value for the set of parsed nodes
                   12700:  *
                   12701:  * Parse an external general entity
                   12702:  * An external general parsed entity is well-formed if it matches the
                   12703:  * production labeled extParsedEnt.
                   12704:  *
                   12705:  * [78] extParsedEnt ::= TextDecl? content
                   12706:  *
                   12707:  * Returns 0 if the entity is well formed, -1 in case of args problem and
                   12708:  *    the parser error code otherwise
                   12709:  */
                   12710: 
                   12711: int
                   12712: xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
                   12713:          int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
                   12714:     return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
                   12715:                                       ID, lst));
                   12716: }
                   12717: 
                   12718: /**
                   12719:  * xmlParseBalancedChunkMemory:
                   12720:  * @doc:  the document the chunk pertains to
                   12721:  * @sax:  the SAX handler bloc (possibly NULL)
                   12722:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
                   12723:  * @depth:  Used for loop detection, use 0
                   12724:  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
                   12725:  * @lst:  the return value for the set of parsed nodes
                   12726:  *
                   12727:  * Parse a well-balanced chunk of an XML document
                   12728:  * called by the parser
                   12729:  * The allowed sequence for the Well Balanced Chunk is the one defined by
                   12730:  * the content production in the XML grammar:
                   12731:  *
                   12732:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   12733:  *
                   12734:  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
                   12735:  *    the parser error code otherwise
                   12736:  */
                   12737: 
                   12738: int
                   12739: xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
                   12740:      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
                   12741:     return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
                   12742:                                                 depth, string, lst, 0 );
                   12743: }
                   12744: #endif /* LIBXML_SAX1_ENABLED */
                   12745: 
                   12746: /**
                   12747:  * xmlParseBalancedChunkMemoryInternal:
                   12748:  * @oldctxt:  the existing parsing context
                   12749:  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
                   12750:  * @user_data:  the user data field for the parser context
                   12751:  * @lst:  the return value for the set of parsed nodes
                   12752:  *
                   12753:  *
                   12754:  * Parse a well-balanced chunk of an XML document
                   12755:  * called by the parser
                   12756:  * The allowed sequence for the Well Balanced Chunk is the one defined by
                   12757:  * the content production in the XML grammar:
                   12758:  *
                   12759:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   12760:  *
                   12761:  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
                   12762:  * error code otherwise
                   12763:  *
                   12764:  * In case recover is set to 1, the nodelist will not be empty even if
                   12765:  * the parsed chunk is not well balanced.
                   12766:  */
                   12767: static xmlParserErrors
                   12768: xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
                   12769:        const xmlChar *string, void *user_data, xmlNodePtr *lst) {
                   12770:     xmlParserCtxtPtr ctxt;
                   12771:     xmlDocPtr newDoc = NULL;
                   12772:     xmlNodePtr newRoot;
                   12773:     xmlSAXHandlerPtr oldsax = NULL;
                   12774:     xmlNodePtr content = NULL;
                   12775:     xmlNodePtr last = NULL;
                   12776:     int size;
                   12777:     xmlParserErrors ret = XML_ERR_OK;
                   12778: #ifdef SAX2
                   12779:     int i;
                   12780: #endif
                   12781: 
                   12782:     if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
                   12783:         (oldctxt->depth >  1024)) {
                   12784:        return(XML_ERR_ENTITY_LOOP);
                   12785:     }
                   12786: 
                   12787: 
                   12788:     if (lst != NULL)
                   12789:         *lst = NULL;
                   12790:     if (string == NULL)
                   12791:         return(XML_ERR_INTERNAL_ERROR);
                   12792: 
                   12793:     size = xmlStrlen(string);
                   12794: 
                   12795:     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
                   12796:     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
                   12797:     if (user_data != NULL)
                   12798:        ctxt->userData = user_data;
                   12799:     else
                   12800:        ctxt->userData = ctxt;
                   12801:     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
                   12802:     ctxt->dict = oldctxt->dict;
                   12803:     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
                   12804:     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
                   12805:     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
                   12806: 
                   12807: #ifdef SAX2
                   12808:     /* propagate namespaces down the entity */
                   12809:     for (i = 0;i < oldctxt->nsNr;i += 2) {
                   12810:         nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
                   12811:     }
                   12812: #endif
                   12813: 
                   12814:     oldsax = ctxt->sax;
                   12815:     ctxt->sax = oldctxt->sax;
                   12816:     xmlDetectSAX2(ctxt);
                   12817:     ctxt->replaceEntities = oldctxt->replaceEntities;
                   12818:     ctxt->options = oldctxt->options;
                   12819: 
                   12820:     ctxt->_private = oldctxt->_private;
                   12821:     if (oldctxt->myDoc == NULL) {
                   12822:        newDoc = xmlNewDoc(BAD_CAST "1.0");
                   12823:        if (newDoc == NULL) {
                   12824:            ctxt->sax = oldsax;
                   12825:            ctxt->dict = NULL;
                   12826:            xmlFreeParserCtxt(ctxt);
                   12827:            return(XML_ERR_INTERNAL_ERROR);
                   12828:        }
                   12829:        newDoc->properties = XML_DOC_INTERNAL;
                   12830:        newDoc->dict = ctxt->dict;
                   12831:        xmlDictReference(newDoc->dict);
                   12832:        ctxt->myDoc = newDoc;
                   12833:     } else {
                   12834:        ctxt->myDoc = oldctxt->myDoc;
                   12835:         content = ctxt->myDoc->children;
                   12836:        last = ctxt->myDoc->last;
                   12837:     }
                   12838:     newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
                   12839:     if (newRoot == NULL) {
                   12840:        ctxt->sax = oldsax;
                   12841:        ctxt->dict = NULL;
                   12842:        xmlFreeParserCtxt(ctxt);
                   12843:        if (newDoc != NULL) {
                   12844:            xmlFreeDoc(newDoc);
                   12845:        }
                   12846:        return(XML_ERR_INTERNAL_ERROR);
                   12847:     }
                   12848:     ctxt->myDoc->children = NULL;
                   12849:     ctxt->myDoc->last = NULL;
                   12850:     xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
                   12851:     nodePush(ctxt, ctxt->myDoc->children);
                   12852:     ctxt->instate = XML_PARSER_CONTENT;
                   12853:     ctxt->depth = oldctxt->depth + 1;
                   12854: 
                   12855:     ctxt->validate = 0;
                   12856:     ctxt->loadsubset = oldctxt->loadsubset;
                   12857:     if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
                   12858:        /*
                   12859:         * ID/IDREF registration will be done in xmlValidateElement below
                   12860:         */
                   12861:        ctxt->loadsubset |= XML_SKIP_IDS;
                   12862:     }
                   12863:     ctxt->dictNames = oldctxt->dictNames;
                   12864:     ctxt->attsDefault = oldctxt->attsDefault;
                   12865:     ctxt->attsSpecial = oldctxt->attsSpecial;
                   12866: 
                   12867:     xmlParseContent(ctxt);
                   12868:     if ((RAW == '<') && (NXT(1) == '/')) {
                   12869:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12870:     } else if (RAW != 0) {
                   12871:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   12872:     }
                   12873:     if (ctxt->node != ctxt->myDoc->children) {
                   12874:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   12875:     }
                   12876: 
                   12877:     if (!ctxt->wellFormed) {
                   12878:         if (ctxt->errNo == 0)
                   12879:            ret = XML_ERR_INTERNAL_ERROR;
                   12880:        else
                   12881:            ret = (xmlParserErrors)ctxt->errNo;
                   12882:     } else {
                   12883:       ret = XML_ERR_OK;
                   12884:     }
                   12885: 
                   12886:     if ((lst != NULL) && (ret == XML_ERR_OK)) {
                   12887:        xmlNodePtr cur;
                   12888: 
                   12889:        /*
                   12890:         * Return the newly created nodeset after unlinking it from
                   12891:         * they pseudo parent.
                   12892:         */
                   12893:        cur = ctxt->myDoc->children->children;
                   12894:        *lst = cur;
                   12895:        while (cur != NULL) {
                   12896: #ifdef LIBXML_VALID_ENABLED
                   12897:            if ((oldctxt->validate) && (oldctxt->wellFormed) &&
                   12898:                (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
                   12899:                (cur->type == XML_ELEMENT_NODE)) {
                   12900:                oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
                   12901:                        oldctxt->myDoc, cur);
                   12902:            }
                   12903: #endif /* LIBXML_VALID_ENABLED */
                   12904:            cur->parent = NULL;
                   12905:            cur = cur->next;
                   12906:        }
                   12907:        ctxt->myDoc->children->children = NULL;
                   12908:     }
                   12909:     if (ctxt->myDoc != NULL) {
                   12910:        xmlFreeNode(ctxt->myDoc->children);
                   12911:         ctxt->myDoc->children = content;
                   12912:         ctxt->myDoc->last = last;
                   12913:     }
                   12914: 
                   12915:     /*
                   12916:      * Record in the parent context the number of entities replacement
                   12917:      * done when parsing that reference.
                   12918:      */
                   12919:     if (oldctxt != NULL)
                   12920:         oldctxt->nbentities += ctxt->nbentities;
                   12921: 
                   12922:     /*
                   12923:      * Also record the last error if any
                   12924:      */
                   12925:     if (ctxt->lastError.code != XML_ERR_OK)
                   12926:         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
                   12927: 
                   12928:     ctxt->sax = oldsax;
                   12929:     ctxt->dict = NULL;
                   12930:     ctxt->attsDefault = NULL;
                   12931:     ctxt->attsSpecial = NULL;
                   12932:     xmlFreeParserCtxt(ctxt);
                   12933:     if (newDoc != NULL) {
                   12934:        xmlFreeDoc(newDoc);
                   12935:     }
                   12936: 
                   12937:     return(ret);
                   12938: }
                   12939: 
                   12940: /**
                   12941:  * xmlParseInNodeContext:
                   12942:  * @node:  the context node
                   12943:  * @data:  the input string
                   12944:  * @datalen:  the input string length in bytes
                   12945:  * @options:  a combination of xmlParserOption
                   12946:  * @lst:  the return value for the set of parsed nodes
                   12947:  *
                   12948:  * Parse a well-balanced chunk of an XML document
                   12949:  * within the context (DTD, namespaces, etc ...) of the given node.
                   12950:  *
                   12951:  * The allowed sequence for the data is a Well Balanced Chunk defined by
                   12952:  * the content production in the XML grammar:
                   12953:  *
                   12954:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   12955:  *
                   12956:  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
                   12957:  * error code otherwise
                   12958:  */
                   12959: xmlParserErrors
                   12960: xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
                   12961:                       int options, xmlNodePtr *lst) {
                   12962: #ifdef SAX2
                   12963:     xmlParserCtxtPtr ctxt;
                   12964:     xmlDocPtr doc = NULL;
                   12965:     xmlNodePtr fake, cur;
                   12966:     int nsnr = 0;
                   12967: 
                   12968:     xmlParserErrors ret = XML_ERR_OK;
                   12969: 
                   12970:     /*
                   12971:      * check all input parameters, grab the document
                   12972:      */
                   12973:     if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
                   12974:         return(XML_ERR_INTERNAL_ERROR);
                   12975:     switch (node->type) {
                   12976:         case XML_ELEMENT_NODE:
                   12977:         case XML_ATTRIBUTE_NODE:
                   12978:         case XML_TEXT_NODE:
                   12979:         case XML_CDATA_SECTION_NODE:
                   12980:         case XML_ENTITY_REF_NODE:
                   12981:         case XML_PI_NODE:
                   12982:         case XML_COMMENT_NODE:
                   12983:         case XML_DOCUMENT_NODE:
                   12984:         case XML_HTML_DOCUMENT_NODE:
                   12985:            break;
                   12986:        default:
                   12987:            return(XML_ERR_INTERNAL_ERROR);
                   12988: 
                   12989:     }
                   12990:     while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
                   12991:            (node->type != XML_DOCUMENT_NODE) &&
                   12992:           (node->type != XML_HTML_DOCUMENT_NODE))
                   12993:        node = node->parent;
                   12994:     if (node == NULL)
                   12995:        return(XML_ERR_INTERNAL_ERROR);
                   12996:     if (node->type == XML_ELEMENT_NODE)
                   12997:        doc = node->doc;
                   12998:     else
                   12999:         doc = (xmlDocPtr) node;
                   13000:     if (doc == NULL)
                   13001:        return(XML_ERR_INTERNAL_ERROR);
                   13002: 
                   13003:     /*
                   13004:      * allocate a context and set-up everything not related to the
                   13005:      * node position in the tree
                   13006:      */
                   13007:     if (doc->type == XML_DOCUMENT_NODE)
                   13008:        ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
                   13009: #ifdef LIBXML_HTML_ENABLED
                   13010:     else if (doc->type == XML_HTML_DOCUMENT_NODE) {
                   13011:        ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
                   13012:         /*
                   13013:          * When parsing in context, it makes no sense to add implied
                   13014:          * elements like html/body/etc...
                   13015:          */
                   13016:         options |= HTML_PARSE_NOIMPLIED;
                   13017:     }
                   13018: #endif
                   13019:     else
                   13020:         return(XML_ERR_INTERNAL_ERROR);
                   13021: 
                   13022:     if (ctxt == NULL)
                   13023:         return(XML_ERR_NO_MEMORY);
                   13024: 
                   13025:     /*
                   13026:      * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
                   13027:      * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
                   13028:      * we must wait until the last moment to free the original one.
                   13029:      */
                   13030:     if (doc->dict != NULL) {
                   13031:         if (ctxt->dict != NULL)
                   13032:            xmlDictFree(ctxt->dict);
                   13033:        ctxt->dict = doc->dict;
                   13034:     } else
                   13035:         options |= XML_PARSE_NODICT;
                   13036: 
                   13037:     if (doc->encoding != NULL) {
                   13038:         xmlCharEncodingHandlerPtr hdlr;
                   13039: 
                   13040:         if (ctxt->encoding != NULL)
                   13041:            xmlFree((xmlChar *) ctxt->encoding);
                   13042:         ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
                   13043: 
                   13044:         hdlr = xmlFindCharEncodingHandler(doc->encoding);
                   13045:         if (hdlr != NULL) {
                   13046:             xmlSwitchToEncoding(ctxt, hdlr);
                   13047:        } else {
                   13048:             return(XML_ERR_UNSUPPORTED_ENCODING);
                   13049:         }
                   13050:     }
                   13051: 
                   13052:     xmlCtxtUseOptionsInternal(ctxt, options, NULL);
                   13053:     xmlDetectSAX2(ctxt);
                   13054:     ctxt->myDoc = doc;
                   13055: 
                   13056:     fake = xmlNewComment(NULL);
                   13057:     if (fake == NULL) {
                   13058:         xmlFreeParserCtxt(ctxt);
                   13059:        return(XML_ERR_NO_MEMORY);
                   13060:     }
                   13061:     xmlAddChild(node, fake);
                   13062: 
                   13063:     if (node->type == XML_ELEMENT_NODE) {
                   13064:        nodePush(ctxt, node);
                   13065:        /*
                   13066:         * initialize the SAX2 namespaces stack
                   13067:         */
                   13068:        cur = node;
                   13069:        while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
                   13070:            xmlNsPtr ns = cur->nsDef;
                   13071:            const xmlChar *iprefix, *ihref;
                   13072: 
                   13073:            while (ns != NULL) {
                   13074:                if (ctxt->dict) {
                   13075:                    iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
                   13076:                    ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
                   13077:                } else {
                   13078:                    iprefix = ns->prefix;
                   13079:                    ihref = ns->href;
                   13080:                }
                   13081: 
                   13082:                if (xmlGetNamespace(ctxt, iprefix) == NULL) {
                   13083:                    nsPush(ctxt, iprefix, ihref);
                   13084:                    nsnr++;
                   13085:                }
                   13086:                ns = ns->next;
                   13087:            }
                   13088:            cur = cur->parent;
                   13089:        }
                   13090:        ctxt->instate = XML_PARSER_CONTENT;
                   13091:     }
                   13092: 
                   13093:     if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
                   13094:        /*
                   13095:         * ID/IDREF registration will be done in xmlValidateElement below
                   13096:         */
                   13097:        ctxt->loadsubset |= XML_SKIP_IDS;
                   13098:     }
                   13099: 
                   13100: #ifdef LIBXML_HTML_ENABLED
                   13101:     if (doc->type == XML_HTML_DOCUMENT_NODE)
                   13102:         __htmlParseContent(ctxt);
                   13103:     else
                   13104: #endif
                   13105:        xmlParseContent(ctxt);
                   13106: 
                   13107:     nsPop(ctxt, nsnr);
                   13108:     if ((RAW == '<') && (NXT(1) == '/')) {
                   13109:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   13110:     } else if (RAW != 0) {
                   13111:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   13112:     }
                   13113:     if ((ctxt->node != NULL) && (ctxt->node != node)) {
                   13114:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   13115:        ctxt->wellFormed = 0;
                   13116:     }
                   13117: 
                   13118:     if (!ctxt->wellFormed) {
                   13119:         if (ctxt->errNo == 0)
                   13120:            ret = XML_ERR_INTERNAL_ERROR;
                   13121:        else
                   13122:            ret = (xmlParserErrors)ctxt->errNo;
                   13123:     } else {
                   13124:         ret = XML_ERR_OK;
                   13125:     }
                   13126: 
                   13127:     /*
                   13128:      * Return the newly created nodeset after unlinking it from
                   13129:      * the pseudo sibling.
                   13130:      */
                   13131: 
                   13132:     cur = fake->next;
                   13133:     fake->next = NULL;
                   13134:     node->last = fake;
                   13135: 
                   13136:     if (cur != NULL) {
                   13137:        cur->prev = NULL;
                   13138:     }
                   13139: 
                   13140:     *lst = cur;
                   13141: 
                   13142:     while (cur != NULL) {
                   13143:        cur->parent = NULL;
                   13144:        cur = cur->next;
                   13145:     }
                   13146: 
                   13147:     xmlUnlinkNode(fake);
                   13148:     xmlFreeNode(fake);
                   13149: 
                   13150: 
                   13151:     if (ret != XML_ERR_OK) {
                   13152:         xmlFreeNodeList(*lst);
                   13153:        *lst = NULL;
                   13154:     }
                   13155: 
                   13156:     if (doc->dict != NULL)
                   13157:         ctxt->dict = NULL;
                   13158:     xmlFreeParserCtxt(ctxt);
                   13159: 
                   13160:     return(ret);
                   13161: #else /* !SAX2 */
                   13162:     return(XML_ERR_INTERNAL_ERROR);
                   13163: #endif
                   13164: }
                   13165: 
                   13166: #ifdef LIBXML_SAX1_ENABLED
                   13167: /**
                   13168:  * xmlParseBalancedChunkMemoryRecover:
                   13169:  * @doc:  the document the chunk pertains to
                   13170:  * @sax:  the SAX handler bloc (possibly NULL)
                   13171:  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
                   13172:  * @depth:  Used for loop detection, use 0
                   13173:  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
                   13174:  * @lst:  the return value for the set of parsed nodes
                   13175:  * @recover: return nodes even if the data is broken (use 0)
                   13176:  *
                   13177:  *
                   13178:  * Parse a well-balanced chunk of an XML document
                   13179:  * called by the parser
                   13180:  * The allowed sequence for the Well Balanced Chunk is the one defined by
                   13181:  * the content production in the XML grammar:
                   13182:  *
                   13183:  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
                   13184:  *
                   13185:  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
                   13186:  *    the parser error code otherwise
                   13187:  *
                   13188:  * In case recover is set to 1, the nodelist will not be empty even if
                   13189:  * the parsed chunk is not well balanced, assuming the parsing succeeded to
                   13190:  * some extent.
                   13191:  */
                   13192: int
                   13193: xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
                   13194:      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
                   13195:      int recover) {
                   13196:     xmlParserCtxtPtr ctxt;
                   13197:     xmlDocPtr newDoc;
                   13198:     xmlSAXHandlerPtr oldsax = NULL;
                   13199:     xmlNodePtr content, newRoot;
                   13200:     int size;
                   13201:     int ret = 0;
                   13202: 
                   13203:     if (depth > 40) {
                   13204:        return(XML_ERR_ENTITY_LOOP);
                   13205:     }
                   13206: 
                   13207: 
                   13208:     if (lst != NULL)
                   13209:         *lst = NULL;
                   13210:     if (string == NULL)
                   13211:         return(-1);
                   13212: 
                   13213:     size = xmlStrlen(string);
                   13214: 
                   13215:     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
                   13216:     if (ctxt == NULL) return(-1);
                   13217:     ctxt->userData = ctxt;
                   13218:     if (sax != NULL) {
                   13219:        oldsax = ctxt->sax;
                   13220:         ctxt->sax = sax;
                   13221:        if (user_data != NULL)
                   13222:            ctxt->userData = user_data;
                   13223:     }
                   13224:     newDoc = xmlNewDoc(BAD_CAST "1.0");
                   13225:     if (newDoc == NULL) {
                   13226:        xmlFreeParserCtxt(ctxt);
                   13227:        return(-1);
                   13228:     }
                   13229:     newDoc->properties = XML_DOC_INTERNAL;
                   13230:     if ((doc != NULL) && (doc->dict != NULL)) {
                   13231:         xmlDictFree(ctxt->dict);
                   13232:        ctxt->dict = doc->dict;
                   13233:        xmlDictReference(ctxt->dict);
                   13234:        ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
                   13235:        ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
                   13236:        ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
                   13237:        ctxt->dictNames = 1;
                   13238:     } else {
                   13239:        xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
                   13240:     }
                   13241:     if (doc != NULL) {
                   13242:        newDoc->intSubset = doc->intSubset;
                   13243:        newDoc->extSubset = doc->extSubset;
                   13244:     }
                   13245:     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
                   13246:     if (newRoot == NULL) {
                   13247:        if (sax != NULL)
                   13248:            ctxt->sax = oldsax;
                   13249:        xmlFreeParserCtxt(ctxt);
                   13250:        newDoc->intSubset = NULL;
                   13251:        newDoc->extSubset = NULL;
                   13252:         xmlFreeDoc(newDoc);
                   13253:        return(-1);
                   13254:     }
                   13255:     xmlAddChild((xmlNodePtr) newDoc, newRoot);
                   13256:     nodePush(ctxt, newRoot);
                   13257:     if (doc == NULL) {
                   13258:        ctxt->myDoc = newDoc;
                   13259:     } else {
                   13260:        ctxt->myDoc = newDoc;
                   13261:        newDoc->children->doc = doc;
                   13262:        /* Ensure that doc has XML spec namespace */
                   13263:        xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
                   13264:        newDoc->oldNs = doc->oldNs;
                   13265:     }
                   13266:     ctxt->instate = XML_PARSER_CONTENT;
                   13267:     ctxt->depth = depth;
                   13268: 
                   13269:     /*
                   13270:      * Doing validity checking on chunk doesn't make sense
                   13271:      */
                   13272:     ctxt->validate = 0;
                   13273:     ctxt->loadsubset = 0;
                   13274:     xmlDetectSAX2(ctxt);
                   13275: 
                   13276:     if ( doc != NULL ){
                   13277:         content = doc->children;
                   13278:         doc->children = NULL;
                   13279:         xmlParseContent(ctxt);
                   13280:         doc->children = content;
                   13281:     }
                   13282:     else {
                   13283:         xmlParseContent(ctxt);
                   13284:     }
                   13285:     if ((RAW == '<') && (NXT(1) == '/')) {
                   13286:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   13287:     } else if (RAW != 0) {
                   13288:        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
                   13289:     }
                   13290:     if (ctxt->node != newDoc->children) {
                   13291:        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
                   13292:     }
                   13293: 
                   13294:     if (!ctxt->wellFormed) {
                   13295:         if (ctxt->errNo == 0)
                   13296:            ret = 1;
                   13297:        else
                   13298:            ret = ctxt->errNo;
                   13299:     } else {
                   13300:       ret = 0;
                   13301:     }
                   13302: 
                   13303:     if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
                   13304:        xmlNodePtr cur;
                   13305: 
                   13306:        /*
                   13307:         * Return the newly created nodeset after unlinking it from
                   13308:         * they pseudo parent.
                   13309:         */
                   13310:        cur = newDoc->children->children;
                   13311:        *lst = cur;
                   13312:        while (cur != NULL) {
                   13313:            xmlSetTreeDoc(cur, doc);
                   13314:            cur->parent = NULL;
                   13315:            cur = cur->next;
                   13316:        }
                   13317:        newDoc->children->children = NULL;
                   13318:     }
                   13319: 
                   13320:     if (sax != NULL)
                   13321:        ctxt->sax = oldsax;
                   13322:     xmlFreeParserCtxt(ctxt);
                   13323:     newDoc->intSubset = NULL;
                   13324:     newDoc->extSubset = NULL;
                   13325:     newDoc->oldNs = NULL;
                   13326:     xmlFreeDoc(newDoc);
                   13327: 
                   13328:     return(ret);
                   13329: }
                   13330: 
                   13331: /**
                   13332:  * xmlSAXParseEntity:
                   13333:  * @sax:  the SAX handler block
                   13334:  * @filename:  the filename
                   13335:  *
                   13336:  * parse an XML external entity out of context and build a tree.
                   13337:  * It use the given SAX function block to handle the parsing callback.
                   13338:  * If sax is NULL, fallback to the default DOM tree building routines.
                   13339:  *
                   13340:  * [78] extParsedEnt ::= TextDecl? content
                   13341:  *
                   13342:  * This correspond to a "Well Balanced" chunk
                   13343:  *
                   13344:  * Returns the resulting document tree
                   13345:  */
                   13346: 
                   13347: xmlDocPtr
                   13348: xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
                   13349:     xmlDocPtr ret;
                   13350:     xmlParserCtxtPtr ctxt;
                   13351: 
                   13352:     ctxt = xmlCreateFileParserCtxt(filename);
                   13353:     if (ctxt == NULL) {
                   13354:        return(NULL);
                   13355:     }
                   13356:     if (sax != NULL) {
                   13357:        if (ctxt->sax != NULL)
                   13358:            xmlFree(ctxt->sax);
                   13359:         ctxt->sax = sax;
                   13360:         ctxt->userData = NULL;
                   13361:     }
                   13362: 
                   13363:     xmlParseExtParsedEnt(ctxt);
                   13364: 
                   13365:     if (ctxt->wellFormed)
                   13366:        ret = ctxt->myDoc;
                   13367:     else {
                   13368:         ret = NULL;
                   13369:         xmlFreeDoc(ctxt->myDoc);
                   13370:         ctxt->myDoc = NULL;
                   13371:     }
                   13372:     if (sax != NULL)
                   13373:         ctxt->sax = NULL;
                   13374:     xmlFreeParserCtxt(ctxt);
                   13375: 
                   13376:     return(ret);
                   13377: }
                   13378: 
                   13379: /**
                   13380:  * xmlParseEntity:
                   13381:  * @filename:  the filename
                   13382:  *
                   13383:  * parse an XML external entity out of context and build a tree.
                   13384:  *
                   13385:  * [78] extParsedEnt ::= TextDecl? content
                   13386:  *
                   13387:  * This correspond to a "Well Balanced" chunk
                   13388:  *
                   13389:  * Returns the resulting document tree
                   13390:  */
                   13391: 
                   13392: xmlDocPtr
                   13393: xmlParseEntity(const char *filename) {
                   13394:     return(xmlSAXParseEntity(NULL, filename));
                   13395: }
                   13396: #endif /* LIBXML_SAX1_ENABLED */
                   13397: 
                   13398: /**
                   13399:  * xmlCreateEntityParserCtxtInternal:
                   13400:  * @URL:  the entity URL
                   13401:  * @ID:  the entity PUBLIC ID
                   13402:  * @base:  a possible base for the target URI
                   13403:  * @pctx:  parser context used to set options on new context
                   13404:  *
                   13405:  * Create a parser context for an external entity
                   13406:  * Automatic support for ZLIB/Compress compressed document is provided
                   13407:  * by default if found at compile-time.
                   13408:  *
                   13409:  * Returns the new parser context or NULL
                   13410:  */
                   13411: static xmlParserCtxtPtr
                   13412: xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
                   13413:                          const xmlChar *base, xmlParserCtxtPtr pctx) {
                   13414:     xmlParserCtxtPtr ctxt;
                   13415:     xmlParserInputPtr inputStream;
                   13416:     char *directory = NULL;
                   13417:     xmlChar *uri;
                   13418: 
                   13419:     ctxt = xmlNewParserCtxt();
                   13420:     if (ctxt == NULL) {
                   13421:        return(NULL);
                   13422:     }
                   13423: 
                   13424:     if (pctx != NULL) {
                   13425:         ctxt->options = pctx->options;
                   13426:         ctxt->_private = pctx->_private;
                   13427:     }
                   13428: 
                   13429:     uri = xmlBuildURI(URL, base);
                   13430: 
                   13431:     if (uri == NULL) {
                   13432:        inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
                   13433:        if (inputStream == NULL) {
                   13434:            xmlFreeParserCtxt(ctxt);
                   13435:            return(NULL);
                   13436:        }
                   13437: 
                   13438:        inputPush(ctxt, inputStream);
                   13439: 
                   13440:        if ((ctxt->directory == NULL) && (directory == NULL))
                   13441:            directory = xmlParserGetDirectory((char *)URL);
                   13442:        if ((ctxt->directory == NULL) && (directory != NULL))
                   13443:            ctxt->directory = directory;
                   13444:     } else {
                   13445:        inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
                   13446:        if (inputStream == NULL) {
                   13447:            xmlFree(uri);
                   13448:            xmlFreeParserCtxt(ctxt);
                   13449:            return(NULL);
                   13450:        }
                   13451: 
                   13452:        inputPush(ctxt, inputStream);
                   13453: 
                   13454:        if ((ctxt->directory == NULL) && (directory == NULL))
                   13455:            directory = xmlParserGetDirectory((char *)uri);
                   13456:        if ((ctxt->directory == NULL) && (directory != NULL))
                   13457:            ctxt->directory = directory;
                   13458:        xmlFree(uri);
                   13459:     }
                   13460:     return(ctxt);
                   13461: }
                   13462: 
                   13463: /**
                   13464:  * xmlCreateEntityParserCtxt:
                   13465:  * @URL:  the entity URL
                   13466:  * @ID:  the entity PUBLIC ID
                   13467:  * @base:  a possible base for the target URI
                   13468:  *
                   13469:  * Create a parser context for an external entity
                   13470:  * Automatic support for ZLIB/Compress compressed document is provided
                   13471:  * by default if found at compile-time.
                   13472:  *
                   13473:  * Returns the new parser context or NULL
                   13474:  */
                   13475: xmlParserCtxtPtr
                   13476: xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
                   13477:                          const xmlChar *base) {
                   13478:     return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
                   13479: 
                   13480: }
                   13481: 
                   13482: /************************************************************************
                   13483:  *                                                                     *
                   13484:  *             Front ends when parsing from a file                     *
                   13485:  *                                                                     *
                   13486:  ************************************************************************/
                   13487: 
                   13488: /**
                   13489:  * xmlCreateURLParserCtxt:
                   13490:  * @filename:  the filename or URL
                   13491:  * @options:  a combination of xmlParserOption
                   13492:  *
                   13493:  * Create a parser context for a file or URL content. 
                   13494:  * Automatic support for ZLIB/Compress compressed document is provided
                   13495:  * by default if found at compile-time and for file accesses
                   13496:  *
                   13497:  * Returns the new parser context or NULL
                   13498:  */
                   13499: xmlParserCtxtPtr
                   13500: xmlCreateURLParserCtxt(const char *filename, int options)
                   13501: {
                   13502:     xmlParserCtxtPtr ctxt;
                   13503:     xmlParserInputPtr inputStream;
                   13504:     char *directory = NULL;
                   13505: 
                   13506:     ctxt = xmlNewParserCtxt();
                   13507:     if (ctxt == NULL) {
                   13508:        xmlErrMemory(NULL, "cannot allocate parser context");
                   13509:        return(NULL);
                   13510:     }
                   13511: 
                   13512:     if (options)
                   13513:        xmlCtxtUseOptionsInternal(ctxt, options, NULL);
                   13514:     ctxt->linenumbers = 1;
                   13515: 
                   13516:     inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
                   13517:     if (inputStream == NULL) {
                   13518:        xmlFreeParserCtxt(ctxt);
                   13519:        return(NULL);
                   13520:     }
                   13521: 
                   13522:     inputPush(ctxt, inputStream);
                   13523:     if ((ctxt->directory == NULL) && (directory == NULL))
                   13524:         directory = xmlParserGetDirectory(filename);
                   13525:     if ((ctxt->directory == NULL) && (directory != NULL))
                   13526:         ctxt->directory = directory;
                   13527: 
                   13528:     return(ctxt);
                   13529: }
                   13530: 
                   13531: /**
                   13532:  * xmlCreateFileParserCtxt:
                   13533:  * @filename:  the filename
                   13534:  *
                   13535:  * Create a parser context for a file content. 
                   13536:  * Automatic support for ZLIB/Compress compressed document is provided
                   13537:  * by default if found at compile-time.
                   13538:  *
                   13539:  * Returns the new parser context or NULL
                   13540:  */
                   13541: xmlParserCtxtPtr
                   13542: xmlCreateFileParserCtxt(const char *filename)
                   13543: {
                   13544:     return(xmlCreateURLParserCtxt(filename, 0));
                   13545: }
                   13546: 
                   13547: #ifdef LIBXML_SAX1_ENABLED
                   13548: /**
                   13549:  * xmlSAXParseFileWithData:
                   13550:  * @sax:  the SAX handler block
                   13551:  * @filename:  the filename
                   13552:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
                   13553:  *             documents
                   13554:  * @data:  the userdata
                   13555:  *
                   13556:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   13557:  * compressed document is provided by default if found at compile-time.
                   13558:  * It use the given SAX function block to handle the parsing callback.
                   13559:  * If sax is NULL, fallback to the default DOM tree building routines.
                   13560:  *
                   13561:  * User data (void *) is stored within the parser context in the
                   13562:  * context's _private member, so it is available nearly everywhere in libxml
                   13563:  *
                   13564:  * Returns the resulting document tree
                   13565:  */
                   13566: 
                   13567: xmlDocPtr
                   13568: xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
                   13569:                         int recovery, void *data) {
                   13570:     xmlDocPtr ret;
                   13571:     xmlParserCtxtPtr ctxt;
                   13572: 
                   13573:     xmlInitParser();
                   13574: 
                   13575:     ctxt = xmlCreateFileParserCtxt(filename);
                   13576:     if (ctxt == NULL) {
                   13577:        return(NULL);
                   13578:     }
                   13579:     if (sax != NULL) {
                   13580:        if (ctxt->sax != NULL)
                   13581:            xmlFree(ctxt->sax);
                   13582:         ctxt->sax = sax;
                   13583:     }
                   13584:     xmlDetectSAX2(ctxt);
                   13585:     if (data!=NULL) {
                   13586:        ctxt->_private = data;
                   13587:     }
                   13588: 
                   13589:     if (ctxt->directory == NULL)
                   13590:         ctxt->directory = xmlParserGetDirectory(filename);
                   13591: 
                   13592:     ctxt->recovery = recovery;
                   13593: 
                   13594:     xmlParseDocument(ctxt);
                   13595: 
                   13596:     if ((ctxt->wellFormed) || recovery) {
                   13597:         ret = ctxt->myDoc;
                   13598:        if (ret != NULL) {
                   13599:            if (ctxt->input->buf->compressed > 0)
                   13600:                ret->compression = 9;
                   13601:            else
                   13602:                ret->compression = ctxt->input->buf->compressed;
                   13603:        }
                   13604:     }
                   13605:     else {
                   13606:        ret = NULL;
                   13607:        xmlFreeDoc(ctxt->myDoc);
                   13608:        ctxt->myDoc = NULL;
                   13609:     }
                   13610:     if (sax != NULL)
                   13611:         ctxt->sax = NULL;
                   13612:     xmlFreeParserCtxt(ctxt);
                   13613:     
                   13614:     return(ret);
                   13615: }
                   13616: 
                   13617: /**
                   13618:  * xmlSAXParseFile:
                   13619:  * @sax:  the SAX handler block
                   13620:  * @filename:  the filename
                   13621:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
                   13622:  *             documents
                   13623:  *
                   13624:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   13625:  * compressed document is provided by default if found at compile-time.
                   13626:  * It use the given SAX function block to handle the parsing callback.
                   13627:  * If sax is NULL, fallback to the default DOM tree building routines.
                   13628:  *
                   13629:  * Returns the resulting document tree
                   13630:  */
                   13631: 
                   13632: xmlDocPtr
                   13633: xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
                   13634:                           int recovery) {
                   13635:     return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
                   13636: }
                   13637: 
                   13638: /**
                   13639:  * xmlRecoverDoc:
                   13640:  * @cur:  a pointer to an array of xmlChar
                   13641:  *
                   13642:  * parse an XML in-memory document and build a tree.
                   13643:  * In the case the document is not Well Formed, a attempt to build a
                   13644:  * tree is tried anyway
                   13645:  *
                   13646:  * Returns the resulting document tree or NULL in case of failure
                   13647:  */
                   13648: 
                   13649: xmlDocPtr
                   13650: xmlRecoverDoc(const xmlChar *cur) {
                   13651:     return(xmlSAXParseDoc(NULL, cur, 1));
                   13652: }
                   13653: 
                   13654: /**
                   13655:  * xmlParseFile:
                   13656:  * @filename:  the filename
                   13657:  *
                   13658:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   13659:  * compressed document is provided by default if found at compile-time.
                   13660:  *
                   13661:  * Returns the resulting document tree if the file was wellformed,
                   13662:  * NULL otherwise.
                   13663:  */
                   13664: 
                   13665: xmlDocPtr
                   13666: xmlParseFile(const char *filename) {
                   13667:     return(xmlSAXParseFile(NULL, filename, 0));
                   13668: }
                   13669: 
                   13670: /**
                   13671:  * xmlRecoverFile:
                   13672:  * @filename:  the filename
                   13673:  *
                   13674:  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
                   13675:  * compressed document is provided by default if found at compile-time.
                   13676:  * In the case the document is not Well Formed, it attempts to build
                   13677:  * a tree anyway
                   13678:  *
                   13679:  * Returns the resulting document tree or NULL in case of failure
                   13680:  */
                   13681: 
                   13682: xmlDocPtr
                   13683: xmlRecoverFile(const char *filename) {
                   13684:     return(xmlSAXParseFile(NULL, filename, 1));
                   13685: }
                   13686: 
                   13687: 
                   13688: /**
                   13689:  * xmlSetupParserForBuffer:
                   13690:  * @ctxt:  an XML parser context
                   13691:  * @buffer:  a xmlChar * buffer
                   13692:  * @filename:  a file name
                   13693:  *
                   13694:  * Setup the parser context to parse a new buffer; Clears any prior
                   13695:  * contents from the parser context. The buffer parameter must not be
                   13696:  * NULL, but the filename parameter can be
                   13697:  */
                   13698: void
                   13699: xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
                   13700:                              const char* filename)
                   13701: {
                   13702:     xmlParserInputPtr input;
                   13703: 
                   13704:     if ((ctxt == NULL) || (buffer == NULL))
                   13705:         return;
                   13706: 
                   13707:     input = xmlNewInputStream(ctxt);
                   13708:     if (input == NULL) {
                   13709:         xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
                   13710:         xmlClearParserCtxt(ctxt);
                   13711:         return;
                   13712:     }
                   13713:   
                   13714:     xmlClearParserCtxt(ctxt);
                   13715:     if (filename != NULL)
                   13716:         input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
                   13717:     input->base = buffer;
                   13718:     input->cur = buffer;
                   13719:     input->end = &buffer[xmlStrlen(buffer)];
                   13720:     inputPush(ctxt, input);
                   13721: }
                   13722: 
                   13723: /**
                   13724:  * xmlSAXUserParseFile:
                   13725:  * @sax:  a SAX handler
                   13726:  * @user_data:  The user data returned on SAX callbacks
                   13727:  * @filename:  a file name
                   13728:  *
                   13729:  * parse an XML file and call the given SAX handler routines.
                   13730:  * Automatic support for ZLIB/Compress compressed document is provided
                   13731:  * 
                   13732:  * Returns 0 in case of success or a error number otherwise
                   13733:  */
                   13734: int
                   13735: xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
                   13736:                     const char *filename) {
                   13737:     int ret = 0;
                   13738:     xmlParserCtxtPtr ctxt;
                   13739:     
                   13740:     ctxt = xmlCreateFileParserCtxt(filename);
                   13741:     if (ctxt == NULL) return -1;
                   13742:     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
                   13743:        xmlFree(ctxt->sax);
                   13744:     ctxt->sax = sax;
                   13745:     xmlDetectSAX2(ctxt);
                   13746: 
                   13747:     if (user_data != NULL)
                   13748:        ctxt->userData = user_data;
                   13749:     
                   13750:     xmlParseDocument(ctxt);
                   13751:     
                   13752:     if (ctxt->wellFormed)
                   13753:        ret = 0;
                   13754:     else {
                   13755:         if (ctxt->errNo != 0)
                   13756:            ret = ctxt->errNo;
                   13757:        else
                   13758:            ret = -1;
                   13759:     }
                   13760:     if (sax != NULL)
                   13761:        ctxt->sax = NULL;
                   13762:     if (ctxt->myDoc != NULL) {
                   13763:         xmlFreeDoc(ctxt->myDoc);
                   13764:        ctxt->myDoc = NULL;
                   13765:     }
                   13766:     xmlFreeParserCtxt(ctxt);
                   13767:     
                   13768:     return ret;
                   13769: }
                   13770: #endif /* LIBXML_SAX1_ENABLED */
                   13771: 
                   13772: /************************************************************************
                   13773:  *                                                                     *
                   13774:  *             Front ends when parsing from memory                     *
                   13775:  *                                                                     *
                   13776:  ************************************************************************/
                   13777: 
                   13778: /**
                   13779:  * xmlCreateMemoryParserCtxt:
                   13780:  * @buffer:  a pointer to a char array
                   13781:  * @size:  the size of the array
                   13782:  *
                   13783:  * Create a parser context for an XML in-memory document.
                   13784:  *
                   13785:  * Returns the new parser context or NULL
                   13786:  */
                   13787: xmlParserCtxtPtr
                   13788: xmlCreateMemoryParserCtxt(const char *buffer, int size) {
                   13789:     xmlParserCtxtPtr ctxt;
                   13790:     xmlParserInputPtr input;
                   13791:     xmlParserInputBufferPtr buf;
                   13792: 
                   13793:     if (buffer == NULL)
                   13794:        return(NULL);
                   13795:     if (size <= 0)
                   13796:        return(NULL);
                   13797: 
                   13798:     ctxt = xmlNewParserCtxt();
                   13799:     if (ctxt == NULL)
                   13800:        return(NULL);
                   13801: 
                   13802:     /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
                   13803:     buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
                   13804:     if (buf == NULL) {
                   13805:        xmlFreeParserCtxt(ctxt);
                   13806:        return(NULL);
                   13807:     }
                   13808: 
                   13809:     input = xmlNewInputStream(ctxt);
                   13810:     if (input == NULL) {
                   13811:        xmlFreeParserInputBuffer(buf);
                   13812:        xmlFreeParserCtxt(ctxt);
                   13813:        return(NULL);
                   13814:     }
                   13815: 
                   13816:     input->filename = NULL;
                   13817:     input->buf = buf;
                   13818:     input->base = input->buf->buffer->content;
                   13819:     input->cur = input->buf->buffer->content;
                   13820:     input->end = &input->buf->buffer->content[input->buf->buffer->use];
                   13821: 
                   13822:     inputPush(ctxt, input);
                   13823:     return(ctxt);
                   13824: }
                   13825: 
                   13826: #ifdef LIBXML_SAX1_ENABLED
                   13827: /**
                   13828:  * xmlSAXParseMemoryWithData:
                   13829:  * @sax:  the SAX handler block
                   13830:  * @buffer:  an pointer to a char array
                   13831:  * @size:  the size of the array
                   13832:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
                   13833:  *             documents
                   13834:  * @data:  the userdata
                   13835:  *
                   13836:  * parse an XML in-memory block and use the given SAX function block
                   13837:  * to handle the parsing callback. If sax is NULL, fallback to the default
                   13838:  * DOM tree building routines.
                   13839:  *
                   13840:  * User data (void *) is stored within the parser context in the
                   13841:  * context's _private member, so it is available nearly everywhere in libxml
                   13842:  *
                   13843:  * Returns the resulting document tree
                   13844:  */
                   13845: 
                   13846: xmlDocPtr
                   13847: xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
                   13848:                  int size, int recovery, void *data) {
                   13849:     xmlDocPtr ret;
                   13850:     xmlParserCtxtPtr ctxt;
                   13851: 
                   13852:     xmlInitParser();
                   13853: 
                   13854:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
                   13855:     if (ctxt == NULL) return(NULL);
                   13856:     if (sax != NULL) {
                   13857:        if (ctxt->sax != NULL)
                   13858:            xmlFree(ctxt->sax);
                   13859:         ctxt->sax = sax;
                   13860:     }
                   13861:     xmlDetectSAX2(ctxt);
                   13862:     if (data!=NULL) {
                   13863:        ctxt->_private=data;
                   13864:     }
                   13865: 
                   13866:     ctxt->recovery = recovery;
                   13867: 
                   13868:     xmlParseDocument(ctxt);
                   13869: 
                   13870:     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
                   13871:     else {
                   13872:        ret = NULL;
                   13873:        xmlFreeDoc(ctxt->myDoc);
                   13874:        ctxt->myDoc = NULL;
                   13875:     }
                   13876:     if (sax != NULL) 
                   13877:        ctxt->sax = NULL;
                   13878:     xmlFreeParserCtxt(ctxt);
                   13879: 
                   13880:     return(ret);
                   13881: }
                   13882: 
                   13883: /**
                   13884:  * xmlSAXParseMemory:
                   13885:  * @sax:  the SAX handler block
                   13886:  * @buffer:  an pointer to a char array
                   13887:  * @size:  the size of the array
                   13888:  * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
                   13889:  *             documents
                   13890:  *
                   13891:  * parse an XML in-memory block and use the given SAX function block
                   13892:  * to handle the parsing callback. If sax is NULL, fallback to the default
                   13893:  * DOM tree building routines.
                   13894:  * 
                   13895:  * Returns the resulting document tree
                   13896:  */
                   13897: xmlDocPtr
                   13898: xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
                   13899:                  int size, int recovery) {
                   13900:     return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
                   13901: }
                   13902: 
                   13903: /**
                   13904:  * xmlParseMemory:
                   13905:  * @buffer:  an pointer to a char array
                   13906:  * @size:  the size of the array
                   13907:  *
                   13908:  * parse an XML in-memory block and build a tree.
                   13909:  * 
                   13910:  * Returns the resulting document tree
                   13911:  */
                   13912: 
                   13913: xmlDocPtr xmlParseMemory(const char *buffer, int size) {
                   13914:    return(xmlSAXParseMemory(NULL, buffer, size, 0));
                   13915: }
                   13916: 
                   13917: /**
                   13918:  * xmlRecoverMemory:
                   13919:  * @buffer:  an pointer to a char array
                   13920:  * @size:  the size of the array
                   13921:  *
                   13922:  * parse an XML in-memory block and build a tree.
                   13923:  * In the case the document is not Well Formed, an attempt to
                   13924:  * build a tree is tried anyway
                   13925:  *
                   13926:  * Returns the resulting document tree or NULL in case of error
                   13927:  */
                   13928: 
                   13929: xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
                   13930:    return(xmlSAXParseMemory(NULL, buffer, size, 1));
                   13931: }
                   13932: 
                   13933: /**
                   13934:  * xmlSAXUserParseMemory:
                   13935:  * @sax:  a SAX handler
                   13936:  * @user_data:  The user data returned on SAX callbacks
                   13937:  * @buffer:  an in-memory XML document input
                   13938:  * @size:  the length of the XML document in bytes
                   13939:  *
                   13940:  * A better SAX parsing routine.
                   13941:  * parse an XML in-memory buffer and call the given SAX handler routines.
                   13942:  *
                   13943:  * Returns 0 in case of success or a error number otherwise
                   13944:  */
                   13945: int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
                   13946:                          const char *buffer, int size) {
                   13947:     int ret = 0;
                   13948:     xmlParserCtxtPtr ctxt;
                   13949: 
                   13950:     xmlInitParser();
                   13951: 
                   13952:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
                   13953:     if (ctxt == NULL) return -1;
                   13954:     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
                   13955:         xmlFree(ctxt->sax);
                   13956:     ctxt->sax = sax;
                   13957:     xmlDetectSAX2(ctxt);
                   13958: 
                   13959:     if (user_data != NULL)
                   13960:        ctxt->userData = user_data;
                   13961: 
                   13962:     xmlParseDocument(ctxt);
                   13963:     
                   13964:     if (ctxt->wellFormed)
                   13965:        ret = 0;
                   13966:     else {
                   13967:         if (ctxt->errNo != 0)
                   13968:            ret = ctxt->errNo;
                   13969:        else
                   13970:            ret = -1;
                   13971:     }
                   13972:     if (sax != NULL)
                   13973:         ctxt->sax = NULL;
                   13974:     if (ctxt->myDoc != NULL) {
                   13975:         xmlFreeDoc(ctxt->myDoc);
                   13976:        ctxt->myDoc = NULL;
                   13977:     }
                   13978:     xmlFreeParserCtxt(ctxt);
                   13979:     
                   13980:     return ret;
                   13981: }
                   13982: #endif /* LIBXML_SAX1_ENABLED */
                   13983: 
                   13984: /**
                   13985:  * xmlCreateDocParserCtxt:
                   13986:  * @cur:  a pointer to an array of xmlChar
                   13987:  *
                   13988:  * Creates a parser context for an XML in-memory document.
                   13989:  *
                   13990:  * Returns the new parser context or NULL
                   13991:  */
                   13992: xmlParserCtxtPtr
                   13993: xmlCreateDocParserCtxt(const xmlChar *cur) {
                   13994:     int len;
                   13995: 
                   13996:     if (cur == NULL)
                   13997:        return(NULL);
                   13998:     len = xmlStrlen(cur);
                   13999:     return(xmlCreateMemoryParserCtxt((const char *)cur, len));
                   14000: }
                   14001: 
                   14002: #ifdef LIBXML_SAX1_ENABLED
                   14003: /**
                   14004:  * xmlSAXParseDoc:
                   14005:  * @sax:  the SAX handler block
                   14006:  * @cur:  a pointer to an array of xmlChar
                   14007:  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
                   14008:  *             documents
                   14009:  *
                   14010:  * parse an XML in-memory document and build a tree.
                   14011:  * It use the given SAX function block to handle the parsing callback.
                   14012:  * If sax is NULL, fallback to the default DOM tree building routines.
                   14013:  * 
                   14014:  * Returns the resulting document tree
                   14015:  */
                   14016: 
                   14017: xmlDocPtr
                   14018: xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
                   14019:     xmlDocPtr ret;
                   14020:     xmlParserCtxtPtr ctxt;
                   14021:     xmlSAXHandlerPtr oldsax = NULL;
                   14022: 
                   14023:     if (cur == NULL) return(NULL);
                   14024: 
                   14025: 
                   14026:     ctxt = xmlCreateDocParserCtxt(cur);
                   14027:     if (ctxt == NULL) return(NULL);
                   14028:     if (sax != NULL) { 
                   14029:         oldsax = ctxt->sax;
                   14030:         ctxt->sax = sax;
                   14031:         ctxt->userData = NULL;
                   14032:     }
                   14033:     xmlDetectSAX2(ctxt);
                   14034: 
                   14035:     xmlParseDocument(ctxt);
                   14036:     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
                   14037:     else {
                   14038:        ret = NULL;
                   14039:        xmlFreeDoc(ctxt->myDoc);
                   14040:        ctxt->myDoc = NULL;
                   14041:     }
                   14042:     if (sax != NULL)
                   14043:        ctxt->sax = oldsax;
                   14044:     xmlFreeParserCtxt(ctxt);
                   14045:     
                   14046:     return(ret);
                   14047: }
                   14048: 
                   14049: /**
                   14050:  * xmlParseDoc:
                   14051:  * @cur:  a pointer to an array of xmlChar
                   14052:  *
                   14053:  * parse an XML in-memory document and build a tree.
                   14054:  * 
                   14055:  * Returns the resulting document tree
                   14056:  */
                   14057: 
                   14058: xmlDocPtr
                   14059: xmlParseDoc(const xmlChar *cur) {
                   14060:     return(xmlSAXParseDoc(NULL, cur, 0));
                   14061: }
                   14062: #endif /* LIBXML_SAX1_ENABLED */
                   14063: 
                   14064: #ifdef LIBXML_LEGACY_ENABLED
                   14065: /************************************************************************
                   14066:  *                                                                     *
                   14067:  *     Specific function to keep track of entities references          *
                   14068:  *     and used by the XSLT debugger                                   *
                   14069:  *                                                                     *
                   14070:  ************************************************************************/
                   14071: 
                   14072: static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
                   14073: 
                   14074: /**
                   14075:  * xmlAddEntityReference:
                   14076:  * @ent : A valid entity
                   14077:  * @firstNode : A valid first node for children of entity
                   14078:  * @lastNode : A valid last node of children entity 
                   14079:  *
                   14080:  * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
                   14081:  */
                   14082: static void
                   14083: xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
                   14084:                       xmlNodePtr lastNode)
                   14085: {
                   14086:     if (xmlEntityRefFunc != NULL) {
                   14087:         (*xmlEntityRefFunc) (ent, firstNode, lastNode);
                   14088:     }
                   14089: }
                   14090: 
                   14091: 
                   14092: /**
                   14093:  * xmlSetEntityReferenceFunc:
                   14094:  * @func: A valid function
                   14095:  *
                   14096:  * Set the function to call call back when a xml reference has been made
                   14097:  */
                   14098: void
                   14099: xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
                   14100: {
                   14101:     xmlEntityRefFunc = func;
                   14102: }
                   14103: #endif /* LIBXML_LEGACY_ENABLED */
                   14104: 
                   14105: /************************************************************************
                   14106:  *                                                                     *
                   14107:  *                             Miscellaneous                           *
                   14108:  *                                                                     *
                   14109:  ************************************************************************/
                   14110: 
                   14111: #ifdef LIBXML_XPATH_ENABLED
                   14112: #include <libxml/xpath.h>
                   14113: #endif
                   14114: 
                   14115: extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
                   14116: static int xmlParserInitialized = 0;
                   14117: 
                   14118: /**
                   14119:  * xmlInitParser:
                   14120:  *
                   14121:  * Initialization function for the XML parser.
                   14122:  * This is not reentrant. Call once before processing in case of
                   14123:  * use in multithreaded programs.
                   14124:  */
                   14125: 
                   14126: void
                   14127: xmlInitParser(void) {
                   14128:     if (xmlParserInitialized != 0)
                   14129:        return;
                   14130: 
                   14131: #ifdef LIBXML_THREAD_ENABLED
                   14132:     __xmlGlobalInitMutexLock();
                   14133:     if (xmlParserInitialized == 0) {
                   14134: #endif
                   14135:        xmlInitThreads();
                   14136:        xmlInitGlobals();
                   14137:        if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
                   14138:            (xmlGenericError == NULL))
                   14139:            initGenericErrorDefaultFunc(NULL);
                   14140:        xmlInitMemory();
                   14141:        xmlInitCharEncodingHandlers();
                   14142:        xmlDefaultSAXHandlerInit();
                   14143:        xmlRegisterDefaultInputCallbacks();
                   14144: #ifdef LIBXML_OUTPUT_ENABLED
                   14145:        xmlRegisterDefaultOutputCallbacks();
                   14146: #endif /* LIBXML_OUTPUT_ENABLED */
                   14147: #ifdef LIBXML_HTML_ENABLED
                   14148:        htmlInitAutoClose();
                   14149:        htmlDefaultSAXHandlerInit();
                   14150: #endif
                   14151: #ifdef LIBXML_XPATH_ENABLED
                   14152:        xmlXPathInit();
                   14153: #endif
                   14154:        xmlParserInitialized = 1;
                   14155: #ifdef LIBXML_THREAD_ENABLED
                   14156:     }
                   14157:     __xmlGlobalInitMutexUnlock();
                   14158: #endif
                   14159: }
                   14160: 
                   14161: /**
                   14162:  * xmlCleanupParser:
                   14163:  *
                   14164:  * This function name is somewhat misleading. It does not clean up
                   14165:  * parser state, it cleans up memory allocated by the library itself.
                   14166:  * It is a cleanup function for the XML library. It tries to reclaim all
                   14167:  * related global memory allocated for the library processing.
                   14168:  * It doesn't deallocate any document related memory. One should
                   14169:  * call xmlCleanupParser() only when the process has finished using
                   14170:  * the library and all XML/HTML documents built with it.
                   14171:  * See also xmlInitParser() which has the opposite function of preparing
                   14172:  * the library for operations.
                   14173:  *
                   14174:  * WARNING: if your application is multithreaded or has plugin support
                   14175:  *          calling this may crash the application if another thread or
                   14176:  *          a plugin is still using libxml2. It's sometimes very hard to
                   14177:  *          guess if libxml2 is in use in the application, some libraries
                   14178:  *          or plugins may use it without notice. In case of doubt abstain
                   14179:  *          from calling this function or do it just before calling exit()
                   14180:  *          to avoid leak reports from valgrind !
                   14181:  */
                   14182: 
                   14183: void
                   14184: xmlCleanupParser(void) {
                   14185:     if (!xmlParserInitialized)
                   14186:        return;
                   14187: 
                   14188:     xmlCleanupCharEncodingHandlers();
                   14189: #ifdef LIBXML_CATALOG_ENABLED
                   14190:     xmlCatalogCleanup();
                   14191: #endif
                   14192:     xmlDictCleanup();
                   14193:     xmlCleanupInputCallbacks();
                   14194: #ifdef LIBXML_OUTPUT_ENABLED
                   14195:     xmlCleanupOutputCallbacks();
                   14196: #endif
                   14197: #ifdef LIBXML_SCHEMAS_ENABLED
                   14198:     xmlSchemaCleanupTypes();
                   14199:     xmlRelaxNGCleanupTypes();
                   14200: #endif
                   14201:     xmlCleanupGlobals();
                   14202:     xmlResetLastError();
                   14203:     xmlCleanupThreads(); /* must be last if called not from the main thread */
                   14204:     xmlCleanupMemory();
                   14205:     xmlParserInitialized = 0;
                   14206: }
                   14207: 
                   14208: /************************************************************************
                   14209:  *                                                                     *
                   14210:  *     New set (2.6.0) of simpler and more flexible APIs               *
                   14211:  *                                                                     *
                   14212:  ************************************************************************/
                   14213: 
                   14214: /**
                   14215:  * DICT_FREE:
                   14216:  * @str:  a string
                   14217:  *
                   14218:  * Free a string if it is not owned by the "dict" dictionnary in the
                   14219:  * current scope
                   14220:  */
                   14221: #define DICT_FREE(str)                                         \
                   14222:        if ((str) && ((!dict) ||                                \
                   14223:            (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
                   14224:            xmlFree((char *)(str));
                   14225: 
                   14226: /**
                   14227:  * xmlCtxtReset:
                   14228:  * @ctxt: an XML parser context
                   14229:  *
                   14230:  * Reset a parser context
                   14231:  */
                   14232: void
                   14233: xmlCtxtReset(xmlParserCtxtPtr ctxt)
                   14234: {
                   14235:     xmlParserInputPtr input;
                   14236:     xmlDictPtr dict;
                   14237:     
                   14238:     if (ctxt == NULL)
                   14239:         return;
                   14240: 
                   14241:     dict = ctxt->dict;
                   14242: 
                   14243:     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
                   14244:         xmlFreeInputStream(input);
                   14245:     }
                   14246:     ctxt->inputNr = 0;
                   14247:     ctxt->input = NULL;
                   14248: 
                   14249:     ctxt->spaceNr = 0;
                   14250:     if (ctxt->spaceTab != NULL) {
                   14251:        ctxt->spaceTab[0] = -1;
                   14252:        ctxt->space = &ctxt->spaceTab[0];
                   14253:     } else {
                   14254:         ctxt->space = NULL;
                   14255:     }
                   14256: 
                   14257: 
                   14258:     ctxt->nodeNr = 0;
                   14259:     ctxt->node = NULL;
                   14260: 
                   14261:     ctxt->nameNr = 0;
                   14262:     ctxt->name = NULL;
                   14263: 
                   14264:     DICT_FREE(ctxt->version);
                   14265:     ctxt->version = NULL;
                   14266:     DICT_FREE(ctxt->encoding);
                   14267:     ctxt->encoding = NULL;
                   14268:     DICT_FREE(ctxt->directory);
                   14269:     ctxt->directory = NULL;
                   14270:     DICT_FREE(ctxt->extSubURI);
                   14271:     ctxt->extSubURI = NULL;
                   14272:     DICT_FREE(ctxt->extSubSystem);
                   14273:     ctxt->extSubSystem = NULL;
                   14274:     if (ctxt->myDoc != NULL)
                   14275:         xmlFreeDoc(ctxt->myDoc);
                   14276:     ctxt->myDoc = NULL;
                   14277: 
                   14278:     ctxt->standalone = -1;
                   14279:     ctxt->hasExternalSubset = 0;
                   14280:     ctxt->hasPErefs = 0;
                   14281:     ctxt->html = 0;
                   14282:     ctxt->external = 0;
                   14283:     ctxt->instate = XML_PARSER_START;
                   14284:     ctxt->token = 0;
                   14285: 
                   14286:     ctxt->wellFormed = 1;
                   14287:     ctxt->nsWellFormed = 1;
                   14288:     ctxt->disableSAX = 0;
                   14289:     ctxt->valid = 1;
                   14290: #if 0
                   14291:     ctxt->vctxt.userData = ctxt;
                   14292:     ctxt->vctxt.error = xmlParserValidityError;
                   14293:     ctxt->vctxt.warning = xmlParserValidityWarning;
                   14294: #endif
                   14295:     ctxt->record_info = 0;
                   14296:     ctxt->nbChars = 0;
                   14297:     ctxt->checkIndex = 0;
                   14298:     ctxt->inSubset = 0;
                   14299:     ctxt->errNo = XML_ERR_OK;
                   14300:     ctxt->depth = 0;
                   14301:     ctxt->charset = XML_CHAR_ENCODING_UTF8;
                   14302:     ctxt->catalogs = NULL;
                   14303:     ctxt->nbentities = 0;
                   14304:     ctxt->sizeentities = 0;
                   14305:     xmlInitNodeInfoSeq(&ctxt->node_seq);
                   14306: 
                   14307:     if (ctxt->attsDefault != NULL) {
                   14308:         xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
                   14309:         ctxt->attsDefault = NULL;
                   14310:     }
                   14311:     if (ctxt->attsSpecial != NULL) {
                   14312:         xmlHashFree(ctxt->attsSpecial, NULL);
                   14313:         ctxt->attsSpecial = NULL;
                   14314:     }
                   14315: 
                   14316: #ifdef LIBXML_CATALOG_ENABLED
                   14317:     if (ctxt->catalogs != NULL)
                   14318:        xmlCatalogFreeLocal(ctxt->catalogs);
                   14319: #endif
                   14320:     if (ctxt->lastError.code != XML_ERR_OK)
                   14321:         xmlResetError(&ctxt->lastError);
                   14322: }
                   14323: 
                   14324: /**
                   14325:  * xmlCtxtResetPush:
                   14326:  * @ctxt: an XML parser context
                   14327:  * @chunk:  a pointer to an array of chars
                   14328:  * @size:  number of chars in the array
                   14329:  * @filename:  an optional file name or URI
                   14330:  * @encoding:  the document encoding, or NULL
                   14331:  *
                   14332:  * Reset a push parser context
                   14333:  *
                   14334:  * Returns 0 in case of success and 1 in case of error
                   14335:  */
                   14336: int
                   14337: xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
                   14338:                  int size, const char *filename, const char *encoding)
                   14339: {
                   14340:     xmlParserInputPtr inputStream;
                   14341:     xmlParserInputBufferPtr buf;
                   14342:     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
                   14343: 
                   14344:     if (ctxt == NULL)
                   14345:         return(1);
                   14346: 
                   14347:     if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
                   14348:         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
                   14349: 
                   14350:     buf = xmlAllocParserInputBuffer(enc);
                   14351:     if (buf == NULL)
                   14352:         return(1);
                   14353: 
                   14354:     if (ctxt == NULL) {
                   14355:         xmlFreeParserInputBuffer(buf);
                   14356:         return(1);
                   14357:     }
                   14358: 
                   14359:     xmlCtxtReset(ctxt);
                   14360: 
                   14361:     if (ctxt->pushTab == NULL) {
                   14362:         ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
                   14363:                                            sizeof(xmlChar *));
                   14364:         if (ctxt->pushTab == NULL) {
                   14365:            xmlErrMemory(ctxt, NULL);
                   14366:             xmlFreeParserInputBuffer(buf);
                   14367:             return(1);
                   14368:         }
                   14369:     }
                   14370: 
                   14371:     if (filename == NULL) {
                   14372:         ctxt->directory = NULL;
                   14373:     } else {
                   14374:         ctxt->directory = xmlParserGetDirectory(filename);
                   14375:     }
                   14376: 
                   14377:     inputStream = xmlNewInputStream(ctxt);
                   14378:     if (inputStream == NULL) {
                   14379:         xmlFreeParserInputBuffer(buf);
                   14380:         return(1);
                   14381:     }
                   14382: 
                   14383:     if (filename == NULL)
                   14384:         inputStream->filename = NULL;
                   14385:     else
                   14386:         inputStream->filename = (char *)
                   14387:             xmlCanonicPath((const xmlChar *) filename);
                   14388:     inputStream->buf = buf;
                   14389:     inputStream->base = inputStream->buf->buffer->content;
                   14390:     inputStream->cur = inputStream->buf->buffer->content;
                   14391:     inputStream->end =
                   14392:         &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
                   14393: 
                   14394:     inputPush(ctxt, inputStream);
                   14395: 
                   14396:     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
                   14397:         (ctxt->input->buf != NULL)) {
                   14398:         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
                   14399:         int cur = ctxt->input->cur - ctxt->input->base;
                   14400: 
                   14401:         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
                   14402: 
                   14403:         ctxt->input->base = ctxt->input->buf->buffer->content + base;
                   14404:         ctxt->input->cur = ctxt->input->base + cur;
                   14405:         ctxt->input->end =
                   14406:             &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->
                   14407:                                                use];
                   14408: #ifdef DEBUG_PUSH
                   14409:         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
                   14410: #endif
                   14411:     }
                   14412: 
                   14413:     if (encoding != NULL) {
                   14414:         xmlCharEncodingHandlerPtr hdlr;
                   14415: 
                   14416:         if (ctxt->encoding != NULL)
                   14417:            xmlFree((xmlChar *) ctxt->encoding);
                   14418:         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
                   14419: 
                   14420:         hdlr = xmlFindCharEncodingHandler(encoding);
                   14421:         if (hdlr != NULL) {
                   14422:             xmlSwitchToEncoding(ctxt, hdlr);
                   14423:        } else {
                   14424:            xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
                   14425:                              "Unsupported encoding %s\n", BAD_CAST encoding);
                   14426:         }
                   14427:     } else if (enc != XML_CHAR_ENCODING_NONE) {
                   14428:         xmlSwitchEncoding(ctxt, enc);
                   14429:     }
                   14430: 
                   14431:     return(0);
                   14432: }
                   14433: 
                   14434: 
                   14435: /**
                   14436:  * xmlCtxtUseOptionsInternal:
                   14437:  * @ctxt: an XML parser context
                   14438:  * @options:  a combination of xmlParserOption
                   14439:  * @encoding:  the user provided encoding to use
                   14440:  *
                   14441:  * Applies the options to the parser context
                   14442:  *
                   14443:  * Returns 0 in case of success, the set of unknown or unimplemented options
                   14444:  *         in case of error.
                   14445:  */
                   14446: static int
                   14447: xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
                   14448: {
                   14449:     if (ctxt == NULL)
                   14450:         return(-1);
                   14451:     if (encoding != NULL) {
                   14452:         if (ctxt->encoding != NULL)
                   14453:            xmlFree((xmlChar *) ctxt->encoding);
                   14454:         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
                   14455:     }
                   14456:     if (options & XML_PARSE_RECOVER) {
                   14457:         ctxt->recovery = 1;
                   14458:         options -= XML_PARSE_RECOVER;
                   14459:        ctxt->options |= XML_PARSE_RECOVER;
                   14460:     } else
                   14461:         ctxt->recovery = 0;
                   14462:     if (options & XML_PARSE_DTDLOAD) {
                   14463:         ctxt->loadsubset = XML_DETECT_IDS;
                   14464:         options -= XML_PARSE_DTDLOAD;
                   14465:        ctxt->options |= XML_PARSE_DTDLOAD;
                   14466:     } else
                   14467:         ctxt->loadsubset = 0;
                   14468:     if (options & XML_PARSE_DTDATTR) {
                   14469:         ctxt->loadsubset |= XML_COMPLETE_ATTRS;
                   14470:         options -= XML_PARSE_DTDATTR;
                   14471:        ctxt->options |= XML_PARSE_DTDATTR;
                   14472:     }
                   14473:     if (options & XML_PARSE_NOENT) {
                   14474:         ctxt->replaceEntities = 1;
                   14475:         /* ctxt->loadsubset |= XML_DETECT_IDS; */
                   14476:         options -= XML_PARSE_NOENT;
                   14477:        ctxt->options |= XML_PARSE_NOENT;
                   14478:     } else
                   14479:         ctxt->replaceEntities = 0;
                   14480:     if (options & XML_PARSE_PEDANTIC) {
                   14481:         ctxt->pedantic = 1;
                   14482:         options -= XML_PARSE_PEDANTIC;
                   14483:        ctxt->options |= XML_PARSE_PEDANTIC;
                   14484:     } else
                   14485:         ctxt->pedantic = 0;
                   14486:     if (options & XML_PARSE_NOBLANKS) {
                   14487:         ctxt->keepBlanks = 0;
                   14488:         ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
                   14489:         options -= XML_PARSE_NOBLANKS;
                   14490:        ctxt->options |= XML_PARSE_NOBLANKS;
                   14491:     } else
                   14492:         ctxt->keepBlanks = 1;
                   14493:     if (options & XML_PARSE_DTDVALID) {
                   14494:         ctxt->validate = 1;
                   14495:         if (options & XML_PARSE_NOWARNING)
                   14496:             ctxt->vctxt.warning = NULL;
                   14497:         if (options & XML_PARSE_NOERROR)
                   14498:             ctxt->vctxt.error = NULL;
                   14499:         options -= XML_PARSE_DTDVALID;
                   14500:        ctxt->options |= XML_PARSE_DTDVALID;
                   14501:     } else
                   14502:         ctxt->validate = 0;
                   14503:     if (options & XML_PARSE_NOWARNING) {
                   14504:         ctxt->sax->warning = NULL;
                   14505:         options -= XML_PARSE_NOWARNING;
                   14506:     }
                   14507:     if (options & XML_PARSE_NOERROR) {
                   14508:         ctxt->sax->error = NULL;
                   14509:         ctxt->sax->fatalError = NULL;
                   14510:         options -= XML_PARSE_NOERROR;
                   14511:     }
                   14512: #ifdef LIBXML_SAX1_ENABLED
                   14513:     if (options & XML_PARSE_SAX1) {
                   14514:         ctxt->sax->startElement = xmlSAX2StartElement;
                   14515:         ctxt->sax->endElement = xmlSAX2EndElement;
                   14516:         ctxt->sax->startElementNs = NULL;
                   14517:         ctxt->sax->endElementNs = NULL;
                   14518:         ctxt->sax->initialized = 1;
                   14519:         options -= XML_PARSE_SAX1;
                   14520:        ctxt->options |= XML_PARSE_SAX1;
                   14521:     }
                   14522: #endif /* LIBXML_SAX1_ENABLED */
                   14523:     if (options & XML_PARSE_NODICT) {
                   14524:         ctxt->dictNames = 0;
                   14525:         options -= XML_PARSE_NODICT;
                   14526:        ctxt->options |= XML_PARSE_NODICT;
                   14527:     } else {
                   14528:         ctxt->dictNames = 1;
                   14529:     }
                   14530:     if (options & XML_PARSE_NOCDATA) {
                   14531:         ctxt->sax->cdataBlock = NULL;
                   14532:         options -= XML_PARSE_NOCDATA;
                   14533:        ctxt->options |= XML_PARSE_NOCDATA;
                   14534:     }
                   14535:     if (options & XML_PARSE_NSCLEAN) {
                   14536:        ctxt->options |= XML_PARSE_NSCLEAN;
                   14537:         options -= XML_PARSE_NSCLEAN;
                   14538:     }
                   14539:     if (options & XML_PARSE_NONET) {
                   14540:        ctxt->options |= XML_PARSE_NONET;
                   14541:         options -= XML_PARSE_NONET;
                   14542:     }
                   14543:     if (options & XML_PARSE_COMPACT) {
                   14544:        ctxt->options |= XML_PARSE_COMPACT;
                   14545:         options -= XML_PARSE_COMPACT;
                   14546:     }
                   14547:     if (options & XML_PARSE_OLD10) {
                   14548:        ctxt->options |= XML_PARSE_OLD10;
                   14549:         options -= XML_PARSE_OLD10;
                   14550:     }
                   14551:     if (options & XML_PARSE_NOBASEFIX) {
                   14552:        ctxt->options |= XML_PARSE_NOBASEFIX;
                   14553:         options -= XML_PARSE_NOBASEFIX;
                   14554:     }
                   14555:     if (options & XML_PARSE_HUGE) {
                   14556:        ctxt->options |= XML_PARSE_HUGE;
                   14557:         options -= XML_PARSE_HUGE;
                   14558:     }
                   14559:     if (options & XML_PARSE_OLDSAX) {
                   14560:        ctxt->options |= XML_PARSE_OLDSAX;
                   14561:         options -= XML_PARSE_OLDSAX;
                   14562:     }
                   14563:     ctxt->linenumbers = 1;
                   14564:     return (options);
                   14565: }
                   14566: 
                   14567: /**
                   14568:  * xmlCtxtUseOptions:
                   14569:  * @ctxt: an XML parser context
                   14570:  * @options:  a combination of xmlParserOption
                   14571:  *
                   14572:  * Applies the options to the parser context
                   14573:  *
                   14574:  * Returns 0 in case of success, the set of unknown or unimplemented options
                   14575:  *         in case of error.
                   14576:  */
                   14577: int
                   14578: xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
                   14579: {
                   14580:    return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
                   14581: }
                   14582: 
                   14583: /**
                   14584:  * xmlDoRead:
                   14585:  * @ctxt:  an XML parser context
                   14586:  * @URL:  the base URL to use for the document
                   14587:  * @encoding:  the document encoding, or NULL
                   14588:  * @options:  a combination of xmlParserOption
                   14589:  * @reuse:  keep the context for reuse
                   14590:  *
                   14591:  * Common front-end for the xmlRead functions
                   14592:  *
                   14593:  * Returns the resulting document tree or NULL
                   14594:  */
                   14595: static xmlDocPtr
                   14596: xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
                   14597:           int options, int reuse)
                   14598: {
                   14599:     xmlDocPtr ret;
                   14600: 
                   14601:     xmlCtxtUseOptionsInternal(ctxt, options, encoding);
                   14602:     if (encoding != NULL) {
                   14603:         xmlCharEncodingHandlerPtr hdlr;
                   14604: 
                   14605:        hdlr = xmlFindCharEncodingHandler(encoding);
                   14606:        if (hdlr != NULL)
                   14607:            xmlSwitchToEncoding(ctxt, hdlr);
                   14608:     }
                   14609:     if ((URL != NULL) && (ctxt->input != NULL) &&
                   14610:         (ctxt->input->filename == NULL))
                   14611:         ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
                   14612:     xmlParseDocument(ctxt);
                   14613:     if ((ctxt->wellFormed) || ctxt->recovery)
                   14614:         ret = ctxt->myDoc;
                   14615:     else {
                   14616:         ret = NULL;
                   14617:        if (ctxt->myDoc != NULL) {
                   14618:            xmlFreeDoc(ctxt->myDoc);
                   14619:        }
                   14620:     }
                   14621:     ctxt->myDoc = NULL;
                   14622:     if (!reuse) {
                   14623:        xmlFreeParserCtxt(ctxt);
                   14624:     }
                   14625: 
                   14626:     return (ret);
                   14627: }
                   14628: 
                   14629: /**
                   14630:  * xmlReadDoc:
                   14631:  * @cur:  a pointer to a zero terminated string
                   14632:  * @URL:  the base URL to use for the document
                   14633:  * @encoding:  the document encoding, or NULL
                   14634:  * @options:  a combination of xmlParserOption
                   14635:  *
                   14636:  * parse an XML in-memory document and build a tree.
                   14637:  * 
                   14638:  * Returns the resulting document tree
                   14639:  */
                   14640: xmlDocPtr
                   14641: xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
                   14642: {
                   14643:     xmlParserCtxtPtr ctxt;
                   14644: 
                   14645:     if (cur == NULL)
                   14646:         return (NULL);
                   14647: 
                   14648:     ctxt = xmlCreateDocParserCtxt(cur);
                   14649:     if (ctxt == NULL)
                   14650:         return (NULL);
                   14651:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
                   14652: }
                   14653: 
                   14654: /**
                   14655:  * xmlReadFile:
                   14656:  * @filename:  a file or URL
                   14657:  * @encoding:  the document encoding, or NULL
                   14658:  * @options:  a combination of xmlParserOption
                   14659:  *
                   14660:  * parse an XML file from the filesystem or the network.
                   14661:  * 
                   14662:  * Returns the resulting document tree
                   14663:  */
                   14664: xmlDocPtr
                   14665: xmlReadFile(const char *filename, const char *encoding, int options)
                   14666: {
                   14667:     xmlParserCtxtPtr ctxt;
                   14668: 
                   14669:     ctxt = xmlCreateURLParserCtxt(filename, options);
                   14670:     if (ctxt == NULL)
                   14671:         return (NULL);
                   14672:     return (xmlDoRead(ctxt, NULL, encoding, options, 0));
                   14673: }
                   14674: 
                   14675: /**
                   14676:  * xmlReadMemory:
                   14677:  * @buffer:  a pointer to a char array
                   14678:  * @size:  the size of the array
                   14679:  * @URL:  the base URL to use for the document
                   14680:  * @encoding:  the document encoding, or NULL
                   14681:  * @options:  a combination of xmlParserOption
                   14682:  *
                   14683:  * parse an XML in-memory document and build a tree.
                   14684:  * 
                   14685:  * Returns the resulting document tree
                   14686:  */
                   14687: xmlDocPtr
                   14688: xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
                   14689: {
                   14690:     xmlParserCtxtPtr ctxt;
                   14691: 
                   14692:     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
                   14693:     if (ctxt == NULL)
                   14694:         return (NULL);
                   14695:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
                   14696: }
                   14697: 
                   14698: /**
                   14699:  * xmlReadFd:
                   14700:  * @fd:  an open file descriptor
                   14701:  * @URL:  the base URL to use for the document
                   14702:  * @encoding:  the document encoding, or NULL
                   14703:  * @options:  a combination of xmlParserOption
                   14704:  *
                   14705:  * parse an XML from a file descriptor and build a tree.
                   14706:  * NOTE that the file descriptor will not be closed when the
                   14707:  *      reader is closed or reset.
                   14708:  * 
                   14709:  * Returns the resulting document tree
                   14710:  */
                   14711: xmlDocPtr
                   14712: xmlReadFd(int fd, const char *URL, const char *encoding, int options)
                   14713: {
                   14714:     xmlParserCtxtPtr ctxt;
                   14715:     xmlParserInputBufferPtr input;
                   14716:     xmlParserInputPtr stream;
                   14717: 
                   14718:     if (fd < 0)
                   14719:         return (NULL);
                   14720: 
                   14721:     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
                   14722:     if (input == NULL)
                   14723:         return (NULL);
                   14724:     input->closecallback = NULL;
                   14725:     ctxt = xmlNewParserCtxt();
                   14726:     if (ctxt == NULL) {
                   14727:         xmlFreeParserInputBuffer(input);
                   14728:         return (NULL);
                   14729:     }
                   14730:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   14731:     if (stream == NULL) {
                   14732:         xmlFreeParserInputBuffer(input);
                   14733:        xmlFreeParserCtxt(ctxt);
                   14734:         return (NULL);
                   14735:     }
                   14736:     inputPush(ctxt, stream);
                   14737:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
                   14738: }
                   14739: 
                   14740: /**
                   14741:  * xmlReadIO:
                   14742:  * @ioread:  an I/O read function
                   14743:  * @ioclose:  an I/O close function
                   14744:  * @ioctx:  an I/O handler
                   14745:  * @URL:  the base URL to use for the document
                   14746:  * @encoding:  the document encoding, or NULL
                   14747:  * @options:  a combination of xmlParserOption
                   14748:  *
                   14749:  * parse an XML document from I/O functions and source and build a tree.
                   14750:  * 
                   14751:  * Returns the resulting document tree
                   14752:  */
                   14753: xmlDocPtr
                   14754: xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
                   14755:           void *ioctx, const char *URL, const char *encoding, int options)
                   14756: {
                   14757:     xmlParserCtxtPtr ctxt;
                   14758:     xmlParserInputBufferPtr input;
                   14759:     xmlParserInputPtr stream;
                   14760: 
                   14761:     if (ioread == NULL)
                   14762:         return (NULL);
                   14763: 
                   14764:     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
                   14765:                                          XML_CHAR_ENCODING_NONE);
                   14766:     if (input == NULL)
                   14767:         return (NULL);
                   14768:     ctxt = xmlNewParserCtxt();
                   14769:     if (ctxt == NULL) {
                   14770:         xmlFreeParserInputBuffer(input);
                   14771:         return (NULL);
                   14772:     }
                   14773:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   14774:     if (stream == NULL) {
                   14775:         xmlFreeParserInputBuffer(input);
                   14776:        xmlFreeParserCtxt(ctxt);
                   14777:         return (NULL);
                   14778:     }
                   14779:     inputPush(ctxt, stream);
                   14780:     return (xmlDoRead(ctxt, URL, encoding, options, 0));
                   14781: }
                   14782: 
                   14783: /**
                   14784:  * xmlCtxtReadDoc:
                   14785:  * @ctxt:  an XML parser context
                   14786:  * @cur:  a pointer to a zero terminated string
                   14787:  * @URL:  the base URL to use for the document
                   14788:  * @encoding:  the document encoding, or NULL
                   14789:  * @options:  a combination of xmlParserOption
                   14790:  *
                   14791:  * parse an XML in-memory document and build a tree.
                   14792:  * This reuses the existing @ctxt parser context
                   14793:  * 
                   14794:  * Returns the resulting document tree
                   14795:  */
                   14796: xmlDocPtr
                   14797: xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
                   14798:                const char *URL, const char *encoding, int options)
                   14799: {
                   14800:     xmlParserInputPtr stream;
                   14801: 
                   14802:     if (cur == NULL)
                   14803:         return (NULL);
                   14804:     if (ctxt == NULL)
                   14805:         return (NULL);
                   14806: 
                   14807:     xmlCtxtReset(ctxt);
                   14808: 
                   14809:     stream = xmlNewStringInputStream(ctxt, cur);
                   14810:     if (stream == NULL) {
                   14811:         return (NULL);
                   14812:     }
                   14813:     inputPush(ctxt, stream);
                   14814:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
                   14815: }
                   14816: 
                   14817: /**
                   14818:  * xmlCtxtReadFile:
                   14819:  * @ctxt:  an XML parser context
                   14820:  * @filename:  a file or URL
                   14821:  * @encoding:  the document encoding, or NULL
                   14822:  * @options:  a combination of xmlParserOption
                   14823:  *
                   14824:  * parse an XML file from the filesystem or the network.
                   14825:  * This reuses the existing @ctxt parser context
                   14826:  * 
                   14827:  * Returns the resulting document tree
                   14828:  */
                   14829: xmlDocPtr
                   14830: xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
                   14831:                 const char *encoding, int options)
                   14832: {
                   14833:     xmlParserInputPtr stream;
                   14834: 
                   14835:     if (filename == NULL)
                   14836:         return (NULL);
                   14837:     if (ctxt == NULL)
                   14838:         return (NULL);
                   14839: 
                   14840:     xmlCtxtReset(ctxt);
                   14841: 
                   14842:     stream = xmlLoadExternalEntity(filename, NULL, ctxt);
                   14843:     if (stream == NULL) {
                   14844:         return (NULL);
                   14845:     }
                   14846:     inputPush(ctxt, stream);
                   14847:     return (xmlDoRead(ctxt, NULL, encoding, options, 1));
                   14848: }
                   14849: 
                   14850: /**
                   14851:  * xmlCtxtReadMemory:
                   14852:  * @ctxt:  an XML parser context
                   14853:  * @buffer:  a pointer to a char array
                   14854:  * @size:  the size of the array
                   14855:  * @URL:  the base URL to use for the document
                   14856:  * @encoding:  the document encoding, or NULL
                   14857:  * @options:  a combination of xmlParserOption
                   14858:  *
                   14859:  * parse an XML in-memory document and build a tree.
                   14860:  * This reuses the existing @ctxt parser context
                   14861:  * 
                   14862:  * Returns the resulting document tree
                   14863:  */
                   14864: xmlDocPtr
                   14865: xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
                   14866:                   const char *URL, const char *encoding, int options)
                   14867: {
                   14868:     xmlParserInputBufferPtr input;
                   14869:     xmlParserInputPtr stream;
                   14870: 
                   14871:     if (ctxt == NULL)
                   14872:         return (NULL);
                   14873:     if (buffer == NULL)
                   14874:         return (NULL);
                   14875: 
                   14876:     xmlCtxtReset(ctxt);
                   14877: 
                   14878:     input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
                   14879:     if (input == NULL) {
                   14880:        return(NULL);
                   14881:     }
                   14882: 
                   14883:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   14884:     if (stream == NULL) {
                   14885:        xmlFreeParserInputBuffer(input);
                   14886:        return(NULL);
                   14887:     }
                   14888: 
                   14889:     inputPush(ctxt, stream);
                   14890:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
                   14891: }
                   14892: 
                   14893: /**
                   14894:  * xmlCtxtReadFd:
                   14895:  * @ctxt:  an XML parser context
                   14896:  * @fd:  an open file descriptor
                   14897:  * @URL:  the base URL to use for the document
                   14898:  * @encoding:  the document encoding, or NULL
                   14899:  * @options:  a combination of xmlParserOption
                   14900:  *
                   14901:  * parse an XML from a file descriptor and build a tree.
                   14902:  * This reuses the existing @ctxt parser context
                   14903:  * NOTE that the file descriptor will not be closed when the
                   14904:  *      reader is closed or reset.
                   14905:  * 
                   14906:  * Returns the resulting document tree
                   14907:  */
                   14908: xmlDocPtr
                   14909: xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
                   14910:               const char *URL, const char *encoding, int options)
                   14911: {
                   14912:     xmlParserInputBufferPtr input;
                   14913:     xmlParserInputPtr stream;
                   14914: 
                   14915:     if (fd < 0)
                   14916:         return (NULL);
                   14917:     if (ctxt == NULL)
                   14918:         return (NULL);
                   14919: 
                   14920:     xmlCtxtReset(ctxt);
                   14921: 
                   14922: 
                   14923:     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
                   14924:     if (input == NULL)
                   14925:         return (NULL);
                   14926:     input->closecallback = NULL;
                   14927:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   14928:     if (stream == NULL) {
                   14929:         xmlFreeParserInputBuffer(input);
                   14930:         return (NULL);
                   14931:     }
                   14932:     inputPush(ctxt, stream);
                   14933:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
                   14934: }
                   14935: 
                   14936: /**
                   14937:  * xmlCtxtReadIO:
                   14938:  * @ctxt:  an XML parser context
                   14939:  * @ioread:  an I/O read function
                   14940:  * @ioclose:  an I/O close function
                   14941:  * @ioctx:  an I/O handler
                   14942:  * @URL:  the base URL to use for the document
                   14943:  * @encoding:  the document encoding, or NULL
                   14944:  * @options:  a combination of xmlParserOption
                   14945:  *
                   14946:  * parse an XML document from I/O functions and source and build a tree.
                   14947:  * This reuses the existing @ctxt parser context
                   14948:  * 
                   14949:  * Returns the resulting document tree
                   14950:  */
                   14951: xmlDocPtr
                   14952: xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
                   14953:               xmlInputCloseCallback ioclose, void *ioctx,
                   14954:              const char *URL,
                   14955:               const char *encoding, int options)
                   14956: {
                   14957:     xmlParserInputBufferPtr input;
                   14958:     xmlParserInputPtr stream;
                   14959: 
                   14960:     if (ioread == NULL)
                   14961:         return (NULL);
                   14962:     if (ctxt == NULL)
                   14963:         return (NULL);
                   14964: 
                   14965:     xmlCtxtReset(ctxt);
                   14966: 
                   14967:     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
                   14968:                                          XML_CHAR_ENCODING_NONE);
                   14969:     if (input == NULL)
                   14970:         return (NULL);
                   14971:     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
                   14972:     if (stream == NULL) {
                   14973:         xmlFreeParserInputBuffer(input);
                   14974:         return (NULL);
                   14975:     }
                   14976:     inputPush(ctxt, stream);
                   14977:     return (xmlDoRead(ctxt, URL, encoding, options, 1));
                   14978: }
                   14979: 
                   14980: #define bottom_parser
                   14981: #include "elfgcchack.h"

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