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