Imported Upstream version 0.18.1.1
[platform/upstream/gettext.git] / gnulib-local / lib / libxml / parser.c
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 /**
84  * xmlParserMaxDepth:
85  *
86  * arbitrary depth limit for the XML documents that we allow to 
87  * process. This is not a limitation of the parser but a safety 
88  * boundary feature.
89  */
90 unsigned int xmlParserMaxDepth = 1024;
91
92 #define SAX2 1
93
94 #define XML_PARSER_BIG_BUFFER_SIZE 300
95 #define XML_PARSER_BUFFER_SIZE 100
96
97 #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
98
99 /*
100  * List of XML prefixed PI allowed by W3C specs
101  */
102
103 static const char *xmlW3CPIs[] = {
104     "xml-stylesheet",
105     NULL
106 };
107
108
109 /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
110 xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
111                                        const xmlChar **str);
112
113 static xmlParserErrors
114 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
115                       xmlSAXHandlerPtr sax,
116                       void *user_data, int depth, const xmlChar *URL,
117                       const xmlChar *ID, xmlNodePtr *list);
118
119 #ifdef LIBXML_LEGACY_ENABLED
120 static void
121 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
122                       xmlNodePtr lastNode);
123 #endif /* LIBXML_LEGACY_ENABLED */
124
125 static xmlParserErrors
126 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
127                       const xmlChar *string, void *user_data, xmlNodePtr *lst);
128
129 /************************************************************************
130  *                                                                      *
131  *              Some factorized error routines                          *
132  *                                                                      *
133  ************************************************************************/
134
135 /**
136  * xmlErrAttributeDup:
137  * @ctxt:  an XML parser context
138  * @prefix:  the attribute prefix
139  * @localname:  the attribute localname
140  *
141  * Handle a redefinition of attribute error
142  */
143 static void
144 xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
145                    const xmlChar * localname)
146 {
147     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
148         (ctxt->instate == XML_PARSER_EOF))
149         return;
150     if (ctxt != NULL)
151         ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
152     if (prefix == NULL)
153         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
154                         ctxt->errNo, XML_ERR_FATAL, NULL, 0,
155                         (const char *) localname, NULL, NULL, 0, 0,
156                         "Attribute %s redefined\n", localname);
157     else
158         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
159                         ctxt->errNo, XML_ERR_FATAL, NULL, 0,
160                         (const char *) prefix, (const char *) localname,
161                         NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
162                         localname);
163     if (ctxt != NULL) {
164         ctxt->wellFormed = 0;
165         if (ctxt->recovery == 0)
166             ctxt->disableSAX = 1;
167     }
168 }
169
170 /**
171  * xmlFatalErr:
172  * @ctxt:  an XML parser context
173  * @error:  the error number
174  * @extra:  extra information string
175  *
176  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
177  */
178 static void
179 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
180 {
181     const char *errmsg;
182
183     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
184         (ctxt->instate == XML_PARSER_EOF))
185         return;
186     switch (error) {
187         case XML_ERR_INVALID_HEX_CHARREF:
188             errmsg = "CharRef: invalid hexadecimal value\n";
189             break;
190         case XML_ERR_INVALID_DEC_CHARREF:
191             errmsg = "CharRef: invalid decimal value\n";
192             break;
193         case XML_ERR_INVALID_CHARREF:
194             errmsg = "CharRef: invalid value\n";
195             break;
196         case XML_ERR_INTERNAL_ERROR:
197             errmsg = "internal error";
198             break;
199         case XML_ERR_PEREF_AT_EOF:
200             errmsg = "PEReference at end of document\n";
201             break;
202         case XML_ERR_PEREF_IN_PROLOG:
203             errmsg = "PEReference in prolog\n";
204             break;
205         case XML_ERR_PEREF_IN_EPILOG:
206             errmsg = "PEReference in epilog\n";
207             break;
208         case XML_ERR_PEREF_NO_NAME:
209             errmsg = "PEReference: no name\n";
210             break;
211         case XML_ERR_PEREF_SEMICOL_MISSING:
212             errmsg = "PEReference: expecting ';'\n";
213             break;
214         case XML_ERR_ENTITY_LOOP:
215             errmsg = "Detected an entity reference loop\n";
216             break;
217         case XML_ERR_ENTITY_NOT_STARTED:
218             errmsg = "EntityValue: \" or ' expected\n";
219             break;
220         case XML_ERR_ENTITY_PE_INTERNAL:
221             errmsg = "PEReferences forbidden in internal subset\n";
222             break;
223         case XML_ERR_ENTITY_NOT_FINISHED:
224             errmsg = "EntityValue: \" or ' expected\n";
225             break;
226         case XML_ERR_ATTRIBUTE_NOT_STARTED:
227             errmsg = "AttValue: \" or ' expected\n";
228             break;
229         case XML_ERR_LT_IN_ATTRIBUTE:
230             errmsg = "Unescaped '<' not allowed in attributes values\n";
231             break;
232         case XML_ERR_LITERAL_NOT_STARTED:
233             errmsg = "SystemLiteral \" or ' expected\n";
234             break;
235         case XML_ERR_LITERAL_NOT_FINISHED:
236             errmsg = "Unfinished System or Public ID \" or ' expected\n";
237             break;
238         case XML_ERR_MISPLACED_CDATA_END:
239             errmsg = "Sequence ']]>' not allowed in content\n";
240             break;
241         case XML_ERR_URI_REQUIRED:
242             errmsg = "SYSTEM or PUBLIC, the URI is missing\n";
243             break;
244         case XML_ERR_PUBID_REQUIRED:
245             errmsg = "PUBLIC, the Public Identifier is missing\n";
246             break;
247         case XML_ERR_HYPHEN_IN_COMMENT:
248             errmsg = "Comment must not contain '--' (double-hyphen)\n";
249             break;
250         case XML_ERR_PI_NOT_STARTED:
251             errmsg = "xmlParsePI : no target name\n";
252             break;
253         case XML_ERR_RESERVED_XML_NAME:
254             errmsg = "Invalid PI name\n";
255             break;
256         case XML_ERR_NOTATION_NOT_STARTED:
257             errmsg = "NOTATION: Name expected here\n";
258             break;
259         case XML_ERR_NOTATION_NOT_FINISHED:
260             errmsg = "'>' required to close NOTATION declaration\n";
261             break;
262         case XML_ERR_VALUE_REQUIRED:
263             errmsg = "Entity value required\n";
264             break;
265         case XML_ERR_URI_FRAGMENT:
266             errmsg = "Fragment not allowed";
267             break;
268         case XML_ERR_ATTLIST_NOT_STARTED:
269             errmsg = "'(' required to start ATTLIST enumeration\n";
270             break;
271         case XML_ERR_NMTOKEN_REQUIRED:
272             errmsg = "NmToken expected in ATTLIST enumeration\n";
273             break;
274         case XML_ERR_ATTLIST_NOT_FINISHED:
275             errmsg = "')' required to finish ATTLIST enumeration\n";
276             break;
277         case XML_ERR_MIXED_NOT_STARTED:
278             errmsg = "MixedContentDecl : '|' or ')*' expected\n";
279             break;
280         case XML_ERR_PCDATA_REQUIRED:
281             errmsg = "MixedContentDecl : '#PCDATA' expected\n";
282             break;
283         case XML_ERR_ELEMCONTENT_NOT_STARTED:
284             errmsg = "ContentDecl : Name or '(' expected\n";
285             break;
286         case XML_ERR_ELEMCONTENT_NOT_FINISHED:
287             errmsg = "ContentDecl : ',' '|' or ')' expected\n";
288             break;
289         case XML_ERR_PEREF_IN_INT_SUBSET:
290             errmsg =
291                 "PEReference: forbidden within markup decl in internal subset\n";
292             break;
293         case XML_ERR_GT_REQUIRED:
294             errmsg = "expected '>'\n";
295             break;
296         case XML_ERR_CONDSEC_INVALID:
297             errmsg = "XML conditional section '[' expected\n";
298             break;
299         case XML_ERR_EXT_SUBSET_NOT_FINISHED:
300             errmsg = "Content error in the external subset\n";
301             break;
302         case XML_ERR_CONDSEC_INVALID_KEYWORD:
303             errmsg =
304                 "conditional section INCLUDE or IGNORE keyword expected\n";
305             break;
306         case XML_ERR_CONDSEC_NOT_FINISHED:
307             errmsg = "XML conditional section not closed\n";
308             break;
309         case XML_ERR_XMLDECL_NOT_STARTED:
310             errmsg = "Text declaration '<?xml' required\n";
311             break;
312         case XML_ERR_XMLDECL_NOT_FINISHED:
313             errmsg = "parsing XML declaration: '?>' expected\n";
314             break;
315         case XML_ERR_EXT_ENTITY_STANDALONE:
316             errmsg = "external parsed entities cannot be standalone\n";
317             break;
318         case XML_ERR_ENTITYREF_SEMICOL_MISSING:
319             errmsg = "EntityRef: expecting ';'\n";
320             break;
321         case XML_ERR_DOCTYPE_NOT_FINISHED:
322             errmsg = "DOCTYPE improperly terminated\n";
323             break;
324         case XML_ERR_LTSLASH_REQUIRED:
325             errmsg = "EndTag: '</' not found\n";
326             break;
327         case XML_ERR_EQUAL_REQUIRED:
328             errmsg = "expected '='\n";
329             break;
330         case XML_ERR_STRING_NOT_CLOSED:
331             errmsg = "String not closed expecting \" or '\n";
332             break;
333         case XML_ERR_STRING_NOT_STARTED:
334             errmsg = "String not started expecting ' or \"\n";
335             break;
336         case XML_ERR_ENCODING_NAME:
337             errmsg = "Invalid XML encoding name\n";
338             break;
339         case XML_ERR_STANDALONE_VALUE:
340             errmsg = "standalone accepts only 'yes' or 'no'\n";
341             break;
342         case XML_ERR_DOCUMENT_EMPTY:
343             errmsg = "Document is empty\n";
344             break;
345         case XML_ERR_DOCUMENT_END:
346             errmsg = "Extra content at the end of the document\n";
347             break;
348         case XML_ERR_NOT_WELL_BALANCED:
349             errmsg = "chunk is not well balanced\n";
350             break;
351         case XML_ERR_EXTRA_CONTENT:
352             errmsg = "extra content at the end of well balanced chunk\n";
353             break;
354         case XML_ERR_VERSION_MISSING:
355             errmsg = "Malformed declaration expecting version\n";
356             break;
357 #if 0
358         case:
359             errmsg = "\n";
360             break;
361 #endif
362         default:
363             errmsg = "Unregistered error message\n";
364     }
365     if (ctxt != NULL)
366         ctxt->errNo = error;
367     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
368                     XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, errmsg,
369                     info);
370     if (ctxt != NULL) {
371         ctxt->wellFormed = 0;
372         if (ctxt->recovery == 0)
373             ctxt->disableSAX = 1;
374     }
375 }
376
377 /**
378  * xmlFatalErrMsg:
379  * @ctxt:  an XML parser context
380  * @error:  the error number
381  * @msg:  the error message
382  *
383  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
384  */
385 static void
386 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
387                const char *msg)
388 {
389     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
390         (ctxt->instate == XML_PARSER_EOF))
391         return;
392     if (ctxt != NULL)
393         ctxt->errNo = error;
394     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
395                     XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, msg);
396     if (ctxt != NULL) {
397         ctxt->wellFormed = 0;
398         if (ctxt->recovery == 0)
399             ctxt->disableSAX = 1;
400     }
401 }
402
403 /**
404  * xmlWarningMsg:
405  * @ctxt:  an XML parser context
406  * @error:  the error number
407  * @msg:  the error message
408  * @str1:  extra data
409  * @str2:  extra data
410  *
411  * Handle a warning.
412  */
413 static void
414 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
415               const char *msg, const xmlChar *str1, const xmlChar *str2)
416 {
417     xmlStructuredErrorFunc schannel = NULL;
418     
419     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
420         (ctxt->instate == XML_PARSER_EOF))
421         return;
422     if ((ctxt != NULL) && (ctxt->sax != NULL) &&
423         (ctxt->sax->initialized == XML_SAX2_MAGIC))
424         schannel = ctxt->sax->serror;
425     __xmlRaiseError(schannel,
426                     (ctxt->sax) ? ctxt->sax->warning : NULL,
427                     ctxt->userData,
428                     ctxt, NULL, XML_FROM_PARSER, error,
429                     XML_ERR_WARNING, NULL, 0,
430                     (const char *) str1, (const char *) str2, NULL, 0, 0,
431                     msg, (const char *) str1, (const char *) str2);
432 }
433
434 /**
435  * xmlValidityError:
436  * @ctxt:  an XML parser context
437  * @error:  the error number
438  * @msg:  the error message
439  * @str1:  extra data
440  *
441  * Handle a validity error.
442  */
443 static void
444 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
445               const char *msg, const xmlChar *str1)
446 {
447     xmlStructuredErrorFunc schannel = NULL;
448
449     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
450         (ctxt->instate == XML_PARSER_EOF))
451         return;
452     if (ctxt != NULL) {
453         ctxt->errNo = error;
454         if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
455             schannel = ctxt->sax->serror;
456     }
457     __xmlRaiseError(schannel,
458                     ctxt->vctxt.error, ctxt->vctxt.userData,
459                     ctxt, NULL, XML_FROM_DTD, error,
460                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
461                     NULL, NULL, 0, 0,
462                     msg, (const char *) str1);
463     if (ctxt != NULL) {
464         ctxt->valid = 0;
465     }
466 }
467
468 /**
469  * xmlFatalErrMsgInt:
470  * @ctxt:  an XML parser context
471  * @error:  the error number
472  * @msg:  the error message
473  * @val:  an integer value
474  *
475  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
476  */
477 static void
478 xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
479                   const char *msg, int val)
480 {
481     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
482         (ctxt->instate == XML_PARSER_EOF))
483         return;
484     if (ctxt != NULL)
485         ctxt->errNo = error;
486     __xmlRaiseError(NULL, NULL, NULL,
487                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
488                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
489     if (ctxt != NULL) {
490         ctxt->wellFormed = 0;
491         if (ctxt->recovery == 0)
492             ctxt->disableSAX = 1;
493     }
494 }
495
496 /**
497  * xmlFatalErrMsgStrIntStr:
498  * @ctxt:  an XML parser context
499  * @error:  the error number
500  * @msg:  the error message
501  * @str1:  an string info
502  * @val:  an integer value
503  * @str2:  an string info
504  *
505  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
506  */
507 static void
508 xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
509                   const char *msg, const xmlChar *str1, int val, 
510                   const xmlChar *str2)
511 {
512     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
513         (ctxt->instate == XML_PARSER_EOF))
514         return;
515     if (ctxt != NULL)
516         ctxt->errNo = error;
517     __xmlRaiseError(NULL, NULL, NULL,
518                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
519                     NULL, 0, (const char *) str1, (const char *) str2,
520                     NULL, val, 0, msg, str1, val, str2);
521     if (ctxt != NULL) {
522         ctxt->wellFormed = 0;
523         if (ctxt->recovery == 0)
524             ctxt->disableSAX = 1;
525     }
526 }
527
528 /**
529  * xmlFatalErrMsgStr:
530  * @ctxt:  an XML parser context
531  * @error:  the error number
532  * @msg:  the error message
533  * @val:  a string value
534  *
535  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
536  */
537 static void
538 xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
539                   const char *msg, const xmlChar * val)
540 {
541     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
542         (ctxt->instate == XML_PARSER_EOF))
543         return;
544     if (ctxt != NULL)
545         ctxt->errNo = error;
546     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
547                     XML_FROM_PARSER, error, XML_ERR_FATAL,
548                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
549                     val);
550     if (ctxt != NULL) {
551         ctxt->wellFormed = 0;
552         if (ctxt->recovery == 0)
553             ctxt->disableSAX = 1;
554     }
555 }
556
557 /**
558  * xmlErrMsgStr:
559  * @ctxt:  an XML parser context
560  * @error:  the error number
561  * @msg:  the error message
562  * @val:  a string value
563  *
564  * Handle a non fatal parser error
565  */
566 static void
567 xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
568                   const char *msg, const xmlChar * val)
569 {
570     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
571         (ctxt->instate == XML_PARSER_EOF))
572         return;
573     if (ctxt != NULL)
574         ctxt->errNo = error;
575     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
576                     XML_FROM_PARSER, error, XML_ERR_ERROR,
577                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
578                     val);
579 }
580
581 /**
582  * xmlNsErr:
583  * @ctxt:  an XML parser context
584  * @error:  the error number
585  * @msg:  the message
586  * @info1:  extra information string
587  * @info2:  extra information string
588  *
589  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
590  */
591 static void
592 xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
593          const char *msg,
594          const xmlChar * info1, const xmlChar * info2,
595          const xmlChar * info3)
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, ctxt, NULL, XML_FROM_NAMESPACE, error,
603                     XML_ERR_ERROR, NULL, 0, (const char *) info1,
604                     (const char *) info2, (const char *) info3, 0, 0, msg,
605                     info1, info2, info3);
606     if (ctxt != NULL)
607         ctxt->nsWellFormed = 0;
608 }
609
610 /************************************************************************
611  *                                                                      *
612  *              Library wide options                                    *
613  *                                                                      *
614  ************************************************************************/
615
616 /**
617   * xmlHasFeature:
618   * @feature: the feature to be examined
619   *
620   * Examines if the library has been compiled with a given feature.
621   *
622   * Returns a non-zero value if the feature exist, otherwise zero.
623   * Returns zero (0) if the feature does not exist or an unknown
624   * unknown feature is requested, non-zero otherwise.
625   */
626 int
627 xmlHasFeature(xmlFeature feature)
628 {
629     switch (feature) {
630         case XML_WITH_THREAD:
631 #ifdef LIBXML_THREAD_ENABLED
632             return(1);
633 #else
634             return(0);
635 #endif
636         case XML_WITH_TREE:
637 #ifdef LIBXML_TREE_ENABLED
638             return(1);
639 #else
640             return(0);
641 #endif
642         case XML_WITH_OUTPUT:
643 #ifdef LIBXML_OUTPUT_ENABLED
644             return(1);
645 #else
646             return(0);
647 #endif
648         case XML_WITH_PUSH:
649 #ifdef LIBXML_PUSH_ENABLED
650             return(1);
651 #else
652             return(0);
653 #endif
654         case XML_WITH_READER:
655 #ifdef LIBXML_READER_ENABLED
656             return(1);
657 #else
658             return(0);
659 #endif
660         case XML_WITH_PATTERN:
661 #ifdef LIBXML_PATTERN_ENABLED
662             return(1);
663 #else
664             return(0);
665 #endif
666         case XML_WITH_WRITER:
667 #ifdef LIBXML_WRITER_ENABLED
668             return(1);
669 #else
670             return(0);
671 #endif
672         case XML_WITH_SAX1:
673 #ifdef LIBXML_SAX1_ENABLED
674             return(1);
675 #else
676             return(0);
677 #endif
678         case XML_WITH_FTP:
679 #ifdef LIBXML_FTP_ENABLED
680             return(1);
681 #else
682             return(0);
683 #endif
684         case XML_WITH_HTTP:
685 #ifdef LIBXML_HTTP_ENABLED
686             return(1);
687 #else
688             return(0);
689 #endif
690         case XML_WITH_VALID:
691 #ifdef LIBXML_VALID_ENABLED
692             return(1);
693 #else
694             return(0);
695 #endif
696         case XML_WITH_HTML:
697 #ifdef LIBXML_HTML_ENABLED
698             return(1);
699 #else
700             return(0);
701 #endif
702         case XML_WITH_LEGACY:
703 #ifdef LIBXML_LEGACY_ENABLED
704             return(1);
705 #else
706             return(0);
707 #endif
708         case XML_WITH_C14N:
709 #ifdef LIBXML_C14N_ENABLED
710             return(1);
711 #else
712             return(0);
713 #endif
714         case XML_WITH_CATALOG:
715 #ifdef LIBXML_CATALOG_ENABLED
716             return(1);
717 #else
718             return(0);
719 #endif
720         case XML_WITH_XPATH:
721 #ifdef LIBXML_XPATH_ENABLED
722             return(1);
723 #else
724             return(0);
725 #endif
726         case XML_WITH_XPTR:
727 #ifdef LIBXML_XPTR_ENABLED
728             return(1);
729 #else
730             return(0);
731 #endif
732         case XML_WITH_XINCLUDE:
733 #ifdef LIBXML_XINCLUDE_ENABLED
734             return(1);
735 #else
736             return(0);
737 #endif
738         case XML_WITH_ICONV:
739 #ifdef LIBXML_ICONV_ENABLED
740             return(1);
741 #else
742             return(0);
743 #endif
744         case XML_WITH_ISO8859X:
745 #ifdef LIBXML_ISO8859X_ENABLED
746             return(1);
747 #else
748             return(0);
749 #endif
750         case XML_WITH_UNICODE:
751 #ifdef LIBXML_UNICODE_ENABLED
752             return(1);
753 #else
754             return(0);
755 #endif
756         case XML_WITH_REGEXP:
757 #ifdef LIBXML_REGEXP_ENABLED
758             return(1);
759 #else
760             return(0);
761 #endif
762         case XML_WITH_AUTOMATA:
763 #ifdef LIBXML_AUTOMATA_ENABLED
764             return(1);
765 #else
766             return(0);
767 #endif
768         case XML_WITH_EXPR:
769 #ifdef LIBXML_EXPR_ENABLED
770             return(1);
771 #else
772             return(0);
773 #endif
774         case XML_WITH_SCHEMAS:
775 #ifdef LIBXML_SCHEMAS_ENABLED
776             return(1);
777 #else
778             return(0);
779 #endif
780         case XML_WITH_SCHEMATRON:
781 #ifdef LIBXML_SCHEMATRON_ENABLED
782             return(1);
783 #else
784             return(0);
785 #endif
786         case XML_WITH_MODULES:
787 #ifdef LIBXML_MODULES_ENABLED
788             return(1);
789 #else
790             return(0);
791 #endif
792         case XML_WITH_DEBUG:
793 #ifdef LIBXML_DEBUG_ENABLED
794             return(1);
795 #else
796             return(0);
797 #endif
798         case XML_WITH_DEBUG_MEM:
799 #ifdef DEBUG_MEMORY_LOCATION
800             return(1);
801 #else
802             return(0);
803 #endif
804         case XML_WITH_DEBUG_RUN:
805 #ifdef LIBXML_DEBUG_RUNTIME
806             return(1);
807 #else
808             return(0);
809 #endif 
810         case XML_WITH_ZLIB:
811 #ifdef LIBXML_ZLIB_ENABLED
812             return(1);
813 #else
814             return(0);
815 #endif
816         default:
817             break;
818      }
819      return(0);
820 }
821
822 /************************************************************************
823  *                                                                      *
824  *              SAX2 defaulted attributes handling                      *
825  *                                                                      *
826  ************************************************************************/
827
828 /**
829  * xmlDetectSAX2:
830  * @ctxt:  an XML parser context
831  *
832  * Do the SAX2 detection and specific intialization
833  */
834 static void
835 xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
836     if (ctxt == NULL) return;
837 #ifdef LIBXML_SAX1_ENABLED
838     if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
839         ((ctxt->sax->startElementNs != NULL) ||
840          (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
841 #else
842     ctxt->sax2 = 1;
843 #endif /* LIBXML_SAX1_ENABLED */
844
845     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
846     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
847     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
848     if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) || 
849                 (ctxt->str_xml_ns == NULL)) {
850         xmlErrMemory(ctxt, NULL);
851     }
852 }
853
854 typedef struct _xmlDefAttrs xmlDefAttrs;
855 typedef xmlDefAttrs *xmlDefAttrsPtr;
856 struct _xmlDefAttrs {
857     int nbAttrs;        /* number of defaulted attributes on that element */
858     int maxAttrs;       /* the size of the array */
859     const xmlChar *values[4]; /* array of localname/prefix/values */
860 };
861
862 /**
863  * xmlAddDefAttrs:
864  * @ctxt:  an XML parser context
865  * @fullname:  the element fullname
866  * @fullattr:  the attribute fullname
867  * @value:  the attribute value
868  *
869  * Add a defaulted attribute for an element
870  */
871 static void
872 xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
873                const xmlChar *fullname,
874                const xmlChar *fullattr,
875                const xmlChar *value) {
876     xmlDefAttrsPtr defaults;
877     int len;
878     const xmlChar *name;
879     const xmlChar *prefix;
880
881     if (ctxt->attsDefault == NULL) {
882         ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
883         if (ctxt->attsDefault == NULL)
884             goto mem_error;
885     }
886
887     /*
888      * split the element name into prefix:localname , the string found
889      * are within the DTD and then not associated to namespace names.
890      */
891     name = xmlSplitQName3(fullname, &len);
892     if (name == NULL) {
893         name = xmlDictLookup(ctxt->dict, fullname, -1);
894         prefix = NULL;
895     } else {
896         name = xmlDictLookup(ctxt->dict, name, -1);
897         prefix = xmlDictLookup(ctxt->dict, fullname, len);
898     }
899
900     /*
901      * make sure there is some storage
902      */
903     defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
904     if (defaults == NULL) {
905         defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
906                            (4 * 4) * sizeof(const xmlChar *));
907         if (defaults == NULL)
908             goto mem_error;
909         defaults->nbAttrs = 0;
910         defaults->maxAttrs = 4;
911         xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, defaults, NULL);
912     } else if (defaults->nbAttrs >= defaults->maxAttrs) {
913         xmlDefAttrsPtr temp;
914
915         temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
916                        (2 * defaults->maxAttrs * 4) * sizeof(const xmlChar *));
917         if (temp == NULL)
918             goto mem_error;
919         defaults = temp;
920         defaults->maxAttrs *= 2;
921         xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, defaults, NULL);
922     }
923
924     /*
925      * Split the element name into prefix:localname , the string found
926      * are within the DTD and hen not associated to namespace names.
927      */
928     name = xmlSplitQName3(fullattr, &len);
929     if (name == NULL) {
930         name = xmlDictLookup(ctxt->dict, fullattr, -1);
931         prefix = NULL;
932     } else {
933         name = xmlDictLookup(ctxt->dict, name, -1);
934         prefix = xmlDictLookup(ctxt->dict, fullattr, len);
935     }
936
937     defaults->values[4 * defaults->nbAttrs] = name;
938     defaults->values[4 * defaults->nbAttrs + 1] = prefix;
939     /* intern the string and precompute the end */
940     len = xmlStrlen(value);
941     value = xmlDictLookup(ctxt->dict, value, len);
942     defaults->values[4 * defaults->nbAttrs + 2] = value;
943     defaults->values[4 * defaults->nbAttrs + 3] = value + len;
944     defaults->nbAttrs++;
945
946     return;
947
948 mem_error:
949     xmlErrMemory(ctxt, NULL);
950     return;
951 }
952
953 /**
954  * xmlAddSpecialAttr:
955  * @ctxt:  an XML parser context
956  * @fullname:  the element fullname
957  * @fullattr:  the attribute fullname
958  * @type:  the attribute type
959  *
960  * Register that this attribute is not CDATA
961  */
962 static void
963 xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
964                   const xmlChar *fullname,
965                   const xmlChar *fullattr,
966                   int type)
967 {
968     if (ctxt->attsSpecial == NULL) {
969         ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
970         if (ctxt->attsSpecial == NULL)
971             goto mem_error;
972     }
973
974     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
975                      (void *) (long) type);
976     return;
977
978 mem_error:
979     xmlErrMemory(ctxt, NULL);
980     return;
981 }
982
983 /**
984  * xmlCheckLanguageID:
985  * @lang:  pointer to the string value
986  *
987  * Checks that the value conforms to the LanguageID production:
988  *
989  * NOTE: this is somewhat deprecated, those productions were removed from
990  *       the XML Second edition.
991  *
992  * [33] LanguageID ::= Langcode ('-' Subcode)*
993  * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
994  * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
995  * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
996  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
997  * [38] Subcode ::= ([a-z] | [A-Z])+
998  *
999  * Returns 1 if correct 0 otherwise
1000  **/
1001 int
1002 xmlCheckLanguageID(const xmlChar * lang)
1003 {
1004     const xmlChar *cur = lang;
1005
1006     if (cur == NULL)
1007         return (0);
1008     if (((cur[0] == 'i') && (cur[1] == '-')) ||
1009         ((cur[0] == 'I') && (cur[1] == '-'))) {
1010         /*
1011          * IANA code
1012          */
1013         cur += 2;
1014         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
1015                ((cur[0] >= 'a') && (cur[0] <= 'z')))
1016             cur++;
1017     } else if (((cur[0] == 'x') && (cur[1] == '-')) ||
1018                ((cur[0] == 'X') && (cur[1] == '-'))) {
1019         /*
1020          * User code
1021          */
1022         cur += 2;
1023         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
1024                ((cur[0] >= 'a') && (cur[0] <= 'z')))
1025             cur++;
1026     } else if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1027                ((cur[0] >= 'a') && (cur[0] <= 'z'))) {
1028         /*
1029          * ISO639
1030          */
1031         cur++;
1032         if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1033             ((cur[0] >= 'a') && (cur[0] <= 'z')))
1034             cur++;
1035         else
1036             return (0);
1037     } else
1038         return (0);
1039     while (cur[0] != 0) {       /* non input consuming */
1040         if (cur[0] != '-')
1041             return (0);
1042         cur++;
1043         if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1044             ((cur[0] >= 'a') && (cur[0] <= 'z')))
1045             cur++;
1046         else
1047             return (0);
1048         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
1049                ((cur[0] >= 'a') && (cur[0] <= 'z')))
1050             cur++;
1051     }
1052     return (1);
1053 }
1054
1055 /************************************************************************
1056  *                                                                      *
1057  *              Parser stacks related functions and macros              *
1058  *                                                                      *
1059  ************************************************************************/
1060
1061 xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
1062                                      const xmlChar ** str);
1063
1064 #ifdef SAX2
1065 /**
1066  * nsPush:
1067  * @ctxt:  an XML parser context
1068  * @prefix:  the namespace prefix or NULL
1069  * @URL:  the namespace name
1070  *
1071  * Pushes a new parser namespace on top of the ns stack
1072  *
1073  * Returns -1 in case of error, -2 if the namespace should be discarded
1074  *         and the index in the stack otherwise.
1075  */
1076 static int
1077 nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
1078 {
1079     if (ctxt->options & XML_PARSE_NSCLEAN) {
1080         int i;
1081         for (i = 0;i < ctxt->nsNr;i += 2) {
1082             if (ctxt->nsTab[i] == prefix) {
1083                 /* in scope */
1084                 if (ctxt->nsTab[i + 1] == URL)
1085                     return(-2);
1086                 /* out of scope keep it */
1087                 break;
1088             }
1089         }
1090     }
1091     if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
1092         ctxt->nsMax = 10;
1093         ctxt->nsNr = 0;
1094         ctxt->nsTab = (const xmlChar **)
1095                       xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
1096         if (ctxt->nsTab == NULL) {
1097             xmlErrMemory(ctxt, NULL);
1098             ctxt->nsMax = 0;
1099             return (-1);
1100         }
1101     } else if (ctxt->nsNr >= ctxt->nsMax) {
1102         ctxt->nsMax *= 2;
1103         ctxt->nsTab = (const xmlChar **)
1104                       xmlRealloc((char *) ctxt->nsTab,
1105                                  ctxt->nsMax * sizeof(ctxt->nsTab[0]));
1106         if (ctxt->nsTab == NULL) {
1107             xmlErrMemory(ctxt, NULL);
1108             ctxt->nsMax /= 2;
1109             return (-1);
1110         }
1111     }
1112     ctxt->nsTab[ctxt->nsNr++] = prefix;
1113     ctxt->nsTab[ctxt->nsNr++] = URL;
1114     return (ctxt->nsNr);
1115 }
1116 /**
1117  * nsPop:
1118  * @ctxt: an XML parser context
1119  * @nr:  the number to pop
1120  *
1121  * Pops the top @nr parser prefix/namespace from the ns stack
1122  *
1123  * Returns the number of namespaces removed
1124  */
1125 static int
1126 nsPop(xmlParserCtxtPtr ctxt, int nr)
1127 {
1128     int i;
1129
1130     if (ctxt->nsTab == NULL) return(0);
1131     if (ctxt->nsNr < nr) {
1132         xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
1133         nr = ctxt->nsNr;
1134     }
1135     if (ctxt->nsNr <= 0)
1136         return (0);
1137     
1138     for (i = 0;i < nr;i++) {
1139          ctxt->nsNr--;
1140          ctxt->nsTab[ctxt->nsNr] = NULL;
1141     }
1142     return(nr);
1143 }
1144 #endif
1145
1146 static int
1147 xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
1148     const xmlChar **atts;
1149     int *attallocs;
1150     int maxatts;
1151
1152     if (ctxt->atts == NULL) {
1153         maxatts = 55; /* allow for 10 attrs by default */
1154         atts = (const xmlChar **)
1155                xmlMalloc(maxatts * sizeof(xmlChar *));
1156         if (atts == NULL) goto mem_error;
1157         ctxt->atts = atts;
1158         attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
1159         if (attallocs == NULL) goto mem_error;
1160         ctxt->attallocs = attallocs;
1161         ctxt->maxatts = maxatts;
1162     } else if (nr + 5 > ctxt->maxatts) {
1163         maxatts = (nr + 5) * 2;
1164         atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
1165                                      maxatts * sizeof(const xmlChar *));
1166         if (atts == NULL) goto mem_error;
1167         ctxt->atts = atts;
1168         attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
1169                                      (maxatts / 5) * sizeof(int));
1170         if (attallocs == NULL) goto mem_error;
1171         ctxt->attallocs = attallocs;
1172         ctxt->maxatts = maxatts;
1173     }
1174     return(ctxt->maxatts);
1175 mem_error:
1176     xmlErrMemory(ctxt, NULL);
1177     return(-1);
1178 }
1179
1180 /**
1181  * inputPush:
1182  * @ctxt:  an XML parser context
1183  * @value:  the parser input
1184  *
1185  * Pushes a new parser input on top of the input stack
1186  *
1187  * Returns 0 in case of error, the index in the stack otherwise
1188  */
1189 int
1190 inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
1191 {
1192     if ((ctxt == NULL) || (value == NULL))
1193         return(0);
1194     if (ctxt->inputNr >= ctxt->inputMax) {
1195         ctxt->inputMax *= 2;
1196         ctxt->inputTab =
1197             (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
1198                                              ctxt->inputMax *
1199                                              sizeof(ctxt->inputTab[0]));
1200         if (ctxt->inputTab == NULL) {
1201             xmlErrMemory(ctxt, NULL);
1202             return (0);
1203         }
1204     }
1205     ctxt->inputTab[ctxt->inputNr] = value;
1206     ctxt->input = value;
1207     return (ctxt->inputNr++);
1208 }
1209 /**
1210  * inputPop:
1211  * @ctxt: an XML parser context
1212  *
1213  * Pops the top parser input from the input stack
1214  *
1215  * Returns the input just removed
1216  */
1217 xmlParserInputPtr
1218 inputPop(xmlParserCtxtPtr ctxt)
1219 {
1220     xmlParserInputPtr ret;
1221
1222     if (ctxt == NULL)
1223         return(NULL);
1224     if (ctxt->inputNr <= 0)
1225         return (NULL);
1226     ctxt->inputNr--;
1227     if (ctxt->inputNr > 0)
1228         ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
1229     else
1230         ctxt->input = NULL;
1231     ret = ctxt->inputTab[ctxt->inputNr];
1232     ctxt->inputTab[ctxt->inputNr] = NULL;
1233     return (ret);
1234 }
1235 /**
1236  * nodePush:
1237  * @ctxt:  an XML parser context
1238  * @value:  the element node
1239  *
1240  * Pushes a new element node on top of the node stack
1241  *
1242  * Returns 0 in case of error, the index in the stack otherwise
1243  */
1244 int
1245 nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
1246 {
1247     if (ctxt == NULL) return(0);
1248     if (ctxt->nodeNr >= ctxt->nodeMax) {
1249         xmlNodePtr *tmp;
1250
1251         tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
1252                                       ctxt->nodeMax * 2 *
1253                                       sizeof(ctxt->nodeTab[0]));
1254         if (tmp == NULL) {
1255             xmlErrMemory(ctxt, NULL);
1256             return (0);
1257         }
1258         ctxt->nodeTab = tmp;
1259         ctxt->nodeMax *= 2;
1260     }
1261     if (((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) {
1262         xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
1263                  "Excessive depth in document: change xmlParserMaxDepth = %d\n",
1264                           xmlParserMaxDepth);
1265         ctxt->instate = XML_PARSER_EOF;
1266         return(0);
1267     }
1268     ctxt->nodeTab[ctxt->nodeNr] = value;
1269     ctxt->node = value;
1270     return (ctxt->nodeNr++);
1271 }
1272 /**
1273  * nodePop:
1274  * @ctxt: an XML parser context
1275  *
1276  * Pops the top element node from the node stack
1277  *
1278  * Returns the node just removed
1279  */
1280 xmlNodePtr
1281 nodePop(xmlParserCtxtPtr ctxt)
1282 {
1283     xmlNodePtr ret;
1284
1285     if (ctxt == NULL) return(NULL);
1286     if (ctxt->nodeNr <= 0)
1287         return (NULL);
1288     ctxt->nodeNr--;
1289     if (ctxt->nodeNr > 0)
1290         ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
1291     else
1292         ctxt->node = NULL;
1293     ret = ctxt->nodeTab[ctxt->nodeNr];
1294     ctxt->nodeTab[ctxt->nodeNr] = NULL;
1295     return (ret);
1296 }
1297
1298 #ifdef LIBXML_PUSH_ENABLED
1299 /**
1300  * nameNsPush:
1301  * @ctxt:  an XML parser context
1302  * @value:  the element name
1303  * @prefix:  the element prefix
1304  * @URI:  the element namespace name
1305  *
1306  * Pushes a new element name/prefix/URL on top of the name stack
1307  *
1308  * Returns -1 in case of error, the index in the stack otherwise
1309  */
1310 static int
1311 nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
1312            const xmlChar *prefix, const xmlChar *URI, int nsNr)
1313 {
1314     if (ctxt->nameNr >= ctxt->nameMax) {
1315         const xmlChar * *tmp;
1316         void **tmp2;
1317         ctxt->nameMax *= 2;
1318         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1319                                     ctxt->nameMax *
1320                                     sizeof(ctxt->nameTab[0]));
1321         if (tmp == NULL) {
1322             ctxt->nameMax /= 2;
1323             goto mem_error;
1324         }
1325         ctxt->nameTab = tmp;
1326         tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
1327                                     ctxt->nameMax * 3 *
1328                                     sizeof(ctxt->pushTab[0]));
1329         if (tmp2 == NULL) {
1330             ctxt->nameMax /= 2;
1331             goto mem_error;
1332         }
1333         ctxt->pushTab = tmp2;
1334     }
1335     ctxt->nameTab[ctxt->nameNr] = value;
1336     ctxt->name = value;
1337     ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
1338     ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
1339     ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
1340     return (ctxt->nameNr++);
1341 mem_error:
1342     xmlErrMemory(ctxt, NULL);
1343     return (-1);
1344 }
1345 /**
1346  * nameNsPop:
1347  * @ctxt: an XML parser context
1348  *
1349  * Pops the top element/prefix/URI name from the name stack
1350  *
1351  * Returns the name just removed
1352  */
1353 static const xmlChar *
1354 nameNsPop(xmlParserCtxtPtr ctxt)
1355 {
1356     const xmlChar *ret;
1357
1358     if (ctxt->nameNr <= 0)
1359         return (NULL);
1360     ctxt->nameNr--;
1361     if (ctxt->nameNr > 0)
1362         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1363     else
1364         ctxt->name = NULL;
1365     ret = ctxt->nameTab[ctxt->nameNr];
1366     ctxt->nameTab[ctxt->nameNr] = NULL;
1367     return (ret);
1368 }
1369 #endif /* LIBXML_PUSH_ENABLED */
1370
1371 /**
1372  * namePush:
1373  * @ctxt:  an XML parser context
1374  * @value:  the element name
1375  *
1376  * Pushes a new element name on top of the name stack
1377  *
1378  * Returns -1 in case of error, the index in the stack otherwise
1379  */
1380 int
1381 namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
1382 {
1383     if (ctxt == NULL) return (-1);
1384
1385     if (ctxt->nameNr >= ctxt->nameMax) {
1386         const xmlChar * *tmp;
1387         ctxt->nameMax *= 2;
1388         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1389                                     ctxt->nameMax *
1390                                     sizeof(ctxt->nameTab[0]));
1391         if (tmp == NULL) {
1392             ctxt->nameMax /= 2;
1393             goto mem_error;
1394         }
1395         ctxt->nameTab = tmp;
1396     }
1397     ctxt->nameTab[ctxt->nameNr] = value;
1398     ctxt->name = value;
1399     return (ctxt->nameNr++);
1400 mem_error:
1401     xmlErrMemory(ctxt, NULL);
1402     return (-1);
1403 }
1404 /**
1405  * namePop:
1406  * @ctxt: an XML parser context
1407  *
1408  * Pops the top element name from the name stack
1409  *
1410  * Returns the name just removed
1411  */
1412 const xmlChar *
1413 namePop(xmlParserCtxtPtr ctxt)
1414 {
1415     const xmlChar *ret;
1416
1417     if ((ctxt == NULL) || (ctxt->nameNr <= 0))
1418         return (NULL);
1419     ctxt->nameNr--;
1420     if (ctxt->nameNr > 0)
1421         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1422     else
1423         ctxt->name = NULL;
1424     ret = ctxt->nameTab[ctxt->nameNr];
1425     ctxt->nameTab[ctxt->nameNr] = NULL;
1426     return (ret);
1427 }
1428
1429 static int spacePush(xmlParserCtxtPtr ctxt, int val) {
1430     if (ctxt->spaceNr >= ctxt->spaceMax) {
1431         ctxt->spaceMax *= 2;
1432         ctxt->spaceTab = (int *) xmlRealloc(ctxt->spaceTab,
1433                      ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
1434         if (ctxt->spaceTab == NULL) {
1435             xmlErrMemory(ctxt, NULL);
1436             return(0);
1437         }
1438     }
1439     ctxt->spaceTab[ctxt->spaceNr] = val;
1440     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
1441     return(ctxt->spaceNr++);
1442 }
1443
1444 static int spacePop(xmlParserCtxtPtr ctxt) {
1445     int ret;
1446     if (ctxt->spaceNr <= 0) return(0);
1447     ctxt->spaceNr--;
1448     if (ctxt->spaceNr > 0)
1449         ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
1450     else
1451         ctxt->space = &ctxt->spaceTab[0];
1452     ret = ctxt->spaceTab[ctxt->spaceNr];
1453     ctxt->spaceTab[ctxt->spaceNr] = -1;
1454     return(ret);
1455 }
1456
1457 /*
1458  * Macros for accessing the content. Those should be used only by the parser,
1459  * and not exported.
1460  *
1461  * Dirty macros, i.e. one often need to make assumption on the context to
1462  * use them
1463  *
1464  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
1465  *           To be used with extreme caution since operations consuming
1466  *           characters may move the input buffer to a different location !
1467  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
1468  *           This should be used internally by the parser
1469  *           only to compare to ASCII values otherwise it would break when
1470  *           running with UTF-8 encoding.
1471  *   RAW     same as CUR but in the input buffer, bypass any token
1472  *           extraction that may have been done
1473  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
1474  *           to compare on ASCII based substring.
1475  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
1476  *           strings without newlines within the parser.
1477  *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII 
1478  *           defined char within the parser.
1479  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
1480  *
1481  *   NEXT    Skip to the next character, this does the proper decoding
1482  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
1483  *   NEXTL(l) Skip the current unicode character of l xmlChars long.
1484  *   CUR_CHAR(l) returns the current unicode character (int), set l
1485  *           to the number of xmlChars used for the encoding [0-5].
1486  *   CUR_SCHAR  same but operate on a string instead of the context
1487  *   COPY_BUF  copy the current unicode char to the target buffer, increment
1488  *            the index
1489  *   GROW, SHRINK  handling of input buffers
1490  */
1491
1492 #define RAW (*ctxt->input->cur)
1493 #define CUR (*ctxt->input->cur)
1494 #define NXT(val) ctxt->input->cur[(val)]
1495 #define CUR_PTR ctxt->input->cur
1496
1497 #define CMP4( s, c1, c2, c3, c4 ) \
1498   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
1499     ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
1500 #define CMP5( s, c1, c2, c3, c4, c5 ) \
1501   ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
1502 #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
1503   ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
1504 #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
1505   ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
1506 #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
1507   ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
1508 #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
1509   ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
1510     ((unsigned char *) s)[ 8 ] == c9 )
1511 #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
1512   ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
1513     ((unsigned char *) s)[ 9 ] == c10 )
1514
1515 #define SKIP(val) do {                                                  \
1516     ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);                   \
1517     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
1518     if ((*ctxt->input->cur == 0) &&                                     \
1519         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))            \
1520             xmlPopInput(ctxt);                                          \
1521   } while (0)
1522
1523 #define SKIPL(val) do {                                                 \
1524     int skipl;                                                          \
1525     for(skipl=0; skipl<val; skipl++) {                                  \
1526         if (*(ctxt->input->cur) == '\n') {                              \
1527         ctxt->input->line++; ctxt->input->col = 1;                      \
1528         } else ctxt->input->col++;                                      \
1529         ctxt->nbChars++;                                                \
1530         ctxt->input->cur++;                                             \
1531     }                                                                   \
1532     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
1533     if ((*ctxt->input->cur == 0) &&                                     \
1534         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))            \
1535             xmlPopInput(ctxt);                                          \
1536   } while (0)
1537
1538 #define SHRINK if ((ctxt->progressive == 0) &&                          \
1539                    (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
1540                    (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
1541         xmlSHRINK (ctxt);
1542
1543 static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
1544     xmlParserInputShrink(ctxt->input);
1545     if ((*ctxt->input->cur == 0) &&
1546         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
1547             xmlPopInput(ctxt);
1548   }
1549
1550 #define GROW if ((ctxt->progressive == 0) &&                            \
1551                  (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))   \
1552         xmlGROW (ctxt);
1553
1554 static void xmlGROW (xmlParserCtxtPtr ctxt) {
1555     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
1556     if ((*ctxt->input->cur == 0) &&
1557         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
1558             xmlPopInput(ctxt);
1559 }
1560
1561 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
1562
1563 #define NEXT xmlNextChar(ctxt)
1564
1565 #define NEXT1 {                                                         \
1566         ctxt->input->col++;                                             \
1567         ctxt->input->cur++;                                             \
1568         ctxt->nbChars++;                                                \
1569         if (*ctxt->input->cur == 0)                                     \
1570             xmlParserInputGrow(ctxt->input, INPUT_CHUNK);               \
1571     }
1572
1573 #define NEXTL(l) do {                                                   \
1574     if (*(ctxt->input->cur) == '\n') {                                  \
1575         ctxt->input->line++; ctxt->input->col = 1;                      \
1576     } else ctxt->input->col++;                                          \
1577     ctxt->input->cur += l;                              \
1578     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
1579   } while (0)
1580
1581 #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
1582 #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
1583
1584 #define COPY_BUF(l,b,i,v)                                               \
1585     if (l == 1) b[i++] = (xmlChar) v;                                   \
1586     else i += xmlCopyCharMultiByte(&b[i],v)
1587
1588 /**
1589  * xmlSkipBlankChars:
1590  * @ctxt:  the XML parser context
1591  *
1592  * skip all blanks character found at that point in the input streams.
1593  * It pops up finished entities in the process if allowable at that point.
1594  *
1595  * Returns the number of space chars skipped
1596  */
1597
1598 int
1599 xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
1600     int res = 0;
1601
1602     /*
1603      * It's Okay to use CUR/NEXT here since all the blanks are on
1604      * the ASCII range.
1605      */
1606     if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
1607         const xmlChar *cur;
1608         /*
1609          * if we are in the document content, go really fast
1610          */
1611         cur = ctxt->input->cur;
1612         while (IS_BLANK_CH(*cur)) {
1613             if (*cur == '\n') {
1614                 ctxt->input->line++; ctxt->input->col = 1;
1615             }
1616             cur++;
1617             res++;
1618             if (*cur == 0) {
1619                 ctxt->input->cur = cur;
1620                 xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
1621                 cur = ctxt->input->cur;
1622             }
1623         }
1624         ctxt->input->cur = cur;
1625     } else {
1626         int cur;
1627         do {
1628             cur = CUR;
1629             while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
1630                 NEXT;
1631                 cur = CUR;
1632                 res++;
1633             }
1634             while ((cur == 0) && (ctxt->inputNr > 1) &&
1635                    (ctxt->instate != XML_PARSER_COMMENT)) {
1636                 xmlPopInput(ctxt);
1637                 cur = CUR;
1638             }
1639             /*
1640              * Need to handle support of entities branching here
1641              */
1642             if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
1643         } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
1644     }
1645     return(res);
1646 }
1647
1648 /************************************************************************
1649  *                                                                      *
1650  *              Commodity functions to handle entities                  *
1651  *                                                                      *
1652  ************************************************************************/
1653
1654 /**
1655  * xmlPopInput:
1656  * @ctxt:  an XML parser context
1657  *
1658  * xmlPopInput: the current input pointed by ctxt->input came to an end
1659  *          pop it and return the next char.
1660  *
1661  * Returns the current xmlChar in the parser context
1662  */
1663 xmlChar
1664 xmlPopInput(xmlParserCtxtPtr ctxt) {
1665     if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
1666     if (xmlParserDebugEntities)
1667         xmlGenericError(xmlGenericErrorContext,
1668                 "Popping input %d\n", ctxt->inputNr);
1669     xmlFreeInputStream(inputPop(ctxt));
1670     if ((*ctxt->input->cur == 0) &&
1671         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
1672             return(xmlPopInput(ctxt));
1673     return(CUR);
1674 }
1675
1676 /**
1677  * xmlPushInput:
1678  * @ctxt:  an XML parser context
1679  * @input:  an XML parser input fragment (entity, XML fragment ...).
1680  *
1681  * xmlPushInput: switch to a new input stream which is stacked on top
1682  *               of the previous one(s).
1683  */
1684 void
1685 xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
1686     if (input == NULL) return;
1687
1688     if (xmlParserDebugEntities) {
1689         if ((ctxt->input != NULL) && (ctxt->input->filename))
1690             xmlGenericError(xmlGenericErrorContext,
1691                     "%s(%d): ", ctxt->input->filename,
1692                     ctxt->input->line);
1693         xmlGenericError(xmlGenericErrorContext,
1694                 "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
1695     }
1696     inputPush(ctxt, input);
1697     GROW;
1698 }
1699
1700 /**
1701  * xmlParseCharRef:
1702  * @ctxt:  an XML parser context
1703  *
1704  * parse Reference declarations
1705  *
1706  * [66] CharRef ::= '&#' [0-9]+ ';' |
1707  *                  '&#x' [0-9a-fA-F]+ ';'
1708  *
1709  * [ WFC: Legal Character ]
1710  * Characters referred to using character references must match the
1711  * production for Char. 
1712  *
1713  * Returns the value parsed (as an int), 0 in case of error
1714  */
1715 int
1716 xmlParseCharRef(xmlParserCtxtPtr ctxt) {
1717     unsigned int val = 0;
1718     int count = 0;
1719     unsigned int outofrange = 0;
1720
1721     /*
1722      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
1723      */
1724     if ((RAW == '&') && (NXT(1) == '#') &&
1725         (NXT(2) == 'x')) {
1726         SKIP(3);
1727         GROW;
1728         while (RAW != ';') { /* loop blocked by count */
1729             if (count++ > 20) {
1730                 count = 0;
1731                 GROW;
1732             }
1733             if ((RAW >= '0') && (RAW <= '9')) 
1734                 val = val * 16 + (CUR - '0');
1735             else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
1736                 val = val * 16 + (CUR - 'a') + 10;
1737             else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
1738                 val = val * 16 + (CUR - 'A') + 10;
1739             else {
1740                 xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
1741                 val = 0;
1742                 break;
1743             }
1744             if (val > 0x10FFFF)
1745                 outofrange = val;
1746
1747             NEXT;
1748             count++;
1749         }
1750         if (RAW == ';') {
1751             /* on purpose to avoid reentrancy problems with NEXT and SKIP */
1752             ctxt->input->col++;
1753             ctxt->nbChars ++;
1754             ctxt->input->cur++;
1755         }
1756     } else if  ((RAW == '&') && (NXT(1) == '#')) {
1757         SKIP(2);
1758         GROW;
1759         while (RAW != ';') { /* loop blocked by count */
1760             if (count++ > 20) {
1761                 count = 0;
1762                 GROW;
1763             }
1764             if ((RAW >= '0') && (RAW <= '9')) 
1765                 val = val * 10 + (CUR - '0');
1766             else {
1767                 xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
1768                 val = 0;
1769                 break;
1770             }
1771             if (val > 0x10FFFF)
1772                 outofrange = val;
1773
1774             NEXT;
1775             count++;
1776         }
1777         if (RAW == ';') {
1778             /* on purpose to avoid reentrancy problems with NEXT and SKIP */
1779             ctxt->input->col++;
1780             ctxt->nbChars ++;
1781             ctxt->input->cur++;
1782         }
1783     } else {
1784         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
1785     }
1786
1787     /*
1788      * [ WFC: Legal Character ]
1789      * Characters referred to using character references must match the
1790      * production for Char. 
1791      */
1792     if ((IS_CHAR(val) && (outofrange == 0))) {
1793         return(val);
1794     } else {
1795         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
1796                           "xmlParseCharRef: invalid xmlChar value %d\n",
1797                           val);
1798     }
1799     return(0);
1800 }
1801
1802 /**
1803  * xmlParseStringCharRef:
1804  * @ctxt:  an XML parser context
1805  * @str:  a pointer to an index in the string
1806  *
1807  * parse Reference declarations, variant parsing from a string rather
1808  * than an an input flow.
1809  *
1810  * [66] CharRef ::= '&#' [0-9]+ ';' |
1811  *                  '&#x' [0-9a-fA-F]+ ';'
1812  *
1813  * [ WFC: Legal Character ]
1814  * Characters referred to using character references must match the
1815  * production for Char. 
1816  *
1817  * Returns the value parsed (as an int), 0 in case of error, str will be
1818  *         updated to the current value of the index
1819  */
1820 static int
1821 xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
1822     const xmlChar *ptr;
1823     xmlChar cur;
1824     unsigned int val = 0;
1825     unsigned int outofrange = 0;
1826
1827     if ((str == NULL) || (*str == NULL)) return(0);
1828     ptr = *str;
1829     cur = *ptr;
1830     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
1831         ptr += 3;
1832         cur = *ptr;
1833         while (cur != ';') { /* Non input consuming loop */
1834             if ((cur >= '0') && (cur <= '9')) 
1835                 val = val * 16 + (cur - '0');
1836             else if ((cur >= 'a') && (cur <= 'f'))
1837                 val = val * 16 + (cur - 'a') + 10;
1838             else if ((cur >= 'A') && (cur <= 'F'))
1839                 val = val * 16 + (cur - 'A') + 10;
1840             else {
1841                 xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
1842                 val = 0;
1843                 break;
1844             }
1845             if (val > 0x10FFFF)
1846                 outofrange = val;
1847
1848             ptr++;
1849             cur = *ptr;
1850         }
1851         if (cur == ';')
1852             ptr++;
1853     } else if  ((cur == '&') && (ptr[1] == '#')){
1854         ptr += 2;
1855         cur = *ptr;
1856         while (cur != ';') { /* Non input consuming loops */
1857             if ((cur >= '0') && (cur <= '9')) 
1858                 val = val * 10 + (cur - '0');
1859             else {
1860                 xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
1861                 val = 0;
1862                 break;
1863             }
1864             if (val > 0x10FFFF)
1865                 outofrange = val;
1866
1867             ptr++;
1868             cur = *ptr;
1869         }
1870         if (cur == ';')
1871             ptr++;
1872     } else {
1873         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
1874         return(0);
1875     }
1876     *str = ptr;
1877
1878     /*
1879      * [ WFC: Legal Character ]
1880      * Characters referred to using character references must match the
1881      * production for Char. 
1882      */
1883     if ((IS_CHAR(val) && (outofrange == 0))) {
1884         return(val);
1885     } else {
1886         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
1887                           "xmlParseStringCharRef: invalid xmlChar value %d\n",
1888                           val);
1889     }
1890     return(0);
1891 }
1892
1893 /**
1894  * xmlNewBlanksWrapperInputStream:
1895  * @ctxt:  an XML parser context
1896  * @entity:  an Entity pointer
1897  *
1898  * Create a new input stream for wrapping
1899  * blanks around a PEReference
1900  *
1901  * Returns the new input stream or NULL
1902  */
1903  
1904 static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
1905  
1906 static xmlParserInputPtr
1907 xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
1908     xmlParserInputPtr input;
1909     xmlChar *buffer;
1910     size_t length;
1911     if (entity == NULL) {
1912         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
1913                     "xmlNewBlanksWrapperInputStream entity\n");
1914         return(NULL);
1915     }
1916     if (xmlParserDebugEntities)
1917         xmlGenericError(xmlGenericErrorContext,
1918                 "new blanks wrapper for entity: %s\n", entity->name);
1919     input = xmlNewInputStream(ctxt);
1920     if (input == NULL) {
1921         return(NULL);
1922     }
1923     length = xmlStrlen(entity->name) + 5;
1924     buffer = xmlMallocAtomic(length);
1925     if (buffer == NULL) {
1926         xmlErrMemory(ctxt, NULL);
1927         return(NULL);
1928     }
1929     buffer [0] = ' ';
1930     buffer [1] = '%';
1931     buffer [length-3] = ';';
1932     buffer [length-2] = ' ';
1933     buffer [length-1] = 0;
1934     memcpy(buffer + 2, entity->name, length - 5);
1935     input->free = deallocblankswrapper;
1936     input->base = buffer;
1937     input->cur = buffer;
1938     input->length = length;
1939     input->end = &buffer[length];
1940     return(input);
1941 }
1942
1943 /**
1944  * xmlParserHandlePEReference:
1945  * @ctxt:  the parser context
1946  * 
1947  * [69] PEReference ::= '%' Name ';'
1948  *
1949  * [ WFC: No Recursion ]
1950  * A parsed entity must not contain a recursive
1951  * reference to itself, either directly or indirectly. 
1952  *
1953  * [ WFC: Entity Declared ]
1954  * In a document without any DTD, a document with only an internal DTD
1955  * subset which contains no parameter entity references, or a document
1956  * with "standalone='yes'", ...  ... The declaration of a parameter
1957  * entity must precede any reference to it...
1958  *
1959  * [ VC: Entity Declared ]
1960  * In a document with an external subset or external parameter entities
1961  * with "standalone='no'", ...  ... The declaration of a parameter entity
1962  * must precede any reference to it...
1963  *
1964  * [ WFC: In DTD ]
1965  * Parameter-entity references may only appear in the DTD.
1966  * NOTE: misleading but this is handled.
1967  *
1968  * A PEReference may have been detected in the current input stream
1969  * the handling is done accordingly to 
1970  *      http://www.w3.org/TR/REC-xml#entproc
1971  * i.e. 
1972  *   - Included in literal in entity values
1973  *   - Included as Parameter Entity reference within DTDs
1974  */
1975 void
1976 xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
1977     const xmlChar *name;
1978     xmlEntityPtr entity = NULL;
1979     xmlParserInputPtr input;
1980
1981     if (RAW != '%') return;
1982     switch(ctxt->instate) {
1983         case XML_PARSER_CDATA_SECTION:
1984             return;
1985         case XML_PARSER_COMMENT:
1986             return;
1987         case XML_PARSER_START_TAG:
1988             return;
1989         case XML_PARSER_END_TAG:
1990             return;
1991         case XML_PARSER_EOF:
1992             xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
1993             return;
1994         case XML_PARSER_PROLOG:
1995         case XML_PARSER_START:
1996         case XML_PARSER_MISC:
1997             xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
1998             return;
1999         case XML_PARSER_ENTITY_DECL:
2000         case XML_PARSER_CONTENT:
2001         case XML_PARSER_ATTRIBUTE_VALUE:
2002         case XML_PARSER_PI:
2003         case XML_PARSER_SYSTEM_LITERAL:
2004         case XML_PARSER_PUBLIC_LITERAL:
2005             /* we just ignore it there */
2006             return;
2007         case XML_PARSER_EPILOG:
2008             xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
2009             return;
2010         case XML_PARSER_ENTITY_VALUE:
2011             /*
2012              * NOTE: in the case of entity values, we don't do the
2013              *       substitution here since we need the literal
2014              *       entity value to be able to save the internal
2015              *       subset of the document.
2016              *       This will be handled by xmlStringDecodeEntities
2017              */
2018             return;
2019         case XML_PARSER_DTD:
2020             /*
2021              * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
2022              * In the internal DTD subset, parameter-entity references
2023              * can occur only where markup declarations can occur, not
2024              * within markup declarations.
2025              * In that case this is handled in xmlParseMarkupDecl
2026              */
2027             if ((ctxt->external == 0) && (ctxt->inputNr == 1))
2028                 return;
2029             if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
2030                 return;
2031             break;
2032         case XML_PARSER_IGNORE:
2033             return;
2034     }
2035
2036     NEXT;
2037     name = xmlParseName(ctxt);
2038     if (xmlParserDebugEntities)
2039         xmlGenericError(xmlGenericErrorContext,
2040                 "PEReference: %s\n", name);
2041     if (name == NULL) {
2042         xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
2043     } else {
2044         if (RAW == ';') {
2045             NEXT;
2046             if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
2047                 entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
2048             if (entity == NULL) {
2049                 
2050                 /*
2051                  * [ WFC: Entity Declared ]
2052                  * In a document without any DTD, a document with only an
2053                  * internal DTD subset which contains no parameter entity
2054                  * references, or a document with "standalone='yes'", ...
2055                  * ... The declaration of a parameter entity must precede
2056                  * any reference to it...
2057                  */
2058                 if ((ctxt->standalone == 1) ||
2059                     ((ctxt->hasExternalSubset == 0) &&
2060                      (ctxt->hasPErefs == 0))) {
2061                     xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
2062                          "PEReference: %%%s; not found\n", name);
2063                 } else {
2064                     /*
2065                      * [ VC: Entity Declared ]
2066                      * In a document with an external subset or external
2067                      * parameter entities with "standalone='no'", ...
2068                      * ... The declaration of a parameter entity must precede
2069                      * any reference to it...
2070                      */
2071                     if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
2072                         xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
2073                                          "PEReference: %%%s; not found\n",
2074                                          name);
2075                     } else 
2076                         xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
2077                                       "PEReference: %%%s; not found\n",
2078                                       name, NULL);
2079                     ctxt->valid = 0;
2080                 }
2081             } else if (ctxt->input->free != deallocblankswrapper) {
2082                     input = xmlNewBlanksWrapperInputStream(ctxt, entity);
2083                     xmlPushInput(ctxt, input);
2084             } else {
2085                 if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
2086                     (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
2087                     xmlChar start[4];
2088                     xmlCharEncoding enc;
2089
2090                     /*
2091                      * handle the extra spaces added before and after
2092                      * c.f. http://www.w3.org/TR/REC-xml#as-PE
2093                      * this is done independently.
2094                      */
2095                     input = xmlNewEntityInputStream(ctxt, entity);
2096                     xmlPushInput(ctxt, input);
2097
2098                     /* 
2099                      * Get the 4 first bytes and decode the charset
2100                      * if enc != XML_CHAR_ENCODING_NONE
2101                      * plug some encoding conversion routines.
2102                      * Note that, since we may have some non-UTF8
2103                      * encoding (like UTF16, bug 135229), the 'length'
2104                      * is not known, but we can calculate based upon
2105                      * the amount of data in the buffer.
2106                      */
2107                     GROW
2108                     if ((ctxt->input->end - ctxt->input->cur)>=4) {
2109                         start[0] = RAW;
2110                         start[1] = NXT(1);
2111                         start[2] = NXT(2);
2112                         start[3] = NXT(3);
2113                         enc = xmlDetectCharEncoding(start, 4);
2114                         if (enc != XML_CHAR_ENCODING_NONE) {
2115                             xmlSwitchEncoding(ctxt, enc);
2116                         }
2117                     }
2118
2119                     if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
2120                         (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
2121                         (IS_BLANK_CH(NXT(5)))) {
2122                         xmlParseTextDecl(ctxt);
2123                     }
2124                 } else {
2125                     xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
2126                              "PEReference: %s is not a parameter entity\n",
2127                                       name);
2128                 }
2129             }
2130         } else {
2131             xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
2132         }
2133     }
2134 }
2135
2136 /*
2137  * Macro used to grow the current buffer.
2138  */
2139 #define growBuffer(buffer) {                                            \
2140     xmlChar *tmp;                                                       \
2141     buffer##_size *= 2;                                                 \
2142     tmp = (xmlChar *)                                                   \
2143                 xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));    \
2144     if (tmp == NULL) goto mem_error;                                    \
2145     buffer = tmp;                                                       \
2146 }
2147
2148 /**
2149  * xmlStringLenDecodeEntities:
2150  * @ctxt:  the parser context
2151  * @str:  the input string
2152  * @len: the string length
2153  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2154  * @end:  an end marker xmlChar, 0 if none
2155  * @end2:  an end marker xmlChar, 0 if none
2156  * @end3:  an end marker xmlChar, 0 if none
2157  * 
2158  * Takes a entity string content and process to do the adequate substitutions.
2159  *
2160  * [67] Reference ::= EntityRef | CharRef
2161  *
2162  * [69] PEReference ::= '%' Name ';'
2163  *
2164  * Returns A newly allocated string with the substitution done. The caller
2165  *      must deallocate it !
2166  */
2167 xmlChar *
2168 xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2169                       int what, xmlChar end, xmlChar  end2, xmlChar end3) {
2170     xmlChar *buffer = NULL;
2171     int buffer_size = 0;
2172
2173     xmlChar *current = NULL;
2174     const xmlChar *last;
2175     xmlEntityPtr ent;
2176     int c,l;
2177     int nbchars = 0;
2178
2179     if ((ctxt == NULL) || (str == NULL) || (len < 0))
2180         return(NULL);
2181     last = str + len;
2182
2183     if (ctxt->depth > 40) {
2184         xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2185         return(NULL);
2186     }
2187
2188     /*
2189      * allocate a translation buffer.
2190      */
2191     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
2192     buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
2193     if (buffer == NULL) goto mem_error;
2194
2195     /*
2196      * OK loop until we reach one of the ending char or a size limit.
2197      * we are operating on already parsed values.
2198      */
2199     if (str < last)
2200         c = CUR_SCHAR(str, l);
2201     else
2202         c = 0;
2203     while ((c != 0) && (c != end) && /* non input consuming loop */
2204            (c != end2) && (c != end3)) {
2205
2206         if (c == 0) break;
2207         if ((c == '&') && (str[1] == '#')) {
2208             int val = xmlParseStringCharRef(ctxt, &str);
2209             if (val != 0) {
2210                 COPY_BUF(0,buffer,nbchars,val);
2211             }
2212             if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
2213                 growBuffer(buffer);
2214             }
2215         } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
2216             if (xmlParserDebugEntities)
2217                 xmlGenericError(xmlGenericErrorContext,
2218                         "String decoding Entity Reference: %.30s\n",
2219                         str);
2220             ent = xmlParseStringEntityRef(ctxt, &str);
2221             if ((ent != NULL) &&
2222                 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
2223                 if (ent->content != NULL) {
2224                     COPY_BUF(0,buffer,nbchars,ent->content[0]);
2225                     if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
2226                         growBuffer(buffer);
2227                     }
2228                 } else {
2229                     xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
2230                             "predefined entity has no content\n");
2231                 }
2232             } else if ((ent != NULL) && (ent->content != NULL)) {
2233                 xmlChar *rep;
2234
2235                 ctxt->depth++;
2236                 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2237                                               0, 0, 0);
2238                 ctxt->depth--;
2239                 if (rep != NULL) {
2240                     current = rep;
2241                     while (*current != 0) { /* non input consuming loop */
2242                         buffer[nbchars++] = *current++;
2243                         if (nbchars >
2244                             buffer_size - XML_PARSER_BUFFER_SIZE) {
2245                             growBuffer(buffer);
2246                         }
2247                     }
2248                     xmlFree(rep);
2249                 }
2250             } else if (ent != NULL) {
2251                 int i = xmlStrlen(ent->name);
2252                 const xmlChar *cur = ent->name;
2253
2254                 buffer[nbchars++] = '&';
2255                 if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
2256                     growBuffer(buffer);
2257                 }
2258                 for (;i > 0;i--)
2259                     buffer[nbchars++] = *cur++;
2260                 buffer[nbchars++] = ';';
2261             }
2262         } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
2263             if (xmlParserDebugEntities)
2264                 xmlGenericError(xmlGenericErrorContext,
2265                         "String decoding PE Reference: %.30s\n", str);
2266             ent = xmlParseStringPEReference(ctxt, &str);
2267             if (ent != NULL) {
2268                 xmlChar *rep;
2269
2270                 ctxt->depth++;
2271                 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2272                                               0, 0, 0);
2273                 ctxt->depth--;
2274                 if (rep != NULL) {
2275                     current = rep;
2276                     while (*current != 0) { /* non input consuming loop */
2277                         buffer[nbchars++] = *current++;
2278                         if (nbchars >
2279                             buffer_size - XML_PARSER_BUFFER_SIZE) {
2280                             growBuffer(buffer);
2281                         }
2282                     }
2283                     xmlFree(rep);
2284                 }
2285             }
2286         } else {
2287             COPY_BUF(l,buffer,nbchars,c);
2288             str += l;
2289             if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
2290               growBuffer(buffer);
2291             }
2292         }
2293         if (str < last)
2294             c = CUR_SCHAR(str, l);
2295         else
2296             c = 0;
2297     }
2298     buffer[nbchars++] = 0;
2299     return(buffer);
2300
2301 mem_error:
2302     xmlErrMemory(ctxt, NULL);
2303     return(NULL);
2304 }
2305
2306 /**
2307  * xmlStringDecodeEntities:
2308  * @ctxt:  the parser context
2309  * @str:  the input string
2310  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2311  * @end:  an end marker xmlChar, 0 if none
2312  * @end2:  an end marker xmlChar, 0 if none
2313  * @end3:  an end marker xmlChar, 0 if none
2314  * 
2315  * Takes a entity string content and process to do the adequate substitutions.
2316  *
2317  * [67] Reference ::= EntityRef | CharRef
2318  *
2319  * [69] PEReference ::= '%' Name ';'
2320  *
2321  * Returns A newly allocated string with the substitution done. The caller
2322  *      must deallocate it !
2323  */
2324 xmlChar *
2325 xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
2326                         xmlChar end, xmlChar  end2, xmlChar end3) {
2327     if ((ctxt == NULL) || (str == NULL)) return(NULL);
2328     return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
2329            end, end2, end3));
2330 }
2331
2332 /************************************************************************
2333  *                                                                      *
2334  *              Commodity functions, cleanup needed ?                   *
2335  *                                                                      *
2336  ************************************************************************/
2337
2338 /**
2339  * areBlanks:
2340  * @ctxt:  an XML parser context
2341  * @str:  a xmlChar *
2342  * @len:  the size of @str
2343  * @blank_chars: we know the chars are blanks
2344  *
2345  * Is this a sequence of blank chars that one can ignore ?
2346  *
2347  * Returns 1 if ignorable 0 otherwise.
2348  */
2349
2350 static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2351                      int blank_chars) {
2352     int i, ret;
2353     xmlNodePtr lastChild;
2354
2355     /*
2356      * Don't spend time trying to differentiate them, the same callback is
2357      * used !
2358      */
2359     if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
2360         return(0);
2361
2362     /*
2363      * Check for xml:space value.
2364      */
2365     if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
2366         (*(ctxt->space) == -2))
2367         return(0);
2368
2369     /*
2370      * Check that the string is made of blanks
2371      */
2372     if (blank_chars == 0) {
2373         for (i = 0;i < len;i++)
2374             if (!(IS_BLANK_CH(str[i]))) return(0);
2375     }
2376
2377     /*
2378      * Look if the element is mixed content in the DTD if available
2379      */
2380     if (ctxt->node == NULL) return(0);
2381     if (ctxt->myDoc != NULL) {
2382         ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
2383         if (ret == 0) return(1);
2384         if (ret == 1) return(0);
2385     }
2386
2387     /*
2388      * Otherwise, heuristic :-\
2389      */
2390     if ((RAW != '<') && (RAW != 0xD)) return(0);
2391     if ((ctxt->node->children == NULL) &&
2392         (RAW == '<') && (NXT(1) == '/')) return(0);
2393
2394     lastChild = xmlGetLastChild(ctxt->node);
2395     if (lastChild == NULL) {
2396         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
2397             (ctxt->node->content != NULL)) return(0);
2398     } else if (xmlNodeIsText(lastChild))
2399         return(0);
2400     else if ((ctxt->node->children != NULL) &&
2401              (xmlNodeIsText(ctxt->node->children)))
2402         return(0);
2403     return(1);
2404 }
2405
2406 /************************************************************************
2407  *                                                                      *
2408  *              Extra stuff for namespace support                       *
2409  *      Relates to http://www.w3.org/TR/WD-xml-names                    *
2410  *                                                                      *
2411  ************************************************************************/
2412
2413 /**
2414  * xmlSplitQName:
2415  * @ctxt:  an XML parser context
2416  * @name:  an XML parser context
2417  * @prefix:  a xmlChar ** 
2418  *
2419  * parse an UTF8 encoded XML qualified name string
2420  *
2421  * [NS 5] QName ::= (Prefix ':')? LocalPart
2422  *
2423  * [NS 6] Prefix ::= NCName
2424  *
2425  * [NS 7] LocalPart ::= NCName
2426  *
2427  * Returns the local part, and prefix is updated
2428  *   to get the Prefix if any.
2429  */
2430
2431 xmlChar *
2432 xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
2433     xmlChar buf[XML_MAX_NAMELEN + 5];
2434     xmlChar *buffer = NULL;
2435     int len = 0;
2436     int max = XML_MAX_NAMELEN;
2437     xmlChar *ret = NULL;
2438     const xmlChar *cur = name;
2439     int c;
2440
2441     if (prefix == NULL) return(NULL);
2442     *prefix = NULL;
2443
2444     if (cur == NULL) return(NULL);
2445
2446 #ifndef XML_XML_NAMESPACE
2447     /* xml: prefix is not really a namespace */
2448     if ((cur[0] == 'x') && (cur[1] == 'm') &&
2449         (cur[2] == 'l') && (cur[3] == ':'))
2450         return(xmlStrdup(name));
2451 #endif
2452
2453     /* nasty but well=formed */
2454     if (cur[0] == ':')
2455         return(xmlStrdup(name));
2456
2457     c = *cur++;
2458     while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
2459         buf[len++] = c;
2460         c = *cur++;
2461     }
2462     if (len >= max) {
2463         /*
2464          * Okay someone managed to make a huge name, so he's ready to pay
2465          * for the processing speed.
2466          */
2467         max = len * 2;
2468         
2469         buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
2470         if (buffer == NULL) {
2471             xmlErrMemory(ctxt, NULL);
2472             return(NULL);
2473         }
2474         memcpy(buffer, buf, len);
2475         while ((c != 0) && (c != ':')) { /* tested bigname.xml */
2476             if (len + 10 > max) {
2477                 xmlChar *tmp;
2478
2479                 max *= 2;
2480                 tmp = (xmlChar *) xmlRealloc(buffer,
2481                                                 max * sizeof(xmlChar));
2482                 if (tmp == NULL) {
2483                     xmlFree(tmp);
2484                     xmlErrMemory(ctxt, NULL);
2485                     return(NULL);
2486                 }
2487                 buffer = tmp;
2488             }
2489             buffer[len++] = c;
2490             c = *cur++;
2491         }
2492         buffer[len] = 0;
2493     }
2494     
2495     if ((c == ':') && (*cur == 0)) {
2496         if (buffer != NULL)
2497             xmlFree(buffer);
2498         *prefix = NULL;
2499         return(xmlStrdup(name));
2500     }
2501
2502     if (buffer == NULL)
2503         ret = xmlStrndup(buf, len);
2504     else {
2505         ret = buffer;
2506         buffer = NULL;
2507         max = XML_MAX_NAMELEN;
2508     }
2509
2510
2511     if (c == ':') {
2512         c = *cur;
2513         *prefix = ret;
2514         if (c == 0) {
2515             return(xmlStrndup(BAD_CAST "", 0));
2516         }
2517         len = 0;
2518
2519         /*
2520          * Check that the first character is proper to start
2521          * a new name
2522          */
2523         if (!(((c >= 0x61) && (c <= 0x7A)) ||
2524               ((c >= 0x41) && (c <= 0x5A)) ||
2525               (c == '_') || (c == ':'))) {
2526             int l;
2527             int first = CUR_SCHAR(cur, l);
2528
2529             if (!IS_LETTER(first) && (first != '_')) {
2530                 xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
2531                             "Name %s is not XML Namespace compliant\n",
2532                                   name);
2533             }
2534         }
2535         cur++;
2536
2537         while ((c != 0) && (len < max)) { /* tested bigname2.xml */
2538             buf[len++] = c;
2539             c = *cur++;
2540         }
2541         if (len >= max) {
2542             /*
2543              * Okay someone managed to make a huge name, so he's ready to pay
2544              * for the processing speed.
2545              */
2546             max = len * 2;
2547             
2548             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
2549             if (buffer == NULL) {
2550                 xmlErrMemory(ctxt, NULL);
2551                 return(NULL);
2552             }
2553             memcpy(buffer, buf, len);
2554             while (c != 0) { /* tested bigname2.xml */
2555                 if (len + 10 > max) {
2556                     xmlChar *tmp;
2557
2558                     max *= 2;
2559                     tmp = (xmlChar *) xmlRealloc(buffer,
2560                                                     max * sizeof(xmlChar));
2561                     if (tmp == NULL) {
2562                         xmlErrMemory(ctxt, NULL);
2563                         xmlFree(buffer);
2564                         return(NULL);
2565                     }
2566                     buffer = tmp;
2567                 }
2568                 buffer[len++] = c;
2569                 c = *cur++;
2570             }
2571             buffer[len] = 0;
2572         }
2573         
2574         if (buffer == NULL)
2575             ret = xmlStrndup(buf, len);
2576         else {
2577             ret = buffer;
2578         }
2579     }
2580
2581     return(ret);
2582 }
2583
2584 /************************************************************************
2585  *                                                                      *
2586  *                      The parser itself                               *
2587  *      Relates to http://www.w3.org/TR/REC-xml                         *
2588  *                                                                      *
2589  ************************************************************************/
2590
2591 static const xmlChar * xmlParseNameComplex(xmlParserCtxtPtr ctxt);
2592 static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
2593                                           int *len, int *alloc, int normalize);
2594
2595 /**
2596  * xmlParseName:
2597  * @ctxt:  an XML parser context
2598  *
2599  * parse an XML name.
2600  *
2601  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
2602  *                  CombiningChar | Extender
2603  *
2604  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
2605  *
2606  * [6] Names ::= Name (#x20 Name)*
2607  *
2608  * Returns the Name parsed or NULL
2609  */
2610
2611 const xmlChar *
2612 xmlParseName(xmlParserCtxtPtr ctxt) {
2613     const xmlChar *in;
2614     const xmlChar *ret;
2615     int count = 0;
2616
2617     GROW;
2618
2619     /*
2620      * Accelerator for simple ASCII names
2621      */
2622     in = ctxt->input->cur;
2623     if (((*in >= 0x61) && (*in <= 0x7A)) ||
2624         ((*in >= 0x41) && (*in <= 0x5A)) ||
2625         (*in == '_') || (*in == ':')) {
2626         in++;
2627         while (((*in >= 0x61) && (*in <= 0x7A)) ||
2628                ((*in >= 0x41) && (*in <= 0x5A)) ||
2629                ((*in >= 0x30) && (*in <= 0x39)) ||
2630                (*in == '_') || (*in == '-') ||
2631                (*in == ':') || (*in == '.'))
2632             in++;
2633         if ((*in > 0) && (*in < 0x80)) {
2634             count = in - ctxt->input->cur;
2635             ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
2636             ctxt->input->cur = in;
2637             ctxt->nbChars += count;
2638             ctxt->input->col += count;
2639             if (ret == NULL)
2640                 xmlErrMemory(ctxt, NULL);
2641             return(ret);
2642         }
2643     }
2644     return(xmlParseNameComplex(ctxt));
2645 }
2646
2647 /**
2648  * xmlParseNameAndCompare:
2649  * @ctxt:  an XML parser context
2650  *
2651  * parse an XML name and compares for match
2652  * (specialized for endtag parsing)
2653  *
2654  * Returns NULL for an illegal name, (xmlChar*) 1 for success
2655  * and the name for mismatch
2656  */
2657
2658 static const xmlChar *
2659 xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
2660     register const xmlChar *cmp = other;
2661     register const xmlChar *in;
2662     const xmlChar *ret;
2663
2664     GROW;
2665     
2666     in = ctxt->input->cur;
2667     while (*in != 0 && *in == *cmp) {
2668         ++in;
2669         ++cmp;
2670         ctxt->input->col++;
2671     }
2672     if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
2673         /* success */
2674         ctxt->input->cur = in;
2675         return (const xmlChar*) 1;
2676     }
2677     /* failure (or end of input buffer), check with full function */
2678     ret = xmlParseName (ctxt);
2679     /* strings coming from the dictionnary direct compare possible */
2680     if (ret == other) {
2681         return (const xmlChar*) 1;
2682     }
2683     return ret;
2684 }
2685
2686 static const xmlChar *
2687 xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
2688     int len = 0, l;
2689     int c;
2690     int count = 0;
2691
2692     /*
2693      * Handler for more complex cases
2694      */
2695     GROW;
2696     c = CUR_CHAR(l);
2697     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
2698         (!IS_LETTER(c) && (c != '_') &&
2699          (c != ':'))) {
2700         return(NULL);
2701     }
2702
2703     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
2704            ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
2705             (c == '.') || (c == '-') ||
2706             (c == '_') || (c == ':') || 
2707             (IS_COMBINING(c)) ||
2708             (IS_EXTENDER(c)))) {
2709         if (count++ > 100) {
2710             count = 0;
2711             GROW;
2712         }
2713         len += l;
2714         NEXTL(l);
2715         c = CUR_CHAR(l);
2716     }
2717     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
2718         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
2719     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
2720 }
2721
2722 /**
2723  * xmlParseStringName:
2724  * @ctxt:  an XML parser context
2725  * @str:  a pointer to the string pointer (IN/OUT)
2726  *
2727  * parse an XML name.
2728  *
2729  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
2730  *                  CombiningChar | Extender
2731  *
2732  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
2733  *
2734  * [6] Names ::= Name (#x20 Name)*
2735  *
2736  * Returns the Name parsed or NULL. The @str pointer 
2737  * is updated to the current location in the string.
2738  */
2739
2740 static xmlChar *
2741 xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
2742     xmlChar buf[XML_MAX_NAMELEN + 5];
2743     const xmlChar *cur = *str;
2744     int len = 0, l;
2745     int c;
2746
2747     c = CUR_SCHAR(cur, l);
2748     if (!IS_LETTER(c) && (c != '_') &&
2749         (c != ':')) {
2750         return(NULL);
2751     }
2752
2753     while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigentname.xml */
2754            (c == '.') || (c == '-') ||
2755            (c == '_') || (c == ':') || 
2756            (IS_COMBINING(c)) ||
2757            (IS_EXTENDER(c))) {
2758         COPY_BUF(l,buf,len,c);
2759         cur += l;
2760         c = CUR_SCHAR(cur, l);
2761         if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
2762             /*
2763              * Okay someone managed to make a huge name, so he's ready to pay
2764              * for the processing speed.
2765              */
2766             xmlChar *buffer;
2767             int max = len * 2;
2768             
2769             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
2770             if (buffer == NULL) {
2771                 xmlErrMemory(ctxt, NULL);
2772                 return(NULL);
2773             }
2774             memcpy(buffer, buf, len);
2775             while ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
2776                      /* test bigentname.xml */
2777                    (c == '.') || (c == '-') ||
2778                    (c == '_') || (c == ':') || 
2779                    (IS_COMBINING(c)) ||
2780                    (IS_EXTENDER(c))) {
2781                 if (len + 10 > max) {
2782                     xmlChar *tmp;
2783                     max *= 2;
2784                     tmp = (xmlChar *) xmlRealloc(buffer,
2785                                                     max * sizeof(xmlChar));
2786                     if (tmp == NULL) {
2787                         xmlErrMemory(ctxt, NULL);
2788                         xmlFree(buffer);
2789                         return(NULL);
2790                     }
2791                     buffer = tmp;
2792                 }
2793                 COPY_BUF(l,buffer,len,c);
2794                 cur += l;
2795                 c = CUR_SCHAR(cur, l);
2796             }
2797             buffer[len] = 0;
2798             *str = cur;
2799             return(buffer);
2800         }
2801     }
2802     *str = cur;
2803     return(xmlStrndup(buf, len));
2804 }
2805
2806 /**
2807  * xmlParseNmtoken:
2808  * @ctxt:  an XML parser context
2809  * 
2810  * parse an XML Nmtoken.
2811  *
2812  * [7] Nmtoken ::= (NameChar)+
2813  *
2814  * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
2815  *
2816  * Returns the Nmtoken parsed or NULL
2817  */
2818
2819 xmlChar *
2820 xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
2821     xmlChar buf[XML_MAX_NAMELEN + 5];
2822     int len = 0, l;
2823     int c;
2824     int count = 0;
2825
2826     GROW;
2827     c = CUR_CHAR(l);
2828
2829     while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */
2830            (c == '.') || (c == '-') ||
2831            (c == '_') || (c == ':') || 
2832            (IS_COMBINING(c)) ||
2833            (IS_EXTENDER(c))) {
2834         if (count++ > 100) {
2835             count = 0;
2836             GROW;
2837         }
2838         COPY_BUF(l,buf,len,c);
2839         NEXTL(l);
2840         c = CUR_CHAR(l);
2841         if (len >= XML_MAX_NAMELEN) {
2842             /*
2843              * Okay someone managed to make a huge token, so he's ready to pay
2844              * for the processing speed.
2845              */
2846             xmlChar *buffer;
2847             int max = len * 2;
2848             
2849             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
2850             if (buffer == NULL) {
2851                 xmlErrMemory(ctxt, NULL);
2852                 return(NULL);
2853             }
2854             memcpy(buffer, buf, len);
2855             while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */
2856                    (c == '.') || (c == '-') ||
2857                    (c == '_') || (c == ':') || 
2858                    (IS_COMBINING(c)) ||
2859                    (IS_EXTENDER(c))) {
2860                 if (count++ > 100) {
2861                     count = 0;
2862                     GROW;
2863                 }
2864                 if (len + 10 > max) {
2865                     xmlChar *tmp;
2866
2867                     max *= 2;
2868                     tmp = (xmlChar *) xmlRealloc(buffer,
2869                                                     max * sizeof(xmlChar));
2870                     if (tmp == NULL) {
2871                         xmlErrMemory(ctxt, NULL);
2872                         xmlFree(buffer);
2873                         return(NULL);
2874                     }
2875                     buffer = tmp;
2876                 }
2877                 COPY_BUF(l,buffer,len,c);
2878                 NEXTL(l);
2879                 c = CUR_CHAR(l);
2880             }
2881             buffer[len] = 0;
2882             return(buffer);
2883         }
2884     }
2885     if (len == 0)
2886         return(NULL);
2887     return(xmlStrndup(buf, len));
2888 }
2889
2890 /**
2891  * xmlParseEntityValue:
2892  * @ctxt:  an XML parser context
2893  * @orig:  if non-NULL store a copy of the original entity value
2894  *
2895  * parse a value for ENTITY declarations
2896  *
2897  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
2898  *                     "'" ([^%&'] | PEReference | Reference)* "'"
2899  *
2900  * Returns the EntityValue parsed with reference substituted or NULL
2901  */
2902
2903 xmlChar *
2904 xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
2905     xmlChar *buf = NULL;
2906     int len = 0;
2907     int size = XML_PARSER_BUFFER_SIZE;
2908     int c, l;
2909     xmlChar stop;
2910     xmlChar *ret = NULL;
2911     const xmlChar *cur = NULL;
2912     xmlParserInputPtr input;
2913
2914     if (RAW == '"') stop = '"';
2915     else if (RAW == '\'') stop = '\'';
2916     else {
2917         xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
2918         return(NULL);
2919     }
2920     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
2921     if (buf == NULL) {
2922         xmlErrMemory(ctxt, NULL);
2923         return(NULL);
2924     }
2925
2926     /*
2927      * The content of the entity definition is copied in a buffer.
2928      */
2929
2930     ctxt->instate = XML_PARSER_ENTITY_VALUE;
2931     input = ctxt->input;
2932     GROW;
2933     NEXT;
2934     c = CUR_CHAR(l);
2935     /*
2936      * NOTE: 4.4.5 Included in Literal
2937      * When a parameter entity reference appears in a literal entity
2938      * value, ... a single or double quote character in the replacement
2939      * text is always treated as a normal data character and will not
2940      * terminate the literal. 
2941      * In practice it means we stop the loop only when back at parsing
2942      * the initial entity and the quote is found
2943      */
2944     while ((IS_CHAR(c)) && ((c != stop) || /* checked */
2945            (ctxt->input != input))) {
2946         if (len + 5 >= size) {
2947             xmlChar *tmp;
2948
2949             size *= 2;
2950             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
2951             if (tmp == NULL) {
2952                 xmlErrMemory(ctxt, NULL);
2953                 xmlFree(buf);
2954                 return(NULL);
2955             }
2956             buf = tmp;
2957         }
2958         COPY_BUF(l,buf,len,c);
2959         NEXTL(l);
2960         /*
2961          * Pop-up of finished entities.
2962          */
2963         while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
2964             xmlPopInput(ctxt);
2965
2966         GROW;
2967         c = CUR_CHAR(l);
2968         if (c == 0) {
2969             GROW;
2970             c = CUR_CHAR(l);
2971         }
2972     }
2973     buf[len] = 0;
2974
2975     /*
2976      * Raise problem w.r.t. '&' and '%' being used in non-entities
2977      * reference constructs. Note Charref will be handled in
2978      * xmlStringDecodeEntities()
2979      */
2980     cur = buf;
2981     while (*cur != 0) { /* non input consuming */
2982         if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
2983             xmlChar *name;
2984             xmlChar tmp = *cur;
2985
2986             cur++;
2987             name = xmlParseStringName(ctxt, &cur);
2988             if ((name == NULL) || (*cur != ';')) {
2989                 xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
2990             "EntityValue: '%c' forbidden except for entities references\n",
2991                                   tmp);
2992             }
2993             if ((tmp == '%') && (ctxt->inSubset == 1) &&
2994                 (ctxt->inputNr == 1)) {
2995                 xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
2996             }
2997             if (name != NULL)
2998                 xmlFree(name);
2999             if (*cur == 0)
3000                 break;
3001         }
3002         cur++;
3003     }
3004
3005     /*
3006      * Then PEReference entities are substituted.
3007      */
3008     if (c != stop) {
3009         xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
3010         xmlFree(buf);
3011     } else {
3012         NEXT;
3013         /*
3014          * NOTE: 4.4.7 Bypassed
3015          * When a general entity reference appears in the EntityValue in
3016          * an entity declaration, it is bypassed and left as is.
3017          * so XML_SUBSTITUTE_REF is not set here.
3018          */
3019         ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
3020                                       0, 0, 0);
3021         if (orig != NULL) 
3022             *orig = buf;
3023         else
3024             xmlFree(buf);
3025     }
3026     
3027     return(ret);
3028 }
3029
3030 /**
3031  * xmlParseAttValueComplex:
3032  * @ctxt:  an XML parser context
3033  * @len:   the resulting attribute len
3034  * @normalize:  wether to apply the inner normalization
3035  *
3036  * parse a value for an attribute, this is the fallback function
3037  * of xmlParseAttValue() when the attribute parsing requires handling
3038  * of non-ASCII characters, or normalization compaction.
3039  *
3040  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
3041  */
3042 static xmlChar *
3043 xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
3044     xmlChar limit = 0;
3045     xmlChar *buf = NULL;
3046     int len = 0;
3047     int buf_size = 0;
3048     int c, l, in_space = 0;
3049     xmlChar *current = NULL;
3050     xmlEntityPtr ent;
3051
3052     if (NXT(0) == '"') {
3053         ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3054         limit = '"';
3055         NEXT;
3056     } else if (NXT(0) == '\'') {
3057         limit = '\'';
3058         ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3059         NEXT;
3060     } else {
3061         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
3062         return(NULL);
3063     }
3064     
3065     /*
3066      * allocate a translation buffer.
3067      */
3068     buf_size = XML_PARSER_BUFFER_SIZE;
3069     buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
3070     if (buf == NULL) goto mem_error;
3071
3072     /*
3073      * OK loop until we reach one of the ending char or a size limit.
3074      */
3075     c = CUR_CHAR(l);
3076     while ((NXT(0) != limit) && /* checked */
3077            (c != '<')) {
3078         if (c == 0) break;
3079         if (c == '&') {
3080             in_space = 0;
3081             if (NXT(1) == '#') {
3082                 int val = xmlParseCharRef(ctxt);
3083
3084                 if (val == '&') {
3085                     if (ctxt->replaceEntities) {
3086                         if (len > buf_size - 10) {
3087                             growBuffer(buf);
3088                         }
3089                         buf[len++] = '&';
3090                     } else {
3091                         /*
3092                          * The reparsing will be done in xmlStringGetNodeList()
3093                          * called by the attribute() function in SAX.c
3094                          */
3095                         if (len > buf_size - 10) {
3096                             growBuffer(buf);
3097                         }
3098                         buf[len++] = '&';
3099                         buf[len++] = '#';
3100                         buf[len++] = '3';
3101                         buf[len++] = '8';
3102                         buf[len++] = ';';
3103                     }
3104                 } else {
3105                     if (len > buf_size - 10) {
3106                         growBuffer(buf);
3107                     }
3108                     len += xmlCopyChar(0, &buf[len], val);
3109                 }
3110             } else {
3111                 ent = xmlParseEntityRef(ctxt);
3112                 if ((ent != NULL) &&
3113                     (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
3114                     if (len > buf_size - 10) {
3115                         growBuffer(buf);
3116                     }
3117                     if ((ctxt->replaceEntities == 0) &&
3118                         (ent->content[0] == '&')) {
3119                         buf[len++] = '&';
3120                         buf[len++] = '#';
3121                         buf[len++] = '3';
3122                         buf[len++] = '8';
3123                         buf[len++] = ';';
3124                     } else {
3125                         buf[len++] = ent->content[0];
3126                     }
3127                 } else if ((ent != NULL) && 
3128                            (ctxt->replaceEntities != 0)) {
3129                     xmlChar *rep;
3130
3131                     if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
3132                         rep = xmlStringDecodeEntities(ctxt, ent->content,
3133                                                       XML_SUBSTITUTE_REF,
3134                                                       0, 0, 0);
3135                         if (rep != NULL) {
3136                             current = rep;
3137                             while (*current != 0) { /* non input consuming */
3138                                 buf[len++] = *current++;
3139                                 if (len > buf_size - 10) {
3140                                     growBuffer(buf);
3141                                 }
3142                             }
3143                             xmlFree(rep);
3144                         }
3145                     } else {
3146                         if (len > buf_size - 10) {
3147                             growBuffer(buf);
3148                         }
3149                         if (ent->content != NULL)
3150                             buf[len++] = ent->content[0];
3151                     }
3152                 } else if (ent != NULL) {
3153                     int i = xmlStrlen(ent->name);
3154                     const xmlChar *cur = ent->name;
3155
3156                     /*
3157                      * This may look absurd but is needed to detect
3158                      * entities problems
3159                      */
3160                     if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
3161                         (ent->content != NULL)) {
3162                         xmlChar *rep;
3163                         rep = xmlStringDecodeEntities(ctxt, ent->content,
3164                                                       XML_SUBSTITUTE_REF, 0, 0, 0);
3165                         if (rep != NULL)
3166                             xmlFree(rep);
3167                     }
3168
3169                     /*
3170                      * Just output the reference
3171                      */
3172                     buf[len++] = '&';
3173                     if (len > buf_size - i - 10) {
3174                         growBuffer(buf);
3175                     }
3176                     for (;i > 0;i--)
3177                         buf[len++] = *cur++;
3178                     buf[len++] = ';';
3179                 }
3180             }
3181         } else {
3182             if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
3183                 if ((len != 0) || (!normalize)) {
3184                     if ((!normalize) || (!in_space)) {
3185                         COPY_BUF(l,buf,len,0x20);
3186                         if (len > buf_size - 10) {
3187                             growBuffer(buf);
3188                         }
3189                     }
3190                     in_space = 1;
3191                 }
3192             } else {
3193                 in_space = 0;
3194                 COPY_BUF(l,buf,len,c);
3195                 if (len > buf_size - 10) {
3196                     growBuffer(buf);
3197                 }
3198             }
3199             NEXTL(l);
3200         }
3201         GROW;
3202         c = CUR_CHAR(l);
3203     }
3204     if ((in_space) && (normalize)) {
3205         while (buf[len - 1] == 0x20) len--;
3206     }
3207     buf[len] = 0;
3208     if (RAW == '<') {
3209         xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
3210     } else if (RAW != limit) {
3211         xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
3212                        "AttValue: ' expected\n");
3213     } else
3214         NEXT;
3215     if (attlen != NULL) *attlen = len;
3216     return(buf);
3217
3218 mem_error:
3219     xmlErrMemory(ctxt, NULL);
3220     return(NULL);
3221 }
3222
3223 /**
3224  * xmlParseAttValue:
3225  * @ctxt:  an XML parser context
3226  *
3227  * parse a value for an attribute
3228  * Note: the parser won't do substitution of entities here, this
3229  * will be handled later in xmlStringGetNodeList
3230  *
3231  * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
3232  *                   "'" ([^<&'] | Reference)* "'"
3233  *
3234  * 3.3.3 Attribute-Value Normalization:
3235  * Before the value of an attribute is passed to the application or
3236  * checked for validity, the XML processor must normalize it as follows: 
3237  * - a character reference is processed by appending the referenced
3238  *   character to the attribute value
3239  * - an entity reference is processed by recursively processing the
3240  *   replacement text of the entity 
3241  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
3242  *   appending #x20 to the normalized value, except that only a single
3243  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
3244  *   parsed entity or the literal entity value of an internal parsed entity 
3245  * - other characters are processed by appending them to the normalized value 
3246  * If the declared value is not CDATA, then the XML processor must further
3247  * process the normalized attribute value by discarding any leading and
3248  * trailing space (#x20) characters, and by replacing sequences of space
3249  * (#x20) characters by a single space (#x20) character.  
3250  * All attributes for which no declaration has been read should be treated
3251  * by a non-validating parser as if declared CDATA.
3252  *
3253  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
3254  */
3255
3256
3257 xmlChar *
3258 xmlParseAttValue(xmlParserCtxtPtr ctxt) {
3259     if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
3260     return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
3261 }
3262
3263 /**
3264  * xmlParseSystemLiteral:
3265  * @ctxt:  an XML parser context
3266  * 
3267  * parse an XML Literal
3268  *
3269  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
3270  *
3271  * Returns the SystemLiteral parsed or NULL
3272  */
3273
3274 xmlChar *
3275 xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
3276     xmlChar *buf = NULL;
3277     int len = 0;
3278     int size = XML_PARSER_BUFFER_SIZE;
3279     int cur, l;
3280     xmlChar stop;
3281     int state = ctxt->instate;
3282     int count = 0;
3283
3284     SHRINK;
3285     if (RAW == '"') {
3286         NEXT;
3287         stop = '"';
3288     } else if (RAW == '\'') {
3289         NEXT;
3290         stop = '\'';
3291     } else {
3292         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
3293         return(NULL);
3294     }
3295     
3296     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3297     if (buf == NULL) {
3298         xmlErrMemory(ctxt, NULL);
3299         return(NULL);
3300     }
3301     ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
3302     cur = CUR_CHAR(l);
3303     while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
3304         if (len + 5 >= size) {
3305             xmlChar *tmp;
3306
3307             size *= 2;
3308             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
3309             if (tmp == NULL) {
3310                 xmlFree(buf);
3311                 xmlErrMemory(ctxt, NULL);
3312                 ctxt->instate = (xmlParserInputState) state;
3313                 return(NULL);
3314             }
3315             buf = tmp;
3316         }
3317         count++;
3318         if (count > 50) {
3319             GROW;
3320             count = 0;
3321         }
3322         COPY_BUF(l,buf,len,cur);
3323         NEXTL(l);
3324         cur = CUR_CHAR(l);
3325         if (cur == 0) {
3326             GROW;
3327             SHRINK;
3328             cur = CUR_CHAR(l);
3329         }
3330     }
3331     buf[len] = 0;
3332     ctxt->instate = (xmlParserInputState) state;
3333     if (!IS_CHAR(cur)) {
3334         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
3335     } else {
3336         NEXT;
3337     }
3338     return(buf);
3339 }
3340
3341 /**
3342  * xmlParsePubidLiteral:
3343  * @ctxt:  an XML parser context
3344  *
3345  * parse an XML public literal
3346  *
3347  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
3348  *
3349  * Returns the PubidLiteral parsed or NULL.
3350  */
3351
3352 xmlChar *
3353 xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
3354     xmlChar *buf = NULL;
3355     int len = 0;
3356     int size = XML_PARSER_BUFFER_SIZE;
3357     xmlChar cur;
3358     xmlChar stop;
3359     int count = 0;
3360     xmlParserInputState oldstate = ctxt->instate;
3361
3362     SHRINK;
3363     if (RAW == '"') {
3364         NEXT;
3365         stop = '"';
3366     } else if (RAW == '\'') {
3367         NEXT;
3368         stop = '\'';
3369     } else {
3370         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
3371         return(NULL);
3372     }
3373     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3374     if (buf == NULL) {
3375         xmlErrMemory(ctxt, NULL);
3376         return(NULL);
3377     }
3378     ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
3379     cur = CUR;
3380     while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
3381         if (len + 1 >= size) {
3382             xmlChar *tmp;
3383
3384             size *= 2;
3385             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
3386             if (tmp == NULL) {
3387                 xmlErrMemory(ctxt, NULL);
3388                 xmlFree(buf);
3389                 return(NULL);
3390             }
3391             buf = tmp;
3392         }
3393         buf[len++] = cur;
3394         count++;
3395         if (count > 50) {
3396             GROW;
3397             count = 0;
3398         }
3399         NEXT;
3400         cur = CUR;
3401         if (cur == 0) {
3402             GROW;
3403             SHRINK;
3404             cur = CUR;
3405         }
3406     }
3407     buf[len] = 0;
3408     if (cur != stop) {
3409         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
3410     } else {
3411         NEXT;
3412     }
3413     ctxt->instate = oldstate;
3414     return(buf);
3415 }
3416
3417 void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
3418
3419 /*
3420  * used for the test in the inner loop of the char data testing
3421  */
3422 static const unsigned char test_char_data[256] = {
3423     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3424     0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
3425     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3426     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3427     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
3428     0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
3429     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
3430     0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
3431     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
3432     0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
3433     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
3434     0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
3435     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
3436     0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
3437     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
3438     0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
3439     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
3440     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3441     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3442     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3443     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3444     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3445     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3446     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3447     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3448     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3449     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3450     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3451     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3452     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3453     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3454     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3455 };
3456
3457 /**
3458  * xmlParseCharData:
3459  * @ctxt:  an XML parser context
3460  * @cdata:  int indicating whether we are within a CDATA section
3461  *
3462  * parse a CharData section.
3463  * if we are within a CDATA section ']]>' marks an end of section.
3464  *
3465  * The right angle bracket (>) may be represented using the string "&gt;",
3466  * and must, for compatibility, be escaped using "&gt;" or a character
3467  * reference when it appears in the string "]]>" in content, when that
3468  * string is not marking the end of a CDATA section. 
3469  *
3470  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
3471  */
3472
3473 void
3474 xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
3475     const xmlChar *in;
3476     int nbchar = 0;
3477     int line = ctxt->input->line;
3478     int col = ctxt->input->col;
3479     int ccol;
3480
3481     SHRINK;
3482     GROW;
3483     /*
3484      * Accelerated common case where input don't need to be
3485      * modified before passing it to the handler.
3486      */
3487     if (!cdata) {
3488         in = ctxt->input->cur;
3489         do {
3490 get_more_space:
3491             while (*in == 0x20) in++;
3492             if (*in == 0xA) {
3493                 do {
3494                     ctxt->input->line++; ctxt->input->col = 1;
3495                     in++;
3496                 } while (*in == 0xA);
3497                 goto get_more_space;
3498             }
3499             if (*in == '<') {
3500                 nbchar = in - ctxt->input->cur;
3501                 if (nbchar > 0) {
3502                     const xmlChar *tmp = ctxt->input->cur;
3503                     ctxt->input->cur = in;
3504
3505                     if ((ctxt->sax != NULL) &&
3506                         (ctxt->sax->ignorableWhitespace !=
3507                          ctxt->sax->characters)) {
3508                         if (areBlanks(ctxt, tmp, nbchar, 1)) {
3509                             if (ctxt->sax->ignorableWhitespace != NULL)
3510                                 ctxt->sax->ignorableWhitespace(ctxt->userData,
3511                                                        tmp, nbchar);
3512                         } else {
3513                             if (ctxt->sax->characters != NULL)
3514                                 ctxt->sax->characters(ctxt->userData,
3515                                                       tmp, nbchar);
3516                             if (*ctxt->space == -1)
3517                                 *ctxt->space = -2;
3518                         }
3519                     } else if ((ctxt->sax != NULL) &&
3520                                (ctxt->sax->characters != NULL)) {
3521                         ctxt->sax->characters(ctxt->userData,
3522                                               tmp, nbchar);
3523                     }
3524                 }
3525                 return;
3526             }
3527
3528 get_more:
3529             ccol = ctxt->input->col;
3530             while (test_char_data[*in]) {
3531                 in++;
3532                 ccol++;
3533             }
3534             ctxt->input->col = ccol;
3535             if (*in == 0xA) {
3536                 do {
3537                     ctxt->input->line++; ctxt->input->col = 1;
3538                     in++;
3539                 } while (*in == 0xA);
3540                 goto get_more;
3541             }
3542             if (*in == ']') {
3543                 if ((in[1] == ']') && (in[2] == '>')) {
3544                     xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
3545                     ctxt->input->cur = in;
3546                     return;
3547                 }
3548                 in++;
3549                 ctxt->input->col++;
3550                 goto get_more;
3551             }
3552             nbchar = in - ctxt->input->cur;
3553             if (nbchar > 0) {
3554                 if ((ctxt->sax != NULL) &&
3555                     (ctxt->sax->ignorableWhitespace !=
3556                      ctxt->sax->characters) &&
3557                     (IS_BLANK_CH(*ctxt->input->cur))) {
3558                     const xmlChar *tmp = ctxt->input->cur;
3559                     ctxt->input->cur = in;
3560
3561                     if (areBlanks(ctxt, tmp, nbchar, 0)) {
3562                         if (ctxt->sax->ignorableWhitespace != NULL)
3563                             ctxt->sax->ignorableWhitespace(ctxt->userData,
3564                                                            tmp, nbchar);
3565                     } else {
3566                         if (ctxt->sax->characters != NULL)
3567                             ctxt->sax->characters(ctxt->userData,
3568                                                   tmp, nbchar);
3569                         if (*ctxt->space == -1)
3570                             *ctxt->space = -2;
3571                     }
3572                     line = ctxt->input->line;
3573                     col = ctxt->input->col;
3574                 } else if (ctxt->sax != NULL) {
3575                     if (ctxt->sax->characters != NULL)
3576                         ctxt->sax->characters(ctxt->userData,
3577                                               ctxt->input->cur, nbchar);
3578                     line = ctxt->input->line;
3579                     col = ctxt->input->col;
3580                 }
3581             }
3582             ctxt->input->cur = in;
3583             if (*in == 0xD) {
3584                 in++;
3585                 if (*in == 0xA) {
3586                     ctxt->input->cur = in;
3587                     in++;
3588                     ctxt->input->line++; ctxt->input->col = 1;
3589                     continue; /* while */
3590                 }
3591                 in--;
3592             }
3593             if (*in == '<') {
3594                 return;
3595             }
3596             if (*in == '&') {
3597                 return;
3598             }
3599             SHRINK;
3600             GROW;
3601             in = ctxt->input->cur;
3602         } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
3603         nbchar = 0;
3604     }
3605     ctxt->input->line = line;
3606     ctxt->input->col = col;
3607     xmlParseCharDataComplex(ctxt, cdata);
3608 }
3609
3610 /**
3611  * xmlParseCharDataComplex:
3612  * @ctxt:  an XML parser context
3613  * @cdata:  int indicating whether we are within a CDATA section
3614  *
3615  * parse a CharData section.this is the fallback function
3616  * of xmlParseCharData() when the parsing requires handling
3617  * of non-ASCII characters.
3618  */
3619 void
3620 xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
3621     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
3622     int nbchar = 0;
3623     int cur, l;
3624     int count = 0;
3625
3626     SHRINK;
3627     GROW;
3628     cur = CUR_CHAR(l);
3629     while ((cur != '<') && /* checked */
3630            (cur != '&') && 
3631            (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
3632         if ((cur == ']') && (NXT(1) == ']') &&
3633             (NXT(2) == '>')) {
3634             if (cdata) break;
3635             else {
3636                 xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
3637             }
3638         }
3639         COPY_BUF(l,buf,nbchar,cur);
3640         if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
3641             buf[nbchar] = 0;
3642
3643             /*
3644              * OK the segment is to be consumed as chars.
3645              */
3646             if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
3647                 if (areBlanks(ctxt, buf, nbchar, 0)) {
3648                     if (ctxt->sax->ignorableWhitespace != NULL)
3649                         ctxt->sax->ignorableWhitespace(ctxt->userData,
3650                                                        buf, nbchar);
3651                 } else {
3652                     if (ctxt->sax->characters != NULL)
3653                         ctxt->sax->characters(ctxt->userData, buf, nbchar);
3654                     if ((ctxt->sax->characters !=
3655                          ctxt->sax->ignorableWhitespace) &&
3656                         (*ctxt->space == -1))
3657                         *ctxt->space = -2;
3658                 }
3659             }
3660             nbchar = 0;
3661         }
3662         count++;
3663         if (count > 50) {
3664             GROW;
3665             count = 0;
3666         }
3667         NEXTL(l);
3668         cur = CUR_CHAR(l);
3669     }
3670     if (nbchar != 0) {
3671         buf[nbchar] = 0;
3672         /*
3673          * OK the segment is to be consumed as chars.
3674          */
3675         if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
3676             if (areBlanks(ctxt, buf, nbchar, 0)) {
3677                 if (ctxt->sax->ignorableWhitespace != NULL)
3678                     ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
3679             } else {
3680                 if (ctxt->sax->characters != NULL)
3681                     ctxt->sax->characters(ctxt->userData, buf, nbchar);
3682                 if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
3683                     (*ctxt->space == -1))
3684                     *ctxt->space = -2;
3685             }
3686         }
3687     }
3688     if ((cur != 0) && (!IS_CHAR(cur))) {
3689         /* Generate the error and skip the offending character */
3690         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
3691                           "PCDATA invalid Char value %d\n",
3692                           cur);
3693         NEXTL(l);
3694     }
3695 }
3696
3697 /**
3698  * xmlParseExternalID:
3699  * @ctxt:  an XML parser context
3700  * @publicID:  a xmlChar** receiving PubidLiteral
3701  * @strict: indicate whether we should restrict parsing to only
3702  *          production [75], see NOTE below
3703  *
3704  * Parse an External ID or a Public ID
3705  *
3706  * NOTE: Productions [75] and [83] interact badly since [75] can generate
3707  *       'PUBLIC' S PubidLiteral S SystemLiteral
3708  *
3709  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
3710  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
3711  *
3712  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
3713  *
3714  * Returns the function returns SystemLiteral and in the second
3715  *                case publicID receives PubidLiteral, is strict is off
3716  *                it is possible to return NULL and have publicID set.
3717  */
3718
3719 xmlChar *
3720 xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
3721     xmlChar *URI = NULL;
3722
3723     SHRINK;
3724
3725     *publicID = NULL;
3726     if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
3727         SKIP(6);
3728         if (!IS_BLANK_CH(CUR)) {
3729             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
3730                            "Space required after 'SYSTEM'\n");
3731         }
3732         SKIP_BLANKS;
3733         URI = xmlParseSystemLiteral(ctxt);
3734         if (URI == NULL) {
3735             xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
3736         }
3737     } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
3738         SKIP(6);
3739         if (!IS_BLANK_CH(CUR)) {
3740             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
3741                     "Space required after 'PUBLIC'\n");
3742         }
3743         SKIP_BLANKS;
3744         *publicID = xmlParsePubidLiteral(ctxt);
3745         if (*publicID == NULL) {
3746             xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
3747         }
3748         if (strict) {
3749             /*
3750              * We don't handle [83] so "S SystemLiteral" is required.
3751              */
3752             if (!IS_BLANK_CH(CUR)) {
3753                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
3754                         "Space required after the Public Identifier\n");
3755             }
3756         } else {
3757             /*
3758              * We handle [83] so we return immediately, if 
3759              * "S SystemLiteral" is not detected. From a purely parsing
3760              * point of view that's a nice mess.
3761              */
3762             const xmlChar *ptr;
3763             GROW;
3764
3765             ptr = CUR_PTR;
3766             if (!IS_BLANK_CH(*ptr)) return(NULL);
3767             
3768             while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
3769             if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
3770         }
3771         SKIP_BLANKS;
3772         URI = xmlParseSystemLiteral(ctxt);
3773         if (URI == NULL) {
3774             xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
3775         }
3776     }
3777     return(URI);
3778 }
3779
3780 /**
3781  * xmlParseCommentComplex:
3782  * @ctxt:  an XML parser context
3783  * @buf:  the already parsed part of the buffer
3784  * @len:  number of bytes filles in the buffer
3785  * @size:  allocated size of the buffer
3786  *
3787  * Skip an XML (SGML) comment <!-- .... -->
3788  *  The spec says that "For compatibility, the string "--" (double-hyphen)
3789  *  must not occur within comments. "
3790  * This is the slow routine in case the accelerator for ascii didn't work
3791  *
3792  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
3793  */
3794 static void
3795 xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, int len, int size) {
3796     int q, ql;
3797     int r, rl;
3798     int cur, l;
3799     xmlParserInputPtr input = ctxt->input;
3800     int count = 0;
3801
3802     if (buf == NULL) {
3803         len = 0;
3804         size = XML_PARSER_BUFFER_SIZE;
3805         buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3806         if (buf == NULL) {
3807             xmlErrMemory(ctxt, NULL);
3808             return;
3809         }
3810     }
3811     q = CUR_CHAR(ql);
3812     if (q == 0)
3813         goto not_terminated;
3814     NEXTL(ql);
3815     r = CUR_CHAR(rl);
3816     if (r == 0)
3817         goto not_terminated;
3818     NEXTL(rl);
3819     cur = CUR_CHAR(l);
3820     if (cur == 0)
3821         goto not_terminated;
3822     while (IS_CHAR(cur) && /* checked */
3823            ((cur != '>') ||
3824             (r != '-') || (q != '-'))) {
3825         if ((r == '-') && (q == '-')) {
3826             xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
3827         }
3828         if (len + 5 >= size) {
3829             xmlChar *new_buf;
3830             size *= 2;
3831             new_buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
3832             if (new_buf == NULL) {
3833                 xmlFree (buf);
3834                 xmlErrMemory(ctxt, NULL);
3835                 return;
3836             }
3837             buf = new_buf;
3838         }
3839         COPY_BUF(ql,buf,len,q);
3840         q = r;
3841         ql = rl;
3842         r = cur;
3843         rl = l;
3844
3845         count++;
3846         if (count > 50) {
3847             GROW;
3848             count = 0;
3849         }
3850         NEXTL(l);
3851         cur = CUR_CHAR(l);
3852         if (cur == 0) {
3853             SHRINK;
3854             GROW;
3855             cur = CUR_CHAR(l);
3856         }
3857     }
3858     buf[len] = 0;
3859     if (!IS_CHAR(cur)) {
3860         xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
3861                              "Comment not terminated \n<!--%.50s\n", buf);
3862         xmlFree(buf);
3863     } else {
3864         if (input != ctxt->input) {
3865             xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
3866                 "Comment doesn't start and stop in the same entity\n");
3867         }
3868         NEXT;
3869         if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
3870             (!ctxt->disableSAX))
3871             ctxt->sax->comment(ctxt->userData, buf);
3872         xmlFree(buf);
3873     }
3874     return;
3875 not_terminated:
3876     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
3877                          "Comment not terminated\n", NULL);
3878     xmlFree(buf);
3879 }
3880 /**
3881  * xmlParseComment:
3882  * @ctxt:  an XML parser context
3883  *
3884  * Skip an XML (SGML) comment <!-- .... -->
3885  *  The spec says that "For compatibility, the string "--" (double-hyphen)
3886  *  must not occur within comments. "
3887  *
3888  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
3889  */
3890 void
3891 xmlParseComment(xmlParserCtxtPtr ctxt) {
3892     xmlChar *buf = NULL;
3893     int size = XML_PARSER_BUFFER_SIZE;
3894     int len = 0;
3895     xmlParserInputState state;
3896     const xmlChar *in;
3897     int nbchar = 0, ccol;
3898
3899     /*
3900      * Check that there is a comment right here.
3901      */
3902     if ((RAW != '<') || (NXT(1) != '!') ||
3903         (NXT(2) != '-') || (NXT(3) != '-')) return;
3904
3905     state = ctxt->instate;
3906     ctxt->instate = XML_PARSER_COMMENT;
3907     SKIP(4);
3908     SHRINK;
3909     GROW;
3910
3911     /*
3912      * Accelerated common case where input don't need to be
3913      * modified before passing it to the handler.
3914      */
3915     in = ctxt->input->cur;
3916     do {
3917         if (*in == 0xA) {
3918             do {
3919                 ctxt->input->line++; ctxt->input->col = 1;
3920                 in++;
3921             } while (*in == 0xA);
3922         }
3923 get_more:
3924         ccol = ctxt->input->col;
3925         while (((*in > '-') && (*in <= 0x7F)) ||
3926                ((*in >= 0x20) && (*in < '-')) ||
3927                (*in == 0x09)) {
3928                     in++;
3929                     ccol++;
3930         }
3931         ctxt->input->col = ccol;
3932         if (*in == 0xA) {
3933             do {
3934                 ctxt->input->line++; ctxt->input->col = 1;
3935                 in++;
3936             } while (*in == 0xA);
3937             goto get_more;
3938         }
3939         nbchar = in - ctxt->input->cur;
3940         /*
3941          * save current set of data
3942          */
3943         if (nbchar > 0) {
3944             if ((ctxt->sax != NULL) &&
3945                 (ctxt->sax->comment != NULL)) {
3946                 if (buf == NULL) {
3947                     if ((*in == '-') && (in[1] == '-'))
3948                         size = nbchar + 1;
3949                     else
3950                         size = XML_PARSER_BUFFER_SIZE + nbchar;
3951                     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3952                     if (buf == NULL) {
3953                         xmlErrMemory(ctxt, NULL);
3954                         ctxt->instate = state;
3955                         return;
3956                     }
3957                     len = 0;
3958                 } else if (len + nbchar + 1 >= size) {
3959                     xmlChar *new_buf;
3960                     size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
3961                     new_buf = (xmlChar *) xmlRealloc(buf,
3962                                                      size * sizeof(xmlChar));
3963                     if (new_buf == NULL) {
3964                         xmlFree (buf);
3965                         xmlErrMemory(ctxt, NULL);
3966                         ctxt->instate = state;
3967                         return;
3968                     }
3969                     buf = new_buf;
3970                 }
3971                 memcpy(&buf[len], ctxt->input->cur, nbchar);
3972                 len += nbchar;
3973                 buf[len] = 0;
3974             }
3975         }
3976         ctxt->input->cur = in;
3977         if (*in == 0xA) {
3978             in++;
3979             ctxt->input->line++; ctxt->input->col = 1;
3980         }
3981         if (*in == 0xD) {
3982             in++;
3983             if (*in == 0xA) {
3984                 ctxt->input->cur = in;
3985                 in++;
3986                 ctxt->input->line++; ctxt->input->col = 1;
3987                 continue; /* while */
3988             }
3989             in--;
3990         }
3991         SHRINK;
3992         GROW;
3993         in = ctxt->input->cur;
3994         if (*in == '-') {
3995             if (in[1] == '-') {
3996                 if (in[2] == '>') {
3997                     SKIP(3);
3998                     if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
3999                         (!ctxt->disableSAX)) {
4000                         if (buf != NULL)
4001                             ctxt->sax->comment(ctxt->userData, buf);
4002                         else
4003                             ctxt->sax->comment(ctxt->userData, BAD_CAST "");
4004                     }
4005                     if (buf != NULL)
4006                         xmlFree(buf);
4007                     ctxt->instate = state;
4008                     return;
4009                 }
4010                 if (buf != NULL)
4011                     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4012                                       "Comment not terminated \n<!--%.50s\n",
4013                                       buf);
4014                 else
4015                     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4016                                       "Comment not terminated \n", NULL);
4017                 in++;
4018                 ctxt->input->col++;
4019             }
4020             in++;
4021             ctxt->input->col++;
4022             goto get_more;
4023         }
4024     } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
4025     xmlParseCommentComplex(ctxt, buf, len, size);
4026     ctxt->instate = state;
4027     return;
4028 }
4029
4030
4031 /**
4032  * xmlParsePITarget:
4033  * @ctxt:  an XML parser context
4034  * 
4035  * parse the name of a PI
4036  *
4037  * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
4038  *
4039  * Returns the PITarget name or NULL
4040  */
4041
4042 const xmlChar *
4043 xmlParsePITarget(xmlParserCtxtPtr ctxt) {
4044     const xmlChar *name;
4045
4046     name = xmlParseName(ctxt);
4047     if ((name != NULL) &&
4048         ((name[0] == 'x') || (name[0] == 'X')) &&
4049         ((name[1] == 'm') || (name[1] == 'M')) &&
4050         ((name[2] == 'l') || (name[2] == 'L'))) {
4051         int i;
4052         if ((name[0] == 'x') && (name[1] == 'm') &&
4053             (name[2] == 'l') && (name[3] == 0)) {
4054             xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
4055                  "XML declaration allowed only at the start of the document\n");
4056             return(name);
4057         } else if (name[3] == 0) {
4058             xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
4059             return(name);
4060         }
4061         for (i = 0;;i++) {
4062             if (xmlW3CPIs[i] == NULL) break;
4063             if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
4064                 return(name);
4065         }
4066         xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
4067                       "xmlParsePITarget: invalid name prefix 'xml'\n",
4068                       NULL, NULL);
4069     }
4070     return(name);
4071 }
4072
4073 #ifdef LIBXML_CATALOG_ENABLED
4074 /**
4075  * xmlParseCatalogPI:
4076  * @ctxt:  an XML parser context
4077  * @catalog:  the PI value string
4078  * 
4079  * parse an XML Catalog Processing Instruction.
4080  *
4081  * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
4082  *
4083  * Occurs only if allowed by the user and if happening in the Misc
4084  * part of the document before any doctype informations
4085  * This will add the given catalog to the parsing context in order
4086  * to be used if there is a resolution need further down in the document
4087  */
4088
4089 static void
4090 xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
4091     xmlChar *URL = NULL;
4092     const xmlChar *tmp, *base;
4093     xmlChar marker;
4094
4095     tmp = catalog;
4096     while (IS_BLANK_CH(*tmp)) tmp++;
4097     if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
4098         goto error;
4099     tmp += 7;
4100     while (IS_BLANK_CH(*tmp)) tmp++;
4101     if (*tmp != '=') {
4102         return;
4103     }
4104     tmp++;
4105     while (IS_BLANK_CH(*tmp)) tmp++;
4106     marker = *tmp;
4107     if ((marker != '\'') && (marker != '"'))
4108         goto error;
4109     tmp++;
4110     base = tmp;
4111     while ((*tmp != 0) && (*tmp != marker)) tmp++;
4112     if (*tmp == 0)
4113         goto error;
4114     URL = xmlStrndup(base, tmp - base);
4115     tmp++;
4116     while (IS_BLANK_CH(*tmp)) tmp++;
4117     if (*tmp != 0)
4118         goto error;
4119
4120     if (URL != NULL) {
4121         ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
4122         xmlFree(URL);
4123     }
4124     return;
4125
4126 error:
4127     xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
4128                   "Catalog PI syntax error: %s\n",
4129                   catalog, NULL);
4130     if (URL != NULL)
4131         xmlFree(URL);
4132 }
4133 #endif
4134
4135 /**
4136  * xmlParsePI:
4137  * @ctxt:  an XML parser context
4138  * 
4139  * parse an XML Processing Instruction.
4140  *
4141  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
4142  *
4143  * The processing is transfered to SAX once parsed.
4144  */
4145
4146 void
4147 xmlParsePI(xmlParserCtxtPtr ctxt) {
4148     xmlChar *buf = NULL;
4149     int len = 0;
4150     int size = XML_PARSER_BUFFER_SIZE;
4151     int cur, l;
4152     const xmlChar *target;
4153     xmlParserInputState state;
4154     int count = 0;
4155
4156     if ((RAW == '<') && (NXT(1) == '?')) {
4157         xmlParserInputPtr input = ctxt->input;
4158         state = ctxt->instate;
4159         ctxt->instate = XML_PARSER_PI;
4160         /*
4161          * this is a Processing Instruction.
4162          */
4163         SKIP(2);
4164         SHRINK;
4165
4166         /*
4167          * Parse the target name and check for special support like
4168          * namespace.
4169          */
4170         target = xmlParsePITarget(ctxt);
4171         if (target != NULL) {
4172             if ((RAW == '?') && (NXT(1) == '>')) {
4173                 if (input != ctxt->input) {
4174                     xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4175             "PI declaration doesn't start and stop in the same entity\n");
4176                 }
4177                 SKIP(2);
4178
4179                 /*
4180                  * SAX: PI detected.
4181                  */
4182                 if ((ctxt->sax) && (!ctxt->disableSAX) &&
4183                     (ctxt->sax->processingInstruction != NULL))
4184                     ctxt->sax->processingInstruction(ctxt->userData,
4185                                                      target, NULL);
4186                 ctxt->instate = state;
4187                 return;
4188             }
4189             buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4190             if (buf == NULL) {
4191                 xmlErrMemory(ctxt, NULL);
4192                 ctxt->instate = state;
4193                 return;
4194             }
4195             cur = CUR;
4196             if (!IS_BLANK(cur)) {
4197                 xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
4198                           "ParsePI: PI %s space expected\n", target);
4199             }
4200             SKIP_BLANKS;
4201             cur = CUR_CHAR(l);
4202             while (IS_CHAR(cur) && /* checked */
4203                    ((cur != '?') || (NXT(1) != '>'))) {
4204                 if (len + 5 >= size) {
4205                     xmlChar *tmp;
4206
4207                     size *= 2;
4208                     tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4209                     if (tmp == NULL) {
4210                         xmlErrMemory(ctxt, NULL);
4211                         xmlFree(buf);
4212                         ctxt->instate = state;
4213                         return;
4214                     }
4215                     buf = tmp;
4216                 }
4217                 count++;
4218                 if (count > 50) {
4219                     GROW;
4220                     count = 0;
4221                 }
4222                 COPY_BUF(l,buf,len,cur);
4223                 NEXTL(l);
4224                 cur = CUR_CHAR(l);
4225                 if (cur == 0) {
4226                     SHRINK;
4227                     GROW;
4228                     cur = CUR_CHAR(l);
4229                 }
4230             }
4231             buf[len] = 0;
4232             if (cur != '?') {
4233                 xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
4234                       "ParsePI: PI %s never end ...\n", target);
4235             } else {
4236                 if (input != ctxt->input) {
4237                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4238             "PI declaration doesn't start and stop in the same entity\n");
4239                 }
4240                 SKIP(2);
4241
4242 #ifdef LIBXML_CATALOG_ENABLED
4243                 if (((state == XML_PARSER_MISC) ||
4244                      (state == XML_PARSER_START)) &&
4245                     (xmlStrEqual(target, XML_CATALOG_PI))) {
4246                     xmlCatalogAllow allow = xmlCatalogGetDefaults();
4247                     if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
4248                         (allow == XML_CATA_ALLOW_ALL))
4249                         xmlParseCatalogPI(ctxt, buf);
4250                 }
4251 #endif
4252
4253
4254                 /*
4255                  * SAX: PI detected.
4256                  */
4257                 if ((ctxt->sax) && (!ctxt->disableSAX) &&
4258                     (ctxt->sax->processingInstruction != NULL))
4259                     ctxt->sax->processingInstruction(ctxt->userData,
4260                                                      target, buf);
4261             }
4262             xmlFree(buf);
4263         } else {
4264             xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
4265         }
4266         ctxt->instate = state;
4267     }
4268 }
4269
4270 /**
4271  * xmlParseNotationDecl:
4272  * @ctxt:  an XML parser context
4273  *
4274  * parse a notation declaration
4275  *
4276  * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
4277  *
4278  * Hence there is actually 3 choices:
4279  *     'PUBLIC' S PubidLiteral
4280  *     'PUBLIC' S PubidLiteral S SystemLiteral
4281  * and 'SYSTEM' S SystemLiteral
4282  *
4283  * See the NOTE on xmlParseExternalID().
4284  */
4285
4286 void
4287 xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
4288     const xmlChar *name;
4289     xmlChar *Pubid;
4290     xmlChar *Systemid;
4291     
4292     if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
4293         xmlParserInputPtr input = ctxt->input;
4294         SHRINK;
4295         SKIP(10);
4296         if (!IS_BLANK_CH(CUR)) {
4297             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4298                            "Space required after '<!NOTATION'\n");
4299             return;
4300         }
4301         SKIP_BLANKS;
4302
4303         name = xmlParseName(ctxt);
4304         if (name == NULL) {
4305             xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
4306             return;
4307         }
4308         if (!IS_BLANK_CH(CUR)) {
4309             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4310                      "Space required after the NOTATION name'\n");
4311             return;
4312         }
4313         SKIP_BLANKS;
4314
4315         /*
4316          * Parse the IDs.
4317          */
4318         Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
4319         SKIP_BLANKS;
4320
4321         if (RAW == '>') {
4322             if (input != ctxt->input) {
4323                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4324         "Notation declaration doesn't start and stop in the same entity\n");
4325             }
4326             NEXT;
4327             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
4328                 (ctxt->sax->notationDecl != NULL))
4329                 ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
4330         } else {
4331             xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
4332         }
4333         if (Systemid != NULL) xmlFree(Systemid);
4334         if (Pubid != NULL) xmlFree(Pubid);
4335     }
4336 }
4337
4338 /**
4339  * xmlParseEntityDecl:
4340  * @ctxt:  an XML parser context
4341  *
4342  * parse <!ENTITY declarations
4343  *
4344  * [70] EntityDecl ::= GEDecl | PEDecl
4345  *
4346  * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
4347  *
4348  * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
4349  *
4350  * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
4351  *
4352  * [74] PEDef ::= EntityValue | ExternalID
4353  *
4354  * [76] NDataDecl ::= S 'NDATA' S Name
4355  *
4356  * [ VC: Notation Declared ]
4357  * The Name must match the declared name of a notation.
4358  */
4359
4360 void
4361 xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
4362     const xmlChar *name = NULL;
4363     xmlChar *value = NULL;
4364     xmlChar *URI = NULL, *literal = NULL;
4365     const xmlChar *ndata = NULL;
4366     int isParameter = 0;
4367     xmlChar *orig = NULL;
4368     int skipped;
4369     
4370     /* GROW; done in the caller */
4371     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
4372         xmlParserInputPtr input = ctxt->input;
4373         SHRINK;
4374         SKIP(8);
4375         skipped = SKIP_BLANKS;
4376         if (skipped == 0) {
4377             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4378                            "Space required after '<!ENTITY'\n");
4379         }
4380
4381         if (RAW == '%') {
4382             NEXT;
4383             skipped = SKIP_BLANKS;
4384             if (skipped == 0) {
4385                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4386                                "Space required after '%'\n");
4387             }
4388             isParameter = 1;
4389         }
4390
4391         name = xmlParseName(ctxt);
4392         if (name == NULL) {
4393             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
4394                            "xmlParseEntityDecl: no name\n");
4395             return;
4396         }
4397         skipped = SKIP_BLANKS;
4398         if (skipped == 0) {
4399             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4400                            "Space required after the entity name\n");
4401         }
4402
4403         ctxt->instate = XML_PARSER_ENTITY_DECL;
4404         /*
4405          * handle the various case of definitions...
4406          */
4407         if (isParameter) {
4408             if ((RAW == '"') || (RAW == '\'')) {
4409                 value = xmlParseEntityValue(ctxt, &orig);
4410                 if (value) {
4411                     if ((ctxt->sax != NULL) &&
4412                         (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
4413                         ctxt->sax->entityDecl(ctxt->userData, name,
4414                                     XML_INTERNAL_PARAMETER_ENTITY,
4415                                     NULL, NULL, value);
4416                 }
4417             } else {
4418                 URI = xmlParseExternalID(ctxt, &literal, 1);
4419                 if ((URI == NULL) && (literal == NULL)) {
4420                     xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
4421                 }
4422                 if (URI) {
4423                     xmlURIPtr uri;
4424
4425                     uri = xmlParseURI((const char *) URI);
4426                     if (uri == NULL) {
4427                         xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
4428                                      "Invalid URI: %s\n", URI);
4429                         /*
4430                          * This really ought to be a well formedness error
4431                          * but the XML Core WG decided otherwise c.f. issue
4432                          * E26 of the XML erratas.
4433                          */
4434                     } else {
4435                         if (uri->fragment != NULL) {
4436                             /*
4437                              * Okay this is foolish to block those but not
4438                              * invalid URIs.
4439                              */
4440                             xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
4441                         } else {
4442                             if ((ctxt->sax != NULL) &&
4443                                 (!ctxt->disableSAX) &&
4444                                 (ctxt->sax->entityDecl != NULL))
4445                                 ctxt->sax->entityDecl(ctxt->userData, name,
4446                                             XML_EXTERNAL_PARAMETER_ENTITY,
4447                                             literal, URI, NULL);
4448                         }
4449                         xmlFreeURI(uri);
4450                     }
4451                 }
4452             }
4453         } else {
4454             if ((RAW == '"') || (RAW == '\'')) {
4455                 value = xmlParseEntityValue(ctxt, &orig);
4456                 if ((ctxt->sax != NULL) &&
4457                     (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
4458                     ctxt->sax->entityDecl(ctxt->userData, name,
4459                                 XML_INTERNAL_GENERAL_ENTITY,
4460                                 NULL, NULL, value);
4461                 /*
4462                  * For expat compatibility in SAX mode.
4463                  */
4464                 if ((ctxt->myDoc == NULL) ||
4465                     (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
4466                     if (ctxt->myDoc == NULL) {
4467                         ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
4468                     }
4469                     if (ctxt->myDoc->intSubset == NULL)
4470                         ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
4471                                             BAD_CAST "fake", NULL, NULL);
4472
4473                     xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
4474                                       NULL, NULL, value);
4475                 }
4476             } else {
4477                 URI = xmlParseExternalID(ctxt, &literal, 1);
4478                 if ((URI == NULL) && (literal == NULL)) {
4479                     xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
4480                 }
4481                 if (URI) {
4482                     xmlURIPtr uri;
4483
4484                     uri = xmlParseURI((const char *)URI);
4485                     if (uri == NULL) {
4486                         xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
4487                                      "Invalid URI: %s\n", URI);
4488                         /*
4489                          * This really ought to be a well formedness error
4490                          * but the XML Core WG decided otherwise c.f. issue
4491                          * E26 of the XML erratas.
4492                          */
4493                     } else {
4494                         if (uri->fragment != NULL) {
4495                             /*
4496                              * Okay this is foolish to block those but not
4497                              * invalid URIs.
4498                              */
4499                             xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
4500                         }
4501                         xmlFreeURI(uri);
4502                     }
4503                 }
4504                 if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
4505                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4506                                    "Space required before 'NDATA'\n");
4507                 }
4508                 SKIP_BLANKS;
4509                 if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
4510                     SKIP(5);
4511                     if (!IS_BLANK_CH(CUR)) {
4512                         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4513                                        "Space required after 'NDATA'\n");
4514                     }
4515                     SKIP_BLANKS;
4516                     ndata = xmlParseName(ctxt);
4517                     if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
4518                         (ctxt->sax->unparsedEntityDecl != NULL))
4519                         ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
4520                                     literal, URI, ndata);
4521                 } else {
4522                     if ((ctxt->sax != NULL) &&
4523                         (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
4524                         ctxt->sax->entityDecl(ctxt->userData, name,
4525                                     XML_EXTERNAL_GENERAL_PARSED_ENTITY,
4526                                     literal, URI, NULL);
4527                     /*
4528                      * For expat compatibility in SAX mode.
4529                      * assuming the entity repalcement was asked for
4530                      */
4531                     if ((ctxt->replaceEntities != 0) &&
4532                         ((ctxt->myDoc == NULL) ||
4533                         (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
4534                         if (ctxt->myDoc == NULL) {
4535                             ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
4536                         }
4537
4538                         if (ctxt->myDoc->intSubset == NULL)
4539                             ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
4540                                                 BAD_CAST "fake", NULL, NULL);
4541                         xmlSAX2EntityDecl(ctxt, name,
4542                                           XML_EXTERNAL_GENERAL_PARSED_ENTITY,
4543                                           literal, URI, NULL);
4544                     }
4545                 }
4546             }
4547         }
4548         SKIP_BLANKS;
4549         if (RAW != '>') {
4550             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
4551                     "xmlParseEntityDecl: entity %s not terminated\n", name);
4552         } else {
4553             if (input != ctxt->input) {
4554                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4555         "Entity declaration doesn't start and stop in the same entity\n");
4556             }
4557             NEXT;
4558         }
4559         if (orig != NULL) {
4560             /*
4561              * Ugly mechanism to save the raw entity value.
4562              */
4563             xmlEntityPtr cur = NULL;
4564
4565             if (isParameter) {
4566                 if ((ctxt->sax != NULL) &&
4567                     (ctxt->sax->getParameterEntity != NULL))
4568                     cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
4569             } else {
4570                 if ((ctxt->sax != NULL) &&
4571                     (ctxt->sax->getEntity != NULL))
4572                     cur = ctxt->sax->getEntity(ctxt->userData, name);
4573                 if ((cur == NULL) && (ctxt->userData==ctxt)) {
4574                     cur = xmlSAX2GetEntity(ctxt, name);
4575                 }
4576             }
4577             if (cur != NULL) {
4578                 if (cur->orig != NULL)
4579                     xmlFree(orig);
4580                 else
4581                     cur->orig = orig;
4582             } else
4583                 xmlFree(orig);
4584         }
4585         if (value != NULL) xmlFree(value);
4586         if (URI != NULL) xmlFree(URI);
4587         if (literal != NULL) xmlFree(literal);
4588     }
4589 }
4590
4591 /**
4592  * xmlParseDefaultDecl:
4593  * @ctxt:  an XML parser context
4594  * @value:  Receive a possible fixed default value for the attribute
4595  *
4596  * Parse an attribute default declaration
4597  *
4598  * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
4599  *
4600  * [ VC: Required Attribute ]
4601  * if the default declaration is the keyword #REQUIRED, then the
4602  * attribute must be specified for all elements of the type in the
4603  * attribute-list declaration.
4604  *
4605  * [ VC: Attribute Default Legal ]
4606  * The declared default value must meet the lexical constraints of
4607  * the declared attribute type c.f. xmlValidateAttributeDecl()
4608  *
4609  * [ VC: Fixed Attribute Default ]
4610  * if an attribute has a default value declared with the #FIXED
4611  * keyword, instances of that attribute must match the default value. 
4612  *
4613  * [ WFC: No < in Attribute Values ]
4614  * handled in xmlParseAttValue()
4615  *
4616  * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
4617  *          or XML_ATTRIBUTE_FIXED. 
4618  */
4619
4620 int
4621 xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
4622     int val;
4623     xmlChar *ret;
4624
4625     *value = NULL;
4626     if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
4627         SKIP(9);
4628         return(XML_ATTRIBUTE_REQUIRED);
4629     }
4630     if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
4631         SKIP(8);
4632         return(XML_ATTRIBUTE_IMPLIED);
4633     }
4634     val = XML_ATTRIBUTE_NONE;
4635     if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
4636         SKIP(6);
4637         val = XML_ATTRIBUTE_FIXED;
4638         if (!IS_BLANK_CH(CUR)) {
4639             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4640                            "Space required after '#FIXED'\n");
4641         }
4642         SKIP_BLANKS;
4643     }
4644     ret = xmlParseAttValue(ctxt);
4645     ctxt->instate = XML_PARSER_DTD;
4646     if (ret == NULL) {
4647         xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
4648                        "Attribute default value declaration error\n");
4649     } else
4650         *value = ret;
4651     return(val);
4652 }
4653
4654 /**
4655  * xmlParseNotationType:
4656  * @ctxt:  an XML parser context
4657  *
4658  * parse an Notation attribute type.
4659  *
4660  * Note: the leading 'NOTATION' S part has already being parsed...
4661  *
4662  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
4663  *
4664  * [ VC: Notation Attributes ]
4665  * Values of this type must match one of the notation names included
4666  * in the declaration; all notation names in the declaration must be declared. 
4667  *
4668  * Returns: the notation attribute tree built while parsing
4669  */
4670
4671 xmlEnumerationPtr
4672 xmlParseNotationType(xmlParserCtxtPtr ctxt) {
4673     const xmlChar *name;
4674     xmlEnumerationPtr ret = NULL, last = NULL, cur;
4675
4676     if (RAW != '(') {
4677         xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
4678         return(NULL);
4679     }
4680     SHRINK;
4681     do {
4682         NEXT;
4683         SKIP_BLANKS;
4684         name = xmlParseName(ctxt);
4685         if (name == NULL) {
4686             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
4687                            "Name expected in NOTATION declaration\n");
4688             return(ret);
4689         }
4690         cur = xmlCreateEnumeration(name);
4691         if (cur == NULL) return(ret);
4692         if (last == NULL) ret = last = cur;
4693         else {
4694             last->next = cur;
4695             last = cur;
4696         }
4697         SKIP_BLANKS;
4698     } while (RAW == '|');
4699     if (RAW != ')') {
4700         xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
4701         if ((last != NULL) && (last != ret))
4702             xmlFreeEnumeration(last);
4703         return(ret);
4704     }
4705     NEXT;
4706     return(ret);
4707 }
4708
4709 /**
4710  * xmlParseEnumerationType:
4711  * @ctxt:  an XML parser context
4712  *
4713  * parse an Enumeration attribute type.
4714  *
4715  * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
4716  *
4717  * [ VC: Enumeration ]
4718  * Values of this type must match one of the Nmtoken tokens in
4719  * the declaration
4720  *
4721  * Returns: the enumeration attribute tree built while parsing
4722  */
4723
4724 xmlEnumerationPtr
4725 xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
4726     xmlChar *name;
4727     xmlEnumerationPtr ret = NULL, last = NULL, cur;
4728
4729     if (RAW != '(') {
4730         xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
4731         return(NULL);
4732     }
4733     SHRINK;
4734     do {
4735         NEXT;
4736         SKIP_BLANKS;
4737         name = xmlParseNmtoken(ctxt);
4738         if (name == NULL) {
4739             xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
4740             return(ret);
4741         }
4742         cur = xmlCreateEnumeration(name);
4743         xmlFree(name);
4744         if (cur == NULL) return(ret);
4745         if (last == NULL) ret = last = cur;
4746         else {
4747             last->next = cur;
4748             last = cur;
4749         }
4750         SKIP_BLANKS;
4751     } while (RAW == '|');
4752     if (RAW != ')') {
4753         xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
4754         return(ret);
4755     }
4756     NEXT;
4757     return(ret);
4758 }
4759
4760 /**
4761  * xmlParseEnumeratedType:
4762  * @ctxt:  an XML parser context
4763  * @tree:  the enumeration tree built while parsing
4764  *
4765  * parse an Enumerated attribute type.
4766  *
4767  * [57] EnumeratedType ::= NotationType | Enumeration
4768  *
4769  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
4770  *
4771  *
4772  * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
4773  */
4774
4775 int
4776 xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
4777     if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
4778         SKIP(8);
4779         if (!IS_BLANK_CH(CUR)) {
4780             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4781                            "Space required after 'NOTATION'\n");
4782             return(0);
4783         }
4784         SKIP_BLANKS;
4785         *tree = xmlParseNotationType(ctxt);
4786         if (*tree == NULL) return(0);
4787         return(XML_ATTRIBUTE_NOTATION);
4788     }
4789     *tree = xmlParseEnumerationType(ctxt);
4790     if (*tree == NULL) return(0);
4791     return(XML_ATTRIBUTE_ENUMERATION);
4792 }
4793
4794 /**
4795  * xmlParseAttributeType:
4796  * @ctxt:  an XML parser context
4797  * @tree:  the enumeration tree built while parsing
4798  *
4799  * parse the Attribute list def for an element
4800  *
4801  * [54] AttType ::= StringType | TokenizedType | EnumeratedType
4802  *
4803  * [55] StringType ::= 'CDATA'
4804  *
4805  * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
4806  *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
4807  *
4808  * Validity constraints for attribute values syntax are checked in
4809  * xmlValidateAttributeValue()
4810  *
4811  * [ VC: ID ]
4812  * Values of type ID must match the Name production. A name must not
4813  * appear more than once in an XML document as a value of this type;
4814  * i.e., ID values must uniquely identify the elements which bear them.
4815  *
4816  * [ VC: One ID per Element Type ]
4817  * No element type may have more than one ID attribute specified.
4818  *
4819  * [ VC: ID Attribute Default ]
4820  * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
4821  *
4822  * [ VC: IDREF ]
4823  * Values of type IDREF must match the Name production, and values
4824  * of type IDREFS must match Names; each IDREF Name must match the value
4825  * of an ID attribute on some element in the XML document; i.e. IDREF
4826  * values must match the value of some ID attribute.
4827  *
4828  * [ VC: Entity Name ]
4829  * Values of type ENTITY must match the Name production, values
4830  * of type ENTITIES must match Names; each Entity Name must match the
4831  * name of an unparsed entity declared in the DTD.  
4832  *
4833  * [ VC: Name Token ]
4834  * Values of type NMTOKEN must match the Nmtoken production; values
4835  * of type NMTOKENS must match Nmtokens. 
4836  *
4837  * Returns the attribute type
4838  */
4839 int 
4840 xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
4841     SHRINK;
4842     if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
4843         SKIP(5);
4844         return(XML_ATTRIBUTE_CDATA);
4845      } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
4846         SKIP(6);
4847         return(XML_ATTRIBUTE_IDREFS);
4848      } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
4849         SKIP(5);
4850         return(XML_ATTRIBUTE_IDREF);
4851      } else if ((RAW == 'I') && (NXT(1) == 'D')) {
4852         SKIP(2);
4853         return(XML_ATTRIBUTE_ID);
4854      } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
4855         SKIP(6);
4856         return(XML_ATTRIBUTE_ENTITY);
4857      } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
4858         SKIP(8);
4859         return(XML_ATTRIBUTE_ENTITIES);
4860      } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
4861         SKIP(8);
4862         return(XML_ATTRIBUTE_NMTOKENS);
4863      } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
4864         SKIP(7);
4865         return(XML_ATTRIBUTE_NMTOKEN);
4866      }
4867      return(xmlParseEnumeratedType(ctxt, tree));
4868 }
4869
4870 /**
4871  * xmlParseAttributeListDecl:
4872  * @ctxt:  an XML parser context
4873  *
4874  * : parse the Attribute list def for an element
4875  *
4876  * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
4877  *
4878  * [53] AttDef ::= S Name S AttType S DefaultDecl
4879  *
4880  */
4881 void
4882 xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
4883     const xmlChar *elemName;
4884     const xmlChar *attrName;
4885     xmlEnumerationPtr tree;
4886
4887     if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
4888         xmlParserInputPtr input = ctxt->input;
4889
4890         SKIP(9);
4891         if (!IS_BLANK_CH(CUR)) {
4892             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4893                                  "Space required after '<!ATTLIST'\n");
4894         }
4895         SKIP_BLANKS;
4896         elemName = xmlParseName(ctxt);
4897         if (elemName == NULL) {
4898             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
4899                            "ATTLIST: no name for Element\n");
4900             return;
4901         }
4902         SKIP_BLANKS;
4903         GROW;
4904         while (RAW != '>') {
4905             const xmlChar *check = CUR_PTR;
4906             int type;
4907             int def;
4908             xmlChar *defaultValue = NULL;
4909
4910             GROW;
4911             tree = NULL;
4912             attrName = xmlParseName(ctxt);
4913             if (attrName == NULL) {
4914                 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
4915                                "ATTLIST: no name for Attribute\n");
4916                 break;
4917             }
4918             GROW;
4919             if (!IS_BLANK_CH(CUR)) {
4920                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4921                         "Space required after the attribute name\n");
4922                 break;
4923             }
4924             SKIP_BLANKS;
4925
4926             type = xmlParseAttributeType(ctxt, &tree);
4927             if (type <= 0) {
4928                 break;
4929             }
4930
4931             GROW;
4932             if (!IS_BLANK_CH(CUR)) {
4933                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4934                                "Space required after the attribute type\n");
4935                 if (tree != NULL)
4936                     xmlFreeEnumeration(tree);
4937                 break;
4938             }
4939             SKIP_BLANKS;
4940
4941             def = xmlParseDefaultDecl(ctxt, &defaultValue);
4942             if (def <= 0) {
4943                 if (defaultValue != NULL)
4944                     xmlFree(defaultValue);
4945                 if (tree != NULL)
4946                     xmlFreeEnumeration(tree);
4947                 break;
4948             }
4949
4950             GROW;
4951             if (RAW != '>') {
4952                 if (!IS_BLANK_CH(CUR)) {
4953                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4954                         "Space required after the attribute default value\n");
4955                     if (defaultValue != NULL)
4956                         xmlFree(defaultValue);
4957                     if (tree != NULL)
4958                         xmlFreeEnumeration(tree);
4959                     break;
4960                 }
4961                 SKIP_BLANKS;
4962             }
4963             if (check == CUR_PTR) {
4964                 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
4965                             "in xmlParseAttributeListDecl\n");
4966                 if (defaultValue != NULL)
4967                     xmlFree(defaultValue);
4968                 if (tree != NULL)
4969                     xmlFreeEnumeration(tree);
4970                 break;
4971             }
4972             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
4973                 (ctxt->sax->attributeDecl != NULL))
4974                 ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
4975                                 type, def, defaultValue, tree);
4976             else if (tree != NULL)
4977                 xmlFreeEnumeration(tree);
4978
4979             if ((ctxt->sax2) && (defaultValue != NULL) &&
4980                 (def != XML_ATTRIBUTE_IMPLIED) && 
4981                 (def != XML_ATTRIBUTE_REQUIRED)) {
4982                 xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
4983             }
4984             if ((ctxt->sax2) && (type != XML_ATTRIBUTE_CDATA)) {
4985                 xmlAddSpecialAttr(ctxt, elemName, attrName, type);
4986             }
4987             if (defaultValue != NULL)
4988                 xmlFree(defaultValue);
4989             GROW;
4990         }
4991         if (RAW == '>') {
4992             if (input != ctxt->input) {
4993                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4994     "Attribute list declaration doesn't start and stop in the same entity\n");
4995             }
4996             NEXT;
4997         }
4998     }
4999 }
5000
5001 /**
5002  * xmlParseElementMixedContentDecl:
5003  * @ctxt:  an XML parser context
5004  * @inputchk:  the input used for the current entity, needed for boundary checks
5005  *
5006  * parse the declaration for a Mixed Element content
5007  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
5008  * 
5009  * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
5010  *                '(' S? '#PCDATA' S? ')'
5011  *
5012  * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
5013  *
5014  * [ VC: No Duplicate Types ]
5015  * The same name must not appear more than once in a single
5016  * mixed-content declaration. 
5017  *
5018  * returns: the list of the xmlElementContentPtr describing the element choices
5019  */
5020 xmlElementContentPtr
5021 xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
5022     xmlElementContentPtr ret = NULL, cur = NULL, n;
5023     const xmlChar *elem = NULL;
5024
5025     GROW;
5026     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
5027         SKIP(7);
5028         SKIP_BLANKS;
5029         SHRINK;
5030         if (RAW == ')') {
5031             if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
5032                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
5033 "Element content declaration doesn't start and stop in the same entity\n",
5034                                  NULL);
5035             }
5036             NEXT;
5037             ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
5038             if (RAW == '*') {
5039                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
5040                 NEXT;
5041             }
5042             return(ret);
5043         }
5044         if ((RAW == '(') || (RAW == '|')) {
5045             ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
5046             if (ret == NULL) return(NULL);
5047         }
5048         while (RAW == '|') {
5049             NEXT;
5050             if (elem == NULL) {
5051                 ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
5052                 if (ret == NULL) return(NULL);
5053                 ret->c1 = cur;
5054                 if (cur != NULL)
5055                     cur->parent = ret;
5056                 cur = ret;
5057             } else {
5058                 n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
5059                 if (n == NULL) return(NULL);
5060                 n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
5061                 if (n->c1 != NULL)
5062                     n->c1->parent = n;
5063                 cur->c2 = n;
5064                 if (n != NULL)
5065                     n->parent = cur;
5066                 cur = n;
5067             }
5068             SKIP_BLANKS;
5069             elem = xmlParseName(ctxt);
5070             if (elem == NULL) {
5071                 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5072                         "xmlParseElementMixedContentDecl : Name expected\n");
5073                 xmlFreeDocElementContent(ctxt->myDoc, cur);
5074                 return(NULL);
5075             }
5076             SKIP_BLANKS;
5077             GROW;
5078         }
5079         if ((RAW == ')') && (NXT(1) == '*')) {
5080             if (elem != NULL) {
5081                 cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
5082                                                XML_ELEMENT_CONTENT_ELEMENT);
5083                 if (cur->c2 != NULL)
5084                     cur->c2->parent = cur;
5085             }
5086             ret->ocur = XML_ELEMENT_CONTENT_MULT;
5087             if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
5088                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
5089 "Element content declaration doesn't start and stop in the same entity\n",
5090                                  NULL);
5091             }
5092             SKIP(2);
5093         } else {
5094             xmlFreeDocElementContent(ctxt->myDoc, ret);
5095             xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
5096             return(NULL);
5097         }
5098
5099     } else {
5100         xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
5101     }
5102     return(ret);
5103 }
5104
5105 /**
5106  * xmlParseElementChildrenContentDecl:
5107  * @ctxt:  an XML parser context
5108  * @inputchk:  the input used for the current entity, needed for boundary checks
5109  *
5110  * parse the declaration for a Mixed Element content
5111  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
5112  * 
5113  *
5114  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
5115  *
5116  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
5117  *
5118  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
5119  *
5120  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
5121  *
5122  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
5123  * TODO Parameter-entity replacement text must be properly nested
5124  *      with parenthesized groups. That is to say, if either of the
5125  *      opening or closing parentheses in a choice, seq, or Mixed
5126  *      construct is contained in the replacement text for a parameter
5127  *      entity, both must be contained in the same replacement text. For
5128  *      interoperability, if a parameter-entity reference appears in a
5129  *      choice, seq, or Mixed construct, its replacement text should not
5130  *      be empty, and neither the first nor last non-blank character of
5131  *      the replacement text should be a connector (| or ,).
5132  *
5133  * Returns the tree of xmlElementContentPtr describing the element 
5134  *          hierarchy.
5135  */
5136 xmlElementContentPtr
5137 xmlParseElementChildrenContentDecl (xmlParserCtxtPtr ctxt, int inputchk) {
5138     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
5139     const xmlChar *elem;
5140     xmlChar type = 0;
5141
5142     SKIP_BLANKS;
5143     GROW;
5144     if (RAW == '(') {
5145         int inputid = ctxt->input->id;
5146
5147         /* Recurse on first child */
5148         NEXT;
5149         SKIP_BLANKS;
5150         cur = ret = xmlParseElementChildrenContentDecl(ctxt, inputid);
5151         SKIP_BLANKS;
5152         GROW;
5153     } else {
5154         elem = xmlParseName(ctxt);
5155         if (elem == NULL) {
5156             xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
5157             return(NULL);
5158         }
5159         cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
5160         if (cur == NULL) {
5161             xmlErrMemory(ctxt, NULL);
5162             return(NULL);
5163         }
5164         GROW;
5165         if (RAW == '?') {
5166             cur->ocur = XML_ELEMENT_CONTENT_OPT;
5167             NEXT;
5168         } else if (RAW == '*') {
5169             cur->ocur = XML_ELEMENT_CONTENT_MULT;
5170             NEXT;
5171         } else if (RAW == '+') {
5172             cur->ocur = XML_ELEMENT_CONTENT_PLUS;
5173             NEXT;
5174         } else {
5175             cur->ocur = XML_ELEMENT_CONTENT_ONCE;
5176         }
5177         GROW;
5178     }
5179     SKIP_BLANKS;
5180     SHRINK;
5181     while (RAW != ')') {
5182         /*
5183          * Each loop we parse one separator and one element.
5184          */
5185         if (RAW == ',') {
5186             if (type == 0) type = CUR;
5187
5188             /*
5189              * Detect "Name | Name , Name" error
5190              */
5191             else if (type != CUR) {
5192                 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
5193                     "xmlParseElementChildrenContentDecl : '%c' expected\n",
5194                                   type);
5195                 if ((last != NULL) && (last != ret))
5196                     xmlFreeDocElementContent(ctxt->myDoc, last);
5197                 if (ret != NULL)
5198                     xmlFreeDocElementContent(ctxt->myDoc, ret);
5199                 return(NULL);
5200             }
5201             NEXT;
5202
5203             op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
5204             if (op == NULL) {
5205                 if ((last != NULL) && (last != ret))
5206                     xmlFreeDocElementContent(ctxt->myDoc, last);
5207                 xmlFreeDocElementContent(ctxt->myDoc, ret);
5208                 return(NULL);
5209             }
5210             if (last == NULL) {
5211                 op->c1 = ret;
5212                 if (ret != NULL)
5213                     ret->parent = op;
5214                 ret = cur = op;
5215             } else {
5216                 cur->c2 = op;
5217                 if (op != NULL)
5218                     op->parent = cur;
5219                 op->c1 = last;
5220                 if (last != NULL)
5221                     last->parent = op;
5222                 cur =op;
5223                 last = NULL;
5224             }
5225         } else if (RAW == '|') {
5226             if (type == 0) type = CUR;
5227
5228             /*
5229              * Detect "Name , Name | Name" error
5230              */
5231             else if (type != CUR) {
5232                 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
5233                     "xmlParseElementChildrenContentDecl : '%c' expected\n",
5234                                   type);
5235                 if ((last != NULL) && (last != ret))
5236                     xmlFreeDocElementContent(ctxt->myDoc, last);
5237                 if (ret != NULL)
5238                     xmlFreeDocElementContent(ctxt->myDoc, ret);
5239                 return(NULL);
5240             }
5241             NEXT;
5242
5243             op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
5244             if (op == NULL) {
5245                 if ((last != NULL) && (last != ret))
5246                     xmlFreeDocElementContent(ctxt->myDoc, last);
5247                 if (ret != NULL)
5248                     xmlFreeDocElementContent(ctxt->myDoc, ret);
5249                 return(NULL);
5250             }
5251             if (last == NULL) {
5252                 op->c1 = ret;
5253                 if (ret != NULL)
5254                     ret->parent = op;
5255                 ret = cur = op;
5256             } else {
5257                 cur->c2 = op;
5258                 if (op != NULL)
5259                     op->parent = cur;
5260                 op->c1 = last;
5261                 if (last != NULL)
5262                     last->parent = op;
5263                 cur =op;
5264                 last = NULL;
5265             }
5266         } else {
5267             xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
5268             if (ret != NULL)
5269                 xmlFreeDocElementContent(ctxt->myDoc, ret);
5270             return(NULL);
5271         }
5272         GROW;
5273         SKIP_BLANKS;
5274         GROW;
5275         if (RAW == '(') {
5276             int inputid = ctxt->input->id;
5277             /* Recurse on second child */
5278             NEXT;
5279             SKIP_BLANKS;
5280             last = xmlParseElementChildrenContentDecl(ctxt, inputid);
5281             SKIP_BLANKS;
5282         } else {
5283             elem = xmlParseName(ctxt);
5284             if (elem == NULL) {
5285                 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
5286                 if (ret != NULL)
5287                     xmlFreeDocElementContent(ctxt->myDoc, ret);
5288                 return(NULL);
5289             }
5290             last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
5291             if (RAW == '?') {
5292                 last->ocur = XML_ELEMENT_CONTENT_OPT;
5293                 NEXT;
5294             } else if (RAW == '*') {
5295                 last->ocur = XML_ELEMENT_CONTENT_MULT;
5296                 NEXT;
5297             } else if (RAW == '+') {
5298                 last->ocur = XML_ELEMENT_CONTENT_PLUS;
5299                 NEXT;
5300             } else {
5301                 last->ocur = XML_ELEMENT_CONTENT_ONCE;
5302             }
5303         }
5304         SKIP_BLANKS;
5305         GROW;
5306     }
5307     if ((cur != NULL) && (last != NULL)) {
5308         cur->c2 = last;
5309         if (last != NULL)
5310             last->parent = cur;
5311     }
5312     if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
5313         xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
5314 "Element content declaration doesn't start and stop in the same entity\n",
5315                          NULL);
5316     }
5317     NEXT;
5318     if (RAW == '?') {
5319         if (ret != NULL) {
5320             if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
5321                 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
5322                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
5323             else
5324                 ret->ocur = XML_ELEMENT_CONTENT_OPT;
5325         }
5326         NEXT;
5327     } else if (RAW == '*') {
5328         if (ret != NULL) {
5329             ret->ocur = XML_ELEMENT_CONTENT_MULT;
5330             cur = ret;
5331             /*
5332              * Some normalization:
5333              * (a | b* | c?)* == (a | b | c)*
5334              */
5335             while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
5336                 if ((cur->c1 != NULL) &&
5337                     ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
5338                      (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
5339                     cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
5340                 if ((cur->c2 != NULL) &&
5341                     ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
5342                      (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
5343                     cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
5344                 cur = cur->c2;
5345             }
5346         }
5347         NEXT;
5348     } else if (RAW == '+') {
5349         if (ret != NULL) {
5350             int found = 0;
5351
5352             if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
5353                 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
5354                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
5355             else
5356                 ret->ocur = XML_ELEMENT_CONTENT_PLUS;
5357             /*
5358              * Some normalization:
5359              * (a | b*)+ == (a | b)*
5360              * (a | b?)+ == (a | b)*
5361              */
5362             while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
5363                 if ((cur->c1 != NULL) &&
5364                     ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
5365                      (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
5366                     cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
5367                     found = 1;
5368                 }
5369                 if ((cur->c2 != NULL) &&
5370                     ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
5371                      (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
5372                     cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
5373                     found = 1;
5374                 }
5375                 cur = cur->c2;
5376             }
5377             if (found)
5378                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
5379         }
5380         NEXT;
5381     }
5382     return(ret);
5383 }
5384
5385 /**
5386  * xmlParseElementContentDecl:
5387  * @ctxt:  an XML parser context
5388  * @name:  the name of the element being defined.
5389  * @result:  the Element Content pointer will be stored here if any
5390  *
5391  * parse the declaration for an Element content either Mixed or Children,
5392  * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
5393  * 
5394  * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
5395  *
5396  * returns: the type of element content XML_ELEMENT_TYPE_xxx
5397  */
5398
5399 int
5400 xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
5401                            xmlElementContentPtr *result) {
5402
5403     xmlElementContentPtr tree = NULL;
5404     int inputid = ctxt->input->id;
5405     int res;
5406
5407     *result = NULL;
5408
5409     if (RAW != '(') {
5410         xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
5411                 "xmlParseElementContentDecl : %s '(' expected\n", name);
5412         return(-1);
5413     }
5414     NEXT;
5415     GROW;
5416     SKIP_BLANKS;
5417     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
5418         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
5419         res = XML_ELEMENT_TYPE_MIXED;
5420     } else {
5421         tree = xmlParseElementChildrenContentDecl(ctxt, inputid);
5422         res = XML_ELEMENT_TYPE_ELEMENT;
5423     }
5424     SKIP_BLANKS;
5425     *result = tree;
5426     return(res);
5427 }
5428
5429 /**
5430  * xmlParseElementDecl:
5431  * @ctxt:  an XML parser context
5432  *
5433  * parse an Element declaration.
5434  *
5435  * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
5436  *
5437  * [ VC: Unique Element Type Declaration ]
5438  * No element type may be declared more than once
5439  *
5440  * Returns the type of the element, or -1 in case of error
5441  */
5442 int
5443 xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
5444     const xmlChar *name;
5445     int ret = -1;
5446     xmlElementContentPtr content  = NULL;
5447
5448     /* GROW; done in the caller */
5449     if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
5450         xmlParserInputPtr input = ctxt->input;
5451
5452         SKIP(9);
5453         if (!IS_BLANK_CH(CUR)) {
5454             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5455                            "Space required after 'ELEMENT'\n");
5456         }
5457         SKIP_BLANKS;
5458         name = xmlParseName(ctxt);
5459         if (name == NULL) {
5460             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5461                            "xmlParseElementDecl: no name for Element\n");
5462             return(-1);
5463         }
5464         while ((RAW == 0) && (ctxt->inputNr > 1))
5465             xmlPopInput(ctxt);
5466         if (!IS_BLANK_CH(CUR)) {
5467             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5468                            "Space required after the element name\n");
5469         }
5470         SKIP_BLANKS;
5471         if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
5472             SKIP(5);
5473             /*
5474              * Element must always be empty.
5475              */
5476             ret = XML_ELEMENT_TYPE_EMPTY;
5477         } else if ((RAW == 'A') && (NXT(1) == 'N') &&
5478                    (NXT(2) == 'Y')) {
5479             SKIP(3);
5480             /*
5481              * Element is a generic container.
5482              */
5483             ret = XML_ELEMENT_TYPE_ANY;
5484         } else if (RAW == '(') {
5485             ret = xmlParseElementContentDecl(ctxt, name, &content);
5486         } else {
5487             /*
5488              * [ WFC: PEs in Internal Subset ] error handling.
5489              */
5490             if ((RAW == '%') && (ctxt->external == 0) &&
5491                 (ctxt->inputNr == 1)) {
5492                 xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
5493           "PEReference: forbidden within markup decl in internal subset\n");
5494             } else {
5495                 xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
5496                       "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
5497             }
5498             return(-1);
5499         }
5500
5501         SKIP_BLANKS;
5502         /*
5503          * Pop-up of finished entities.
5504          */
5505         while ((RAW == 0) && (ctxt->inputNr > 1))
5506             xmlPopInput(ctxt);
5507         SKIP_BLANKS;
5508
5509         if (RAW != '>') {
5510             xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
5511             if (content != NULL) {
5512                 xmlFreeDocElementContent(ctxt->myDoc, content);
5513             }
5514         } else {
5515             if (input != ctxt->input) {
5516                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5517     "Element declaration doesn't start and stop in the same entity\n");
5518             }
5519                 
5520             NEXT;
5521             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5522                 (ctxt->sax->elementDecl != NULL)) {
5523                 if (content != NULL)
5524                     content->parent = NULL;
5525                 ctxt->sax->elementDecl(ctxt->userData, name, ret,
5526                                        content);
5527                 if ((content != NULL) && (content->parent == NULL)) {
5528                     /*
5529                      * this is a trick: if xmlAddElementDecl is called,
5530                      * instead of copying the full tree it is plugged directly
5531                      * if called from the parser. Avoid duplicating the 
5532                      * interfaces or change the API/ABI
5533                      */
5534                     xmlFreeDocElementContent(ctxt->myDoc, content);
5535                 }
5536             } else if (content != NULL) {
5537                 xmlFreeDocElementContent(ctxt->myDoc, content);
5538             }
5539         }
5540     }
5541     return(ret);
5542 }
5543
5544 /**
5545  * xmlParseConditionalSections
5546  * @ctxt:  an XML parser context
5547  *
5548  * [61] conditionalSect ::= includeSect | ignoreSect 
5549  * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>' 
5550  * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
5551  * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
5552  * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
5553  */
5554
5555 static void
5556 xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
5557     SKIP(3);
5558     SKIP_BLANKS;
5559     if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
5560         SKIP(7);
5561         SKIP_BLANKS;
5562         if (RAW != '[') {
5563             xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
5564         } else {
5565             NEXT;
5566         }
5567         if (xmlParserDebugEntities) {
5568             if ((ctxt->input != NULL) && (ctxt->input->filename))
5569                 xmlGenericError(xmlGenericErrorContext,
5570                         "%s(%d): ", ctxt->input->filename,
5571                         ctxt->input->line);
5572             xmlGenericError(xmlGenericErrorContext,
5573                     "Entering INCLUDE Conditional Section\n");
5574         }
5575
5576         while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
5577                (NXT(2) != '>'))) {
5578             const xmlChar *check = CUR_PTR;
5579             unsigned int cons = ctxt->input->consumed;
5580
5581             if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
5582                 xmlParseConditionalSections(ctxt);
5583             } else if (IS_BLANK_CH(CUR)) {
5584                 NEXT;
5585             } else if (RAW == '%') {
5586                 xmlParsePEReference(ctxt);
5587             } else
5588                 xmlParseMarkupDecl(ctxt);
5589
5590             /*
5591              * Pop-up of finished entities.
5592              */
5593             while ((RAW == 0) && (ctxt->inputNr > 1))
5594                 xmlPopInput(ctxt);
5595
5596             if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
5597                 xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
5598                 break;
5599             }
5600         }
5601         if (xmlParserDebugEntities) {
5602             if ((ctxt->input != NULL) && (ctxt->input->filename))
5603                 xmlGenericError(xmlGenericErrorContext,
5604                         "%s(%d): ", ctxt->input->filename,
5605                         ctxt->input->line);
5606             xmlGenericError(xmlGenericErrorContext,
5607                     "Leaving INCLUDE Conditional Section\n");
5608         }
5609
5610     } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
5611         int state;
5612         xmlParserInputState instate;
5613         int depth = 0;
5614
5615         SKIP(6);
5616         SKIP_BLANKS;
5617         if (RAW != '[') {
5618             xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
5619         } else {
5620             NEXT;
5621         }
5622         if (xmlParserDebugEntities) {
5623             if ((ctxt->input != NULL) && (ctxt->input->filename))
5624                 xmlGenericError(xmlGenericErrorContext,
5625                         "%s(%d): ", ctxt->input->filename,
5626                         ctxt->input->line);
5627             xmlGenericError(xmlGenericErrorContext,
5628                     "Entering IGNORE Conditional Section\n");
5629         }
5630
5631         /*
5632          * Parse up to the end of the conditional section
5633          * But disable SAX event generating DTD building in the meantime
5634          */
5635         state = ctxt->disableSAX;
5636         instate = ctxt->instate;
5637         if (ctxt->recovery == 0) ctxt->disableSAX = 1;
5638         ctxt->instate = XML_PARSER_IGNORE;
5639
5640         while ((depth >= 0) && (RAW != 0)) {
5641           if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
5642             depth++;
5643             SKIP(3);
5644             continue;
5645           }
5646           if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
5647             if (--depth >= 0) SKIP(3);
5648             continue;
5649           }
5650           NEXT;
5651           continue;
5652         }
5653
5654         ctxt->disableSAX = state;
5655         ctxt->instate = instate;
5656
5657         if (xmlParserDebugEntities) {
5658             if ((ctxt->input != NULL) && (ctxt->input->filename))
5659                 xmlGenericError(xmlGenericErrorContext,
5660                         "%s(%d): ", ctxt->input->filename,
5661                         ctxt->input->line);
5662             xmlGenericError(xmlGenericErrorContext,
5663                     "Leaving IGNORE Conditional Section\n");
5664         }
5665
5666     } else {
5667         xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
5668     }
5669
5670     if (RAW == 0)
5671         SHRINK;
5672
5673     if (RAW == 0) {
5674         xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
5675     } else {
5676         SKIP(3);
5677     }
5678 }
5679
5680 /**
5681  * xmlParseMarkupDecl:
5682  * @ctxt:  an XML parser context
5683  * 
5684  * parse Markup declarations
5685  *
5686  * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
5687  *                     NotationDecl | PI | Comment
5688  *
5689  * [ VC: Proper Declaration/PE Nesting ]
5690  * Parameter-entity replacement text must be properly nested with
5691  * markup declarations. That is to say, if either the first character
5692  * or the last character of a markup declaration (markupdecl above) is
5693  * contained in the replacement text for a parameter-entity reference,
5694  * both must be contained in the same replacement text.
5695  *
5696  * [ WFC: PEs in Internal Subset ]
5697  * In the internal DTD subset, parameter-entity references can occur
5698  * only where markup declarations can occur, not within markup declarations.
5699  * (This does not apply to references that occur in external parameter
5700  * entities or to the external subset.) 
5701  */
5702 void
5703 xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
5704     GROW;
5705     if (CUR == '<') {
5706         if (NXT(1) == '!') {
5707             switch (NXT(2)) {
5708                 case 'E':
5709                     if (NXT(3) == 'L')
5710                         xmlParseElementDecl(ctxt);
5711                     else if (NXT(3) == 'N')
5712                         xmlParseEntityDecl(ctxt);
5713                     break;
5714                 case 'A':
5715                     xmlParseAttributeListDecl(ctxt);
5716                     break;
5717                 case 'N':
5718                     xmlParseNotationDecl(ctxt);
5719                     break;
5720                 case '-':
5721                     xmlParseComment(ctxt);
5722                     break;
5723                 default:
5724                     /* there is an error but it will be detected later */
5725                     break;
5726             }
5727         } else if (NXT(1) == '?') {
5728             xmlParsePI(ctxt);
5729         }
5730     }
5731     /*
5732      * This is only for internal subset. On external entities,
5733      * the replacement is done before parsing stage
5734      */
5735     if ((ctxt->external == 0) && (ctxt->inputNr == 1))
5736         xmlParsePEReference(ctxt);
5737
5738     /*
5739      * Conditional sections are allowed from entities included
5740      * by PE References in the internal subset.
5741      */
5742     if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
5743         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
5744             xmlParseConditionalSections(ctxt);
5745         }
5746     }
5747
5748     ctxt->instate = XML_PARSER_DTD;
5749 }
5750
5751 /**
5752  * xmlParseTextDecl:
5753  * @ctxt:  an XML parser context
5754  * 
5755  * parse an XML declaration header for external entities
5756  *
5757  * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
5758  *
5759  * Question: Seems that EncodingDecl is mandatory ? Is that a typo ?
5760  */
5761
5762 void
5763 xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
5764     xmlChar *version;
5765     const xmlChar *encoding;
5766
5767     /*
5768      * We know that '<?xml' is here.
5769      */
5770     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
5771         SKIP(5);
5772     } else {
5773         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
5774         return;
5775     }
5776
5777     if (!IS_BLANK_CH(CUR)) {
5778         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5779                        "Space needed after '<?xml'\n");
5780     }
5781     SKIP_BLANKS;
5782
5783     /*
5784      * We may have the VersionInfo here.
5785      */
5786     version = xmlParseVersionInfo(ctxt);
5787     if (version == NULL)
5788         version = xmlCharStrdup(XML_DEFAULT_VERSION);
5789     else {
5790         if (!IS_BLANK_CH(CUR)) {
5791             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5792                            "Space needed here\n");
5793         }
5794     }
5795     ctxt->input->version = version;
5796
5797     /*
5798      * We must have the encoding declaration
5799      */
5800     encoding = xmlParseEncodingDecl(ctxt);
5801     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
5802         /*
5803          * The XML REC instructs us to stop parsing right here
5804          */
5805         return;
5806     }
5807     if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
5808         xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
5809                        "Missing encoding in text declaration\n");
5810     }
5811
5812     SKIP_BLANKS;
5813     if ((RAW == '?') && (NXT(1) == '>')) {
5814         SKIP(2);
5815     } else if (RAW == '>') {
5816         /* Deprecated old WD ... */
5817         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
5818         NEXT;
5819     } else {
5820         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
5821         MOVETO_ENDTAG(CUR_PTR);
5822         NEXT;
5823     }
5824 }
5825
5826 /**
5827  * xmlParseExternalSubset:
5828  * @ctxt:  an XML parser context
5829  * @ExternalID: the external identifier
5830  * @SystemID: the system identifier (or URL)
5831  * 
5832  * parse Markup declarations from an external subset
5833  *
5834  * [30] extSubset ::= textDecl? extSubsetDecl
5835  *
5836  * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
5837  */
5838 void
5839 xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
5840                        const xmlChar *SystemID) {
5841     xmlDetectSAX2(ctxt);
5842     GROW;
5843     if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
5844         xmlParseTextDecl(ctxt);
5845         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
5846             /*
5847              * The XML REC instructs us to stop parsing right here
5848              */
5849             ctxt->instate = XML_PARSER_EOF;
5850             return;
5851         }
5852     }
5853     if (ctxt->myDoc == NULL) {
5854         ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
5855     }
5856     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
5857         xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
5858
5859     ctxt->instate = XML_PARSER_DTD;
5860     ctxt->external = 1;
5861     while (((RAW == '<') && (NXT(1) == '?')) ||
5862            ((RAW == '<') && (NXT(1) == '!')) ||
5863            (RAW == '%') || IS_BLANK_CH(CUR)) {
5864         const xmlChar *check = CUR_PTR;
5865         unsigned int cons = ctxt->input->consumed;
5866
5867         GROW;
5868         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
5869             xmlParseConditionalSections(ctxt);
5870         } else if (IS_BLANK_CH(CUR)) {
5871             NEXT;
5872         } else if (RAW == '%') {
5873             xmlParsePEReference(ctxt);
5874         } else
5875             xmlParseMarkupDecl(ctxt);
5876
5877         /*
5878          * Pop-up of finished entities.
5879          */
5880         while ((RAW == 0) && (ctxt->inputNr > 1))
5881             xmlPopInput(ctxt);
5882
5883         if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
5884             xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
5885             break;
5886         }
5887     }
5888     
5889     if (RAW != 0) {
5890         xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
5891     }
5892
5893 }
5894
5895 /**
5896  * xmlParseReference:
5897  * @ctxt:  an XML parser context
5898  * 
5899  * parse and handle entity references in content, depending on the SAX
5900  * interface, this may end-up in a call to character() if this is a
5901  * CharRef, a predefined entity, if there is no reference() callback.
5902  * or if the parser was asked to switch to that mode.
5903  *
5904  * [67] Reference ::= EntityRef | CharRef
5905  */
5906 void
5907 xmlParseReference(xmlParserCtxtPtr ctxt) {
5908     xmlEntityPtr ent;
5909     xmlChar *val;
5910     if (RAW != '&') return;
5911
5912     if (NXT(1) == '#') {
5913         int i = 0;
5914         xmlChar out[10];
5915         int hex = NXT(2);
5916         int value = xmlParseCharRef(ctxt);
5917         
5918         if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
5919             /*
5920              * So we are using non-UTF-8 buffers
5921              * Check that the char fit on 8bits, if not
5922              * generate a CharRef.
5923              */
5924             if (value <= 0xFF) {
5925                 out[0] = value;
5926                 out[1] = 0;
5927                 if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
5928                     (!ctxt->disableSAX))
5929                     ctxt->sax->characters(ctxt->userData, out, 1);
5930             } else {
5931                 if ((hex == 'x') || (hex == 'X'))
5932                     snprintf((char *)out, sizeof(out), "#x%X", value);
5933                 else
5934                     snprintf((char *)out, sizeof(out), "#%d", value);
5935                 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
5936                     (!ctxt->disableSAX))
5937                     ctxt->sax->reference(ctxt->userData, out);
5938             }
5939         } else {
5940             /*
5941              * Just encode the value in UTF-8
5942              */
5943             COPY_BUF(0 ,out, i, value);
5944             out[i] = 0;
5945             if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
5946                 (!ctxt->disableSAX))
5947                 ctxt->sax->characters(ctxt->userData, out, i);
5948         }
5949     } else {
5950         int was_checked;
5951
5952         ent = xmlParseEntityRef(ctxt);
5953         if (ent == NULL) return;
5954         if (!ctxt->wellFormed)
5955             return;
5956         was_checked = ent->checked;
5957         if ((ent->name != NULL) && 
5958             (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
5959             xmlNodePtr list = NULL;
5960             xmlParserErrors ret = XML_ERR_OK;
5961
5962
5963             /*
5964              * The first reference to the entity trigger a parsing phase
5965              * where the ent->children is filled with the result from
5966              * the parsing.
5967              */
5968             if (ent->checked == 0) {
5969                 xmlChar *value;
5970
5971                 value = ent->content;
5972
5973                 /*
5974                  * Check that this entity is well formed
5975                  */
5976                 if ((value != NULL) && (value[0] != 0) &&
5977                     (value[1] == 0) && (value[0] == '<') &&
5978                     (xmlStrEqual(ent->name, BAD_CAST "lt"))) {
5979                     /*
5980                      * DONE: get definite answer on this !!!
5981                      * Lots of entity decls are used to declare a single
5982                      * char 
5983                      *    <!ENTITY lt     "<">
5984                      * Which seems to be valid since
5985                      * 2.4: The ampersand character (&) and the left angle
5986                      * bracket (<) may appear in their literal form only
5987                      * when used ... They are also legal within the literal
5988                      * entity value of an internal entity declaration;i
5989                      * see "4.3.2 Well-Formed Parsed Entities". 
5990                      * IMHO 2.4 and 4.3.2 are directly in contradiction.
5991                      * Looking at the OASIS test suite and James Clark 
5992                      * tests, this is broken. However the XML REC uses
5993                      * it. Is the XML REC not well-formed ????
5994                      * This is a hack to avoid this problem
5995                      *
5996                      * ANSWER: since lt gt amp .. are already defined,
5997                      *   this is a redefinition and hence the fact that the
5998                      *   content is not well balanced is not a Wf error, this
5999                      *   is lousy but acceptable.
6000                      */
6001                     list = xmlNewDocText(ctxt->myDoc, value);
6002                     if (list != NULL) {
6003                         if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) &&
6004                             (ent->children == NULL)) {
6005                             ent->children = list;
6006                             ent->last = list;
6007                             ent->owner = 1;
6008                             list->parent = (xmlNodePtr) ent;
6009                         } else {
6010                             xmlFreeNodeList(list);
6011                         }
6012                     } else if (list != NULL) {
6013                         xmlFreeNodeList(list);
6014                     }
6015                 } else {
6016                     /*
6017                      * 4.3.2: An internal general parsed entity is well-formed
6018                      * if its replacement text matches the production labeled
6019                      * content.
6020                      */
6021
6022                     void *user_data;
6023                     /*
6024                      * This is a bit hackish but this seems the best
6025                      * way to make sure both SAX and DOM entity support
6026                      * behaves okay.
6027                      */
6028                     if (ctxt->userData == ctxt)
6029                         user_data = NULL;
6030                     else
6031                         user_data = ctxt->userData;
6032
6033                     if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
6034                         ctxt->depth++;
6035                         ret = xmlParseBalancedChunkMemoryInternal(ctxt,
6036                                            value, user_data, &list);
6037                         ctxt->depth--;
6038                     } else if (ent->etype ==
6039                                XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
6040                         ctxt->depth++;
6041                         ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
6042                                    ctxt->sax, user_data, ctxt->depth,
6043                                    ent->URI, ent->ExternalID, &list);
6044                         ctxt->depth--;
6045                     } else {
6046                         ret = XML_ERR_ENTITY_PE_INTERNAL;
6047                         xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
6048                                      "invalid entity type found\n", NULL);
6049                     }
6050                     if (ret == XML_ERR_ENTITY_LOOP) {
6051                         xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
6052                         return;
6053                     } else if ((ret == XML_ERR_OK) && (list != NULL)) {
6054                         if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
6055                          (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
6056                             (ent->children == NULL)) {
6057                             ent->children = list;
6058                             if (ctxt->replaceEntities) {
6059                                 /*
6060                                  * Prune it directly in the generated document
6061                                  * except for single text nodes.
6062                                  */
6063                                 if (((list->type == XML_TEXT_NODE) &&
6064                                      (list->next == NULL)) ||
6065                                     (ctxt->parseMode == XML_PARSE_READER)) {
6066                                     list->parent = (xmlNodePtr) ent;
6067                                     list = NULL;
6068                                     ent->owner = 1;
6069                                 } else {
6070                                     ent->owner = 0;
6071                                     while (list != NULL) {
6072                                         list->parent = (xmlNodePtr) ctxt->node;
6073                                         list->doc = ctxt->myDoc;
6074                                         if (list->next == NULL)
6075                                             ent->last = list;
6076                                         list = list->next;
6077                                     }
6078                                     list = ent->children;
6079 #ifdef LIBXML_LEGACY_ENABLED
6080                                     if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
6081                                       xmlAddEntityReference(ent, list, NULL);
6082 #endif /* LIBXML_LEGACY_ENABLED */
6083                                 }
6084                             } else {
6085                                 ent->owner = 1;
6086                                 while (list != NULL) {
6087                                     list->parent = (xmlNodePtr) ent;
6088                                     if (list->next == NULL)
6089                                         ent->last = list;
6090                                     list = list->next;
6091                                 }
6092                             }
6093                         } else {
6094                             xmlFreeNodeList(list);
6095                             list = NULL;
6096                         }
6097                     } else if ((ret != XML_ERR_OK) &&
6098                                (ret != XML_WAR_UNDECLARED_ENTITY)) {
6099                         xmlFatalErr(ctxt, ret, NULL);
6100                     } else if (list != NULL) {
6101                         xmlFreeNodeList(list);
6102                         list = NULL;
6103                     }
6104                 }
6105                 ent->checked = 1;
6106             }
6107
6108             if (ent->children == NULL) {
6109                 /*
6110                  * Probably running in SAX mode and the callbacks don't
6111                  * build the entity content. So unless we already went
6112                  * though parsing for first checking go though the entity
6113                  * content to generate callbacks associated to the entity
6114                  */
6115                 if (was_checked == 1) {
6116                     void *user_data;
6117                     /*
6118                      * This is a bit hackish but this seems the best
6119                      * way to make sure both SAX and DOM entity support
6120                      * behaves okay.
6121                      */
6122                     if (ctxt->userData == ctxt)
6123                         user_data = NULL;
6124                     else
6125                         user_data = ctxt->userData;
6126
6127                     if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
6128                         ctxt->depth++;
6129                         ret = xmlParseBalancedChunkMemoryInternal(ctxt,
6130                                            ent->content, user_data, NULL);
6131                         ctxt->depth--;
6132                     } else if (ent->etype ==
6133                                XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
6134                         ctxt->depth++;
6135                         ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
6136                                    ctxt->sax, user_data, ctxt->depth,
6137                                    ent->URI, ent->ExternalID, NULL);
6138                         ctxt->depth--;
6139                     } else {
6140                         ret = XML_ERR_ENTITY_PE_INTERNAL;
6141                         xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
6142                                      "invalid entity type found\n", NULL);
6143                     }
6144                     if (ret == XML_ERR_ENTITY_LOOP) {
6145                         xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
6146                         return;
6147                     }
6148                 }
6149                 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
6150                     (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
6151                     /*
6152                      * Entity reference callback comes second, it's somewhat
6153                      * superfluous but a compatibility to historical behaviour
6154                      */
6155                     ctxt->sax->reference(ctxt->userData, ent->name);
6156                 }
6157                 return;
6158             }
6159             if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
6160                 (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
6161                 /*
6162                  * Create a node.
6163                  */
6164                 ctxt->sax->reference(ctxt->userData, ent->name);
6165                 return;
6166             }
6167             if ((ctxt->replaceEntities) || (ent->children == NULL))  {
6168                 /*
6169                  * There is a problem on the handling of _private for entities
6170                  * (bug 155816): Should we copy the content of the field from
6171                  * the entity (possibly overwriting some value set by the user
6172                  * when a copy is created), should we leave it alone, or should
6173                  * we try to take care of different situations?  The problem
6174                  * is exacerbated by the usage of this field by the xmlReader.
6175                  * To fix this bug, we look at _private on the created node
6176                  * and, if it's NULL, we copy in whatever was in the entity.
6177                  * If it's not NULL we leave it alone.  This is somewhat of a
6178                  * hack - maybe we should have further tests to determine
6179                  * what to do.
6180                  */
6181                 if ((ctxt->node != NULL) && (ent->children != NULL)) {
6182                     /*
6183                      * Seems we are generating the DOM content, do
6184                      * a simple tree copy for all references except the first
6185                      * In the first occurrence list contains the replacement.
6186                      * progressive == 2 means we are operating on the Reader
6187                      * and since nodes are discarded we must copy all the time.
6188                      */
6189                     if (((list == NULL) && (ent->owner == 0)) ||
6190                         (ctxt->parseMode == XML_PARSE_READER)) {
6191                         xmlNodePtr nw = NULL, cur, firstChild = NULL;
6192
6193                         /*
6194                          * when operating on a reader, the entities definitions
6195                          * are always owning the entities subtree.
6196                         if (ctxt->parseMode == XML_PARSE_READER)
6197                             ent->owner = 1;
6198                          */
6199
6200                         cur = ent->children;
6201                         while (cur != NULL) {
6202                             nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
6203                             if (nw != NULL) {
6204                                 if (nw->_private == NULL)
6205                                     nw->_private = cur->_private;
6206                                 if (firstChild == NULL){
6207                                     firstChild = nw;
6208                                 }
6209                                 nw = xmlAddChild(ctxt->node, nw);
6210                             }
6211                             if (cur == ent->last) {
6212                                 /*
6213                                  * needed to detect some strange empty
6214                                  * node cases in the reader tests
6215                                  */
6216                                 if ((ctxt->parseMode == XML_PARSE_READER) &&
6217                                     (nw != NULL) &&
6218                                     (nw->type == XML_ELEMENT_NODE) &&
6219                                     (nw->children == NULL))
6220                                     nw->extra = 1;
6221
6222                                 break;
6223                             }
6224                             cur = cur->next;
6225                         }
6226 #ifdef LIBXML_LEGACY_ENABLED
6227                         if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)                         
6228                           xmlAddEntityReference(ent, firstChild, nw);
6229 #endif /* LIBXML_LEGACY_ENABLED */
6230                     } else if (list == NULL) {
6231                         xmlNodePtr nw = NULL, cur, next, last,
6232                                    firstChild = NULL;
6233                         /*
6234                          * Copy the entity child list and make it the new
6235                          * entity child list. The goal is to make sure any
6236                          * ID or REF referenced will be the one from the
6237                          * document content and not the entity copy.
6238                          */
6239                         cur = ent->children;
6240                         ent->children = NULL;
6241                         last = ent->last;
6242                         ent->last = NULL;
6243                         while (cur != NULL) {
6244                             next = cur->next;
6245                             cur->next = NULL;
6246                             cur->parent = NULL;
6247                             nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
6248                             if (nw != NULL) {
6249                                 if (nw->_private == NULL)
6250                                     nw->_private = cur->_private;
6251                                 if (firstChild == NULL){
6252                                     firstChild = cur;
6253                                 }
6254                                 xmlAddChild((xmlNodePtr) ent, nw);
6255                                 xmlAddChild(ctxt->node, cur);
6256                             }
6257                             if (cur == last)
6258                                 break;
6259                             cur = next;
6260                         }
6261                         ent->owner = 1;
6262 #ifdef LIBXML_LEGACY_ENABLED
6263                         if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)                         
6264                           xmlAddEntityReference(ent, firstChild, nw);
6265 #endif /* LIBXML_LEGACY_ENABLED */
6266                     } else {
6267                         const xmlChar *nbktext;
6268
6269                         /*
6270                          * the name change is to avoid coalescing of the
6271                          * node with a possible previous text one which
6272                          * would make ent->children a dangling pointer
6273                          */
6274                         nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
6275                                                 -1);
6276                         if (ent->children->type == XML_TEXT_NODE)
6277                             ent->children->name = nbktext;
6278                         if ((ent->last != ent->children) &&
6279                             (ent->last->type == XML_TEXT_NODE))
6280                             ent->last->name = nbktext;
6281                         xmlAddChildList(ctxt->node, ent->children);
6282                     }
6283
6284                     /*
6285                      * This is to avoid a nasty side effect, see
6286                      * characters() in SAX.c
6287                      */
6288                     ctxt->nodemem = 0;
6289                     ctxt->nodelen = 0;
6290                     return;
6291                 }
6292             }
6293         } else {
6294             val = ent->content;
6295             if (val == NULL) return;
6296             /*
6297              * inline the entity.
6298              */
6299             if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
6300                 (!ctxt->disableSAX))
6301                 ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
6302         }
6303     }
6304 }
6305
6306 /**
6307  * xmlParseEntityRef:
6308  * @ctxt:  an XML parser context
6309  *
6310  * parse ENTITY references declarations
6311  *
6312  * [68] EntityRef ::= '&' Name ';'
6313  *
6314  * [ WFC: Entity Declared ]
6315  * In a document without any DTD, a document with only an internal DTD
6316  * subset which contains no parameter entity references, or a document
6317  * with "standalone='yes'", the Name given in the entity reference
6318  * must match that in an entity declaration, except that well-formed
6319  * documents need not declare any of the following entities: amp, lt,
6320  * gt, apos, quot.  The declaration of a parameter entity must precede
6321  * any reference to it.  Similarly, the declaration of a general entity
6322  * must precede any reference to it which appears in a default value in an
6323  * attribute-list declaration. Note that if entities are declared in the
6324  * external subset or in external parameter entities, a non-validating
6325  * processor is not obligated to read and process their declarations;
6326  * for such documents, the rule that an entity must be declared is a
6327  * well-formedness constraint only if standalone='yes'.
6328  *
6329  * [ WFC: Parsed Entity ]
6330  * An entity reference must not contain the name of an unparsed entity
6331  *
6332  * Returns the xmlEntityPtr if found, or NULL otherwise.
6333  */
6334 xmlEntityPtr
6335 xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
6336     const xmlChar *name;
6337     xmlEntityPtr ent = NULL;
6338
6339     GROW;
6340     
6341     if (RAW == '&') {
6342         NEXT;
6343         name = xmlParseName(ctxt);
6344         if (name == NULL) {
6345             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6346                            "xmlParseEntityRef: no name\n");
6347         } else {
6348             if (RAW == ';') {
6349                 NEXT;
6350                 /*
6351                  * Ask first SAX for entity resolution, otherwise try the
6352                  * predefined set.
6353                  */
6354                 if (ctxt->sax != NULL) {
6355                     if (ctxt->sax->getEntity != NULL)
6356                         ent = ctxt->sax->getEntity(ctxt->userData, name);
6357                     if ((ctxt->wellFormed == 1 ) && (ent == NULL))
6358                         ent = xmlGetPredefinedEntity(name);
6359                     if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
6360                         (ctxt->userData==ctxt)) {
6361                         ent = xmlSAX2GetEntity(ctxt, name);
6362                     }
6363                 }
6364                 /*
6365                  * [ WFC: Entity Declared ]
6366                  * In a document without any DTD, a document with only an
6367                  * internal DTD subset which contains no parameter entity
6368                  * references, or a document with "standalone='yes'", the
6369                  * Name given in the entity reference must match that in an
6370                  * entity declaration, except that well-formed documents
6371                  * need not declare any of the following entities: amp, lt,
6372                  * gt, apos, quot.
6373                  * The declaration of a parameter entity must precede any
6374                  * reference to it.
6375                  * Similarly, the declaration of a general entity must
6376                  * precede any reference to it which appears in a default
6377                  * value in an attribute-list declaration. Note that if
6378                  * entities are declared in the external subset or in
6379                  * external parameter entities, a non-validating processor
6380                  * is not obligated to read and process their declarations;
6381                  * for such documents, the rule that an entity must be
6382                  * declared is a well-formedness constraint only if
6383                  * standalone='yes'. 
6384                  */
6385                 if (ent == NULL) {
6386                     if ((ctxt->standalone == 1) ||
6387                         ((ctxt->hasExternalSubset == 0) &&
6388                          (ctxt->hasPErefs == 0))) {
6389                         xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
6390                                  "Entity '%s' not defined\n", name);
6391                     } else {
6392                         xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
6393                                  "Entity '%s' not defined\n", name);
6394                         if ((ctxt->inSubset == 0) &&
6395                             (ctxt->sax != NULL) &&
6396                             (ctxt->sax->reference != NULL)) {
6397                             ctxt->sax->reference(ctxt->userData, name);
6398                         }
6399                     }
6400                     ctxt->valid = 0;
6401                 }
6402
6403                 /*
6404                  * [ WFC: Parsed Entity ]
6405                  * An entity reference must not contain the name of an
6406                  * unparsed entity
6407                  */
6408                 else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
6409                     xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
6410                              "Entity reference to unparsed entity %s\n", name);
6411                 }
6412
6413                 /*
6414                  * [ WFC: No External Entity References ]
6415                  * Attribute values cannot contain direct or indirect
6416                  * entity references to external entities.
6417                  */
6418                 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
6419                          (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
6420                     xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
6421                          "Attribute references external entity '%s'\n", name);
6422                 }
6423                 /*
6424                  * [ WFC: No < in Attribute Values ]
6425                  * The replacement text of any entity referred to directly or
6426                  * indirectly in an attribute value (other than "&lt;") must
6427                  * not contain a <. 
6428                  */
6429                 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
6430                          (ent != NULL) &&
6431                          (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
6432                          (ent->content != NULL) &&
6433                          (xmlStrchr(ent->content, '<'))) {
6434                     xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
6435          "'<' in entity '%s' is not allowed in attributes values\n", name);
6436                 }
6437
6438                 /*
6439                  * Internal check, no parameter entities here ...
6440                  */
6441                 else {
6442                     switch (ent->etype) {
6443                         case XML_INTERNAL_PARAMETER_ENTITY:
6444                         case XML_EXTERNAL_PARAMETER_ENTITY:
6445                         xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
6446                          "Attempt to reference the parameter entity '%s'\n",
6447                                           name);
6448                         break;
6449                         default:
6450                         break;
6451                     }
6452                 }
6453
6454                 /*
6455                  * [ WFC: No Recursion ]
6456                  * A parsed entity must not contain a recursive reference
6457                  * to itself, either directly or indirectly. 
6458                  * Done somewhere else
6459                  */
6460
6461             } else {
6462                 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
6463             }
6464         }
6465     }
6466     return(ent);
6467 }
6468
6469 /**
6470  * xmlParseStringEntityRef:
6471  * @ctxt:  an XML parser context
6472  * @str:  a pointer to an index in the string
6473  *
6474  * parse ENTITY references declarations, but this version parses it from
6475  * a string value.
6476  *
6477  * [68] EntityRef ::= '&' Name ';'
6478  *
6479  * [ WFC: Entity Declared ]
6480  * In a document without any DTD, a document with only an internal DTD
6481  * subset which contains no parameter entity references, or a document
6482  * with "standalone='yes'", the Name given in the entity reference
6483  * must match that in an entity declaration, except that well-formed
6484  * documents need not declare any of the following entities: amp, lt,
6485  * gt, apos, quot.  The declaration of a parameter entity must precede
6486  * any reference to it.  Similarly, the declaration of a general entity
6487  * must precede any reference to it which appears in a default value in an
6488  * attribute-list declaration. Note that if entities are declared in the
6489  * external subset or in external parameter entities, a non-validating
6490  * processor is not obligated to read and process their declarations;
6491  * for such documents, the rule that an entity must be declared is a
6492  * well-formedness constraint only if standalone='yes'.
6493  *
6494  * [ WFC: Parsed Entity ]
6495  * An entity reference must not contain the name of an unparsed entity
6496  *
6497  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
6498  * is updated to the current location in the string.
6499  */
6500 xmlEntityPtr
6501 xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
6502     xmlChar *name;
6503     const xmlChar *ptr;
6504     xmlChar cur;
6505     xmlEntityPtr ent = NULL;
6506
6507     if ((str == NULL) || (*str == NULL))
6508         return(NULL);
6509     ptr = *str;
6510     cur = *ptr;
6511     if (cur == '&') {
6512         ptr++;
6513         cur = *ptr;
6514         name = xmlParseStringName(ctxt, &ptr);
6515         if (name == NULL) {
6516             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6517                            "xmlParseStringEntityRef: no name\n");
6518         } else {
6519             if (*ptr == ';') {
6520                 ptr++;
6521                 /*
6522                  * Ask first SAX for entity resolution, otherwise try the
6523                  * predefined set.
6524                  */
6525                 if (ctxt->sax != NULL) {
6526                     if (ctxt->sax->getEntity != NULL)
6527                         ent = ctxt->sax->getEntity(ctxt->userData, name);
6528                     if (ent == NULL)
6529                         ent = xmlGetPredefinedEntity(name);
6530                     if ((ent == NULL) && (ctxt->userData==ctxt)) {
6531                         ent = xmlSAX2GetEntity(ctxt, name);
6532                     }
6533                 }
6534                 /*
6535                  * [ WFC: Entity Declared ]
6536                  * In a document without any DTD, a document with only an
6537                  * internal DTD subset which contains no parameter entity
6538                  * references, or a document with "standalone='yes'", the
6539                  * Name given in the entity reference must match that in an
6540                  * entity declaration, except that well-formed documents
6541                  * need not declare any of the following entities: amp, lt,
6542                  * gt, apos, quot.
6543                  * The declaration of a parameter entity must precede any
6544                  * reference to it.
6545                  * Similarly, the declaration of a general entity must
6546                  * precede any reference to it which appears in a default
6547                  * value in an attribute-list declaration. Note that if
6548                  * entities are declared in the external subset or in
6549                  * external parameter entities, a non-validating processor
6550                  * is not obligated to read and process their declarations;
6551                  * for such documents, the rule that an entity must be
6552                  * declared is a well-formedness constraint only if
6553                  * standalone='yes'. 
6554                  */
6555                 if (ent == NULL) {
6556                     if ((ctxt->standalone == 1) ||
6557                         ((ctxt->hasExternalSubset == 0) &&
6558                          (ctxt->hasPErefs == 0))) {
6559                         xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
6560                                  "Entity '%s' not defined\n", name);
6561                     } else {
6562                         xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
6563                                       "Entity '%s' not defined\n",
6564                                       name);
6565                     }
6566                     /* TODO ? check regressions ctxt->valid = 0; */
6567                 }
6568
6569                 /*
6570                  * [ WFC: Parsed Entity ]
6571                  * An entity reference must not contain the name of an
6572                  * unparsed entity
6573                  */
6574                 else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
6575                     xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
6576                              "Entity reference to unparsed entity %s\n", name);
6577                 }
6578
6579                 /*
6580                  * [ WFC: No External Entity References ]
6581                  * Attribute values cannot contain direct or indirect
6582                  * entity references to external entities.
6583                  */
6584                 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
6585                          (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
6586                     xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
6587                      "Attribute references external entity '%s'\n", name);
6588                 }
6589                 /*
6590                  * [ WFC: No < in Attribute Values ]
6591                  * The replacement text of any entity referred to directly or
6592                  * indirectly in an attribute value (other than "&lt;") must
6593                  * not contain a <. 
6594                  */
6595                 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
6596                          (ent != NULL) &&
6597                          (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
6598                          (ent->content != NULL) &&
6599                          (xmlStrchr(ent->content, '<'))) {
6600                     xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
6601                  "'<' in entity '%s' is not allowed in attributes values\n",
6602                                       name);
6603                 }
6604
6605                 /*
6606                  * Internal check, no parameter entities here ...
6607                  */
6608                 else {
6609                     switch (ent->etype) {
6610                         case XML_INTERNAL_PARAMETER_ENTITY:
6611                         case XML_EXTERNAL_PARAMETER_ENTITY:
6612                             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
6613                          "Attempt to reference the parameter entity '%s'\n",
6614                                               name);
6615                         break;
6616                         default:
6617                         break;
6618                     }
6619                 }
6620
6621                 /*
6622                  * [ WFC: No Recursion ]
6623                  * A parsed entity must not contain a recursive reference
6624                  * to itself, either directly or indirectly. 
6625                  * Done somewhere else
6626                  */
6627
6628             } else {
6629                 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
6630             }
6631             xmlFree(name);
6632         }
6633     }
6634     *str = ptr;
6635     return(ent);
6636 }
6637
6638 /**
6639  * xmlParsePEReference:
6640  * @ctxt:  an XML parser context
6641  *
6642  * parse PEReference declarations
6643  * The entity content is handled directly by pushing it's content as
6644  * a new input stream.
6645  *
6646  * [69] PEReference ::= '%' Name ';'
6647  *
6648  * [ WFC: No Recursion ]
6649  * A parsed entity must not contain a recursive
6650  * reference to itself, either directly or indirectly. 
6651  *
6652  * [ WFC: Entity Declared ]
6653  * In a document without any DTD, a document with only an internal DTD
6654  * subset which contains no parameter entity references, or a document
6655  * with "standalone='yes'", ...  ... The declaration of a parameter
6656  * entity must precede any reference to it...
6657  *
6658  * [ VC: Entity Declared ]
6659  * In a document with an external subset or external parameter entities
6660  * with "standalone='no'", ...  ... The declaration of a parameter entity
6661  * must precede any reference to it...
6662  *
6663  * [ WFC: In DTD ]
6664  * Parameter-entity references may only appear in the DTD.
6665  * NOTE: misleading but this is handled.
6666  */
6667 void
6668 xmlParsePEReference(xmlParserCtxtPtr ctxt)
6669 {
6670     const xmlChar *name;
6671     xmlEntityPtr entity = NULL;
6672     xmlParserInputPtr input;
6673
6674     if (RAW == '%') {
6675         NEXT;
6676         name = xmlParseName(ctxt);
6677         if (name == NULL) {
6678             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6679                            "xmlParsePEReference: no name\n");
6680         } else {
6681             if (RAW == ';') {
6682                 NEXT;
6683                 if ((ctxt->sax != NULL) &&
6684                     (ctxt->sax->getParameterEntity != NULL))
6685                     entity = ctxt->sax->getParameterEntity(ctxt->userData,
6686                                                            name);
6687                 if (entity == NULL) {
6688                     /*
6689                      * [ WFC: Entity Declared ]
6690                      * In a document without any DTD, a document with only an
6691                      * internal DTD subset which contains no parameter entity
6692                      * references, or a document with "standalone='yes'", ...
6693                      * ... The declaration of a parameter entity must precede
6694                      * any reference to it...
6695                      */
6696                     if ((ctxt->standalone == 1) ||
6697                         ((ctxt->hasExternalSubset == 0) &&
6698                          (ctxt->hasPErefs == 0))) {
6699                         xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
6700                                           "PEReference: %%%s; not found\n",
6701                                           name);
6702                     } else {
6703                         /*
6704                          * [ VC: Entity Declared ]
6705                          * In a document with an external subset or external
6706                          * parameter entities with "standalone='no'", ...
6707                          * ... The declaration of a parameter entity must
6708                          * precede any reference to it...
6709                          */
6710                         xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
6711                                       "PEReference: %%%s; not found\n",
6712                                       name, NULL);
6713                         ctxt->valid = 0;
6714                     }
6715                 } else {
6716                     /*
6717                      * Internal checking in case the entity quest barfed
6718                      */
6719                     if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
6720                         (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
6721                         xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
6722                               "Internal: %%%s; is not a parameter entity\n",
6723                                       name, NULL);
6724                     } else if (ctxt->input->free != deallocblankswrapper) {
6725                         input =
6726                             xmlNewBlanksWrapperInputStream(ctxt, entity);
6727                         xmlPushInput(ctxt, input);
6728                     } else {
6729                         /*
6730                          * TODO !!!
6731                          * handle the extra spaces added before and after
6732                          * c.f. http://www.w3.org/TR/REC-xml#as-PE
6733                          */
6734                         input = xmlNewEntityInputStream(ctxt, entity);
6735                         xmlPushInput(ctxt, input);
6736                         if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
6737                             (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
6738                             (IS_BLANK_CH(NXT(5)))) {
6739                             xmlParseTextDecl(ctxt);
6740                             if (ctxt->errNo ==
6741                                 XML_ERR_UNSUPPORTED_ENCODING) {
6742                                 /*
6743                                  * The XML REC instructs us to stop parsing
6744                                  * right here
6745                                  */
6746                                 ctxt->instate = XML_PARSER_EOF;
6747                                 return;
6748                             }
6749                         }
6750                     }
6751                 }
6752                 ctxt->hasPErefs = 1;
6753             } else {
6754                 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
6755             }
6756         }
6757     }
6758 }
6759
6760 /**
6761  * xmlParseStringPEReference:
6762  * @ctxt:  an XML parser context
6763  * @str:  a pointer to an index in the string
6764  *
6765  * parse PEReference declarations
6766  *
6767  * [69] PEReference ::= '%' Name ';'
6768  *
6769  * [ WFC: No Recursion ]
6770  * A parsed entity must not contain a recursive
6771  * reference to itself, either directly or indirectly. 
6772  *
6773  * [ WFC: Entity Declared ]
6774  * In a document without any DTD, a document with only an internal DTD
6775  * subset which contains no parameter entity references, or a document
6776  * with "standalone='yes'", ...  ... The declaration of a parameter
6777  * entity must precede any reference to it...
6778  *
6779  * [ VC: Entity Declared ]
6780  * In a document with an external subset or external parameter entities
6781  * with "standalone='no'", ...  ... The declaration of a parameter entity
6782  * must precede any reference to it...
6783  *
6784  * [ WFC: In DTD ]
6785  * Parameter-entity references may only appear in the DTD.
6786  * NOTE: misleading but this is handled.
6787  *
6788  * Returns the string of the entity content.
6789  *         str is updated to the current value of the index
6790  */
6791 xmlEntityPtr
6792 xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
6793     const xmlChar *ptr;
6794     xmlChar cur;
6795     xmlChar *name;
6796     xmlEntityPtr entity = NULL;
6797
6798     if ((str == NULL) || (*str == NULL)) return(NULL);
6799     ptr = *str;
6800     cur = *ptr;
6801     if (cur == '%') {
6802         ptr++;
6803         cur = *ptr;
6804         name = xmlParseStringName(ctxt, &ptr);
6805         if (name == NULL) {
6806             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6807                            "xmlParseStringPEReference: no name\n");
6808         } else {
6809             cur = *ptr;
6810             if (cur == ';') {
6811                 ptr++;
6812                 cur = *ptr;
6813                 if ((ctxt->sax != NULL) &&
6814                     (ctxt->sax->getParameterEntity != NULL))
6815                     entity = ctxt->sax->getParameterEntity(ctxt->userData,
6816                                                            name);
6817                 if (entity == NULL) {
6818                     /*
6819                      * [ WFC: Entity Declared ]
6820                      * In a document without any DTD, a document with only an
6821                      * internal DTD subset which contains no parameter entity
6822                      * references, or a document with "standalone='yes'", ...
6823                      * ... The declaration of a parameter entity must precede
6824                      * any reference to it...
6825                      */
6826                     if ((ctxt->standalone == 1) ||
6827                         ((ctxt->hasExternalSubset == 0) &&
6828                          (ctxt->hasPErefs == 0))) {
6829                         xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
6830                              "PEReference: %%%s; not found\n", name);
6831                     } else {
6832                         /*
6833                          * [ VC: Entity Declared ]
6834                          * In a document with an external subset or external
6835                          * parameter entities with "standalone='no'", ...
6836                          * ... The declaration of a parameter entity must
6837                          * precede any reference to it...
6838                          */
6839                         xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
6840                                       "PEReference: %%%s; not found\n",
6841                                       name, NULL);
6842                         ctxt->valid = 0;
6843                     }
6844                 } else {
6845                     /*
6846                      * Internal checking in case the entity quest barfed
6847                      */
6848                     if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
6849                         (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
6850                         xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
6851                                       "%%%s; is not a parameter entity\n",
6852                                       name, NULL);
6853                     }
6854                 }
6855                 ctxt->hasPErefs = 1;
6856             } else {
6857                 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
6858             }
6859             xmlFree(name);
6860         }
6861     }
6862     *str = ptr;
6863     return(entity);
6864 }
6865
6866 /**
6867  * xmlParseDocTypeDecl:
6868  * @ctxt:  an XML parser context
6869  *
6870  * parse a DOCTYPE declaration
6871  *
6872  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? 
6873  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
6874  *
6875  * [ VC: Root Element Type ]
6876  * The Name in the document type declaration must match the element
6877  * type of the root element. 
6878  */
6879
6880 void
6881 xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
6882     const xmlChar *name = NULL;
6883     xmlChar *ExternalID = NULL;
6884     xmlChar *URI = NULL;
6885
6886     /*
6887      * We know that '<!DOCTYPE' has been detected.
6888      */
6889     SKIP(9);
6890
6891     SKIP_BLANKS;
6892
6893     /*
6894      * Parse the DOCTYPE name.
6895      */
6896     name = xmlParseName(ctxt);
6897     if (name == NULL) {
6898         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6899                        "xmlParseDocTypeDecl : no DOCTYPE name !\n");
6900     }
6901     ctxt->intSubName = name;
6902
6903     SKIP_BLANKS;
6904
6905     /*
6906      * Check for SystemID and ExternalID
6907      */
6908     URI = xmlParseExternalID(ctxt, &ExternalID, 1);
6909
6910     if ((URI != NULL) || (ExternalID != NULL)) {
6911         ctxt->hasExternalSubset = 1;
6912     }
6913     ctxt->extSubURI = URI;
6914     ctxt->extSubSystem = ExternalID;
6915
6916     SKIP_BLANKS;
6917
6918     /*
6919      * Create and update the internal subset.
6920      */
6921     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
6922         (!ctxt->disableSAX))
6923         ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
6924
6925     /*
6926      * Is there any internal subset declarations ?
6927      * they are handled separately in xmlParseInternalSubset()
6928      */
6929     if (RAW == '[')
6930         return;
6931
6932     /*
6933      * We should be at the end of the DOCTYPE declaration.
6934      */
6935     if (RAW != '>') {
6936         xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
6937     }
6938     NEXT;
6939 }
6940
6941 /**
6942  * xmlParseInternalSubset:
6943  * @ctxt:  an XML parser context
6944  *
6945  * parse the internal subset declaration
6946  *
6947  * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
6948  */
6949
6950 static void
6951 xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
6952     /*
6953      * Is there any DTD definition ?
6954      */
6955     if (RAW == '[') {
6956         ctxt->instate = XML_PARSER_DTD;
6957         NEXT;
6958         /*
6959          * Parse the succession of Markup declarations and 
6960          * PEReferences.
6961          * Subsequence (markupdecl | PEReference | S)*
6962          */
6963         while (RAW != ']') {
6964             const xmlChar *check = CUR_PTR;
6965             unsigned int cons = ctxt->input->consumed;
6966
6967             SKIP_BLANKS;
6968             xmlParseMarkupDecl(ctxt);
6969             xmlParsePEReference(ctxt);
6970
6971             /*
6972              * Pop-up of finished entities.
6973              */
6974             while ((RAW == 0) && (ctxt->inputNr > 1))
6975                 xmlPopInput(ctxt);
6976
6977             if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
6978                 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
6979              "xmlParseInternalSubset: error detected in Markup declaration\n");
6980                 break;
6981             }
6982         }
6983         if (RAW == ']') { 
6984             NEXT;
6985             SKIP_BLANKS;
6986         }
6987     }
6988
6989     /*
6990      * We should be at the end of the DOCTYPE declaration.
6991      */
6992     if (RAW != '>') {
6993         xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
6994     }
6995     NEXT;
6996 }
6997
6998 #ifdef LIBXML_SAX1_ENABLED
6999 /**
7000  * xmlParseAttribute:
7001  * @ctxt:  an XML parser context
7002  * @value:  a xmlChar ** used to store the value of the attribute
7003  *
7004  * parse an attribute
7005  *
7006  * [41] Attribute ::= Name Eq AttValue
7007  *
7008  * [ WFC: No External Entity References ]
7009  * Attribute values cannot contain direct or indirect entity references
7010  * to external entities.
7011  *
7012  * [ WFC: No < in Attribute Values ]
7013  * The replacement text of any entity referred to directly or indirectly in
7014  * an attribute value (other than "&lt;") must not contain a <. 
7015  * 
7016  * [ VC: Attribute Value Type ]
7017  * The attribute must have been declared; the value must be of the type
7018  * declared for it.
7019  *
7020  * [25] Eq ::= S? '=' S?
7021  *
7022  * With namespace:
7023  *
7024  * [NS 11] Attribute ::= QName Eq AttValue
7025  *
7026  * Also the case QName == xmlns:??? is handled independently as a namespace
7027  * definition.
7028  *
7029  * Returns the attribute name, and the value in *value.
7030  */
7031
7032 const xmlChar *
7033 xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
7034     const xmlChar *name;
7035     xmlChar *val;
7036
7037     *value = NULL;
7038     GROW;
7039     name = xmlParseName(ctxt);
7040     if (name == NULL) {
7041         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7042                        "error parsing attribute name\n");
7043         return(NULL);
7044     }
7045
7046     /*
7047      * read the value
7048      */
7049     SKIP_BLANKS;
7050     if (RAW == '=') {
7051         NEXT;
7052         SKIP_BLANKS;
7053         val = xmlParseAttValue(ctxt);
7054         ctxt->instate = XML_PARSER_CONTENT;
7055     } else {
7056         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
7057                "Specification mandate value for attribute %s\n", name);
7058         return(NULL);
7059     }
7060
7061     /*
7062      * Check that xml:lang conforms to the specification
7063      * No more registered as an error, just generate a warning now
7064      * since this was deprecated in XML second edition
7065      */
7066     if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
7067         if (!xmlCheckLanguageID(val)) {
7068             xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
7069                           "Malformed value for xml:lang : %s\n",
7070                           val, NULL);
7071         }
7072     }
7073
7074     /*
7075      * Check that xml:space conforms to the specification
7076      */
7077     if (xmlStrEqual(name, BAD_CAST "xml:space")) {
7078         if (xmlStrEqual(val, BAD_CAST "default"))
7079             *(ctxt->space) = 0;
7080         else if (xmlStrEqual(val, BAD_CAST "preserve"))
7081             *(ctxt->space) = 1;
7082         else {
7083                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
7084 "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
7085                                  val, NULL);
7086         }
7087     }
7088
7089     *value = val;
7090     return(name);
7091 }
7092
7093 /**
7094  * xmlParseStartTag:
7095  * @ctxt:  an XML parser context
7096  * 
7097  * parse a start of tag either for rule element or
7098  * EmptyElement. In both case we don't parse the tag closing chars.
7099  *
7100  * [40] STag ::= '<' Name (S Attribute)* S? '>'
7101  *
7102  * [ WFC: Unique Att Spec ]
7103  * No attribute name may appear more than once in the same start-tag or
7104  * empty-element tag. 
7105  *
7106  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
7107  *
7108  * [ WFC: Unique Att Spec ]
7109  * No attribute name may appear more than once in the same start-tag or
7110  * empty-element tag. 
7111  *
7112  * With namespace:
7113  *
7114  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
7115  *
7116  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
7117  *
7118  * Returns the element name parsed
7119  */
7120
7121 const xmlChar *
7122 xmlParseStartTag(xmlParserCtxtPtr ctxt) {
7123     const xmlChar *name;
7124     const xmlChar *attname;
7125     xmlChar *attvalue;
7126     const xmlChar **atts = ctxt->atts;
7127     int nbatts = 0;
7128     int maxatts = ctxt->maxatts;
7129     int i;
7130
7131     if (RAW != '<') return(NULL);
7132     NEXT1;
7133
7134     name = xmlParseName(ctxt);
7135     if (name == NULL) {
7136         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7137              "xmlParseStartTag: invalid element name\n");
7138         return(NULL);
7139     }
7140
7141     /*
7142      * Now parse the attributes, it ends up with the ending
7143      *
7144      * (S Attribute)* S?
7145      */
7146     SKIP_BLANKS;
7147     GROW;
7148
7149     while ((RAW != '>') && 
7150            ((RAW != '/') || (NXT(1) != '>')) &&
7151            (IS_BYTE_CHAR(RAW))) {
7152         const xmlChar *q = CUR_PTR;
7153         unsigned int cons = ctxt->input->consumed;
7154
7155         attname = xmlParseAttribute(ctxt, &attvalue);
7156         if ((attname != NULL) && (attvalue != NULL)) {
7157             /*
7158              * [ WFC: Unique Att Spec ]
7159              * No attribute name may appear more than once in the same
7160              * start-tag or empty-element tag. 
7161              */
7162             for (i = 0; i < nbatts;i += 2) {
7163                 if (xmlStrEqual(atts[i], attname)) {
7164                     xmlErrAttributeDup(ctxt, NULL, attname);
7165                     xmlFree(attvalue);
7166                     goto failed;
7167                 }
7168             }
7169             /*
7170              * Add the pair to atts
7171              */
7172             if (atts == NULL) {
7173                 maxatts = 22; /* allow for 10 attrs by default */
7174                 atts = (const xmlChar **)
7175                        xmlMalloc(maxatts * sizeof(xmlChar *));
7176                 if (atts == NULL) {
7177                     xmlErrMemory(ctxt, NULL);
7178                     if (attvalue != NULL)
7179                         xmlFree(attvalue);
7180                     goto failed;
7181                 }
7182                 ctxt->atts = atts;
7183                 ctxt->maxatts = maxatts;
7184             } else if (nbatts + 4 > maxatts) {
7185                 const xmlChar **n;
7186
7187                 maxatts *= 2;
7188                 n = (const xmlChar **) xmlRealloc((void *) atts,
7189                                              maxatts * sizeof(const xmlChar *));
7190                 if (n == NULL) {
7191                     xmlErrMemory(ctxt, NULL);
7192                     if (attvalue != NULL)
7193                         xmlFree(attvalue);
7194                     goto failed;
7195                 }
7196                 atts = n;
7197                 ctxt->atts = atts;
7198                 ctxt->maxatts = maxatts;
7199             }
7200             atts[nbatts++] = attname;
7201             atts[nbatts++] = attvalue;
7202             atts[nbatts] = NULL;
7203             atts[nbatts + 1] = NULL;
7204         } else {
7205             if (attvalue != NULL)
7206                 xmlFree(attvalue);
7207         }
7208
7209 failed:     
7210
7211         GROW
7212         if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
7213             break;
7214         if (!IS_BLANK_CH(RAW)) {
7215             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
7216                            "attributes construct error\n");
7217         }
7218         SKIP_BLANKS;
7219         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
7220             (attname == NULL) && (attvalue == NULL)) {
7221             xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
7222                            "xmlParseStartTag: problem parsing attributes\n");
7223             break;
7224         }
7225         SHRINK;
7226         GROW;
7227     }
7228
7229     /*
7230      * SAX: Start of Element !
7231      */
7232     if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
7233         (!ctxt->disableSAX)) {
7234         if (nbatts > 0)
7235             ctxt->sax->startElement(ctxt->userData, name, atts);
7236         else
7237             ctxt->sax->startElement(ctxt->userData, name, NULL);
7238     }
7239
7240     if (atts != NULL) {
7241         /* Free only the content strings */
7242         for (i = 1;i < nbatts;i+=2)
7243             if (atts[i] != NULL)
7244                xmlFree((xmlChar *) atts[i]);
7245     }
7246     return(name);
7247 }
7248
7249 /**
7250  * xmlParseEndTag1:
7251  * @ctxt:  an XML parser context
7252  * @line:  line of the start tag
7253  * @nsNr:  number of namespaces on the start tag
7254  *
7255  * parse an end of tag
7256  *
7257  * [42] ETag ::= '</' Name S? '>'
7258  *
7259  * With namespace
7260  *
7261  * [NS 9] ETag ::= '</' QName S? '>'
7262  */
7263
7264 static void
7265 xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
7266     const xmlChar *name;
7267
7268     GROW;
7269     if ((RAW != '<') || (NXT(1) != '/')) {
7270         xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
7271                        "xmlParseEndTag: '</' not found\n");
7272         return;
7273     }
7274     SKIP(2);
7275
7276     name = xmlParseNameAndCompare(ctxt,ctxt->name);
7277
7278     /*
7279      * We should definitely be at the ending "S? '>'" part
7280      */
7281     GROW;
7282     SKIP_BLANKS;
7283     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
7284         xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
7285     } else
7286         NEXT1;
7287
7288     /*
7289      * [ WFC: Element Type Match ]
7290      * The Name in an element's end-tag must match the element type in the
7291      * start-tag. 
7292      *
7293      */
7294     if (name != (xmlChar*)1) {
7295         if (name == NULL) name = BAD_CAST "unparseable";
7296         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
7297                      "Opening and ending tag mismatch: %s line %d and %s\n",
7298                                 ctxt->name, line, name);
7299     }
7300
7301     /*
7302      * SAX: End of Tag
7303      */
7304     if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
7305         (!ctxt->disableSAX))
7306         ctxt->sax->endElement(ctxt->userData, ctxt->name);
7307
7308     namePop(ctxt);
7309     spacePop(ctxt);
7310     return;
7311 }
7312
7313 /**
7314  * xmlParseEndTag:
7315  * @ctxt:  an XML parser context
7316  *
7317  * parse an end of tag
7318  *
7319  * [42] ETag ::= '</' Name S? '>'
7320  *
7321  * With namespace
7322  *
7323  * [NS 9] ETag ::= '</' QName S? '>'
7324  */
7325
7326 void
7327 xmlParseEndTag(xmlParserCtxtPtr ctxt) {
7328     xmlParseEndTag1(ctxt, 0);
7329 }
7330 #endif /* LIBXML_SAX1_ENABLED */
7331
7332 /************************************************************************
7333  *                                                                      *
7334  *                    SAX 2 specific operations                         *
7335  *                                                                      *
7336  ************************************************************************/
7337
7338 static const xmlChar *
7339 xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
7340     int len = 0, l;
7341     int c;
7342     int count = 0;
7343
7344     /*
7345      * Handler for more complex cases
7346      */
7347     GROW;
7348     c = CUR_CHAR(l);
7349     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
7350         (!IS_LETTER(c) && (c != '_'))) {
7351         return(NULL);
7352     }
7353
7354     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
7355            ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
7356             (c == '.') || (c == '-') || (c == '_') ||
7357             (IS_COMBINING(c)) ||
7358             (IS_EXTENDER(c)))) {
7359         if (count++ > 100) {
7360             count = 0;
7361             GROW;
7362         }
7363         len += l;
7364         NEXTL(l);
7365         c = CUR_CHAR(l);
7366     }
7367     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
7368 }
7369
7370 /*
7371  * xmlGetNamespace:
7372  * @ctxt:  an XML parser context
7373  * @prefix:  the prefix to lookup
7374  *
7375  * Lookup the namespace name for the @prefix (which ca be NULL)
7376  * The prefix must come from the @ctxt->dict dictionnary
7377  *
7378  * Returns the namespace name or NULL if not bound
7379  */
7380 static const xmlChar *
7381 xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
7382     int i;
7383
7384     if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
7385     for (i = ctxt->nsNr - 2;i >= 0;i-=2)
7386         if (ctxt->nsTab[i] == prefix) {
7387             if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
7388                 return(NULL);
7389             return(ctxt->nsTab[i + 1]);
7390         }
7391     return(NULL);
7392 }
7393
7394 /**
7395  * xmlParseNCName:
7396  * @ctxt:  an XML parser context
7397  * @len:  lenght of the string parsed
7398  *
7399  * parse an XML name.
7400  *
7401  * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
7402  *                      CombiningChar | Extender
7403  *
7404  * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
7405  *
7406  * Returns the Name parsed or NULL
7407  */
7408
7409 static const xmlChar *
7410 xmlParseNCName(xmlParserCtxtPtr ctxt) {
7411     const xmlChar *in;
7412     const xmlChar *ret;
7413     int count = 0;
7414
7415     /*
7416      * Accelerator for simple ASCII names
7417      */
7418     in = ctxt->input->cur;
7419     if (((*in >= 0x61) && (*in <= 0x7A)) ||
7420         ((*in >= 0x41) && (*in <= 0x5A)) ||
7421         (*in == '_')) {
7422         in++;
7423         while (((*in >= 0x61) && (*in <= 0x7A)) ||
7424                ((*in >= 0x41) && (*in <= 0x5A)) ||
7425                ((*in >= 0x30) && (*in <= 0x39)) ||
7426                (*in == '_') || (*in == '-') ||
7427                (*in == '.'))
7428             in++;
7429         if ((*in > 0) && (*in < 0x80)) {
7430             count = in - ctxt->input->cur;
7431             ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
7432             ctxt->input->cur = in;
7433             ctxt->nbChars += count;
7434             ctxt->input->col += count;
7435             if (ret == NULL) {
7436                 xmlErrMemory(ctxt, NULL);
7437             }
7438             return(ret);
7439         }
7440     }
7441     return(xmlParseNCNameComplex(ctxt));
7442 }
7443
7444 /**
7445  * xmlParseQName:
7446  * @ctxt:  an XML parser context
7447  * @prefix:  pointer to store the prefix part
7448  *
7449  * parse an XML Namespace QName
7450  *
7451  * [6]  QName  ::= (Prefix ':')? LocalPart
7452  * [7]  Prefix  ::= NCName
7453  * [8]  LocalPart  ::= NCName
7454  *
7455  * Returns the Name parsed or NULL
7456  */
7457
7458 static const xmlChar *
7459 xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
7460     const xmlChar *l, *p;
7461
7462     GROW;
7463
7464     l = xmlParseNCName(ctxt);
7465     if (l == NULL) {
7466         if (CUR == ':') {
7467             l = xmlParseName(ctxt);
7468             if (l != NULL) {
7469                 xmlNsErr(ctxt, XML_NS_ERR_QNAME, 
7470                          "Failed to parse QName '%s'\n", l, NULL, NULL);
7471                 *prefix = NULL;
7472                 return(l);
7473             }
7474         }
7475         return(NULL);
7476     }
7477     if (CUR == ':') {
7478         NEXT;
7479         p = l;
7480         l = xmlParseNCName(ctxt);
7481         if (l == NULL) {
7482             xmlChar *tmp;
7483
7484             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
7485                      "Failed to parse QName '%s:'\n", p, NULL, NULL);
7486             tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
7487             p = xmlDictLookup(ctxt->dict, tmp, -1);
7488             if (tmp != NULL) xmlFree(tmp);
7489             *prefix = NULL;
7490             return(p);
7491         }
7492         if (CUR == ':') {
7493             xmlChar *tmp;
7494
7495             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
7496                      "Failed to parse QName '%s:%s:'\n", p, l, NULL);
7497             NEXT;
7498             tmp = (xmlChar *) xmlParseName(ctxt);
7499             if (tmp != NULL) {
7500                 tmp = xmlBuildQName(tmp, l, NULL, 0);
7501                 l = xmlDictLookup(ctxt->dict, tmp, -1);
7502                 if (tmp != NULL) xmlFree(tmp);
7503                 *prefix = p;
7504                 return(l);
7505             }
7506             tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
7507             l = xmlDictLookup(ctxt->dict, tmp, -1);
7508             if (tmp != NULL) xmlFree(tmp);
7509             *prefix = p;
7510             return(l);
7511         }
7512         *prefix = p;
7513     } else
7514         *prefix = NULL;
7515     return(l);
7516 }
7517
7518 /**
7519  * xmlParseQNameAndCompare:
7520  * @ctxt:  an XML parser context
7521  * @name:  the localname
7522  * @prefix:  the prefix, if any.
7523  *
7524  * parse an XML name and compares for match
7525  * (specialized for endtag parsing)
7526  *
7527  * Returns NULL for an illegal name, (xmlChar*) 1 for success
7528  * and the name for mismatch
7529  */
7530
7531 static const xmlChar *
7532 xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
7533                         xmlChar const *prefix) {
7534     const xmlChar *cmp = name;
7535     const xmlChar *in;
7536     const xmlChar *ret;
7537     const xmlChar *prefix2;
7538
7539     if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
7540
7541     GROW;
7542     in = ctxt->input->cur;
7543     
7544     cmp = prefix;
7545     while (*in != 0 && *in == *cmp) {
7546         ++in;
7547         ++cmp;
7548     }
7549     if ((*cmp == 0) && (*in == ':')) {
7550         in++;
7551         cmp = name;
7552         while (*in != 0 && *in == *cmp) {
7553             ++in;
7554             ++cmp;
7555         }
7556         if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
7557             /* success */
7558             ctxt->input->cur = in;
7559             return((const xmlChar*) 1);
7560         }
7561     }
7562     /*
7563      * all strings coms from the dictionary, equality can be done directly
7564      */
7565     ret = xmlParseQName (ctxt, &prefix2);
7566     if ((ret == name) && (prefix == prefix2))
7567         return((const xmlChar*) 1);
7568     return ret;
7569 }
7570
7571 /**
7572  * xmlParseAttValueInternal:
7573  * @ctxt:  an XML parser context
7574  * @len:  attribute len result
7575  * @alloc:  whether the attribute was reallocated as a new string
7576  * @normalize:  if 1 then further non-CDATA normalization must be done
7577  *
7578  * parse a value for an attribute.
7579  * NOTE: if no normalization is needed, the routine will return pointers
7580  *       directly from the data buffer.
7581  *
7582  * 3.3.3 Attribute-Value Normalization:
7583  * Before the value of an attribute is passed to the application or
7584  * checked for validity, the XML processor must normalize it as follows: 
7585  * - a character reference is processed by appending the referenced
7586  *   character to the attribute value
7587  * - an entity reference is processed by recursively processing the
7588  *   replacement text of the entity 
7589  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
7590  *   appending #x20 to the normalized value, except that only a single
7591  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
7592  *   parsed entity or the literal entity value of an internal parsed entity 
7593  * - other characters are processed by appending them to the normalized value 
7594  * If the declared value is not CDATA, then the XML processor must further
7595  * process the normalized attribute value by discarding any leading and
7596  * trailing space (#x20) characters, and by replacing sequences of space
7597  * (#x20) characters by a single space (#x20) character.  
7598  * All attributes for which no declaration has been read should be treated
7599  * by a non-validating parser as if declared CDATA.
7600  *
7601  * Returns the AttValue parsed or NULL. The value has to be freed by the
7602  *     caller if it was copied, this can be detected by val[*len] == 0.
7603  */
7604
7605 static xmlChar *
7606 xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
7607                          int normalize)
7608 {
7609     xmlChar limit = 0;
7610     const xmlChar *in = NULL, *start, *end, *last;
7611     xmlChar *ret = NULL;
7612
7613     GROW;
7614     in = (xmlChar *) CUR_PTR;
7615     if (*in != '"' && *in != '\'') {
7616         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
7617         return (NULL);
7618     }
7619     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
7620
7621     /*
7622      * try to handle in this routine the most common case where no
7623      * allocation of a new string is required and where content is
7624      * pure ASCII.
7625      */
7626     limit = *in++;
7627     end = ctxt->input->end;
7628     start = in;
7629     if (in >= end) {
7630         const xmlChar *oldbase = ctxt->input->base;
7631         GROW;
7632         if (oldbase != ctxt->input->base) {
7633             long delta = ctxt->input->base - oldbase;
7634             start = start + delta;
7635             in = in + delta;
7636         }
7637         end = ctxt->input->end;
7638     }
7639     if (normalize) {
7640         /*
7641          * Skip any leading spaces
7642          */
7643         while ((in < end) && (*in != limit) && 
7644                ((*in == 0x20) || (*in == 0x9) ||
7645                 (*in == 0xA) || (*in == 0xD))) {
7646             in++;
7647             start = in;
7648             if (in >= end) {
7649                 const xmlChar *oldbase = ctxt->input->base;
7650                 GROW;
7651                 if (oldbase != ctxt->input->base) {
7652                     long delta = ctxt->input->base - oldbase;
7653                     start = start + delta;
7654                     in = in + delta;
7655                 }
7656                 end = ctxt->input->end;
7657             }
7658         }
7659         while ((in < end) && (*in != limit) && (*in >= 0x20) &&
7660                (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
7661             if ((*in++ == 0x20) && (*in == 0x20)) break;
7662             if (in >= end) {
7663                 const xmlChar *oldbase = ctxt->input->base;
7664                 GROW;
7665                 if (oldbase != ctxt->input->base) {
7666                     long delta = ctxt->input->base - oldbase;
7667                     start = start + delta;
7668                     in = in + delta;
7669                 }
7670                 end = ctxt->input->end;
7671             }
7672         }
7673         last = in;
7674         /*
7675          * skip the trailing blanks
7676          */
7677         while ((last[-1] == 0x20) && (last > start)) last--;
7678         while ((in < end) && (*in != limit) && 
7679                ((*in == 0x20) || (*in == 0x9) ||
7680                 (*in == 0xA) || (*in == 0xD))) {
7681             in++;
7682             if (in >= end) {
7683                 const xmlChar *oldbase = ctxt->input->base;
7684                 GROW;
7685                 if (oldbase != ctxt->input->base) {
7686                     long delta = ctxt->input->base - oldbase;
7687                     start = start + delta;
7688                     in = in + delta;
7689                     last = last + delta;
7690                 }
7691                 end = ctxt->input->end;
7692             }
7693         }
7694         if (*in != limit) goto need_complex;
7695     } else {
7696         while ((in < end) && (*in != limit) && (*in >= 0x20) &&
7697                (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
7698             in++;
7699             if (in >= end) {
7700                 const xmlChar *oldbase = ctxt->input->base;
7701                 GROW;
7702                 if (oldbase != ctxt->input->base) {
7703                     long delta = ctxt->input->base - oldbase;
7704                     start = start + delta;
7705                     in = in + delta;
7706                 }
7707                 end = ctxt->input->end;
7708             }
7709         }
7710         last = in;
7711         if (*in != limit) goto need_complex;
7712     }
7713     in++;
7714     if (len != NULL) {
7715         *len = last - start;
7716         ret = (xmlChar *) start;
7717     } else {
7718         if (alloc) *alloc = 1;
7719         ret = xmlStrndup(start, last - start);
7720     }
7721     CUR_PTR = in;
7722     if (alloc) *alloc = 0;
7723     return ret;
7724 need_complex:
7725     if (alloc) *alloc = 1;
7726     return xmlParseAttValueComplex(ctxt, len, normalize);
7727 }
7728
7729 /**
7730  * xmlParseAttribute2:
7731  * @ctxt:  an XML parser context
7732  * @pref:  the element prefix
7733  * @elem:  the element name
7734  * @prefix:  a xmlChar ** used to store the value of the attribute prefix
7735  * @value:  a xmlChar ** used to store the value of the attribute
7736  * @len:  an int * to save the length of the attribute
7737  * @alloc:  an int * to indicate if the attribute was allocated
7738  *
7739  * parse an attribute in the new SAX2 framework.
7740  *
7741  * Returns the attribute name, and the value in *value, .
7742  */
7743
7744 static const xmlChar *
7745 xmlParseAttribute2(xmlParserCtxtPtr ctxt,
7746                    const xmlChar *pref, const xmlChar *elem,
7747                    const xmlChar **prefix, xmlChar **value,
7748                    int *len, int *alloc) {
7749     const xmlChar *name;
7750     xmlChar *val, *internal_val = NULL;
7751     int normalize = 0;
7752
7753     *value = NULL;
7754     GROW;
7755     name = xmlParseQName(ctxt, prefix);
7756     if (name == NULL) {
7757         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7758                        "error parsing attribute name\n");
7759         return(NULL);
7760     }
7761
7762     /*
7763      * get the type if needed
7764      */
7765     if (ctxt->attsSpecial != NULL) {
7766         int type;
7767
7768         type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
7769                                             pref, elem, *prefix, name);
7770         if (type != 0) normalize = 1;
7771     }
7772
7773     /*
7774      * read the value
7775      */
7776     SKIP_BLANKS;
7777     if (RAW == '=') {
7778         NEXT;
7779         SKIP_BLANKS;
7780         val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
7781         ctxt->instate = XML_PARSER_CONTENT;
7782     } else {
7783         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
7784                "Specification mandate value for attribute %s\n", name);
7785         return(NULL);
7786     }
7787
7788         if (*prefix == ctxt->str_xml) {
7789                 /*
7790                  * Check that xml:lang conforms to the specification
7791                  * No more registered as an error, just generate a warning now
7792                  * since this was deprecated in XML second edition
7793                  */
7794                 if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
7795                         internal_val = xmlStrndup(val, *len);
7796                         if (!xmlCheckLanguageID(internal_val)) {
7797                                 xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
7798                                                   "Malformed value for xml:lang : %s\n",
7799                                           internal_val, NULL);
7800                         }
7801                 }
7802
7803                 /*
7804                  * Check that xml:space conforms to the specification
7805                  */
7806                 if (xmlStrEqual(name, BAD_CAST "space")) {
7807                         internal_val = xmlStrndup(val, *len);
7808                         if (xmlStrEqual(internal_val, BAD_CAST "default"))
7809                                 *(ctxt->space) = 0;
7810                         else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
7811                                 *(ctxt->space) = 1;
7812                         else {
7813                                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
7814 "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
7815                                  internal_val, NULL);
7816                         }
7817                 }
7818                 if (internal_val) {
7819                         xmlFree(internal_val);
7820                 }
7821         }
7822
7823     *value = val;
7824     return(name);
7825 }
7826
7827 /**
7828  * xmlParseStartTag2:
7829  * @ctxt:  an XML parser context
7830  * 
7831  * parse a start of tag either for rule element or
7832  * EmptyElement. In both case we don't parse the tag closing chars.
7833  * This routine is called when running SAX2 parsing
7834  *
7835  * [40] STag ::= '<' Name (S Attribute)* S? '>'
7836  *
7837  * [ WFC: Unique Att Spec ]
7838  * No attribute name may appear more than once in the same start-tag or
7839  * empty-element tag. 
7840  *
7841  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
7842  *
7843  * [ WFC: Unique Att Spec ]
7844  * No attribute name may appear more than once in the same start-tag or
7845  * empty-element tag. 
7846  *
7847  * With namespace:
7848  *
7849  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
7850  *
7851  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
7852  *
7853  * Returns the element name parsed
7854  */
7855
7856 static const xmlChar *
7857 xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
7858                   const xmlChar **URI, int *tlen) {
7859     const xmlChar *localname;
7860     const xmlChar *prefix;
7861     const xmlChar *attname;
7862     const xmlChar *aprefix;
7863     const xmlChar *nsname;
7864     xmlChar *attvalue;
7865     const xmlChar **atts = ctxt->atts;
7866     int maxatts = ctxt->maxatts;
7867     int nratts, nbatts, nbdef;
7868     int i, j, nbNs, attval, oldline, oldcol;
7869     const xmlChar *base;
7870     unsigned long cur;
7871     int nsNr = ctxt->nsNr;
7872
7873     if (RAW != '<') return(NULL);
7874     NEXT1;
7875
7876     /*
7877      * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
7878      *       point since the attribute values may be stored as pointers to
7879      *       the buffer and calling SHRINK would destroy them !
7880      *       The Shrinking is only possible once the full set of attribute
7881      *       callbacks have been done.
7882      */
7883 reparse:
7884     SHRINK;
7885     base = ctxt->input->base;
7886     cur = ctxt->input->cur - ctxt->input->base;
7887     oldline = ctxt->input->line;
7888     oldcol = ctxt->input->col;
7889     nbatts = 0;
7890     nratts = 0;
7891     nbdef = 0;
7892     nbNs = 0;
7893     attval = 0;
7894     /* Forget any namespaces added during an earlier parse of this element. */
7895     ctxt->nsNr = nsNr;
7896
7897     localname = xmlParseQName(ctxt, &prefix);
7898     if (localname == NULL) {
7899         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7900                        "StartTag: invalid element name\n");
7901         return(NULL);
7902     }
7903     *tlen = ctxt->input->cur - ctxt->input->base - cur;
7904
7905     /*
7906      * Now parse the attributes, it ends up with the ending
7907      *
7908      * (S Attribute)* S?
7909      */
7910     SKIP_BLANKS;
7911     GROW;
7912     if (ctxt->input->base != base) goto base_changed;
7913
7914     while ((RAW != '>') && 
7915            ((RAW != '/') || (NXT(1) != '>')) &&
7916            (IS_BYTE_CHAR(RAW))) {
7917         const xmlChar *q = CUR_PTR;
7918         unsigned int cons = ctxt->input->consumed;
7919         int len = -1, alloc = 0;
7920
7921         attname = xmlParseAttribute2(ctxt, prefix, localname,
7922                                      &aprefix, &attvalue, &len, &alloc);
7923         if (ctxt->input->base != base) {
7924             if ((attvalue != NULL) && (alloc != 0))
7925                 xmlFree(attvalue);
7926             attvalue = NULL;
7927             goto base_changed;
7928         }
7929         if ((attname != NULL) && (attvalue != NULL)) {
7930             if (len < 0) len = xmlStrlen(attvalue);
7931             if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
7932                 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
7933                 xmlURIPtr uri;
7934
7935                 if (*URL != 0) {
7936                     uri = xmlParseURI((const char *) URL);
7937                     if (uri == NULL) {
7938                         xmlWarningMsg(ctxt, XML_WAR_NS_URI,
7939                                       "xmlns: %s not a valid URI\n",
7940                                       URL, NULL);
7941                     } else {
7942                         if (uri->scheme == NULL) {
7943                             xmlWarningMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
7944                                    "xmlns: URI %s is not absolute\n",
7945                                           URL, NULL);
7946                         }
7947                         xmlFreeURI(uri);
7948                     }
7949                 }
7950                 /*
7951                  * check that it's not a defined namespace
7952                  */
7953                 for (j = 1;j <= nbNs;j++)
7954                     if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
7955                         break;
7956                 if (j <= nbNs)
7957                     xmlErrAttributeDup(ctxt, NULL, attname);
7958                 else
7959                     if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
7960                 if (alloc != 0) xmlFree(attvalue);
7961                 SKIP_BLANKS;
7962                 continue;
7963             }
7964             if (aprefix == ctxt->str_xmlns) {
7965                 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
7966                 xmlURIPtr uri;
7967
7968                 if (attname == ctxt->str_xml) {
7969                     if (URL != ctxt->str_xml_ns) {
7970                         xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
7971                                  "xml namespace prefix mapped to wrong URI\n",
7972                                  NULL, NULL, NULL);
7973                     }
7974                     /*
7975                      * Do not keep a namespace definition node
7976                      */
7977                     if (alloc != 0) xmlFree(attvalue);
7978                     SKIP_BLANKS;
7979                     continue;
7980                 }
7981                 uri = xmlParseURI((const char *) URL);
7982                 if (uri == NULL) {
7983                     xmlWarningMsg(ctxt, XML_WAR_NS_URI,
7984                          "xmlns:%s: '%s' is not a valid URI\n",
7985                                        attname, URL);
7986                 } else {
7987                     if ((ctxt->pedantic) && (uri->scheme == NULL)) {
7988                         xmlWarningMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
7989                                       "xmlns:%s: URI %s is not absolute\n",
7990                                       attname, URL);
7991                     }
7992                     xmlFreeURI(uri);
7993                 }
7994
7995                 /*
7996                  * check that it's not a defined namespace
7997                  */
7998                 for (j = 1;j <= nbNs;j++)
7999                     if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
8000                         break;
8001                 if (j <= nbNs)
8002                     xmlErrAttributeDup(ctxt, aprefix, attname);
8003                 else
8004                     if (nsPush(ctxt, attname, URL) > 0) nbNs++;
8005                 if (alloc != 0) xmlFree(attvalue);
8006                 SKIP_BLANKS;
8007                 if (ctxt->input->base != base) goto base_changed;
8008                 continue;
8009             }
8010
8011             /*
8012              * Add the pair to atts
8013              */
8014             if ((atts == NULL) || (nbatts + 5 > maxatts)) {
8015                 if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
8016                     if (attvalue[len] == 0)
8017                         xmlFree(attvalue);
8018                     goto failed;
8019                 }
8020                 maxatts = ctxt->maxatts;
8021                 atts = ctxt->atts;
8022             }
8023             ctxt->attallocs[nratts++] = alloc;
8024             atts[nbatts++] = attname;
8025             atts[nbatts++] = aprefix;
8026             atts[nbatts++] = NULL; /* the URI will be fetched later */
8027             atts[nbatts++] = attvalue;
8028             attvalue += len;
8029             atts[nbatts++] = attvalue;
8030             /*
8031              * tag if some deallocation is needed
8032              */
8033             if (alloc != 0) attval = 1;
8034         } else {
8035             if ((attvalue != NULL) && (attvalue[len] == 0))
8036                 xmlFree(attvalue);
8037         }
8038
8039 failed:     
8040
8041         GROW
8042         if (ctxt->input->base != base) goto base_changed;
8043         if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
8044             break;
8045         if (!IS_BLANK_CH(RAW)) {
8046             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
8047                            "attributes construct error\n");
8048             break;
8049         }
8050         SKIP_BLANKS;
8051         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
8052             (attname == NULL) && (attvalue == NULL)) {
8053             xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8054                  "xmlParseStartTag: problem parsing attributes\n");
8055             break;
8056         }
8057         GROW;
8058         if (ctxt->input->base != base) goto base_changed;
8059     }
8060
8061     /*
8062      * The attributes defaulting
8063      */
8064     if (ctxt->attsDefault != NULL) {
8065         xmlDefAttrsPtr defaults;
8066
8067         defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
8068         if (defaults != NULL) {
8069             for (i = 0;i < defaults->nbAttrs;i++) {
8070                 attname = defaults->values[4 * i];
8071                 aprefix = defaults->values[4 * i + 1];
8072
8073                 /*
8074                  * special work for namespaces defaulted defs
8075                  */
8076                 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
8077                     /*
8078                      * check that it's not a defined namespace
8079                      */
8080                     for (j = 1;j <= nbNs;j++)
8081                         if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
8082                             break;
8083                     if (j <= nbNs) continue;
8084
8085                     nsname = xmlGetNamespace(ctxt, NULL);
8086                     if (nsname != defaults->values[4 * i + 2]) {
8087                         if (nsPush(ctxt, NULL,
8088                                    defaults->values[4 * i + 2]) > 0)
8089                             nbNs++;
8090                     }
8091                 } else if (aprefix == ctxt->str_xmlns) {
8092                     /*
8093                      * check that it's not a defined namespace
8094                      */
8095                     for (j = 1;j <= nbNs;j++)
8096                         if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
8097                             break;
8098                     if (j <= nbNs) continue;
8099
8100                     nsname = xmlGetNamespace(ctxt, attname);
8101                     if (nsname != defaults->values[2]) {
8102                         if (nsPush(ctxt, attname,
8103                                    defaults->values[4 * i + 2]) > 0)
8104                             nbNs++;
8105                     }
8106                 } else {
8107                     /*
8108                      * check that it's not a defined attribute
8109                      */
8110                     for (j = 0;j < nbatts;j+=5) {
8111                         if ((attname == atts[j]) && (aprefix == atts[j+1]))
8112                             break;
8113                     }
8114                     if (j < nbatts) continue;
8115
8116                     if ((atts == NULL) || (nbatts + 5 > maxatts)) {
8117                         if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
8118                             return(NULL);
8119                         }
8120                         maxatts = ctxt->maxatts;
8121                         atts = ctxt->atts;
8122                     }
8123                     atts[nbatts++] = attname;
8124                     atts[nbatts++] = aprefix;
8125                     if (aprefix == NULL)
8126                         atts[nbatts++] = NULL;
8127                     else
8128                         atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
8129                     atts[nbatts++] = defaults->values[4 * i + 2];
8130                     atts[nbatts++] = defaults->values[4 * i + 3];
8131                     nbdef++;
8132                 }
8133             }
8134         }
8135     }
8136
8137     /*
8138      * The attributes checkings
8139      */
8140     for (i = 0; i < nbatts;i += 5) {
8141         /*
8142         * The default namespace does not apply to attribute names.
8143         */
8144         if (atts[i + 1] != NULL) {
8145             nsname = xmlGetNamespace(ctxt, atts[i + 1]);
8146             if (nsname == NULL) {
8147                 xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
8148                     "Namespace prefix %s for %s on %s is not defined\n",
8149                     atts[i + 1], atts[i], localname);
8150             }
8151             atts[i + 2] = nsname;
8152         } else
8153             nsname = NULL;
8154         /*
8155          * [ WFC: Unique Att Spec ]
8156          * No attribute name may appear more than once in the same
8157          * start-tag or empty-element tag. 
8158          * As extended by the Namespace in XML REC.
8159          */
8160         for (j = 0; j < i;j += 5) {
8161             if (atts[i] == atts[j]) {
8162                 if (atts[i+1] == atts[j+1]) {
8163                     xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
8164                     break;
8165                 }
8166                 if ((nsname != NULL) && (atts[j + 2] == nsname)) {
8167                     xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
8168                              "Namespaced Attribute %s in '%s' redefined\n",
8169                              atts[i], nsname, NULL);
8170                     break;
8171                 }
8172             }
8173         }
8174     }
8175
8176     nsname = xmlGetNamespace(ctxt, prefix);
8177     if ((prefix != NULL) && (nsname == NULL)) {
8178         xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
8179                  "Namespace prefix %s on %s is not defined\n",
8180                  prefix, localname, NULL);
8181     }
8182     *pref = prefix;
8183     *URI = nsname;
8184
8185     /*
8186      * SAX: Start of Element !
8187      */
8188     if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
8189         (!ctxt->disableSAX)) {
8190         if (nbNs > 0)
8191             ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
8192                           nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
8193                           nbatts / 5, nbdef, atts);
8194         else
8195             ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
8196                           nsname, 0, NULL, nbatts / 5, nbdef, atts);
8197     }
8198
8199     /*
8200      * Free up attribute allocated strings if needed
8201      */
8202     if (attval != 0) {
8203         for (i = 3,j = 0; j < nratts;i += 5,j++)
8204             if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
8205                 xmlFree((xmlChar *) atts[i]);
8206     }
8207
8208     return(localname);
8209
8210 base_changed:
8211     /*
8212      * the attribute strings are valid iif the base didn't changed
8213      */
8214     if (attval != 0) {
8215         for (i = 3,j = 0; j < nratts;i += 5,j++)
8216             if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
8217                 xmlFree((xmlChar *) atts[i]);
8218     }
8219     ctxt->input->cur = ctxt->input->base + cur;
8220     ctxt->input->line = oldline;
8221     ctxt->input->col = oldcol;
8222     if (ctxt->wellFormed == 1) {
8223         goto reparse;
8224     }
8225     return(NULL);
8226 }
8227
8228 /**
8229  * xmlParseEndTag2:
8230  * @ctxt:  an XML parser context
8231  * @line:  line of the start tag
8232  * @nsNr:  number of namespaces on the start tag
8233  *
8234  * parse an end of tag
8235  *
8236  * [42] ETag ::= '</' Name S? '>'
8237  *
8238  * With namespace
8239  *
8240  * [NS 9] ETag ::= '</' QName S? '>'
8241  */
8242
8243 static void
8244 xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
8245                 const xmlChar *URI, int line, int nsNr, int tlen) {
8246     const xmlChar *name;
8247
8248     GROW;
8249     if ((RAW != '<') || (NXT(1) != '/')) {
8250         xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
8251         return;
8252     }
8253     SKIP(2);
8254
8255     if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
8256         if (ctxt->input->cur[tlen] == '>') {
8257             ctxt->input->cur += tlen + 1;
8258             goto done;
8259         }
8260         ctxt->input->cur += tlen;
8261         name = (xmlChar*)1;
8262     } else {
8263         if (prefix == NULL)
8264             name = xmlParseNameAndCompare(ctxt, ctxt->name);
8265         else
8266             name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
8267     }
8268
8269     /*
8270      * We should definitely be at the ending "S? '>'" part
8271      */
8272     GROW;
8273     SKIP_BLANKS;
8274     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
8275         xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
8276     } else
8277         NEXT1;
8278
8279     /*
8280      * [ WFC: Element Type Match ]
8281      * The Name in an element's end-tag must match the element type in the
8282      * start-tag. 
8283      *
8284      */
8285     if (name != (xmlChar*)1) {
8286         if (name == NULL) name = BAD_CAST "unparseable";
8287         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
8288                      "Opening and ending tag mismatch: %s line %d and %s\n",
8289                                 ctxt->name, line, name);
8290     }
8291
8292     /*
8293      * SAX: End of Tag
8294      */
8295 done:
8296     if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
8297         (!ctxt->disableSAX))
8298         ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
8299
8300     spacePop(ctxt);
8301     if (nsNr != 0)
8302         nsPop(ctxt, nsNr);
8303     return;
8304 }
8305
8306 /**
8307  * xmlParseCDSect:
8308  * @ctxt:  an XML parser context
8309  * 
8310  * Parse escaped pure raw content.
8311  *
8312  * [18] CDSect ::= CDStart CData CDEnd
8313  *
8314  * [19] CDStart ::= '<![CDATA['
8315  *
8316  * [20] Data ::= (Char* - (Char* ']]>' Char*))
8317  *
8318  * [21] CDEnd ::= ']]>'
8319  */
8320 void
8321 xmlParseCDSect(xmlParserCtxtPtr ctxt) {
8322     xmlChar *buf = NULL;
8323     int len = 0;
8324     int size = XML_PARSER_BUFFER_SIZE;
8325     int r, rl;
8326     int s, sl;
8327     int cur, l;
8328     int count = 0;
8329
8330     /* Check 2.6.0 was NXT(0) not RAW */
8331     if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
8332         SKIP(9);
8333     } else
8334         return;
8335
8336     ctxt->instate = XML_PARSER_CDATA_SECTION;
8337     r = CUR_CHAR(rl);
8338     if (!IS_CHAR(r)) {
8339         xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
8340         ctxt->instate = XML_PARSER_CONTENT;
8341         return;
8342     }
8343     NEXTL(rl);
8344     s = CUR_CHAR(sl);
8345     if (!IS_CHAR(s)) {
8346         xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
8347         ctxt->instate = XML_PARSER_CONTENT;
8348         return;
8349     }
8350     NEXTL(sl);
8351     cur = CUR_CHAR(l);
8352     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
8353     if (buf == NULL) {
8354         xmlErrMemory(ctxt, NULL);
8355         return;
8356     }
8357     while (IS_CHAR(cur) &&
8358            ((r != ']') || (s != ']') || (cur != '>'))) {
8359         if (len + 5 >= size) {
8360             xmlChar *tmp;
8361
8362             size *= 2;
8363             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
8364             if (tmp == NULL) {
8365                 xmlFree(buf);
8366                 xmlErrMemory(ctxt, NULL);
8367                 return;
8368             }
8369             buf = tmp;
8370         }
8371         COPY_BUF(rl,buf,len,r);
8372         r = s;
8373         rl = sl;
8374         s = cur;
8375         sl = l;
8376         count++;
8377         if (count > 50) {
8378             GROW;
8379             count = 0;
8380         }
8381         NEXTL(l);
8382         cur = CUR_CHAR(l);
8383     }
8384     buf[len] = 0;
8385     ctxt->instate = XML_PARSER_CONTENT;
8386     if (cur != '>') {
8387         xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
8388                              "CData section not finished\n%.50s\n", buf);
8389         xmlFree(buf);
8390         return;
8391     }
8392     NEXTL(l);
8393
8394     /*
8395      * OK the buffer is to be consumed as cdata.
8396      */
8397     if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
8398         if (ctxt->sax->cdataBlock != NULL)
8399             ctxt->sax->cdataBlock(ctxt->userData, buf, len);
8400         else if (ctxt->sax->characters != NULL)
8401             ctxt->sax->characters(ctxt->userData, buf, len);
8402     }
8403     xmlFree(buf);
8404 }
8405
8406 /**
8407  * xmlParseContent:
8408  * @ctxt:  an XML parser context
8409  *
8410  * Parse a content:
8411  *
8412  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
8413  */
8414
8415 void
8416 xmlParseContent(xmlParserCtxtPtr ctxt) {
8417     GROW;
8418     while ((RAW != 0) &&
8419            ((RAW != '<') || (NXT(1) != '/')) &&
8420            (ctxt->instate != XML_PARSER_EOF)) {
8421         const xmlChar *test = CUR_PTR;
8422         unsigned int cons = ctxt->input->consumed;
8423         const xmlChar *cur = ctxt->input->cur;
8424
8425         /*
8426          * First case : a Processing Instruction.
8427          */
8428         if ((*cur == '<') && (cur[1] == '?')) {
8429             xmlParsePI(ctxt);
8430         }
8431
8432         /*
8433          * Second case : a CDSection
8434          */
8435         /* 2.6.0 test was *cur not RAW */
8436         else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
8437             xmlParseCDSect(ctxt);
8438         }
8439
8440         /*
8441          * Third case :  a comment
8442          */
8443         else if ((*cur == '<') && (NXT(1) == '!') &&
8444                  (NXT(2) == '-') && (NXT(3) == '-')) {
8445             xmlParseComment(ctxt);
8446             ctxt->instate = XML_PARSER_CONTENT;
8447         }
8448
8449         /*
8450          * Fourth case :  a sub-element.
8451          */
8452         else if (*cur == '<') {
8453             xmlParseElement(ctxt);
8454         }
8455
8456         /*
8457          * Fifth case : a reference. If if has not been resolved,
8458          *    parsing returns it's Name, create the node 
8459          */
8460
8461         else if (*cur == '&') {
8462             xmlParseReference(ctxt);
8463         }
8464
8465         /*
8466          * Last case, text. Note that References are handled directly.
8467          */
8468         else {
8469             xmlParseCharData(ctxt, 0);
8470         }
8471
8472         GROW;
8473         /*
8474          * Pop-up of finished entities.
8475          */
8476         while ((RAW == 0) && (ctxt->inputNr > 1))
8477             xmlPopInput(ctxt);
8478         SHRINK;
8479
8480         if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
8481             xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8482                         "detected an error in element content\n");
8483             ctxt->instate = XML_PARSER_EOF;
8484             break;
8485         }
8486     }
8487 }
8488
8489 /**
8490  * xmlParseElement:
8491  * @ctxt:  an XML parser context
8492  *
8493  * parse an XML element, this is highly recursive
8494  *
8495  * [39] element ::= EmptyElemTag | STag content ETag
8496  *
8497  * [ WFC: Element Type Match ]
8498  * The Name in an element's end-tag must match the element type in the
8499  * start-tag. 
8500  *
8501  */
8502
8503 void
8504 xmlParseElement(xmlParserCtxtPtr ctxt) {
8505     const xmlChar *name;
8506     const xmlChar *prefix;
8507     const xmlChar *URI;
8508     xmlParserNodeInfo node_info;
8509     int line, tlen;
8510     xmlNodePtr ret;
8511     int nsNr = ctxt->nsNr;
8512
8513     if ((unsigned int) ctxt->nameNr > xmlParserMaxDepth) {
8514         xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
8515               "Excessive depth in document: change xmlParserMaxDepth = %d\n",
8516                           xmlParserMaxDepth);
8517         ctxt->instate = XML_PARSER_EOF;
8518         return;
8519     }
8520
8521     /* Capture start position */
8522     if (ctxt->record_info) {
8523         node_info.begin_pos = ctxt->input->consumed +
8524                           (CUR_PTR - ctxt->input->base);
8525         node_info.begin_line = ctxt->input->line;
8526     }
8527
8528     if (ctxt->spaceNr == 0)
8529         spacePush(ctxt, -1);
8530     else if (*ctxt->space == -2)
8531         spacePush(ctxt, -1);
8532     else
8533         spacePush(ctxt, *ctxt->space);
8534
8535     line = ctxt->input->line;
8536 #ifdef LIBXML_SAX1_ENABLED
8537     if (ctxt->sax2)
8538 #endif /* LIBXML_SAX1_ENABLED */
8539         name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
8540 #ifdef LIBXML_SAX1_ENABLED
8541     else
8542         name = xmlParseStartTag(ctxt);
8543 #endif /* LIBXML_SAX1_ENABLED */
8544     if (name == NULL) {
8545         spacePop(ctxt);
8546         return;
8547     }
8548     namePush(ctxt, name);
8549     ret = ctxt->node;
8550
8551 #ifdef LIBXML_VALID_ENABLED
8552     /*
8553      * [ VC: Root Element Type ]
8554      * The Name in the document type declaration must match the element
8555      * type of the root element. 
8556      */
8557     if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
8558         ctxt->node && (ctxt->node == ctxt->myDoc->children))
8559         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
8560 #endif /* LIBXML_VALID_ENABLED */
8561
8562     /*
8563      * Check for an Empty Element.
8564      */
8565     if ((RAW == '/') && (NXT(1) == '>')) {
8566         SKIP(2);
8567         if (ctxt->sax2) {
8568             if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
8569                 (!ctxt->disableSAX))
8570                 ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
8571 #ifdef LIBXML_SAX1_ENABLED
8572         } else {
8573             if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
8574                 (!ctxt->disableSAX))
8575                 ctxt->sax->endElement(ctxt->userData, name);
8576 #endif /* LIBXML_SAX1_ENABLED */
8577         }
8578         namePop(ctxt);
8579         spacePop(ctxt);
8580         if (nsNr != ctxt->nsNr)
8581             nsPop(ctxt, ctxt->nsNr - nsNr);
8582         if ( ret != NULL && ctxt->record_info ) {
8583            node_info.end_pos = ctxt->input->consumed +
8584                               (CUR_PTR - ctxt->input->base);
8585            node_info.end_line = ctxt->input->line;
8586            node_info.node = ret;
8587            xmlParserAddNodeInfo(ctxt, &node_info);
8588         }
8589         return;
8590     }
8591     if (RAW == '>') {
8592         NEXT1;
8593     } else {
8594         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
8595                      "Couldn't find end of Start Tag %s line %d\n",
8596                                 name, line, NULL);
8597
8598         /*
8599          * end of parsing of this node.
8600          */
8601         nodePop(ctxt);
8602         namePop(ctxt);
8603         spacePop(ctxt);
8604         if (nsNr != ctxt->nsNr)
8605             nsPop(ctxt, ctxt->nsNr - nsNr);
8606
8607         /*
8608          * Capture end position and add node
8609          */
8610         if ( ret != NULL && ctxt->record_info ) {
8611            node_info.end_pos = ctxt->input->consumed +
8612                               (CUR_PTR - ctxt->input->base);
8613            node_info.end_line = ctxt->input->line;
8614            node_info.node = ret;
8615            xmlParserAddNodeInfo(ctxt, &node_info);
8616         }
8617         return;
8618     }
8619
8620     /*
8621      * Parse the content of the element:
8622      */
8623     xmlParseContent(ctxt);
8624     if (!IS_BYTE_CHAR(RAW)) {
8625         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
8626          "Premature end of data in tag %s line %d\n",
8627                                 name, line, NULL);
8628
8629         /*
8630          * end of parsing of this node.
8631          */
8632         nodePop(ctxt);
8633         namePop(ctxt);
8634         spacePop(ctxt);
8635         if (nsNr != ctxt->nsNr)
8636             nsPop(ctxt, ctxt->nsNr - nsNr);
8637         return;
8638     }
8639
8640     /*
8641      * parse the end of tag: '</' should be here.
8642      */
8643     if (ctxt->sax2) {
8644         xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
8645         namePop(ctxt);
8646     }
8647 #ifdef LIBXML_SAX1_ENABLED
8648       else
8649         xmlParseEndTag1(ctxt, line);
8650 #endif /* LIBXML_SAX1_ENABLED */
8651
8652     /*
8653      * Capture end position and add node
8654      */
8655     if ( ret != NULL && ctxt->record_info ) {
8656        node_info.end_pos = ctxt->input->consumed +
8657                           (CUR_PTR - ctxt->input->base);
8658        node_info.end_line = ctxt->input->line;
8659        node_info.node = ret;
8660        xmlParserAddNodeInfo(ctxt, &node_info);
8661     }
8662 }
8663
8664 /**
8665  * xmlParseVersionNum:
8666  * @ctxt:  an XML parser context
8667  *
8668  * parse the XML version value.
8669  *
8670  * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
8671  *
8672  * Returns the string giving the XML version number, or NULL
8673  */
8674 xmlChar *
8675 xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
8676     xmlChar *buf = NULL;
8677     int len = 0;
8678     int size = 10;
8679     xmlChar cur;
8680
8681     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
8682     if (buf == NULL) {
8683         xmlErrMemory(ctxt, NULL);
8684         return(NULL);
8685     }
8686     cur = CUR;
8687     while (((cur >= 'a') && (cur <= 'z')) ||
8688            ((cur >= 'A') && (cur <= 'Z')) ||
8689            ((cur >= '0') && (cur <= '9')) ||
8690            (cur == '_') || (cur == '.') ||
8691            (cur == ':') || (cur == '-')) {
8692         if (len + 1 >= size) {
8693             xmlChar *tmp;
8694
8695             size *= 2;
8696             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
8697             if (tmp == NULL) {
8698                 xmlErrMemory(ctxt, NULL);
8699                 return(NULL);
8700             }
8701             buf = tmp;
8702         }
8703         buf[len++] = cur;
8704         NEXT;
8705         cur=CUR;
8706     }
8707     buf[len] = 0;
8708     return(buf);
8709 }
8710
8711 /**
8712  * xmlParseVersionInfo:
8713  * @ctxt:  an XML parser context
8714  * 
8715  * parse the XML version.
8716  *
8717  * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
8718  * 
8719  * [25] Eq ::= S? '=' S?
8720  *
8721  * Returns the version string, e.g. "1.0"
8722  */
8723
8724 xmlChar *
8725 xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
8726     xmlChar *version = NULL;
8727
8728     if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
8729         SKIP(7);
8730         SKIP_BLANKS;
8731         if (RAW != '=') {
8732             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
8733             return(NULL);
8734         }
8735         NEXT;
8736         SKIP_BLANKS;
8737         if (RAW == '"') {
8738             NEXT;
8739             version = xmlParseVersionNum(ctxt);
8740             if (RAW != '"') {
8741                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
8742             } else
8743                 NEXT;
8744         } else if (RAW == '\''){
8745             NEXT;
8746             version = xmlParseVersionNum(ctxt);
8747             if (RAW != '\'') {
8748                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
8749             } else
8750                 NEXT;
8751         } else {
8752             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
8753         }
8754     }
8755     return(version);
8756 }
8757
8758 /**
8759  * xmlParseEncName:
8760  * @ctxt:  an XML parser context
8761  *
8762  * parse the XML encoding name
8763  *
8764  * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
8765  *
8766  * Returns the encoding name value or NULL
8767  */
8768 xmlChar *
8769 xmlParseEncName(xmlParserCtxtPtr ctxt) {
8770     xmlChar *buf = NULL;
8771     int len = 0;
8772     int size = 10;
8773     xmlChar cur;
8774
8775     cur = CUR;
8776     if (((cur >= 'a') && (cur <= 'z')) ||
8777         ((cur >= 'A') && (cur <= 'Z'))) {
8778         buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
8779         if (buf == NULL) {
8780             xmlErrMemory(ctxt, NULL);
8781             return(NULL);
8782         }
8783         
8784         buf[len++] = cur;
8785         NEXT;
8786         cur = CUR;
8787         while (((cur >= 'a') && (cur <= 'z')) ||
8788                ((cur >= 'A') && (cur <= 'Z')) ||
8789                ((cur >= '0') && (cur <= '9')) ||
8790                (cur == '.') || (cur == '_') ||
8791                (cur == '-')) {
8792             if (len + 1 >= size) {
8793                 xmlChar *tmp;
8794
8795                 size *= 2;
8796                 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
8797                 if (tmp == NULL) {
8798                     xmlErrMemory(ctxt, NULL);
8799                     xmlFree(buf);
8800                     return(NULL);
8801                 }
8802                 buf = tmp;
8803             }
8804             buf[len++] = cur;
8805             NEXT;
8806             cur = CUR;
8807             if (cur == 0) {
8808                 SHRINK;
8809                 GROW;
8810                 cur = CUR;
8811             }
8812         }
8813         buf[len] = 0;
8814     } else {
8815         xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
8816     }
8817     return(buf);
8818 }
8819
8820 /**
8821  * xmlParseEncodingDecl:
8822  * @ctxt:  an XML parser context
8823  * 
8824  * parse the XML encoding declaration
8825  *
8826  * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
8827  *
8828  * this setups the conversion filters.
8829  *
8830  * Returns the encoding value or NULL
8831  */
8832
8833 const xmlChar *
8834 xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
8835     xmlChar *encoding = NULL;
8836
8837     SKIP_BLANKS;
8838     if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
8839         SKIP(8);
8840         SKIP_BLANKS;
8841         if (RAW != '=') {
8842             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
8843             return(NULL);
8844         }
8845         NEXT;
8846         SKIP_BLANKS;
8847         if (RAW == '"') {
8848             NEXT;
8849             encoding = xmlParseEncName(ctxt);
8850             if (RAW != '"') {
8851                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
8852             } else
8853                 NEXT;
8854         } else if (RAW == '\''){
8855             NEXT;
8856             encoding = xmlParseEncName(ctxt);
8857             if (RAW != '\'') {
8858                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
8859             } else
8860                 NEXT;
8861         } else {
8862             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
8863         }
8864         /*
8865          * UTF-16 encoding stwich has already taken place at this stage,
8866          * more over the little-endian/big-endian selection is already done
8867          */
8868         if ((encoding != NULL) &&
8869             ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
8870              (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
8871             if (ctxt->encoding != NULL)
8872                 xmlFree((xmlChar *) ctxt->encoding);
8873             ctxt->encoding = encoding;
8874         }
8875         /*
8876          * UTF-8 encoding is handled natively
8877          */
8878         else if ((encoding != NULL) &&
8879             ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
8880              (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
8881             if (ctxt->encoding != NULL)
8882                 xmlFree((xmlChar *) ctxt->encoding);
8883             ctxt->encoding = encoding;
8884         }
8885         else if (encoding != NULL) {
8886             xmlCharEncodingHandlerPtr handler;
8887
8888             if (ctxt->input->encoding != NULL)
8889                 xmlFree((xmlChar *) ctxt->input->encoding);
8890             ctxt->input->encoding = encoding;
8891
8892             handler = xmlFindCharEncodingHandler((const char *) encoding);
8893             if (handler != NULL) {
8894                 xmlSwitchToEncoding(ctxt, handler);
8895             } else {
8896                 xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
8897                         "Unsupported encoding %s\n", encoding);
8898                 return(NULL);
8899             }
8900         }
8901     }
8902     return(encoding);
8903 }
8904
8905 /**
8906  * xmlParseSDDecl:
8907  * @ctxt:  an XML parser context
8908  *
8909  * parse the XML standalone declaration
8910  *
8911  * [32] SDDecl ::= S 'standalone' Eq
8912  *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"')) 
8913  *
8914  * [ VC: Standalone Document Declaration ]
8915  * TODO The standalone document declaration must have the value "no"
8916  * if any external markup declarations contain declarations of:
8917  *  - attributes with default values, if elements to which these
8918  *    attributes apply appear in the document without specifications
8919  *    of values for these attributes, or
8920  *  - entities (other than amp, lt, gt, apos, quot), if references
8921  *    to those entities appear in the document, or
8922  *  - attributes with values subject to normalization, where the
8923  *    attribute appears in the document with a value which will change
8924  *    as a result of normalization, or
8925  *  - element types with element content, if white space occurs directly
8926  *    within any instance of those types.
8927  *
8928  * Returns 1 if standalone, 0 otherwise
8929  */
8930
8931 int
8932 xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
8933     int standalone = -1;
8934
8935     SKIP_BLANKS;
8936     if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
8937         SKIP(10);
8938         SKIP_BLANKS;
8939         if (RAW != '=') {
8940             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
8941             return(standalone);
8942         }
8943         NEXT;
8944         SKIP_BLANKS;
8945         if (RAW == '\''){
8946             NEXT;
8947             if ((RAW == 'n') && (NXT(1) == 'o')) {
8948                 standalone = 0;
8949                 SKIP(2);
8950             } else if ((RAW == 'y') && (NXT(1) == 'e') &&
8951                        (NXT(2) == 's')) {
8952                 standalone = 1;
8953                 SKIP(3);
8954             } else {
8955                 xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
8956             }
8957             if (RAW != '\'') {
8958                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
8959             } else
8960                 NEXT;
8961         } else if (RAW == '"'){
8962             NEXT;
8963             if ((RAW == 'n') && (NXT(1) == 'o')) {
8964                 standalone = 0;
8965                 SKIP(2);
8966             } else if ((RAW == 'y') && (NXT(1) == 'e') &&
8967                        (NXT(2) == 's')) {
8968                 standalone = 1;
8969                 SKIP(3);
8970             } else {
8971                 xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
8972             }
8973             if (RAW != '"') {
8974                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
8975             } else
8976                 NEXT;
8977         } else {
8978             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
8979         }
8980     }
8981     return(standalone);
8982 }
8983
8984 /**
8985  * xmlParseXMLDecl:
8986  * @ctxt:  an XML parser context
8987  * 
8988  * parse an XML declaration header
8989  *
8990  * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
8991  */
8992
8993 void
8994 xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
8995     xmlChar *version;
8996
8997     /*
8998      * This value for standalone indicates that the document has an
8999      * XML declaration but it does not have a standalone attribute.
9000      * It will be overwritten later if a standalone attribute is found.
9001      */
9002     ctxt->input->standalone = -2;
9003
9004     /*
9005      * We know that '<?xml' is here.
9006      */
9007     SKIP(5);
9008
9009     if (!IS_BLANK_CH(RAW)) {
9010         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9011                        "Blank needed after '<?xml'\n");
9012     }
9013     SKIP_BLANKS;
9014
9015     /*
9016      * We must have the VersionInfo here.
9017      */
9018     version = xmlParseVersionInfo(ctxt);
9019     if (version == NULL) {
9020         xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
9021     } else {
9022         if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
9023             /*
9024              * TODO: Blueberry should be detected here
9025              */
9026             xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
9027                           "Unsupported version '%s'\n",
9028                           version, NULL);
9029         }
9030         if (ctxt->version != NULL)
9031             xmlFree((void *) ctxt->version);
9032         ctxt->version = version;
9033     }
9034
9035     /*
9036      * We may have the encoding declaration
9037      */
9038     if (!IS_BLANK_CH(RAW)) {
9039         if ((RAW == '?') && (NXT(1) == '>')) {
9040             SKIP(2);
9041             return;
9042         }
9043         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
9044     }
9045     xmlParseEncodingDecl(ctxt);
9046     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
9047         /*
9048          * The XML REC instructs us to stop parsing right here
9049          */
9050         return;
9051     }
9052
9053     /*
9054      * We may have the standalone status.
9055      */
9056     if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
9057         if ((RAW == '?') && (NXT(1) == '>')) {
9058             SKIP(2);
9059             return;
9060         }
9061         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
9062     }
9063     SKIP_BLANKS;
9064     ctxt->input->standalone = xmlParseSDDecl(ctxt);
9065
9066     SKIP_BLANKS;
9067     if ((RAW == '?') && (NXT(1) == '>')) {
9068         SKIP(2);
9069     } else if (RAW == '>') {
9070         /* Deprecated old WD ... */
9071         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
9072         NEXT;
9073     } else {
9074         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
9075         MOVETO_ENDTAG(CUR_PTR);
9076         NEXT;
9077     }
9078 }
9079
9080 /**
9081  * xmlParseMisc:
9082  * @ctxt:  an XML parser context
9083  * 
9084  * parse an XML Misc* optional field.
9085  *
9086  * [27] Misc ::= Comment | PI |  S
9087  */
9088
9089 void
9090 xmlParseMisc(xmlParserCtxtPtr ctxt) {
9091     while (((RAW == '<') && (NXT(1) == '?')) ||
9092            (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
9093            IS_BLANK_CH(CUR)) {
9094         if ((RAW == '<') && (NXT(1) == '?')) {
9095             xmlParsePI(ctxt);
9096         } else if (IS_BLANK_CH(CUR)) {
9097             NEXT;
9098         } else
9099             xmlParseComment(ctxt);
9100     }
9101 }
9102
9103 /**
9104  * xmlParseDocument:
9105  * @ctxt:  an XML parser context
9106  * 
9107  * parse an XML document (and build a tree if using the standard SAX
9108  * interface).
9109  *
9110  * [1] document ::= prolog element Misc*
9111  *
9112  * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
9113  *
9114  * Returns 0, -1 in case of error. the parser context is augmented
9115  *                as a result of the parsing.
9116  */
9117
9118 int
9119 xmlParseDocument(xmlParserCtxtPtr ctxt) {
9120     xmlChar start[4];
9121     xmlCharEncoding enc;
9122
9123     xmlInitParser();
9124
9125     if ((ctxt == NULL) || (ctxt->input == NULL))
9126         return(-1);
9127
9128     GROW;
9129
9130     /*
9131      * SAX: detecting the level.
9132      */
9133     xmlDetectSAX2(ctxt);
9134
9135     /*
9136      * SAX: beginning of the document processing.
9137      */
9138     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
9139         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
9140
9141     if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
9142         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
9143         /* 
9144          * Get the 4 first bytes and decode the charset
9145          * if enc != XML_CHAR_ENCODING_NONE
9146          * plug some encoding conversion routines.
9147          */
9148         start[0] = RAW;
9149         start[1] = NXT(1);
9150         start[2] = NXT(2);
9151         start[3] = NXT(3);
9152         enc = xmlDetectCharEncoding(&start[0], 4);
9153         if (enc != XML_CHAR_ENCODING_NONE) {
9154             xmlSwitchEncoding(ctxt, enc);
9155         }
9156     }
9157
9158
9159     if (CUR == 0) {
9160         xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
9161     }
9162
9163     /*
9164      * Check for the XMLDecl in the Prolog.
9165      */
9166     GROW;
9167     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
9168
9169         /*
9170          * Note that we will switch encoding on the fly.
9171          */
9172         xmlParseXMLDecl(ctxt);
9173         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
9174             /*
9175              * The XML REC instructs us to stop parsing right here
9176              */
9177             return(-1);
9178         }
9179         ctxt->standalone = ctxt->input->standalone;
9180         SKIP_BLANKS;
9181     } else {
9182         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
9183     }
9184     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
9185         ctxt->sax->startDocument(ctxt->userData);
9186
9187     /*
9188      * The Misc part of the Prolog
9189      */
9190     GROW;
9191     xmlParseMisc(ctxt);
9192
9193     /*
9194      * Then possibly doc type declaration(s) and more Misc
9195      * (doctypedecl Misc*)?
9196      */
9197     GROW;
9198     if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
9199
9200         ctxt->inSubset = 1;
9201         xmlParseDocTypeDecl(ctxt);
9202         if (RAW == '[') {
9203             ctxt->instate = XML_PARSER_DTD;
9204             xmlParseInternalSubset(ctxt);
9205         }
9206
9207         /*
9208          * Create and update the external subset.
9209          */
9210         ctxt->inSubset = 2;
9211         if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
9212             (!ctxt->disableSAX))
9213             ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
9214                                       ctxt->extSubSystem, ctxt->extSubURI);
9215         ctxt->inSubset = 0;
9216
9217
9218         ctxt->instate = XML_PARSER_PROLOG;
9219         xmlParseMisc(ctxt);
9220     }
9221
9222     /*
9223      * Time to start parsing the tree itself
9224      */
9225     GROW;
9226     if (RAW != '<') {
9227         xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
9228                        "Start tag expected, '<' not found\n");
9229     } else {
9230         ctxt->instate = XML_PARSER_CONTENT;
9231         xmlParseElement(ctxt);
9232         ctxt->instate = XML_PARSER_EPILOG;
9233
9234
9235         /*
9236          * The Misc part at the end
9237          */
9238         xmlParseMisc(ctxt);
9239
9240         if (RAW != 0) {
9241             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
9242         }
9243         ctxt->instate = XML_PARSER_EOF;
9244     }
9245
9246     /*
9247      * SAX: end of the document processing.
9248      */
9249     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
9250         ctxt->sax->endDocument(ctxt->userData);
9251
9252     /*
9253      * Remove locally kept entity definitions if the tree was not built
9254      */
9255     if ((ctxt->myDoc != NULL) &&
9256         (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
9257         xmlFreeDoc(ctxt->myDoc);
9258         ctxt->myDoc = NULL;
9259     }
9260
9261     if (! ctxt->wellFormed) {
9262         ctxt->valid = 0;
9263         return(-1);
9264     }
9265     return(0);
9266 }
9267
9268 /**
9269  * xmlParseExtParsedEnt:
9270  * @ctxt:  an XML parser context
9271  * 
9272  * parse a general parsed entity
9273  * An external general parsed entity is well-formed if it matches the
9274  * production labeled extParsedEnt.
9275  *
9276  * [78] extParsedEnt ::= TextDecl? content
9277  *
9278  * Returns 0, -1 in case of error. the parser context is augmented
9279  *                as a result of the parsing.
9280  */
9281
9282 int
9283 xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
9284     xmlChar start[4];
9285     xmlCharEncoding enc;
9286
9287     if ((ctxt == NULL) || (ctxt->input == NULL))
9288         return(-1);
9289
9290     xmlDefaultSAXHandlerInit();
9291
9292     xmlDetectSAX2(ctxt);
9293
9294     GROW;
9295
9296     /*
9297      * SAX: beginning of the document processing.
9298      */
9299     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
9300         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
9301
9302     /* 
9303      * Get the 4 first bytes and decode the charset
9304      * if enc != XML_CHAR_ENCODING_NONE
9305      * plug some encoding conversion routines.
9306      */
9307     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
9308         start[0] = RAW;
9309         start[1] = NXT(1);
9310         start[2] = NXT(2);
9311         start[3] = NXT(3);
9312         enc = xmlDetectCharEncoding(start, 4);
9313         if (enc != XML_CHAR_ENCODING_NONE) {
9314             xmlSwitchEncoding(ctxt, enc);
9315         }
9316     }
9317
9318
9319     if (CUR == 0) {
9320         xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
9321     }
9322
9323     /*
9324      * Check for the XMLDecl in the Prolog.
9325      */
9326     GROW;
9327     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
9328
9329         /*
9330          * Note that we will switch encoding on the fly.
9331          */
9332         xmlParseXMLDecl(ctxt);
9333         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
9334             /*
9335              * The XML REC instructs us to stop parsing right here
9336              */
9337             return(-1);
9338         }
9339         SKIP_BLANKS;
9340     } else {
9341         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
9342     }
9343     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
9344         ctxt->sax->startDocument(ctxt->userData);
9345
9346     /*
9347      * Doing validity checking on chunk doesn't make sense
9348      */
9349     ctxt->instate = XML_PARSER_CONTENT;
9350     ctxt->validate = 0;
9351     ctxt->loadsubset = 0;
9352     ctxt->depth = 0;
9353
9354     xmlParseContent(ctxt);
9355    
9356     if ((RAW == '<') && (NXT(1) == '/')) {
9357         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
9358     } else if (RAW != 0) {
9359         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
9360     }
9361
9362     /*
9363      * SAX: end of the document processing.
9364      */
9365     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
9366         ctxt->sax->endDocument(ctxt->userData);
9367
9368     if (! ctxt->wellFormed) return(-1);
9369     return(0);
9370 }
9371
9372 #ifdef LIBXML_PUSH_ENABLED
9373 /************************************************************************
9374  *                                                                      *
9375  *              Progressive parsing interfaces                          *
9376  *                                                                      *
9377  ************************************************************************/
9378
9379 /**
9380  * xmlParseLookupSequence:
9381  * @ctxt:  an XML parser context
9382  * @first:  the first char to lookup
9383  * @next:  the next char to lookup or zero
9384  * @third:  the next char to lookup or zero
9385  *
9386  * Try to find if a sequence (first, next, third) or  just (first next) or
9387  * (first) is available in the input stream.
9388  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
9389  * to avoid rescanning sequences of bytes, it DOES change the state of the
9390  * parser, do not use liberally.
9391  *
9392  * Returns the index to the current parsing point if the full sequence
9393  *      is available, -1 otherwise.
9394  */
9395 static int
9396 xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
9397                        xmlChar next, xmlChar third) {
9398     int base, len;
9399     xmlParserInputPtr in;
9400     const xmlChar *buf;
9401
9402     in = ctxt->input;
9403     if (in == NULL) return(-1);
9404     base = in->cur - in->base;
9405     if (base < 0) return(-1);
9406     if (ctxt->checkIndex > base)
9407         base = ctxt->checkIndex;
9408     if (in->buf == NULL) {
9409         buf = in->base;
9410         len = in->length;
9411     } else {
9412         buf = in->buf->buffer->content;
9413         len = in->buf->buffer->use;
9414     }
9415     /* take into account the sequence length */
9416     if (third) len -= 2;
9417     else if (next) len --;
9418     for (;base < len;base++) {
9419         if (buf[base] == first) {
9420             if (third != 0) {
9421                 if ((buf[base + 1] != next) ||
9422                     (buf[base + 2] != third)) continue;
9423             } else if (next != 0) {
9424                 if (buf[base + 1] != next) continue;
9425             }
9426             ctxt->checkIndex = 0;
9427 #ifdef DEBUG_PUSH
9428             if (next == 0)
9429                 xmlGenericError(xmlGenericErrorContext,
9430                         "PP: lookup '%c' found at %d\n",
9431                         first, base);
9432             else if (third == 0)
9433                 xmlGenericError(xmlGenericErrorContext,
9434                         "PP: lookup '%c%c' found at %d\n",
9435                         first, next, base);
9436             else 
9437                 xmlGenericError(xmlGenericErrorContext,
9438                         "PP: lookup '%c%c%c' found at %d\n",
9439                         first, next, third, base);
9440 #endif
9441             return(base - (in->cur - in->base));
9442         }
9443     }
9444     ctxt->checkIndex = base;
9445 #ifdef DEBUG_PUSH
9446     if (next == 0)
9447         xmlGenericError(xmlGenericErrorContext,
9448                 "PP: lookup '%c' failed\n", first);
9449     else if (third == 0)
9450         xmlGenericError(xmlGenericErrorContext,
9451                 "PP: lookup '%c%c' failed\n", first, next);
9452     else        
9453         xmlGenericError(xmlGenericErrorContext,
9454                 "PP: lookup '%c%c%c' failed\n", first, next, third);
9455 #endif
9456     return(-1);
9457 }
9458
9459 /**
9460  * xmlParseGetLasts:
9461  * @ctxt:  an XML parser context
9462  * @lastlt:  pointer to store the last '<' from the input
9463  * @lastgt:  pointer to store the last '>' from the input
9464  *
9465  * Lookup the last < and > in the current chunk
9466  */
9467 static void
9468 xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
9469                  const xmlChar **lastgt) {
9470     const xmlChar *tmp;
9471
9472     if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
9473         xmlGenericError(xmlGenericErrorContext,
9474                     "Internal error: xmlParseGetLasts\n");
9475         return;
9476     }
9477     if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
9478         tmp = ctxt->input->end;
9479         tmp--;
9480         while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
9481         if (tmp < ctxt->input->base) {
9482             *lastlt = NULL;
9483             *lastgt = NULL;
9484         } else {
9485             *lastlt = tmp;
9486             tmp++;
9487             while ((tmp < ctxt->input->end) && (*tmp != '>')) {
9488                 if (*tmp == '\'') {
9489                     tmp++;
9490                     while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
9491                     if (tmp < ctxt->input->end) tmp++;
9492                 } else if (*tmp == '"') {
9493                     tmp++;
9494                     while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
9495                     if (tmp < ctxt->input->end) tmp++;
9496                 } else
9497                     tmp++;
9498             }
9499             if (tmp < ctxt->input->end)
9500                 *lastgt = tmp;
9501             else {
9502                 tmp = *lastlt;
9503                 tmp--;
9504                 while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
9505                 if (tmp >= ctxt->input->base)
9506                     *lastgt = tmp;
9507                 else
9508                     *lastgt = NULL;
9509             }
9510         }
9511     } else {
9512         *lastlt = NULL;
9513         *lastgt = NULL;
9514     }
9515 }
9516 /**
9517  * xmlCheckCdataPush:
9518  * @cur: pointer to the bock of characters
9519  * @len: length of the block in bytes
9520  *
9521  * Check that the block of characters is okay as SCdata content [20]
9522  *
9523  * Returns the number of bytes to pass if okay, a negative index where an
9524  *         UTF-8 error occured otherwise
9525  */
9526 static int
9527 xmlCheckCdataPush(const xmlChar *utf, int len) {
9528     int ix;
9529     unsigned char c;
9530     int codepoint;
9531
9532     if ((utf == NULL) || (len <= 0))
9533         return(0);
9534     
9535     for (ix = 0; ix < len;) {      /* string is 0-terminated */
9536         c = utf[ix];
9537         if ((c & 0x80) == 0x00) {       /* 1-byte code, starts with 10 */
9538             if (c >= 0x20)
9539                 ix++;
9540             else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
9541                 ix++;
9542             else
9543                 return(-ix);
9544         } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
9545             if (ix + 2 > len) return(ix);
9546             if ((utf[ix+1] & 0xc0 ) != 0x80)
9547                 return(-ix);
9548             codepoint = (utf[ix] & 0x1f) << 6;
9549             codepoint |= utf[ix+1] & 0x3f;
9550             if (!xmlIsCharQ(codepoint))
9551                 return(-ix);
9552             ix += 2;
9553         } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
9554             if (ix + 3 > len) return(ix);
9555             if (((utf[ix+1] & 0xc0) != 0x80) ||
9556                 ((utf[ix+2] & 0xc0) != 0x80))
9557                     return(-ix);
9558             codepoint = (utf[ix] & 0xf) << 12;
9559             codepoint |= (utf[ix+1] & 0x3f) << 6;
9560             codepoint |= utf[ix+2] & 0x3f;
9561             if (!xmlIsCharQ(codepoint))
9562                 return(-ix);
9563             ix += 3;
9564         } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
9565             if (ix + 4 > len) return(ix);
9566             if (((utf[ix+1] & 0xc0) != 0x80) ||
9567                 ((utf[ix+2] & 0xc0) != 0x80) ||
9568                 ((utf[ix+3] & 0xc0) != 0x80))
9569                     return(-ix);
9570             codepoint = (utf[ix] & 0x7) << 18;
9571             codepoint |= (utf[ix+1] & 0x3f) << 12;
9572             codepoint |= (utf[ix+2] & 0x3f) << 6;
9573             codepoint |= utf[ix+3] & 0x3f;
9574             if (!xmlIsCharQ(codepoint))
9575                 return(-ix);
9576             ix += 4;
9577         } else                          /* unknown encoding */
9578             return(-ix);
9579       }
9580       return(ix);
9581 }
9582
9583 /**
9584  * xmlParseTryOrFinish:
9585  * @ctxt:  an XML parser context
9586  * @terminate:  last chunk indicator
9587  *
9588  * Try to progress on parsing
9589  *
9590  * Returns zero if no parsing was possible
9591  */
9592 static int
9593 xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
9594     int ret = 0;
9595     int avail, tlen;
9596     xmlChar cur, next;
9597     const xmlChar *lastlt, *lastgt;
9598
9599     if (ctxt->input == NULL)
9600         return(0);
9601
9602 #ifdef DEBUG_PUSH
9603     switch (ctxt->instate) {
9604         case XML_PARSER_EOF:
9605             xmlGenericError(xmlGenericErrorContext,
9606                     "PP: try EOF\n"); break;
9607         case XML_PARSER_START:
9608             xmlGenericError(xmlGenericErrorContext,
9609                     "PP: try START\n"); break;
9610         case XML_PARSER_MISC:
9611             xmlGenericError(xmlGenericErrorContext,
9612                     "PP: try MISC\n");break;
9613         case XML_PARSER_COMMENT:
9614             xmlGenericError(xmlGenericErrorContext,
9615                     "PP: try COMMENT\n");break;
9616         case XML_PARSER_PROLOG:
9617             xmlGenericError(xmlGenericErrorContext,
9618                     "PP: try PROLOG\n");break;
9619         case XML_PARSER_START_TAG:
9620             xmlGenericError(xmlGenericErrorContext,
9621                     "PP: try START_TAG\n");break;
9622         case XML_PARSER_CONTENT:
9623             xmlGenericError(xmlGenericErrorContext,
9624                     "PP: try CONTENT\n");break;
9625         case XML_PARSER_CDATA_SECTION:
9626             xmlGenericError(xmlGenericErrorContext,
9627                     "PP: try CDATA_SECTION\n");break;
9628         case XML_PARSER_END_TAG:
9629             xmlGenericError(xmlGenericErrorContext,
9630                     "PP: try END_TAG\n");break;
9631         case XML_PARSER_ENTITY_DECL:
9632             xmlGenericError(xmlGenericErrorContext,
9633                     "PP: try ENTITY_DECL\n");break;
9634         case XML_PARSER_ENTITY_VALUE:
9635             xmlGenericError(xmlGenericErrorContext,
9636                     "PP: try ENTITY_VALUE\n");break;
9637         case XML_PARSER_ATTRIBUTE_VALUE:
9638             xmlGenericError(xmlGenericErrorContext,
9639                     "PP: try ATTRIBUTE_VALUE\n");break;
9640         case XML_PARSER_DTD:
9641             xmlGenericError(xmlGenericErrorContext,
9642                     "PP: try DTD\n");break;
9643         case XML_PARSER_EPILOG:
9644             xmlGenericError(xmlGenericErrorContext,
9645                     "PP: try EPILOG\n");break;
9646         case XML_PARSER_PI:
9647             xmlGenericError(xmlGenericErrorContext,
9648                     "PP: try PI\n");break;
9649         case XML_PARSER_IGNORE:
9650             xmlGenericError(xmlGenericErrorContext,
9651                     "PP: try IGNORE\n");break;
9652     }
9653 #endif
9654
9655     if ((ctxt->input != NULL) &&
9656         (ctxt->input->cur - ctxt->input->base > 4096)) {
9657         xmlSHRINK(ctxt);
9658         ctxt->checkIndex = 0;
9659     }
9660     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
9661
9662     while (1) {
9663         if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
9664             return(0);
9665
9666         
9667         /*
9668          * Pop-up of finished entities.
9669          */
9670         while ((RAW == 0) && (ctxt->inputNr > 1))
9671             xmlPopInput(ctxt);
9672
9673         if (ctxt->input == NULL) break;
9674         if (ctxt->input->buf == NULL)
9675             avail = ctxt->input->length -
9676                     (ctxt->input->cur - ctxt->input->base);
9677         else {
9678             /*
9679              * If we are operating on converted input, try to flush
9680              * remainng chars to avoid them stalling in the non-converted
9681              * buffer.
9682              */
9683             if ((ctxt->input->buf->raw != NULL) &&
9684                 (ctxt->input->buf->raw->use > 0)) {
9685                 int base = ctxt->input->base -
9686                            ctxt->input->buf->buffer->content;
9687                 int current = ctxt->input->cur - ctxt->input->base;
9688
9689                 xmlParserInputBufferPush(ctxt->input->buf, 0, "");
9690                 ctxt->input->base = ctxt->input->buf->buffer->content + base;
9691                 ctxt->input->cur = ctxt->input->base + current;
9692                 ctxt->input->end =
9693                     &ctxt->input->buf->buffer->content[
9694                                        ctxt->input->buf->buffer->use];
9695             }
9696             avail = ctxt->input->buf->buffer->use -
9697                     (ctxt->input->cur - ctxt->input->base);
9698         }
9699         if (avail < 1)
9700             goto done;
9701         switch (ctxt->instate) {
9702             case XML_PARSER_EOF:
9703                 /*
9704                  * Document parsing is done !
9705                  */
9706                 goto done;
9707             case XML_PARSER_START:
9708                 if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
9709                     xmlChar start[4];
9710                     xmlCharEncoding enc;
9711
9712                     /*
9713                      * Very first chars read from the document flow.
9714                      */
9715                     if (avail < 4)
9716                         goto done;
9717
9718                     /* 
9719                      * Get the 4 first bytes and decode the charset
9720                      * if enc != XML_CHAR_ENCODING_NONE
9721                      * plug some encoding conversion routines,
9722                      * else xmlSwitchEncoding will set to (default)
9723                      * UTF8.
9724                      */
9725                     start[0] = RAW;
9726                     start[1] = NXT(1);
9727                     start[2] = NXT(2);
9728                     start[3] = NXT(3);
9729                     enc = xmlDetectCharEncoding(start, 4);
9730                     xmlSwitchEncoding(ctxt, enc);
9731                     break;
9732                 }
9733
9734                 if (avail < 2)
9735                     goto done;
9736                 cur = ctxt->input->cur[0];
9737                 next = ctxt->input->cur[1];
9738                 if (cur == 0) {
9739                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
9740                         ctxt->sax->setDocumentLocator(ctxt->userData,
9741                                                       &xmlDefaultSAXLocator);
9742                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
9743                     ctxt->instate = XML_PARSER_EOF;
9744 #ifdef DEBUG_PUSH
9745                     xmlGenericError(xmlGenericErrorContext,
9746                             "PP: entering EOF\n");
9747 #endif
9748                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
9749                         ctxt->sax->endDocument(ctxt->userData);
9750                     goto done;
9751                 }
9752                 if ((cur == '<') && (next == '?')) {
9753                     /* PI or XML decl */
9754                     if (avail < 5) return(ret);
9755                     if ((!terminate) &&
9756                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
9757                         return(ret);
9758                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
9759                         ctxt->sax->setDocumentLocator(ctxt->userData,
9760                                                       &xmlDefaultSAXLocator);
9761                     if ((ctxt->input->cur[2] == 'x') &&
9762                         (ctxt->input->cur[3] == 'm') &&
9763                         (ctxt->input->cur[4] == 'l') &&
9764                         (IS_BLANK_CH(ctxt->input->cur[5]))) {
9765                         ret += 5;
9766 #ifdef DEBUG_PUSH
9767                         xmlGenericError(xmlGenericErrorContext,
9768                                 "PP: Parsing XML Decl\n");
9769 #endif
9770                         xmlParseXMLDecl(ctxt);
9771                         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
9772                             /*
9773                              * The XML REC instructs us to stop parsing right
9774                              * here
9775                              */
9776                             ctxt->instate = XML_PARSER_EOF;
9777                             return(0);
9778                         }
9779                         ctxt->standalone = ctxt->input->standalone;
9780                         if ((ctxt->encoding == NULL) &&
9781                             (ctxt->input->encoding != NULL))
9782                             ctxt->encoding = xmlStrdup(ctxt->input->encoding);
9783                         if ((ctxt->sax) && (ctxt->sax->startDocument) &&
9784                             (!ctxt->disableSAX))
9785                             ctxt->sax->startDocument(ctxt->userData);
9786                         ctxt->instate = XML_PARSER_MISC;
9787 #ifdef DEBUG_PUSH
9788                         xmlGenericError(xmlGenericErrorContext,
9789                                 "PP: entering MISC\n");
9790 #endif
9791                     } else {
9792                         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
9793                         if ((ctxt->sax) && (ctxt->sax->startDocument) &&
9794                             (!ctxt->disableSAX))
9795                             ctxt->sax->startDocument(ctxt->userData);
9796                         ctxt->instate = XML_PARSER_MISC;
9797 #ifdef DEBUG_PUSH
9798                         xmlGenericError(xmlGenericErrorContext,
9799                                 "PP: entering MISC\n");
9800 #endif
9801                     }
9802                 } else {
9803                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
9804                         ctxt->sax->setDocumentLocator(ctxt->userData,
9805                                                       &xmlDefaultSAXLocator);
9806                     ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
9807                     if (ctxt->version == NULL) {
9808                         xmlErrMemory(ctxt, NULL);
9809                         break;
9810                     }
9811                     if ((ctxt->sax) && (ctxt->sax->startDocument) &&
9812                         (!ctxt->disableSAX))
9813                         ctxt->sax->startDocument(ctxt->userData);
9814                     ctxt->instate = XML_PARSER_MISC;
9815 #ifdef DEBUG_PUSH
9816                     xmlGenericError(xmlGenericErrorContext,
9817                             "PP: entering MISC\n");
9818 #endif
9819                 }
9820                 break;
9821             case XML_PARSER_START_TAG: {
9822                 const xmlChar *name;
9823                 const xmlChar *prefix;
9824                 const xmlChar *URI;
9825                 int nsNr = ctxt->nsNr;
9826
9827                 if ((avail < 2) && (ctxt->inputNr == 1))
9828                     goto done;
9829                 cur = ctxt->input->cur[0];
9830                 if (cur != '<') {
9831                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
9832                     ctxt->instate = XML_PARSER_EOF;
9833                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
9834                         ctxt->sax->endDocument(ctxt->userData);
9835                     goto done;
9836                 }
9837                 if (!terminate) {
9838                     if (ctxt->progressive) {
9839                         /* > can be found unescaped in attribute values */
9840                         if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
9841                             goto done;
9842                     } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
9843                         goto done;
9844                     }
9845                 }
9846                 if (ctxt->spaceNr == 0)
9847                     spacePush(ctxt, -1);
9848                 else if (*ctxt->space == -2)
9849                     spacePush(ctxt, -1);
9850                 else
9851                     spacePush(ctxt, *ctxt->space);
9852 #ifdef LIBXML_SAX1_ENABLED
9853                 if (ctxt->sax2)
9854 #endif /* LIBXML_SAX1_ENABLED */
9855                     name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
9856 #ifdef LIBXML_SAX1_ENABLED
9857                 else
9858                     name = xmlParseStartTag(ctxt);
9859 #endif /* LIBXML_SAX1_ENABLED */
9860                 if (name == NULL) {
9861                     spacePop(ctxt);
9862                     ctxt->instate = XML_PARSER_EOF;
9863                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
9864                         ctxt->sax->endDocument(ctxt->userData);
9865                     goto done;
9866                 }
9867 #ifdef LIBXML_VALID_ENABLED
9868                 /*
9869                  * [ VC: Root Element Type ]
9870                  * The Name in the document type declaration must match
9871                  * the element type of the root element. 
9872                  */
9873                 if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
9874                     ctxt->node && (ctxt->node == ctxt->myDoc->children))
9875                     ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
9876 #endif /* LIBXML_VALID_ENABLED */
9877
9878                 /*
9879                  * Check for an Empty Element.
9880                  */
9881                 if ((RAW == '/') && (NXT(1) == '>')) {
9882                     SKIP(2);
9883
9884                     if (ctxt->sax2) {
9885                         if ((ctxt->sax != NULL) &&
9886                             (ctxt->sax->endElementNs != NULL) &&
9887                             (!ctxt->disableSAX))
9888                             ctxt->sax->endElementNs(ctxt->userData, name,
9889                                                     prefix, URI);
9890                         if (ctxt->nsNr - nsNr > 0)
9891                             nsPop(ctxt, ctxt->nsNr - nsNr);
9892 #ifdef LIBXML_SAX1_ENABLED
9893                     } else {
9894                         if ((ctxt->sax != NULL) &&
9895                             (ctxt->sax->endElement != NULL) &&
9896                             (!ctxt->disableSAX))
9897                             ctxt->sax->endElement(ctxt->userData, name);
9898 #endif /* LIBXML_SAX1_ENABLED */
9899                     }
9900                     spacePop(ctxt);
9901                     if (ctxt->nameNr == 0) {
9902                         ctxt->instate = XML_PARSER_EPILOG;
9903                     } else {
9904                         ctxt->instate = XML_PARSER_CONTENT;
9905                     }
9906                     break;
9907                 }
9908                 if (RAW == '>') {
9909                     NEXT;
9910                 } else {
9911                     xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
9912                                          "Couldn't find end of Start Tag %s\n",
9913                                          name);
9914                     nodePop(ctxt);
9915                     spacePop(ctxt);
9916                 }
9917                 if (ctxt->sax2)
9918                     nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
9919 #ifdef LIBXML_SAX1_ENABLED
9920                 else
9921                     namePush(ctxt, name);
9922 #endif /* LIBXML_SAX1_ENABLED */
9923
9924                 ctxt->instate = XML_PARSER_CONTENT;
9925                 break;
9926             }
9927             case XML_PARSER_CONTENT: {
9928                 const xmlChar *test;
9929                 unsigned int cons;
9930                 if ((avail < 2) && (ctxt->inputNr == 1))
9931                     goto done;
9932                 cur = ctxt->input->cur[0];
9933                 next = ctxt->input->cur[1];
9934
9935                 test = CUR_PTR;
9936                 cons = ctxt->input->consumed;
9937                 if ((cur == '<') && (next == '/')) {
9938                     ctxt->instate = XML_PARSER_END_TAG;
9939                     break;
9940                 } else if ((cur == '<') && (next == '?')) {
9941                     if ((!terminate) &&
9942                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
9943                         goto done;
9944                     xmlParsePI(ctxt);
9945                 } else if ((cur == '<') && (next != '!')) {
9946                     ctxt->instate = XML_PARSER_START_TAG;
9947                     break;
9948                 } else if ((cur == '<') && (next == '!') &&
9949                            (ctxt->input->cur[2] == '-') &&
9950                            (ctxt->input->cur[3] == '-')) {
9951                     int term;
9952
9953                     if (avail < 4)
9954                         goto done;
9955                     ctxt->input->cur += 4;
9956                     term = xmlParseLookupSequence(ctxt, '-', '-', '>');
9957                     ctxt->input->cur -= 4;
9958                     if ((!terminate) && (term < 0))
9959                         goto done;
9960                     xmlParseComment(ctxt);
9961                     ctxt->instate = XML_PARSER_CONTENT;
9962                 } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
9963                     (ctxt->input->cur[2] == '[') &&
9964                     (ctxt->input->cur[3] == 'C') &&
9965                     (ctxt->input->cur[4] == 'D') &&
9966                     (ctxt->input->cur[5] == 'A') &&
9967                     (ctxt->input->cur[6] == 'T') &&
9968                     (ctxt->input->cur[7] == 'A') &&
9969                     (ctxt->input->cur[8] == '[')) {
9970                     SKIP(9);
9971                     ctxt->instate = XML_PARSER_CDATA_SECTION;
9972                     break;
9973                 } else if ((cur == '<') && (next == '!') &&
9974                            (avail < 9)) {
9975                     goto done;
9976                 } else if (cur == '&') {
9977                     if ((!terminate) &&
9978                         (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
9979                         goto done;
9980                     xmlParseReference(ctxt);
9981                 } else {
9982                     /* TODO Avoid the extra copy, handle directly !!! */
9983                     /*
9984                      * Goal of the following test is:
9985                      *  - minimize calls to the SAX 'character' callback
9986                      *    when they are mergeable
9987                      *  - handle an problem for isBlank when we only parse
9988                      *    a sequence of blank chars and the next one is
9989                      *    not available to check against '<' presence.
9990                      *  - tries to homogenize the differences in SAX
9991                      *    callbacks between the push and pull versions
9992                      *    of the parser.
9993                      */
9994                     if ((ctxt->inputNr == 1) &&
9995                         (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
9996                         if (!terminate) {
9997                             if (ctxt->progressive) {
9998                                 if ((lastlt == NULL) ||
9999                                     (ctxt->input->cur > lastlt))
10000                                     goto done;
10001                             } else if (xmlParseLookupSequence(ctxt,
10002                                                               '<', 0, 0) < 0) {
10003                                 goto done;
10004                             }
10005                         }
10006                     }
10007                     ctxt->checkIndex = 0;
10008                     xmlParseCharData(ctxt, 0);
10009                 }
10010                 /*
10011                  * Pop-up of finished entities.
10012                  */
10013                 while ((RAW == 0) && (ctxt->inputNr > 1))
10014                     xmlPopInput(ctxt);
10015                 if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
10016                     xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
10017                                 "detected an error in element content\n");
10018                     ctxt->instate = XML_PARSER_EOF;
10019                     break;
10020                 }
10021                 break;
10022             }
10023             case XML_PARSER_END_TAG:
10024                 if (avail < 2)
10025                     goto done;
10026                 if (!terminate) {
10027                     if (ctxt->progressive) {
10028                         /* > can be found unescaped in attribute values */
10029                         if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
10030                             goto done;
10031                     } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
10032                         goto done;
10033                     }
10034                 }
10035                 if (ctxt->sax2) {
10036                     xmlParseEndTag2(ctxt,
10037                            (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
10038                            (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
10039                        (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
10040                     nameNsPop(ctxt);
10041                 }
10042 #ifdef LIBXML_SAX1_ENABLED
10043                   else
10044                     xmlParseEndTag1(ctxt, 0);
10045 #endif /* LIBXML_SAX1_ENABLED */
10046                 if (ctxt->nameNr == 0) {
10047                     ctxt->instate = XML_PARSER_EPILOG;
10048                 } else {
10049                     ctxt->instate = XML_PARSER_CONTENT;
10050                 }
10051                 break;
10052             case XML_PARSER_CDATA_SECTION: {
10053                 /*
10054                  * The Push mode need to have the SAX callback for 
10055                  * cdataBlock merge back contiguous callbacks.
10056                  */
10057                 int base;
10058
10059                 base = xmlParseLookupSequence(ctxt, ']', ']', '>');
10060                 if (base < 0) {
10061                     if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
10062                         int tmp;
10063
10064                         tmp = xmlCheckCdataPush(ctxt->input->cur, 
10065                                                 XML_PARSER_BIG_BUFFER_SIZE);
10066                         if (tmp < 0) {
10067                             tmp = -tmp;
10068                             ctxt->input->cur += tmp;
10069                             goto encoding_error;
10070                         }
10071                         if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
10072                             if (ctxt->sax->cdataBlock != NULL)
10073                                 ctxt->sax->cdataBlock(ctxt->userData,
10074                                                       ctxt->input->cur, tmp);
10075                             else if (ctxt->sax->characters != NULL)
10076                                 ctxt->sax->characters(ctxt->userData,
10077                                                       ctxt->input->cur, tmp);
10078                         }
10079                         SKIPL(tmp);
10080                         ctxt->checkIndex = 0;
10081                     }
10082                     goto done;
10083                 } else {
10084                     int tmp;
10085
10086                     tmp = xmlCheckCdataPush(ctxt->input->cur, base);
10087                     if ((tmp < 0) || (tmp != base)) {
10088                         tmp = -tmp;
10089                         ctxt->input->cur += tmp;
10090                         goto encoding_error;
10091                     }
10092                     if ((ctxt->sax != NULL) && (base > 0) &&
10093                         (!ctxt->disableSAX)) {
10094                         if (ctxt->sax->cdataBlock != NULL)
10095                             ctxt->sax->cdataBlock(ctxt->userData,
10096                                                   ctxt->input->cur, base);
10097                         else if (ctxt->sax->characters != NULL)
10098                             ctxt->sax->characters(ctxt->userData,
10099                                                   ctxt->input->cur, base);
10100                     }
10101                     SKIPL(base + 3);
10102                     ctxt->checkIndex = 0;
10103                     ctxt->instate = XML_PARSER_CONTENT;
10104 #ifdef DEBUG_PUSH
10105                     xmlGenericError(xmlGenericErrorContext,
10106                             "PP: entering CONTENT\n");
10107 #endif
10108                 }
10109                 break;
10110             }
10111             case XML_PARSER_MISC:
10112                 SKIP_BLANKS;
10113                 if (ctxt->input->buf == NULL)
10114                     avail = ctxt->input->length -
10115                             (ctxt->input->cur - ctxt->input->base);
10116                 else
10117                     avail = ctxt->input->buf->buffer->use -
10118                             (ctxt->input->cur - ctxt->input->base);
10119                 if (avail < 2)
10120                     goto done;
10121                 cur = ctxt->input->cur[0];
10122                 next = ctxt->input->cur[1];
10123                 if ((cur == '<') && (next == '?')) {
10124                     if ((!terminate) &&
10125                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
10126                         goto done;
10127 #ifdef DEBUG_PUSH
10128                     xmlGenericError(xmlGenericErrorContext,
10129                             "PP: Parsing PI\n");
10130 #endif
10131                     xmlParsePI(ctxt);
10132                 } else if ((cur == '<') && (next == '!') &&
10133                     (ctxt->input->cur[2] == '-') &&
10134                     (ctxt->input->cur[3] == '-')) {
10135                     if ((!terminate) &&
10136                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
10137                         goto done;
10138 #ifdef DEBUG_PUSH
10139                     xmlGenericError(xmlGenericErrorContext,
10140                             "PP: Parsing Comment\n");
10141 #endif
10142                     xmlParseComment(ctxt);
10143                     ctxt->instate = XML_PARSER_MISC;
10144                 } else if ((cur == '<') && (next == '!') &&
10145                     (ctxt->input->cur[2] == 'D') &&
10146                     (ctxt->input->cur[3] == 'O') &&
10147                     (ctxt->input->cur[4] == 'C') &&
10148                     (ctxt->input->cur[5] == 'T') &&
10149                     (ctxt->input->cur[6] == 'Y') &&
10150                     (ctxt->input->cur[7] == 'P') &&
10151                     (ctxt->input->cur[8] == 'E')) {
10152                     if ((!terminate) &&
10153                         (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
10154                         goto done;
10155 #ifdef DEBUG_PUSH
10156                     xmlGenericError(xmlGenericErrorContext,
10157                             "PP: Parsing internal subset\n");
10158 #endif
10159                     ctxt->inSubset = 1;
10160                     xmlParseDocTypeDecl(ctxt);
10161                     if (RAW == '[') {
10162                         ctxt->instate = XML_PARSER_DTD;
10163 #ifdef DEBUG_PUSH
10164                         xmlGenericError(xmlGenericErrorContext,
10165                                 "PP: entering DTD\n");
10166 #endif
10167                     } else {
10168                         /*
10169                          * Create and update the external subset.
10170                          */
10171                         ctxt->inSubset = 2;
10172                         if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
10173                             (ctxt->sax->externalSubset != NULL))
10174                             ctxt->sax->externalSubset(ctxt->userData,
10175                                     ctxt->intSubName, ctxt->extSubSystem,
10176                                     ctxt->extSubURI);
10177                         ctxt->inSubset = 0;
10178                         ctxt->instate = XML_PARSER_PROLOG;
10179 #ifdef DEBUG_PUSH
10180                         xmlGenericError(xmlGenericErrorContext,
10181                                 "PP: entering PROLOG\n");
10182 #endif
10183                     }
10184                 } else if ((cur == '<') && (next == '!') &&
10185                            (avail < 9)) {
10186                     goto done;
10187                 } else {
10188                     ctxt->instate = XML_PARSER_START_TAG;
10189                     ctxt->progressive = 1;
10190                     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
10191 #ifdef DEBUG_PUSH
10192                     xmlGenericError(xmlGenericErrorContext,
10193                             "PP: entering START_TAG\n");
10194 #endif
10195                 }
10196                 break;
10197             case XML_PARSER_PROLOG:
10198                 SKIP_BLANKS;
10199                 if (ctxt->input->buf == NULL)
10200                     avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
10201                 else
10202                     avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
10203                 if (avail < 2) 
10204                     goto done;
10205                 cur = ctxt->input->cur[0];
10206                 next = ctxt->input->cur[1];
10207                 if ((cur == '<') && (next == '?')) {
10208                     if ((!terminate) &&
10209                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
10210                         goto done;
10211 #ifdef DEBUG_PUSH
10212                     xmlGenericError(xmlGenericErrorContext,
10213                             "PP: Parsing PI\n");
10214 #endif
10215                     xmlParsePI(ctxt);
10216                 } else if ((cur == '<') && (next == '!') &&
10217                     (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
10218                     if ((!terminate) &&
10219                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
10220                         goto done;
10221 #ifdef DEBUG_PUSH
10222                     xmlGenericError(xmlGenericErrorContext,
10223                             "PP: Parsing Comment\n");
10224 #endif
10225                     xmlParseComment(ctxt);
10226                     ctxt->instate = XML_PARSER_PROLOG;
10227                 } else if ((cur == '<') && (next == '!') &&
10228                            (avail < 4)) {
10229                     goto done;
10230                 } else {
10231                     ctxt->instate = XML_PARSER_START_TAG;
10232                     if (ctxt->progressive == 0)
10233                         ctxt->progressive = 1;
10234                     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
10235 #ifdef DEBUG_PUSH
10236                     xmlGenericError(xmlGenericErrorContext,
10237                             "PP: entering START_TAG\n");
10238 #endif
10239                 }
10240                 break;
10241             case XML_PARSER_EPILOG:
10242                 SKIP_BLANKS;
10243                 if (ctxt->input->buf == NULL)
10244                     avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
10245                 else
10246                     avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
10247                 if (avail < 2)
10248                     goto done;
10249                 cur = ctxt->input->cur[0];
10250                 next = ctxt->input->cur[1];
10251                 if ((cur == '<') && (next == '?')) {
10252                     if ((!terminate) &&
10253                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
10254                         goto done;
10255 #ifdef DEBUG_PUSH
10256                     xmlGenericError(xmlGenericErrorContext,
10257                             "PP: Parsing PI\n");
10258 #endif
10259                     xmlParsePI(ctxt);
10260                     ctxt->instate = XML_PARSER_EPILOG;
10261                 } else if ((cur == '<') && (next == '!') &&
10262                     (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
10263                     if ((!terminate) &&
10264                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
10265                         goto done;
10266 #ifdef DEBUG_PUSH
10267                     xmlGenericError(xmlGenericErrorContext,
10268                             "PP: Parsing Comment\n");
10269 #endif
10270                     xmlParseComment(ctxt);
10271                     ctxt->instate = XML_PARSER_EPILOG;
10272                 } else if ((cur == '<') && (next == '!') &&
10273                            (avail < 4)) {
10274                     goto done;
10275                 } else {
10276                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10277                     ctxt->instate = XML_PARSER_EOF;
10278 #ifdef DEBUG_PUSH
10279                     xmlGenericError(xmlGenericErrorContext,
10280                             "PP: entering EOF\n");
10281 #endif
10282                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10283                         ctxt->sax->endDocument(ctxt->userData);
10284                     goto done;
10285                 }
10286                 break;
10287             case XML_PARSER_DTD: {
10288                 /*
10289                  * Sorry but progressive parsing of the internal subset
10290                  * is not expected to be supported. We first check that
10291                  * the full content of the internal subset is available and
10292                  * the parsing is launched only at that point.
10293                  * Internal subset ends up with "']' S? '>'" in an unescaped
10294                  * section and not in a ']]>' sequence which are conditional
10295                  * sections (whoever argued to keep that crap in XML deserve
10296                  * a place in hell !).
10297                  */
10298                 int base, i;
10299                 xmlChar *buf;
10300                 xmlChar quote = 0;
10301
10302                 base = ctxt->input->cur - ctxt->input->base;
10303                 if (base < 0) return(0);
10304                 if (ctxt->checkIndex > base)
10305                     base = ctxt->checkIndex;
10306                 buf = ctxt->input->buf->buffer->content;
10307                 for (;(unsigned int) base < ctxt->input->buf->buffer->use;
10308                      base++) {
10309                     if (quote != 0) {
10310                         if (buf[base] == quote)
10311                             quote = 0;
10312                         continue;    
10313                     }
10314                     if ((quote == 0) && (buf[base] == '<')) {
10315                         int found  = 0;
10316                         /* special handling of comments */
10317                         if (((unsigned int) base + 4 <
10318                              ctxt->input->buf->buffer->use) &&
10319                             (buf[base + 1] == '!') &&
10320                             (buf[base + 2] == '-') &&
10321                             (buf[base + 3] == '-')) {
10322                             for (;(unsigned int) base + 3 <
10323                                   ctxt->input->buf->buffer->use; base++) {
10324                                 if ((buf[base] == '-') &&
10325                                     (buf[base + 1] == '-') &&
10326                                     (buf[base + 2] == '>')) {
10327                                     found = 1;
10328                                     base += 2;
10329                                     break;
10330                                 }
10331                             }
10332                             if (!found) {
10333 #if 0
10334                                 fprintf(stderr, "unfinished comment\n");
10335 #endif
10336                                 break; /* for */
10337                             }
10338                             continue;
10339                         }
10340                     }
10341                     if (buf[base] == '"') {
10342                         quote = '"';
10343                         continue;
10344                     }
10345                     if (buf[base] == '\'') {
10346                         quote = '\'';
10347                         continue;
10348                     }
10349                     if (buf[base] == ']') {
10350 #if 0
10351                         fprintf(stderr, "%c%c%c%c: ", buf[base],
10352                                 buf[base + 1], buf[base + 2], buf[base + 3]);
10353 #endif
10354                         if ((unsigned int) base +1 >=
10355                             ctxt->input->buf->buffer->use)
10356                             break;
10357                         if (buf[base + 1] == ']') {
10358                             /* conditional crap, skip both ']' ! */
10359                             base++;
10360                             continue;
10361                         }
10362                         for (i = 1;
10363                      (unsigned int) base + i < ctxt->input->buf->buffer->use;
10364                              i++) {
10365                             if (buf[base + i] == '>') {
10366 #if 0
10367                                 fprintf(stderr, "found\n");
10368 #endif
10369                                 goto found_end_int_subset;
10370                             }
10371                             if (!IS_BLANK_CH(buf[base + i])) {
10372 #if 0
10373                                 fprintf(stderr, "not found\n");
10374 #endif
10375                                 goto not_end_of_int_subset;
10376                             }
10377                         }
10378 #if 0
10379                         fprintf(stderr, "end of stream\n");
10380 #endif
10381                         break;
10382                         
10383                     }
10384 not_end_of_int_subset:
10385                     continue; /* for */
10386                 }
10387                 /*
10388                  * We didn't found the end of the Internal subset
10389                  */
10390 #ifdef DEBUG_PUSH
10391                 if (next == 0)
10392                     xmlGenericError(xmlGenericErrorContext,
10393                             "PP: lookup of int subset end filed\n");
10394 #endif
10395                 goto done;
10396
10397 found_end_int_subset:
10398                 xmlParseInternalSubset(ctxt);
10399                 ctxt->inSubset = 2;
10400                 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
10401                     (ctxt->sax->externalSubset != NULL))
10402                     ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
10403                             ctxt->extSubSystem, ctxt->extSubURI);
10404                 ctxt->inSubset = 0;
10405                 ctxt->instate = XML_PARSER_PROLOG;
10406                 ctxt->checkIndex = 0;
10407 #ifdef DEBUG_PUSH
10408                 xmlGenericError(xmlGenericErrorContext,
10409                         "PP: entering PROLOG\n");
10410 #endif
10411                 break;
10412             }
10413             case XML_PARSER_COMMENT:
10414                 xmlGenericError(xmlGenericErrorContext,
10415                         "PP: internal error, state == COMMENT\n");
10416                 ctxt->instate = XML_PARSER_CONTENT;
10417 #ifdef DEBUG_PUSH
10418                 xmlGenericError(xmlGenericErrorContext,
10419                         "PP: entering CONTENT\n");
10420 #endif
10421                 break;
10422             case XML_PARSER_IGNORE:
10423                 xmlGenericError(xmlGenericErrorContext,
10424                         "PP: internal error, state == IGNORE");
10425                 ctxt->instate = XML_PARSER_DTD;
10426 #ifdef DEBUG_PUSH
10427                 xmlGenericError(xmlGenericErrorContext,
10428                         "PP: entering DTD\n");
10429 #endif
10430                 break;
10431             case XML_PARSER_PI:
10432                 xmlGenericError(xmlGenericErrorContext,
10433                         "PP: internal error, state == PI\n");
10434                 ctxt->instate = XML_PARSER_CONTENT;
10435 #ifdef DEBUG_PUSH
10436                 xmlGenericError(xmlGenericErrorContext,
10437                         "PP: entering CONTENT\n");
10438 #endif
10439                 break;
10440             case XML_PARSER_ENTITY_DECL:
10441                 xmlGenericError(xmlGenericErrorContext,
10442                         "PP: internal error, state == ENTITY_DECL\n");
10443                 ctxt->instate = XML_PARSER_DTD;
10444 #ifdef DEBUG_PUSH
10445                 xmlGenericError(xmlGenericErrorContext,
10446                         "PP: entering DTD\n");
10447 #endif
10448                 break;
10449             case XML_PARSER_ENTITY_VALUE:
10450                 xmlGenericError(xmlGenericErrorContext,
10451                         "PP: internal error, state == ENTITY_VALUE\n");
10452                 ctxt->instate = XML_PARSER_CONTENT;
10453 #ifdef DEBUG_PUSH
10454                 xmlGenericError(xmlGenericErrorContext,
10455                         "PP: entering DTD\n");
10456 #endif
10457                 break;
10458             case XML_PARSER_ATTRIBUTE_VALUE:
10459                 xmlGenericError(xmlGenericErrorContext,
10460                         "PP: internal error, state == ATTRIBUTE_VALUE\n");
10461                 ctxt->instate = XML_PARSER_START_TAG;
10462 #ifdef DEBUG_PUSH
10463                 xmlGenericError(xmlGenericErrorContext,
10464                         "PP: entering START_TAG\n");
10465 #endif
10466                 break;
10467             case XML_PARSER_SYSTEM_LITERAL:
10468                 xmlGenericError(xmlGenericErrorContext,
10469                         "PP: internal error, state == SYSTEM_LITERAL\n");
10470                 ctxt->instate = XML_PARSER_START_TAG;
10471 #ifdef DEBUG_PUSH
10472                 xmlGenericError(xmlGenericErrorContext,
10473                         "PP: entering START_TAG\n");
10474 #endif
10475                 break;
10476             case XML_PARSER_PUBLIC_LITERAL:
10477                 xmlGenericError(xmlGenericErrorContext,
10478                         "PP: internal error, state == PUBLIC_LITERAL\n");
10479                 ctxt->instate = XML_PARSER_START_TAG;
10480 #ifdef DEBUG_PUSH
10481                 xmlGenericError(xmlGenericErrorContext,
10482                         "PP: entering START_TAG\n");
10483 #endif
10484                 break;
10485         }
10486     }
10487 done:    
10488 #ifdef DEBUG_PUSH
10489     xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
10490 #endif
10491     return(ret);
10492 encoding_error:
10493     {
10494         char buffer[150];
10495
10496         snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
10497                         ctxt->input->cur[0], ctxt->input->cur[1],
10498                         ctxt->input->cur[2], ctxt->input->cur[3]);
10499         __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
10500                      "Input is not proper UTF-8, indicate encoding !\n%s",
10501                      BAD_CAST buffer, NULL);
10502     }
10503     return(0);
10504 }
10505
10506 /**
10507  * xmlParseChunk:
10508  * @ctxt:  an XML parser context
10509  * @chunk:  an char array
10510  * @size:  the size in byte of the chunk
10511  * @terminate:  last chunk indicator
10512  *
10513  * Parse a Chunk of memory
10514  *
10515  * Returns zero if no error, the xmlParserErrors otherwise.
10516  */
10517 int
10518 xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
10519               int terminate) {
10520     int end_in_lf = 0;
10521
10522     if (ctxt == NULL)
10523         return(XML_ERR_INTERNAL_ERROR);
10524     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
10525         return(ctxt->errNo);
10526     if (ctxt->instate == XML_PARSER_START)
10527         xmlDetectSAX2(ctxt);
10528     if ((size > 0) && (chunk != NULL) && (!terminate) &&
10529         (chunk[size - 1] == '\r')) {
10530         end_in_lf = 1;
10531         size--;
10532     }
10533     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
10534         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
10535         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
10536         int cur = ctxt->input->cur - ctxt->input->base;
10537         int res;
10538         
10539         res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
10540         if (res < 0) {
10541             ctxt->errNo = XML_PARSER_EOF;
10542             ctxt->disableSAX = 1;
10543             return (XML_PARSER_EOF);
10544         }
10545         ctxt->input->base = ctxt->input->buf->buffer->content + base;
10546         ctxt->input->cur = ctxt->input->base + cur;
10547         ctxt->input->end =
10548             &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
10549 #ifdef DEBUG_PUSH
10550         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
10551 #endif
10552
10553     } else if (ctxt->instate != XML_PARSER_EOF) {
10554         if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
10555             xmlParserInputBufferPtr in = ctxt->input->buf;
10556             if ((in->encoder != NULL) && (in->buffer != NULL) &&
10557                     (in->raw != NULL)) {
10558                 int nbchars;
10559                     
10560                 nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
10561                 if (nbchars < 0) {
10562                     /* TODO 2.6.0 */
10563                     xmlGenericError(xmlGenericErrorContext,
10564                                     "xmlParseChunk: encoder error\n");
10565                     return(XML_ERR_INVALID_ENCODING);
10566                 }
10567             }
10568         }
10569     }
10570     xmlParseTryOrFinish(ctxt, terminate);
10571     if ((end_in_lf == 1) && (ctxt->input != NULL) &&
10572         (ctxt->input->buf != NULL)) {
10573         xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
10574     }
10575     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
10576         return(ctxt->errNo);
10577     if (terminate) {
10578         /*
10579          * Check for termination
10580          */
10581         int avail = 0;
10582
10583         if (ctxt->input != NULL) {
10584             if (ctxt->input->buf == NULL)
10585                 avail = ctxt->input->length -
10586                         (ctxt->input->cur - ctxt->input->base);
10587             else
10588                 avail = ctxt->input->buf->buffer->use -
10589                         (ctxt->input->cur - ctxt->input->base);
10590         }
10591                             
10592         if ((ctxt->instate != XML_PARSER_EOF) &&
10593             (ctxt->instate != XML_PARSER_EPILOG)) {
10594             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10595         } 
10596         if ((ctxt->instate == XML_PARSER_EPILOG) && (avail > 0)) {
10597             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10598         }
10599         if (ctxt->instate != XML_PARSER_EOF) {
10600             if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10601                 ctxt->sax->endDocument(ctxt->userData);
10602         }
10603         ctxt->instate = XML_PARSER_EOF;
10604     }
10605     return((xmlParserErrors) ctxt->errNo);            
10606 }
10607
10608 /************************************************************************
10609  *                                                                      *
10610  *              I/O front end functions to the parser                   *
10611  *                                                                      *
10612  ************************************************************************/
10613
10614 /**
10615  * xmlCreatePushParserCtxt:
10616  * @sax:  a SAX handler
10617  * @user_data:  The user data returned on SAX callbacks
10618  * @chunk:  a pointer to an array of chars
10619  * @size:  number of chars in the array
10620  * @filename:  an optional file name or URI
10621  *
10622  * Create a parser context for using the XML parser in push mode.
10623  * If @buffer and @size are non-NULL, the data is used to detect
10624  * the encoding.  The remaining characters will be parsed so they
10625  * don't need to be fed in again through xmlParseChunk.
10626  * To allow content encoding detection, @size should be >= 4
10627  * The value of @filename is used for fetching external entities
10628  * and error/warning reports.
10629  *
10630  * Returns the new parser context or NULL
10631  */
10632
10633 xmlParserCtxtPtr
10634 xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data, 
10635                         const char *chunk, int size, const char *filename) {
10636     xmlParserCtxtPtr ctxt;
10637     xmlParserInputPtr inputStream;
10638     xmlParserInputBufferPtr buf;
10639     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
10640
10641     /*
10642      * plug some encoding conversion routines
10643      */
10644     if ((chunk != NULL) && (size >= 4))
10645         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
10646
10647     buf = xmlAllocParserInputBuffer(enc);
10648     if (buf == NULL) return(NULL);
10649
10650     ctxt = xmlNewParserCtxt();
10651     if (ctxt == NULL) {
10652         xmlErrMemory(NULL, "creating parser: out of memory\n");
10653         xmlFreeParserInputBuffer(buf);
10654         return(NULL);
10655     }
10656     ctxt->dictNames = 1;
10657     ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
10658     if (ctxt->pushTab == NULL) {
10659         xmlErrMemory(ctxt, NULL);
10660         xmlFreeParserInputBuffer(buf);
10661         xmlFreeParserCtxt(ctxt);
10662         return(NULL);
10663     }
10664     if (sax != NULL) {
10665 #ifdef LIBXML_SAX1_ENABLED
10666         if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
10667 #endif /* LIBXML_SAX1_ENABLED */
10668             xmlFree(ctxt->sax);
10669         ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
10670         if (ctxt->sax == NULL) {
10671             xmlErrMemory(ctxt, NULL);
10672             xmlFreeParserInputBuffer(buf);
10673             xmlFreeParserCtxt(ctxt);
10674             return(NULL);
10675         }
10676         memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
10677         if (sax->initialized == XML_SAX2_MAGIC)
10678             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
10679         else
10680             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
10681         if (user_data != NULL)
10682             ctxt->userData = user_data;
10683     }   
10684     if (filename == NULL) {
10685         ctxt->directory = NULL;
10686     } else {
10687         ctxt->directory = xmlParserGetDirectory(filename);
10688     }
10689
10690     inputStream = xmlNewInputStream(ctxt);
10691     if (inputStream == NULL) {
10692         xmlFreeParserCtxt(ctxt);
10693         xmlFreeParserInputBuffer(buf);
10694         return(NULL);
10695     }
10696
10697     if (filename == NULL)
10698         inputStream->filename = NULL;
10699     else {
10700         inputStream->filename = (char *)
10701             xmlCanonicPath((const xmlChar *) filename);
10702         if (inputStream->filename == NULL) {
10703             xmlFreeParserCtxt(ctxt);
10704             xmlFreeParserInputBuffer(buf);
10705             return(NULL);
10706         }
10707     }
10708     inputStream->buf = buf;
10709     inputStream->base = inputStream->buf->buffer->content;
10710     inputStream->cur = inputStream->buf->buffer->content;
10711     inputStream->end = 
10712         &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
10713
10714     inputPush(ctxt, inputStream);
10715
10716     /*
10717      * If the caller didn't provide an initial 'chunk' for determining
10718      * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
10719      * that it can be automatically determined later
10720      */
10721     if ((size == 0) || (chunk == NULL)) {
10722         ctxt->charset = XML_CHAR_ENCODING_NONE;
10723     } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
10724         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
10725         int cur = ctxt->input->cur - ctxt->input->base;
10726
10727         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);              
10728
10729         ctxt->input->base = ctxt->input->buf->buffer->content + base;
10730         ctxt->input->cur = ctxt->input->base + cur;
10731         ctxt->input->end =
10732             &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
10733 #ifdef DEBUG_PUSH
10734         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
10735 #endif
10736     }
10737
10738     if (enc != XML_CHAR_ENCODING_NONE) {
10739         xmlSwitchEncoding(ctxt, enc);
10740     }
10741
10742     return(ctxt);
10743 }
10744 #endif /* LIBXML_PUSH_ENABLED */
10745
10746 /**
10747  * xmlStopParser:
10748  * @ctxt:  an XML parser context
10749  *
10750  * Blocks further parser processing
10751  */
10752 void           
10753 xmlStopParser(xmlParserCtxtPtr ctxt) {
10754     if (ctxt == NULL)
10755         return;
10756     ctxt->instate = XML_PARSER_EOF;
10757     ctxt->disableSAX = 1;
10758     if (ctxt->input != NULL) {
10759         ctxt->input->cur = BAD_CAST"";
10760         ctxt->input->base = ctxt->input->cur;
10761     }
10762 }
10763
10764 /**
10765  * xmlCreateIOParserCtxt:
10766  * @sax:  a SAX handler
10767  * @user_data:  The user data returned on SAX callbacks
10768  * @ioread:  an I/O read function
10769  * @ioclose:  an I/O close function
10770  * @ioctx:  an I/O handler
10771  * @enc:  the charset encoding if known
10772  *
10773  * Create a parser context for using the XML parser with an existing
10774  * I/O stream
10775  *
10776  * Returns the new parser context or NULL
10777  */
10778 xmlParserCtxtPtr
10779 xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
10780         xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
10781         void *ioctx, xmlCharEncoding enc) {
10782     xmlParserCtxtPtr ctxt;
10783     xmlParserInputPtr inputStream;
10784     xmlParserInputBufferPtr buf;
10785     
10786     if (ioread == NULL) return(NULL);
10787
10788     buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
10789     if (buf == NULL) return(NULL);
10790
10791     ctxt = xmlNewParserCtxt();
10792     if (ctxt == NULL) {
10793         xmlFreeParserInputBuffer(buf);
10794         return(NULL);
10795     }
10796     if (sax != NULL) {
10797 #ifdef LIBXML_SAX1_ENABLED
10798         if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
10799 #endif /* LIBXML_SAX1_ENABLED */
10800             xmlFree(ctxt->sax);
10801         ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
10802         if (ctxt->sax == NULL) {
10803             xmlErrMemory(ctxt, NULL);
10804             xmlFreeParserCtxt(ctxt);
10805             return(NULL);
10806         }
10807         memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
10808         if (sax->initialized == XML_SAX2_MAGIC)
10809             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
10810         else
10811             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
10812         if (user_data != NULL)
10813             ctxt->userData = user_data;
10814     }   
10815
10816     inputStream = xmlNewIOInputStream(ctxt, buf, enc);
10817     if (inputStream == NULL) {
10818         xmlFreeParserCtxt(ctxt);
10819         return(NULL);
10820     }
10821     inputPush(ctxt, inputStream);
10822
10823     return(ctxt);
10824 }
10825
10826 #ifdef LIBXML_VALID_ENABLED
10827 /************************************************************************
10828  *                                                                      *
10829  *              Front ends when parsing a DTD                           *
10830  *                                                                      *
10831  ************************************************************************/
10832
10833 /**
10834  * xmlIOParseDTD:
10835  * @sax:  the SAX handler block or NULL
10836  * @input:  an Input Buffer
10837  * @enc:  the charset encoding if known
10838  *
10839  * Load and parse a DTD
10840  * 
10841  * Returns the resulting xmlDtdPtr or NULL in case of error.
10842  * @input will be freed by the function in any case.
10843  */
10844
10845 xmlDtdPtr
10846 xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
10847               xmlCharEncoding enc) {
10848     xmlDtdPtr ret = NULL;
10849     xmlParserCtxtPtr ctxt;
10850     xmlParserInputPtr pinput = NULL;
10851     xmlChar start[4];
10852
10853     if (input == NULL)
10854         return(NULL);
10855
10856     ctxt = xmlNewParserCtxt();
10857     if (ctxt == NULL) {
10858         xmlFreeParserInputBuffer(input);
10859         return(NULL);
10860     }
10861
10862     /*
10863      * Set-up the SAX context
10864      */
10865     if (sax != NULL) { 
10866         if (ctxt->sax != NULL)
10867             xmlFree(ctxt->sax);
10868         ctxt->sax = sax;
10869         ctxt->userData = ctxt;
10870     }
10871     xmlDetectSAX2(ctxt);
10872
10873     /*
10874      * generate a parser input from the I/O handler
10875      */
10876
10877     pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
10878     if (pinput == NULL) {
10879         if (sax != NULL) ctxt->sax = NULL;
10880         xmlFreeParserInputBuffer(input);
10881         xmlFreeParserCtxt(ctxt);
10882         return(NULL);
10883     }
10884
10885     /*
10886      * plug some encoding conversion routines here.
10887      */
10888     xmlPushInput(ctxt, pinput);
10889     if (enc != XML_CHAR_ENCODING_NONE) {
10890         xmlSwitchEncoding(ctxt, enc);
10891     }
10892
10893     pinput->filename = NULL;
10894     pinput->line = 1;
10895     pinput->col = 1;
10896     pinput->base = ctxt->input->cur;
10897     pinput->cur = ctxt->input->cur;
10898     pinput->free = NULL;
10899
10900     /*
10901      * let's parse that entity knowing it's an external subset.
10902      */
10903     ctxt->inSubset = 2;
10904     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
10905     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
10906                                        BAD_CAST "none", BAD_CAST "none");
10907
10908     if ((enc == XML_CHAR_ENCODING_NONE) &&
10909         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
10910         /* 
10911          * Get the 4 first bytes and decode the charset
10912          * if enc != XML_CHAR_ENCODING_NONE
10913          * plug some encoding conversion routines.
10914          */
10915         start[0] = RAW;
10916         start[1] = NXT(1);
10917         start[2] = NXT(2);
10918         start[3] = NXT(3);
10919         enc = xmlDetectCharEncoding(start, 4);
10920         if (enc != XML_CHAR_ENCODING_NONE) {
10921             xmlSwitchEncoding(ctxt, enc);
10922         }
10923     }
10924
10925     xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
10926
10927     if (ctxt->myDoc != NULL) {
10928         if (ctxt->wellFormed) {
10929             ret = ctxt->myDoc->extSubset;
10930             ctxt->myDoc->extSubset = NULL;
10931             if (ret != NULL) {
10932                 xmlNodePtr tmp;
10933
10934                 ret->doc = NULL;
10935                 tmp = ret->children;
10936                 while (tmp != NULL) {
10937                     tmp->doc = NULL;
10938                     tmp = tmp->next;
10939                 }
10940             }
10941         } else {
10942             ret = NULL;
10943         }
10944         xmlFreeDoc(ctxt->myDoc);
10945         ctxt->myDoc = NULL;
10946     }
10947     if (sax != NULL) ctxt->sax = NULL;
10948     xmlFreeParserCtxt(ctxt);
10949     
10950     return(ret);
10951 }
10952
10953 /**
10954  * xmlSAXParseDTD:
10955  * @sax:  the SAX handler block
10956  * @ExternalID:  a NAME* containing the External ID of the DTD
10957  * @SystemID:  a NAME* containing the URL to the DTD
10958  *
10959  * Load and parse an external subset.
10960  * 
10961  * Returns the resulting xmlDtdPtr or NULL in case of error.
10962  */
10963
10964 xmlDtdPtr
10965 xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
10966                           const xmlChar *SystemID) {
10967     xmlDtdPtr ret = NULL;
10968     xmlParserCtxtPtr ctxt;
10969     xmlParserInputPtr input = NULL;
10970     xmlCharEncoding enc;
10971     xmlChar* systemIdCanonic;
10972
10973     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
10974
10975     ctxt = xmlNewParserCtxt();
10976     if (ctxt == NULL) {
10977         return(NULL);
10978     }
10979
10980     /*
10981      * Set-up the SAX context
10982      */
10983     if (sax != NULL) { 
10984         if (ctxt->sax != NULL)
10985             xmlFree(ctxt->sax);
10986         ctxt->sax = sax;
10987         ctxt->userData = ctxt;
10988     }
10989     
10990     /*
10991      * Canonicalise the system ID
10992      */
10993     systemIdCanonic = xmlCanonicPath(SystemID);
10994     if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
10995         xmlFreeParserCtxt(ctxt);
10996         return(NULL);
10997     }
10998
10999     /*
11000      * Ask the Entity resolver to load the damn thing
11001      */
11002
11003     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
11004         input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
11005                                          systemIdCanonic);
11006     if (input == NULL) {
11007         if (sax != NULL) ctxt->sax = NULL;
11008         xmlFreeParserCtxt(ctxt);
11009         if (systemIdCanonic != NULL)
11010             xmlFree(systemIdCanonic);
11011         return(NULL);
11012     }
11013
11014     /*
11015      * plug some encoding conversion routines here.
11016      */
11017     xmlPushInput(ctxt, input);
11018     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
11019         enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
11020         xmlSwitchEncoding(ctxt, enc);
11021     }
11022
11023     if (input->filename == NULL)
11024         input->filename = (char *) systemIdCanonic;
11025     else
11026         xmlFree(systemIdCanonic);
11027     input->line = 1;
11028     input->col = 1;
11029     input->base = ctxt->input->cur;
11030     input->cur = ctxt->input->cur;
11031     input->free = NULL;
11032
11033     /*
11034      * let's parse that entity knowing it's an external subset.
11035      */
11036     ctxt->inSubset = 2;
11037     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
11038     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
11039                                        ExternalID, SystemID);
11040     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
11041
11042     if (ctxt->myDoc != NULL) {
11043         if (ctxt->wellFormed) {
11044             ret = ctxt->myDoc->extSubset;
11045             ctxt->myDoc->extSubset = NULL;
11046             if (ret != NULL) {
11047                 xmlNodePtr tmp;
11048
11049                 ret->doc = NULL;
11050                 tmp = ret->children;
11051                 while (tmp != NULL) {
11052                     tmp->doc = NULL;
11053                     tmp = tmp->next;
11054                 }
11055             }
11056         } else {
11057             ret = NULL;
11058         }
11059         xmlFreeDoc(ctxt->myDoc);
11060         ctxt->myDoc = NULL;
11061     }
11062     if (sax != NULL) ctxt->sax = NULL;
11063     xmlFreeParserCtxt(ctxt);
11064     
11065     return(ret);
11066 }
11067
11068
11069 /**
11070  * xmlParseDTD:
11071  * @ExternalID:  a NAME* containing the External ID of the DTD
11072  * @SystemID:  a NAME* containing the URL to the DTD
11073  *
11074  * Load and parse an external subset.
11075  * 
11076  * Returns the resulting xmlDtdPtr or NULL in case of error.
11077  */
11078
11079 xmlDtdPtr
11080 xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
11081     return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
11082 }
11083 #endif /* LIBXML_VALID_ENABLED */
11084
11085 /************************************************************************
11086  *                                                                      *
11087  *              Front ends when parsing an Entity                       *
11088  *                                                                      *
11089  ************************************************************************/
11090
11091 /**
11092  * xmlParseCtxtExternalEntity:
11093  * @ctx:  the existing parsing context
11094  * @URL:  the URL for the entity to load
11095  * @ID:  the System ID for the entity to load
11096  * @lst:  the return value for the set of parsed nodes
11097  *
11098  * Parse an external general entity within an existing parsing context
11099  * An external general parsed entity is well-formed if it matches the
11100  * production labeled extParsedEnt.
11101  *
11102  * [78] extParsedEnt ::= TextDecl? content
11103  *
11104  * Returns 0 if the entity is well formed, -1 in case of args problem and
11105  *    the parser error code otherwise
11106  */
11107
11108 int
11109 xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
11110                        const xmlChar *ID, xmlNodePtr *lst) {
11111     xmlParserCtxtPtr ctxt;
11112     xmlDocPtr newDoc;
11113     xmlNodePtr newRoot;
11114     xmlSAXHandlerPtr oldsax = NULL;
11115     int ret = 0;
11116     xmlChar start[4];
11117     xmlCharEncoding enc;
11118     xmlParserInputPtr inputStream;
11119     char *directory = NULL;
11120
11121     if (ctx == NULL) return(-1);
11122
11123     if (ctx->depth > 40) {
11124         return(XML_ERR_ENTITY_LOOP);
11125     }
11126
11127     if (lst != NULL)
11128         *lst = NULL;
11129     if ((URL == NULL) && (ID == NULL))
11130         return(-1);
11131     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
11132         return(-1);
11133
11134     ctxt = xmlNewParserCtxt();
11135     if (ctxt == NULL) {
11136         return(-1);
11137     }
11138     
11139     ctxt->userData = ctxt;
11140     ctxt->_private = ctx->_private;
11141     
11142     inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
11143     if (inputStream == NULL) {
11144         xmlFreeParserCtxt(ctxt);
11145         return(-1);
11146     }
11147
11148     inputPush(ctxt, inputStream);
11149
11150     if ((ctxt->directory == NULL) && (directory == NULL))
11151         directory = xmlParserGetDirectory((char *)URL);
11152     if ((ctxt->directory == NULL) && (directory != NULL))
11153         ctxt->directory = directory;
11154     
11155     oldsax = ctxt->sax;
11156     ctxt->sax = ctx->sax;
11157     xmlDetectSAX2(ctxt);
11158     newDoc = xmlNewDoc(BAD_CAST "1.0");
11159     if (newDoc == NULL) {
11160         xmlFreeParserCtxt(ctxt);
11161         return(-1);
11162     }
11163     if (ctx->myDoc->dict) {
11164         newDoc->dict = ctx->myDoc->dict;
11165         xmlDictReference(newDoc->dict);
11166     }
11167     if (ctx->myDoc != NULL) {
11168         newDoc->intSubset = ctx->myDoc->intSubset;
11169         newDoc->extSubset = ctx->myDoc->extSubset;
11170     }
11171     if (ctx->myDoc->URL != NULL) {
11172         newDoc->URL = xmlStrdup(ctx->myDoc->URL);
11173     }
11174     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
11175     if (newRoot == NULL) {
11176         ctxt->sax = oldsax;
11177         xmlFreeParserCtxt(ctxt);
11178         newDoc->intSubset = NULL;
11179         newDoc->extSubset = NULL;
11180         xmlFreeDoc(newDoc);
11181         return(-1);
11182     }
11183     xmlAddChild((xmlNodePtr) newDoc, newRoot);
11184     nodePush(ctxt, newDoc->children);
11185     if (ctx->myDoc == NULL) {
11186         ctxt->myDoc = newDoc;
11187     } else {
11188         ctxt->myDoc = ctx->myDoc;
11189         newDoc->children->doc = ctx->myDoc;
11190     }
11191
11192     /* 
11193      * Get the 4 first bytes and decode the charset
11194      * if enc != XML_CHAR_ENCODING_NONE
11195      * plug some encoding conversion routines.
11196      */
11197     GROW
11198     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
11199         start[0] = RAW;
11200         start[1] = NXT(1);
11201         start[2] = NXT(2);
11202         start[3] = NXT(3);
11203         enc = xmlDetectCharEncoding(start, 4);
11204         if (enc != XML_CHAR_ENCODING_NONE) {
11205             xmlSwitchEncoding(ctxt, enc);
11206         }
11207     }
11208
11209     /*
11210      * Parse a possible text declaration first
11211      */
11212     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
11213         xmlParseTextDecl(ctxt);
11214     }
11215
11216     /*
11217      * Doing validity checking on chunk doesn't make sense
11218      */
11219     ctxt->instate = XML_PARSER_CONTENT;
11220     ctxt->validate = ctx->validate;
11221     ctxt->valid = ctx->valid;
11222     ctxt->loadsubset = ctx->loadsubset;
11223     ctxt->depth = ctx->depth + 1;
11224     ctxt->replaceEntities = ctx->replaceEntities;
11225     if (ctxt->validate) {
11226         ctxt->vctxt.error = ctx->vctxt.error;
11227         ctxt->vctxt.warning = ctx->vctxt.warning;
11228     } else {
11229         ctxt->vctxt.error = NULL;
11230         ctxt->vctxt.warning = NULL;
11231     }
11232     ctxt->vctxt.nodeTab = NULL;
11233     ctxt->vctxt.nodeNr = 0;
11234     ctxt->vctxt.nodeMax = 0;
11235     ctxt->vctxt.node = NULL;
11236     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
11237     ctxt->dict = ctx->dict;
11238     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
11239     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
11240     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
11241     ctxt->dictNames = ctx->dictNames;
11242     ctxt->attsDefault = ctx->attsDefault;
11243     ctxt->attsSpecial = ctx->attsSpecial;
11244     ctxt->linenumbers = ctx->linenumbers;
11245
11246     xmlParseContent(ctxt);
11247    
11248     ctx->validate = ctxt->validate;
11249     ctx->valid = ctxt->valid;
11250     if ((RAW == '<') && (NXT(1) == '/')) {
11251         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11252     } else if (RAW != 0) {
11253         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
11254     }
11255     if (ctxt->node != newDoc->children) {
11256         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11257     }
11258
11259     if (!ctxt->wellFormed) {
11260         if (ctxt->errNo == 0)
11261             ret = 1;
11262         else
11263             ret = ctxt->errNo;
11264     } else {
11265         if (lst != NULL) {
11266             xmlNodePtr cur;
11267
11268             /*
11269              * Return the newly created nodeset after unlinking it from
11270              * they pseudo parent.
11271              */
11272             cur = newDoc->children->children;
11273             *lst = cur;
11274             while (cur != NULL) {
11275                 cur->parent = NULL;
11276                 cur = cur->next;
11277             }
11278             newDoc->children->children = NULL;
11279         }
11280         ret = 0;
11281     }
11282     ctxt->sax = oldsax;
11283     ctxt->dict = NULL;
11284     ctxt->attsDefault = NULL;
11285     ctxt->attsSpecial = NULL;
11286     xmlFreeParserCtxt(ctxt);
11287     newDoc->intSubset = NULL;
11288     newDoc->extSubset = NULL;
11289     xmlFreeDoc(newDoc);
11290     
11291     return(ret);
11292 }
11293
11294 /**
11295  * xmlParseExternalEntityPrivate:
11296  * @doc:  the document the chunk pertains to
11297  * @oldctxt:  the previous parser context if available
11298  * @sax:  the SAX handler bloc (possibly NULL)
11299  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
11300  * @depth:  Used for loop detection, use 0
11301  * @URL:  the URL for the entity to load
11302  * @ID:  the System ID for the entity to load
11303  * @list:  the return value for the set of parsed nodes
11304  *
11305  * Private version of xmlParseExternalEntity()
11306  *
11307  * Returns 0 if the entity is well formed, -1 in case of args problem and
11308  *    the parser error code otherwise
11309  */
11310
11311 static xmlParserErrors
11312 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
11313                       xmlSAXHandlerPtr sax,
11314                       void *user_data, int depth, const xmlChar *URL,
11315                       const xmlChar *ID, xmlNodePtr *list) {
11316     xmlParserCtxtPtr ctxt;
11317     xmlDocPtr newDoc;
11318     xmlNodePtr newRoot;
11319     xmlSAXHandlerPtr oldsax = NULL;
11320     xmlParserErrors ret = XML_ERR_OK;
11321     xmlChar start[4];
11322     xmlCharEncoding enc;
11323
11324     if (depth > 40) {
11325         return(XML_ERR_ENTITY_LOOP);
11326     }
11327
11328
11329
11330     if (list != NULL)
11331         *list = NULL;
11332     if ((URL == NULL) && (ID == NULL))
11333         return(XML_ERR_INTERNAL_ERROR);
11334     if (doc == NULL)
11335         return(XML_ERR_INTERNAL_ERROR);
11336
11337
11338     ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
11339     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
11340     ctxt->userData = ctxt;
11341     if (oldctxt != NULL) {
11342         ctxt->_private = oldctxt->_private;
11343         ctxt->loadsubset = oldctxt->loadsubset;
11344         ctxt->validate = oldctxt->validate;
11345         ctxt->external = oldctxt->external;
11346         ctxt->record_info = oldctxt->record_info;
11347         ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
11348         ctxt->node_seq.length = oldctxt->node_seq.length;
11349         ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
11350     } else {
11351         /*
11352          * Doing validity checking on chunk without context
11353          * doesn't make sense
11354          */
11355         ctxt->_private = NULL;
11356         ctxt->validate = 0;
11357         ctxt->external = 2;
11358         ctxt->loadsubset = 0;
11359     }
11360     if (sax != NULL) {
11361         oldsax = ctxt->sax;
11362         ctxt->sax = sax;
11363         if (user_data != NULL)
11364             ctxt->userData = user_data;
11365     }
11366     xmlDetectSAX2(ctxt);
11367     newDoc = xmlNewDoc(BAD_CAST "1.0");
11368     if (newDoc == NULL) {
11369         ctxt->node_seq.maximum = 0;
11370         ctxt->node_seq.length = 0;
11371         ctxt->node_seq.buffer = NULL;
11372         xmlFreeParserCtxt(ctxt);
11373         return(XML_ERR_INTERNAL_ERROR);
11374     }
11375     newDoc->intSubset = doc->intSubset;
11376     newDoc->extSubset = doc->extSubset;
11377     newDoc->dict = doc->dict;
11378     xmlDictReference(newDoc->dict);
11379
11380     if (doc->URL != NULL) {
11381         newDoc->URL = xmlStrdup(doc->URL);
11382     }
11383     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
11384     if (newRoot == NULL) {
11385         if (sax != NULL)
11386             ctxt->sax = oldsax;
11387         ctxt->node_seq.maximum = 0;
11388         ctxt->node_seq.length = 0;
11389         ctxt->node_seq.buffer = NULL;
11390         xmlFreeParserCtxt(ctxt);
11391         newDoc->intSubset = NULL;
11392         newDoc->extSubset = NULL;
11393         xmlFreeDoc(newDoc);
11394         return(XML_ERR_INTERNAL_ERROR);
11395     }
11396     xmlAddChild((xmlNodePtr) newDoc, newRoot);
11397     nodePush(ctxt, newDoc->children);
11398     ctxt->myDoc = doc;
11399     newRoot->doc = doc;
11400
11401     /* 
11402      * Get the 4 first bytes and decode the charset
11403      * if enc != XML_CHAR_ENCODING_NONE
11404      * plug some encoding conversion routines.
11405      */
11406     GROW;
11407     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
11408         start[0] = RAW;
11409         start[1] = NXT(1);
11410         start[2] = NXT(2);
11411         start[3] = NXT(3);
11412         enc = xmlDetectCharEncoding(start, 4);
11413         if (enc != XML_CHAR_ENCODING_NONE) {
11414             xmlSwitchEncoding(ctxt, enc);
11415         }
11416     }
11417
11418     /*
11419      * Parse a possible text declaration first
11420      */
11421     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
11422         xmlParseTextDecl(ctxt);
11423     }
11424
11425     ctxt->instate = XML_PARSER_CONTENT;
11426     ctxt->depth = depth;
11427
11428     xmlParseContent(ctxt);
11429    
11430     if ((RAW == '<') && (NXT(1) == '/')) {
11431         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11432     } else if (RAW != 0) {
11433         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
11434     }
11435     if (ctxt->node != newDoc->children) {
11436         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11437     }
11438
11439     if (!ctxt->wellFormed) {
11440         if (ctxt->errNo == 0)
11441             ret = XML_ERR_INTERNAL_ERROR;
11442         else
11443             ret = (xmlParserErrors)ctxt->errNo;
11444     } else {
11445         if (list != NULL) {
11446             xmlNodePtr cur;
11447
11448             /*
11449              * Return the newly created nodeset after unlinking it from
11450              * they pseudo parent.
11451              */
11452             cur = newDoc->children->children;
11453             *list = cur;
11454             while (cur != NULL) {
11455                 cur->parent = NULL;
11456                 cur = cur->next;
11457             }
11458             newDoc->children->children = NULL;
11459         }
11460         ret = XML_ERR_OK;
11461     }
11462     if (sax != NULL) 
11463         ctxt->sax = oldsax;
11464     oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
11465     oldctxt->node_seq.length = ctxt->node_seq.length;
11466     oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
11467     ctxt->node_seq.maximum = 0;
11468     ctxt->node_seq.length = 0;
11469     ctxt->node_seq.buffer = NULL;
11470     xmlFreeParserCtxt(ctxt);
11471     newDoc->intSubset = NULL;
11472     newDoc->extSubset = NULL;
11473     xmlFreeDoc(newDoc);
11474     
11475     return(ret);
11476 }
11477
11478 #ifdef LIBXML_SAX1_ENABLED
11479 /**
11480  * xmlParseExternalEntity:
11481  * @doc:  the document the chunk pertains to
11482  * @sax:  the SAX handler bloc (possibly NULL)
11483  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
11484  * @depth:  Used for loop detection, use 0
11485  * @URL:  the URL for the entity to load
11486  * @ID:  the System ID for the entity to load
11487  * @lst:  the return value for the set of parsed nodes
11488  *
11489  * Parse an external general entity
11490  * An external general parsed entity is well-formed if it matches the
11491  * production labeled extParsedEnt.
11492  *
11493  * [78] extParsedEnt ::= TextDecl? content
11494  *
11495  * Returns 0 if the entity is well formed, -1 in case of args problem and
11496  *    the parser error code otherwise
11497  */
11498
11499 int
11500 xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
11501           int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
11502     return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
11503                                        ID, lst));
11504 }
11505
11506 /**
11507  * xmlParseBalancedChunkMemory:
11508  * @doc:  the document the chunk pertains to
11509  * @sax:  the SAX handler bloc (possibly NULL)
11510  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
11511  * @depth:  Used for loop detection, use 0
11512  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
11513  * @lst:  the return value for the set of parsed nodes
11514  *
11515  * Parse a well-balanced chunk of an XML document
11516  * called by the parser
11517  * The allowed sequence for the Well Balanced Chunk is the one defined by
11518  * the content production in the XML grammar:
11519  *
11520  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
11521  *
11522  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
11523  *    the parser error code otherwise
11524  */
11525
11526 int
11527 xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
11528      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
11529     return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
11530                                                 depth, string, lst, 0 );
11531 }
11532 #endif /* LIBXML_SAX1_ENABLED */
11533
11534 /**
11535  * xmlParseBalancedChunkMemoryInternal:
11536  * @oldctxt:  the existing parsing context
11537  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
11538  * @user_data:  the user data field for the parser context
11539  * @lst:  the return value for the set of parsed nodes
11540  *
11541  *
11542  * Parse a well-balanced chunk of an XML document
11543  * called by the parser
11544  * The allowed sequence for the Well Balanced Chunk is the one defined by
11545  * the content production in the XML grammar:
11546  *
11547  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
11548  *
11549  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
11550  * error code otherwise
11551  *    
11552  * In case recover is set to 1, the nodelist will not be empty even if
11553  * the parsed chunk is not well balanced. 
11554  */
11555 static xmlParserErrors
11556 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
11557         const xmlChar *string, void *user_data, xmlNodePtr *lst) {
11558     xmlParserCtxtPtr ctxt;
11559     xmlDocPtr newDoc = NULL;
11560     xmlNodePtr newRoot;
11561     xmlSAXHandlerPtr oldsax = NULL;
11562     xmlNodePtr content = NULL;
11563     xmlNodePtr last = NULL;
11564     int size;
11565     xmlParserErrors ret = XML_ERR_OK;
11566
11567     if (oldctxt->depth > 40) {
11568         return(XML_ERR_ENTITY_LOOP);
11569     }
11570
11571
11572     if (lst != NULL)
11573         *lst = NULL;
11574     if (string == NULL)
11575         return(XML_ERR_INTERNAL_ERROR);
11576
11577     size = xmlStrlen(string);
11578
11579     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
11580     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
11581     if (user_data != NULL)
11582         ctxt->userData = user_data;
11583     else
11584         ctxt->userData = ctxt;
11585     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
11586     ctxt->dict = oldctxt->dict;
11587     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
11588     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
11589     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
11590
11591     oldsax = ctxt->sax;
11592     ctxt->sax = oldctxt->sax;
11593     xmlDetectSAX2(ctxt);
11594     ctxt->replaceEntities = oldctxt->replaceEntities;
11595     ctxt->options = oldctxt->options;
11596     
11597     ctxt->_private = oldctxt->_private;
11598     if (oldctxt->myDoc == NULL) {
11599         newDoc = xmlNewDoc(BAD_CAST "1.0");
11600         if (newDoc == NULL) {
11601             ctxt->sax = oldsax;
11602             ctxt->dict = NULL;
11603             xmlFreeParserCtxt(ctxt);
11604             return(XML_ERR_INTERNAL_ERROR);
11605         }
11606         newDoc->dict = ctxt->dict;
11607         xmlDictReference(newDoc->dict);
11608         ctxt->myDoc = newDoc;
11609     } else {
11610         ctxt->myDoc = oldctxt->myDoc;
11611         content = ctxt->myDoc->children;
11612         last = ctxt->myDoc->last;
11613     }
11614     newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
11615     if (newRoot == NULL) {
11616         ctxt->sax = oldsax;
11617         ctxt->dict = NULL;
11618         xmlFreeParserCtxt(ctxt);
11619         if (newDoc != NULL) {
11620             xmlFreeDoc(newDoc);
11621         }
11622         return(XML_ERR_INTERNAL_ERROR);
11623     }
11624     ctxt->myDoc->children = NULL;
11625     ctxt->myDoc->last = NULL;
11626     xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
11627     nodePush(ctxt, ctxt->myDoc->children);
11628     ctxt->instate = XML_PARSER_CONTENT;
11629     ctxt->depth = oldctxt->depth + 1;
11630
11631     ctxt->validate = 0;
11632     ctxt->loadsubset = oldctxt->loadsubset;
11633     if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
11634         /*
11635          * ID/IDREF registration will be done in xmlValidateElement below
11636          */
11637         ctxt->loadsubset |= XML_SKIP_IDS;
11638     }
11639     ctxt->dictNames = oldctxt->dictNames;
11640     ctxt->attsDefault = oldctxt->attsDefault;
11641     ctxt->attsSpecial = oldctxt->attsSpecial;
11642
11643     xmlParseContent(ctxt);
11644     if ((RAW == '<') && (NXT(1) == '/')) {
11645         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11646     } else if (RAW != 0) {
11647         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
11648     }
11649     if (ctxt->node != ctxt->myDoc->children) {
11650         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11651     }
11652
11653     if (!ctxt->wellFormed) {
11654         if (ctxt->errNo == 0)
11655             ret = XML_ERR_INTERNAL_ERROR;
11656         else
11657             ret = (xmlParserErrors)ctxt->errNo;
11658     } else {
11659       ret = XML_ERR_OK;
11660     }
11661     
11662     if ((lst != NULL) && (ret == XML_ERR_OK)) {
11663         xmlNodePtr cur;
11664
11665         /*
11666          * Return the newly created nodeset after unlinking it from
11667          * they pseudo parent.
11668          */
11669         cur = ctxt->myDoc->children->children;
11670         *lst = cur;
11671         while (cur != NULL) {
11672 #ifdef LIBXML_VALID_ENABLED
11673             if ((oldctxt->validate) && (oldctxt->wellFormed) &&
11674                 (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
11675                 (cur->type == XML_ELEMENT_NODE)) {
11676                 oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
11677                         oldctxt->myDoc, cur);
11678             }
11679 #endif /* LIBXML_VALID_ENABLED */
11680             cur->parent = NULL;
11681             cur = cur->next;
11682         }
11683         ctxt->myDoc->children->children = NULL;
11684     }
11685     if (ctxt->myDoc != NULL) {
11686         xmlFreeNode(ctxt->myDoc->children);
11687         ctxt->myDoc->children = content;
11688         ctxt->myDoc->last = last;
11689     }
11690         
11691     ctxt->sax = oldsax;
11692     ctxt->dict = NULL;
11693     ctxt->attsDefault = NULL;
11694     ctxt->attsSpecial = NULL;
11695     xmlFreeParserCtxt(ctxt);
11696     if (newDoc != NULL) {
11697         xmlFreeDoc(newDoc);
11698     }
11699     
11700     return(ret);
11701 }
11702
11703 /**
11704  * xmlParseInNodeContext:
11705  * @node:  the context node
11706  * @data:  the input string
11707  * @datalen:  the input string length in bytes
11708  * @options:  a combination of xmlParserOption
11709  * @lst:  the return value for the set of parsed nodes
11710  *
11711  * Parse a well-balanced chunk of an XML document
11712  * within the context (DTD, namespaces, etc ...) of the given node.
11713  *
11714  * The allowed sequence for the data is a Well Balanced Chunk defined by
11715  * the content production in the XML grammar:
11716  *
11717  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
11718  *
11719  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
11720  * error code otherwise
11721  */
11722 xmlParserErrors
11723 xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
11724                       int options, xmlNodePtr *lst) {
11725 #ifdef SAX2
11726     xmlParserCtxtPtr ctxt;
11727     xmlDocPtr doc = NULL;
11728     xmlNodePtr fake, cur;
11729     int nsnr = 0;
11730
11731     xmlParserErrors ret = XML_ERR_OK;
11732
11733     /*
11734      * check all input parameters, grab the document
11735      */
11736     if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
11737         return(XML_ERR_INTERNAL_ERROR);
11738     switch (node->type) {
11739         case XML_ELEMENT_NODE:
11740         case XML_ATTRIBUTE_NODE:
11741         case XML_TEXT_NODE:
11742         case XML_CDATA_SECTION_NODE:
11743         case XML_ENTITY_REF_NODE:
11744         case XML_PI_NODE:
11745         case XML_COMMENT_NODE:
11746         case XML_DOCUMENT_NODE:
11747         case XML_HTML_DOCUMENT_NODE:
11748             break;
11749         default:
11750             return(XML_ERR_INTERNAL_ERROR);
11751
11752     }
11753     while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
11754            (node->type != XML_DOCUMENT_NODE) &&
11755            (node->type != XML_HTML_DOCUMENT_NODE))
11756         node = node->parent;
11757     if (node == NULL)
11758         return(XML_ERR_INTERNAL_ERROR);
11759     if (node->type == XML_ELEMENT_NODE)
11760         doc = node->doc;
11761     else
11762         doc = (xmlDocPtr) node;
11763     if (doc == NULL)
11764         return(XML_ERR_INTERNAL_ERROR);
11765
11766     /*
11767      * allocate a context and set-up everything not related to the
11768      * node position in the tree
11769      */
11770     if (doc->type == XML_DOCUMENT_NODE)
11771         ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
11772 #ifdef LIBXML_HTML_ENABLED
11773     else if (doc->type == XML_HTML_DOCUMENT_NODE)
11774         ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
11775 #endif
11776     else
11777         return(XML_ERR_INTERNAL_ERROR);
11778
11779     if (ctxt == NULL)
11780         return(XML_ERR_NO_MEMORY);
11781     fake = xmlNewComment(NULL);
11782     if (fake == NULL) {
11783         xmlFreeParserCtxt(ctxt);
11784         return(XML_ERR_NO_MEMORY);
11785     }
11786     xmlAddChild(node, fake);
11787
11788     /* 
11789      * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
11790      * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
11791      * we must wait until the last moment to free the original one.
11792      */
11793     if (doc->dict != NULL) {
11794         if (ctxt->dict != NULL)
11795             xmlDictFree(ctxt->dict);
11796         ctxt->dict = doc->dict;
11797     } else
11798         options |= XML_PARSE_NODICT;
11799
11800     xmlCtxtUseOptions(ctxt, options);
11801     xmlDetectSAX2(ctxt);
11802     ctxt->myDoc = doc;
11803
11804     if (node->type == XML_ELEMENT_NODE) {
11805         nodePush(ctxt, node);
11806         /*
11807          * initialize the SAX2 namespaces stack
11808          */
11809         cur = node;
11810         while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
11811             xmlNsPtr ns = cur->nsDef;
11812             const xmlChar *iprefix, *ihref;
11813
11814             while (ns != NULL) {
11815                 if (ctxt->dict) {
11816                     iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
11817                     ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
11818                 } else {
11819                     iprefix = ns->prefix;
11820                     ihref = ns->href;
11821                 }
11822
11823                 if (xmlGetNamespace(ctxt, iprefix) == NULL) {
11824                     nsPush(ctxt, iprefix, ihref);
11825                     nsnr++;
11826                 }
11827                 ns = ns->next;
11828             }
11829             cur = cur->parent;
11830         }
11831         ctxt->instate = XML_PARSER_CONTENT;
11832     } 
11833
11834     if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
11835         /*
11836          * ID/IDREF registration will be done in xmlValidateElement below
11837          */
11838         ctxt->loadsubset |= XML_SKIP_IDS;
11839     }
11840
11841 #ifdef LIBXML_HTML_ENABLED
11842     if (doc->type == XML_HTML_DOCUMENT_NODE)
11843         __htmlParseContent(ctxt);
11844     else
11845 #endif
11846         xmlParseContent(ctxt);
11847
11848     nsPop(ctxt, nsnr);
11849     if ((RAW == '<') && (NXT(1) == '/')) {
11850         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11851     } else if (RAW != 0) {
11852         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
11853     }
11854     if ((ctxt->node != NULL) && (ctxt->node != node)) {
11855         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
11856         ctxt->wellFormed = 0;
11857     }
11858
11859     if (!ctxt->wellFormed) {
11860         if (ctxt->errNo == 0)
11861             ret = XML_ERR_INTERNAL_ERROR;
11862         else
11863             ret = (xmlParserErrors)ctxt->errNo;
11864     } else {
11865         ret = XML_ERR_OK;
11866     }
11867     
11868     /*
11869      * Return the newly created nodeset after unlinking it from
11870      * the pseudo sibling.
11871      */
11872     
11873     cur = fake->next;
11874     fake->next = NULL;
11875     node->last = fake;
11876
11877     if (cur != NULL) {
11878         cur->prev = NULL;
11879     }
11880
11881     *lst = cur;
11882
11883     while (cur != NULL) {
11884         cur->parent = NULL;
11885         cur = cur->next;
11886     }
11887
11888     xmlUnlinkNode(fake);
11889     xmlFreeNode(fake);
11890
11891
11892     if (ret != XML_ERR_OK) {
11893         xmlFreeNodeList(*lst);
11894         *lst = NULL;
11895     }
11896
11897     if (doc->dict != NULL)
11898         ctxt->dict = NULL;
11899     xmlFreeParserCtxt(ctxt);
11900     
11901     return(ret);
11902 #else /* !SAX2 */
11903     return(XML_ERR_INTERNAL_ERROR);
11904 #endif
11905 }
11906
11907 #ifdef LIBXML_SAX1_ENABLED
11908 /**
11909  * xmlParseBalancedChunkMemoryRecover:
11910  * @doc:  the document the chunk pertains to
11911  * @sax:  the SAX handler bloc (possibly NULL)
11912  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
11913  * @depth:  Used for loop detection, use 0
11914  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
11915  * @lst:  the return value for the set of parsed nodes
11916  * @recover: return nodes even if the data is broken (use 0)
11917  *
11918  *
11919  * Parse a well-balanced chunk of an XML document
11920  * called by the parser
11921  * The allowed sequence for the Well Balanced Chunk is the one defined by
11922  * the content production in the XML grammar:
11923  *
11924  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
11925  *
11926  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
11927  *    the parser error code otherwise
11928  *    
11929  * In case recover is set to 1, the nodelist will not be empty even if
11930  * the parsed chunk is not well balanced. 
11931  */
11932 int
11933 xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
11934      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst, 
11935      int recover) {
11936     xmlParserCtxtPtr ctxt;
11937     xmlDocPtr newDoc;
11938     xmlSAXHandlerPtr oldsax = NULL;
11939     xmlNodePtr content, newRoot;
11940     int size;
11941     int ret = 0;
11942
11943     if (depth > 40) {
11944         return(XML_ERR_ENTITY_LOOP);
11945     }
11946
11947
11948     if (lst != NULL)
11949         *lst = NULL;
11950     if (string == NULL)
11951         return(-1);
11952
11953     size = xmlStrlen(string);
11954
11955     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
11956     if (ctxt == NULL) return(-1);
11957     ctxt->userData = ctxt;
11958     if (sax != NULL) {
11959         oldsax = ctxt->sax;
11960         ctxt->sax = sax;
11961         if (user_data != NULL)
11962             ctxt->userData = user_data;
11963     }
11964     newDoc = xmlNewDoc(BAD_CAST "1.0");
11965     if (newDoc == NULL) {
11966         xmlFreeParserCtxt(ctxt);
11967         return(-1);
11968     }
11969     if ((doc != NULL) && (doc->dict != NULL)) {
11970         xmlDictFree(ctxt->dict);
11971         ctxt->dict = doc->dict;
11972         xmlDictReference(ctxt->dict);
11973         ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
11974         ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
11975         ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
11976         ctxt->dictNames = 1;
11977     } else {
11978         xmlCtxtUseOptions(ctxt, XML_PARSE_NODICT);
11979     }
11980     if (doc != NULL) {
11981         newDoc->intSubset = doc->intSubset;
11982         newDoc->extSubset = doc->extSubset;
11983     }
11984     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
11985     if (newRoot == NULL) {
11986         if (sax != NULL)
11987             ctxt->sax = oldsax;
11988         xmlFreeParserCtxt(ctxt);
11989         newDoc->intSubset = NULL;
11990         newDoc->extSubset = NULL;
11991         xmlFreeDoc(newDoc);
11992         return(-1);
11993     }
11994     xmlAddChild((xmlNodePtr) newDoc, newRoot);
11995     nodePush(ctxt, newRoot);
11996     if (doc == NULL) {
11997         ctxt->myDoc = newDoc;
11998     } else {
11999         ctxt->myDoc = newDoc;
12000         newDoc->children->doc = doc;
12001         /* Ensure that doc has XML spec namespace */
12002         xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
12003         newDoc->oldNs = doc->oldNs;
12004     }
12005     ctxt->instate = XML_PARSER_CONTENT;
12006     ctxt->depth = depth;
12007
12008     /*
12009      * Doing validity checking on chunk doesn't make sense
12010      */
12011     ctxt->validate = 0;
12012     ctxt->loadsubset = 0;
12013     xmlDetectSAX2(ctxt);
12014
12015     if ( doc != NULL ){
12016         content = doc->children;
12017         doc->children = NULL;
12018         xmlParseContent(ctxt);
12019         doc->children = content;
12020     }
12021     else {
12022         xmlParseContent(ctxt);
12023     }
12024     if ((RAW == '<') && (NXT(1) == '/')) {
12025         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12026     } else if (RAW != 0) {
12027         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
12028     }
12029     if (ctxt->node != newDoc->children) {
12030         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12031     }
12032
12033     if (!ctxt->wellFormed) {
12034         if (ctxt->errNo == 0)
12035             ret = 1;
12036         else
12037             ret = ctxt->errNo;
12038     } else {
12039       ret = 0;
12040     }
12041     
12042     if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
12043         xmlNodePtr cur;
12044
12045         /*
12046          * Return the newly created nodeset after unlinking it from
12047          * they pseudo parent.
12048          */
12049         cur = newDoc->children->children;
12050         *lst = cur;
12051         while (cur != NULL) {
12052             xmlSetTreeDoc(cur, doc);
12053             cur->parent = NULL;
12054             cur = cur->next;
12055         }
12056         newDoc->children->children = NULL;
12057     }
12058         
12059     if (sax != NULL) 
12060         ctxt->sax = oldsax;
12061     xmlFreeParserCtxt(ctxt);
12062     newDoc->intSubset = NULL;
12063     newDoc->extSubset = NULL;
12064     newDoc->oldNs = NULL;
12065     xmlFreeDoc(newDoc);
12066     
12067     return(ret);
12068 }
12069
12070 /**
12071  * xmlSAXParseEntity:
12072  * @sax:  the SAX handler block
12073  * @filename:  the filename
12074  *
12075  * parse an XML external entity out of context and build a tree.
12076  * It use the given SAX function block to handle the parsing callback.
12077  * If sax is NULL, fallback to the default DOM tree building routines.
12078  *
12079  * [78] extParsedEnt ::= TextDecl? content
12080  *
12081  * This correspond to a "Well Balanced" chunk
12082  *
12083  * Returns the resulting document tree
12084  */
12085
12086 xmlDocPtr
12087 xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
12088     xmlDocPtr ret;
12089     xmlParserCtxtPtr ctxt;
12090
12091     ctxt = xmlCreateFileParserCtxt(filename);
12092     if (ctxt == NULL) {
12093         return(NULL);
12094     }
12095     if (sax != NULL) {
12096         if (ctxt->sax != NULL)
12097             xmlFree(ctxt->sax);
12098         ctxt->sax = sax;
12099         ctxt->userData = NULL;
12100     }
12101
12102     xmlParseExtParsedEnt(ctxt);
12103
12104     if (ctxt->wellFormed)
12105         ret = ctxt->myDoc;
12106     else {
12107         ret = NULL;
12108         xmlFreeDoc(ctxt->myDoc);
12109         ctxt->myDoc = NULL;
12110     }
12111     if (sax != NULL)
12112         ctxt->sax = NULL;
12113     xmlFreeParserCtxt(ctxt);
12114     
12115     return(ret);
12116 }
12117
12118 /**
12119  * xmlParseEntity:
12120  * @filename:  the filename
12121  *
12122  * parse an XML external entity out of context and build a tree.
12123  *
12124  * [78] extParsedEnt ::= TextDecl? content
12125  *
12126  * This correspond to a "Well Balanced" chunk
12127  *
12128  * Returns the resulting document tree
12129  */
12130
12131 xmlDocPtr
12132 xmlParseEntity(const char *filename) {
12133     return(xmlSAXParseEntity(NULL, filename));
12134 }
12135 #endif /* LIBXML_SAX1_ENABLED */
12136
12137 /**
12138  * xmlCreateEntityParserCtxt:
12139  * @URL:  the entity URL
12140  * @ID:  the entity PUBLIC ID
12141  * @base:  a possible base for the target URI
12142  *
12143  * Create a parser context for an external entity
12144  * Automatic support for ZLIB/Compress compressed document is provided
12145  * by default if found at compile-time.
12146  *
12147  * Returns the new parser context or NULL
12148  */
12149 xmlParserCtxtPtr
12150 xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
12151                           const xmlChar *base) {
12152     xmlParserCtxtPtr ctxt;
12153     xmlParserInputPtr inputStream;
12154     char *directory = NULL;
12155     xmlChar *uri;
12156     
12157     ctxt = xmlNewParserCtxt();
12158     if (ctxt == NULL) {
12159         return(NULL);
12160     }
12161
12162     uri = xmlBuildURI(URL, base);
12163
12164     if (uri == NULL) {
12165         inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
12166         if (inputStream == NULL) {
12167             xmlFreeParserCtxt(ctxt);
12168             return(NULL);
12169         }
12170
12171         inputPush(ctxt, inputStream);
12172
12173         if ((ctxt->directory == NULL) && (directory == NULL))
12174             directory = xmlParserGetDirectory((char *)URL);
12175         if ((ctxt->directory == NULL) && (directory != NULL))
12176             ctxt->directory = directory;
12177     } else {
12178         inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
12179         if (inputStream == NULL) {
12180             xmlFree(uri);
12181             xmlFreeParserCtxt(ctxt);
12182             return(NULL);
12183         }
12184
12185         inputPush(ctxt, inputStream);
12186
12187         if ((ctxt->directory == NULL) && (directory == NULL))
12188             directory = xmlParserGetDirectory((char *)uri);
12189         if ((ctxt->directory == NULL) && (directory != NULL))
12190             ctxt->directory = directory;
12191         xmlFree(uri);
12192     }
12193     return(ctxt);
12194 }
12195
12196 /************************************************************************
12197  *                                                                      *
12198  *              Front ends when parsing from a file                     *
12199  *                                                                      *
12200  ************************************************************************/
12201
12202 /**
12203  * xmlCreateURLParserCtxt:
12204  * @filename:  the filename or URL
12205  * @options:  a combination of xmlParserOption
12206  *
12207  * Create a parser context for a file or URL content. 
12208  * Automatic support for ZLIB/Compress compressed document is provided
12209  * by default if found at compile-time and for file accesses
12210  *
12211  * Returns the new parser context or NULL
12212  */
12213 xmlParserCtxtPtr
12214 xmlCreateURLParserCtxt(const char *filename, int options)
12215 {
12216     xmlParserCtxtPtr ctxt;
12217     xmlParserInputPtr inputStream;
12218     char *directory = NULL;
12219
12220     ctxt = xmlNewParserCtxt();
12221     if (ctxt == NULL) {
12222         xmlErrMemory(NULL, "cannot allocate parser context");
12223         return(NULL);
12224     }
12225
12226     if (options)
12227         xmlCtxtUseOptions(ctxt, options);
12228     ctxt->linenumbers = 1;
12229     
12230     inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
12231     if (inputStream == NULL) {
12232         xmlFreeParserCtxt(ctxt);
12233         return(NULL);
12234     }
12235
12236     inputPush(ctxt, inputStream);
12237     if ((ctxt->directory == NULL) && (directory == NULL))
12238         directory = xmlParserGetDirectory(filename);
12239     if ((ctxt->directory == NULL) && (directory != NULL))
12240         ctxt->directory = directory;
12241
12242     return(ctxt);
12243 }
12244
12245 /**
12246  * xmlCreateFileParserCtxt:
12247  * @filename:  the filename
12248  *
12249  * Create a parser context for a file content. 
12250  * Automatic support for ZLIB/Compress compressed document is provided
12251  * by default if found at compile-time.
12252  *
12253  * Returns the new parser context or NULL
12254  */
12255 xmlParserCtxtPtr
12256 xmlCreateFileParserCtxt(const char *filename)
12257 {
12258     return(xmlCreateURLParserCtxt(filename, 0));
12259 }
12260
12261 #ifdef LIBXML_SAX1_ENABLED
12262 /**
12263  * xmlSAXParseFileWithData:
12264  * @sax:  the SAX handler block
12265  * @filename:  the filename
12266  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
12267  *             documents
12268  * @data:  the userdata
12269  *
12270  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
12271  * compressed document is provided by default if found at compile-time.
12272  * It use the given SAX function block to handle the parsing callback.
12273  * If sax is NULL, fallback to the default DOM tree building routines.
12274  *
12275  * User data (void *) is stored within the parser context in the
12276  * context's _private member, so it is available nearly everywhere in libxml
12277  *
12278  * Returns the resulting document tree
12279  */
12280
12281 xmlDocPtr
12282 xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
12283                         int recovery, void *data) {
12284     xmlDocPtr ret;
12285     xmlParserCtxtPtr ctxt;
12286     char *directory = NULL;
12287
12288     xmlInitParser();
12289
12290     ctxt = xmlCreateFileParserCtxt(filename);
12291     if (ctxt == NULL) {
12292         return(NULL);
12293     }
12294     if (sax != NULL) {
12295         if (ctxt->sax != NULL)
12296             xmlFree(ctxt->sax);
12297         ctxt->sax = sax;
12298     }
12299     xmlDetectSAX2(ctxt);
12300     if (data!=NULL) {
12301         ctxt->_private = data;
12302     }
12303
12304     if ((ctxt->directory == NULL) && (directory == NULL))
12305         directory = xmlParserGetDirectory(filename);
12306     if ((ctxt->directory == NULL) && (directory != NULL))
12307         ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
12308
12309     ctxt->recovery = recovery;
12310
12311     xmlParseDocument(ctxt);
12312
12313     if ((ctxt->wellFormed) || recovery) {
12314         ret = ctxt->myDoc;
12315         if (ret != NULL) {
12316             if (ctxt->input->buf->compressed > 0)
12317                 ret->compression = 9;
12318             else
12319                 ret->compression = ctxt->input->buf->compressed;
12320         }
12321     }
12322     else {
12323        ret = NULL;
12324        xmlFreeDoc(ctxt->myDoc);
12325        ctxt->myDoc = NULL;
12326     }
12327     if (sax != NULL)
12328         ctxt->sax = NULL;
12329     xmlFreeParserCtxt(ctxt);
12330     
12331     return(ret);
12332 }
12333
12334 /**
12335  * xmlSAXParseFile:
12336  * @sax:  the SAX handler block
12337  * @filename:  the filename
12338  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
12339  *             documents
12340  *
12341  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
12342  * compressed document is provided by default if found at compile-time.
12343  * It use the given SAX function block to handle the parsing callback.
12344  * If sax is NULL, fallback to the default DOM tree building routines.
12345  *
12346  * Returns the resulting document tree
12347  */
12348
12349 xmlDocPtr
12350 xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
12351                           int recovery) {
12352     return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
12353 }
12354
12355 /**
12356  * xmlRecoverDoc:
12357  * @cur:  a pointer to an array of xmlChar
12358  *
12359  * parse an XML in-memory document and build a tree.
12360  * In the case the document is not Well Formed, a tree is built anyway
12361  * 
12362  * Returns the resulting document tree
12363  */
12364
12365 xmlDocPtr
12366 xmlRecoverDoc(xmlChar *cur) {
12367     return(xmlSAXParseDoc(NULL, cur, 1));
12368 }
12369
12370 /**
12371  * xmlParseFile:
12372  * @filename:  the filename
12373  *
12374  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
12375  * compressed document is provided by default if found at compile-time.
12376  *
12377  * Returns the resulting document tree if the file was wellformed,
12378  * NULL otherwise.
12379  */
12380
12381 xmlDocPtr
12382 xmlParseFile(const char *filename) {
12383     return(xmlSAXParseFile(NULL, filename, 0));
12384 }
12385
12386 /**
12387  * xmlRecoverFile:
12388  * @filename:  the filename
12389  *
12390  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
12391  * compressed document is provided by default if found at compile-time.
12392  * In the case the document is not Well Formed, a tree is built anyway
12393  *
12394  * Returns the resulting document tree
12395  */
12396
12397 xmlDocPtr
12398 xmlRecoverFile(const char *filename) {
12399     return(xmlSAXParseFile(NULL, filename, 1));
12400 }
12401
12402
12403 /**
12404  * xmlSetupParserForBuffer:
12405  * @ctxt:  an XML parser context
12406  * @buffer:  a xmlChar * buffer
12407  * @filename:  a file name
12408  *
12409  * Setup the parser context to parse a new buffer; Clears any prior
12410  * contents from the parser context. The buffer parameter must not be
12411  * NULL, but the filename parameter can be
12412  */
12413 void
12414 xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
12415                              const char* filename)
12416 {
12417     xmlParserInputPtr input;
12418
12419     if ((ctxt == NULL) || (buffer == NULL))
12420         return;
12421
12422     input = xmlNewInputStream(ctxt);
12423     if (input == NULL) {
12424         xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
12425         xmlClearParserCtxt(ctxt);
12426         return;
12427     }
12428   
12429     xmlClearParserCtxt(ctxt);
12430     if (filename != NULL)
12431         input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
12432     input->base = buffer;
12433     input->cur = buffer;
12434     input->end = &buffer[xmlStrlen(buffer)];
12435     inputPush(ctxt, input);
12436 }
12437
12438 /**
12439  * xmlSAXUserParseFile:
12440  * @sax:  a SAX handler
12441  * @user_data:  The user data returned on SAX callbacks
12442  * @filename:  a file name
12443  *
12444  * parse an XML file and call the given SAX handler routines.
12445  * Automatic support for ZLIB/Compress compressed document is provided
12446  * 
12447  * Returns 0 in case of success or a error number otherwise
12448  */
12449 int
12450 xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
12451                     const char *filename) {
12452     int ret = 0;
12453     xmlParserCtxtPtr ctxt;
12454     
12455     ctxt = xmlCreateFileParserCtxt(filename);
12456     if (ctxt == NULL) return -1;
12457 #ifdef LIBXML_SAX1_ENABLED
12458     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12459 #endif /* LIBXML_SAX1_ENABLED */
12460         xmlFree(ctxt->sax);
12461     ctxt->sax = sax;
12462     xmlDetectSAX2(ctxt);
12463
12464     if (user_data != NULL)
12465         ctxt->userData = user_data;
12466     
12467     xmlParseDocument(ctxt);
12468     
12469     if (ctxt->wellFormed)
12470         ret = 0;
12471     else {
12472         if (ctxt->errNo != 0)
12473             ret = ctxt->errNo;
12474         else
12475             ret = -1;
12476     }
12477     if (sax != NULL)
12478         ctxt->sax = NULL;
12479     if (ctxt->myDoc != NULL) {
12480         xmlFreeDoc(ctxt->myDoc);
12481         ctxt->myDoc = NULL;
12482     }
12483     xmlFreeParserCtxt(ctxt);
12484     
12485     return ret;
12486 }
12487 #endif /* LIBXML_SAX1_ENABLED */
12488
12489 /************************************************************************
12490  *                                                                      *
12491  *              Front ends when parsing from memory                     *
12492  *                                                                      *
12493  ************************************************************************/
12494
12495 /**
12496  * xmlCreateMemoryParserCtxt:
12497  * @buffer:  a pointer to a char array
12498  * @size:  the size of the array
12499  *
12500  * Create a parser context for an XML in-memory document.
12501  *
12502  * Returns the new parser context or NULL
12503  */
12504 xmlParserCtxtPtr
12505 xmlCreateMemoryParserCtxt(const char *buffer, int size) {
12506     xmlParserCtxtPtr ctxt;
12507     xmlParserInputPtr input;
12508     xmlParserInputBufferPtr buf;
12509
12510     if (buffer == NULL)
12511         return(NULL);
12512     if (size <= 0)
12513         return(NULL);
12514
12515     ctxt = xmlNewParserCtxt();
12516     if (ctxt == NULL)
12517         return(NULL);
12518
12519     /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
12520     buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
12521     if (buf == NULL) {
12522         xmlFreeParserCtxt(ctxt);
12523         return(NULL);
12524     }
12525
12526     input = xmlNewInputStream(ctxt);
12527     if (input == NULL) {
12528         xmlFreeParserInputBuffer(buf);
12529         xmlFreeParserCtxt(ctxt);
12530         return(NULL);
12531     }
12532
12533     input->filename = NULL;
12534     input->buf = buf;
12535     input->base = input->buf->buffer->content;
12536     input->cur = input->buf->buffer->content;
12537     input->end = &input->buf->buffer->content[input->buf->buffer->use];
12538
12539     inputPush(ctxt, input);
12540     return(ctxt);
12541 }
12542
12543 #ifdef LIBXML_SAX1_ENABLED
12544 /**
12545  * xmlSAXParseMemoryWithData:
12546  * @sax:  the SAX handler block
12547  * @buffer:  an pointer to a char array
12548  * @size:  the size of the array
12549  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
12550  *             documents
12551  * @data:  the userdata
12552  *
12553  * parse an XML in-memory block and use the given SAX function block
12554  * to handle the parsing callback. If sax is NULL, fallback to the default
12555  * DOM tree building routines.
12556  *
12557  * User data (void *) is stored within the parser context in the
12558  * context's _private member, so it is available nearly everywhere in libxml
12559  *
12560  * Returns the resulting document tree
12561  */
12562
12563 xmlDocPtr
12564 xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
12565                   int size, int recovery, void *data) {
12566     xmlDocPtr ret;
12567     xmlParserCtxtPtr ctxt;
12568
12569     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
12570     if (ctxt == NULL) return(NULL);
12571     if (sax != NULL) {
12572         if (ctxt->sax != NULL)
12573             xmlFree(ctxt->sax);
12574         ctxt->sax = sax;
12575     }
12576     xmlDetectSAX2(ctxt);
12577     if (data!=NULL) {
12578         ctxt->_private=data;
12579     }
12580
12581     ctxt->recovery = recovery;
12582
12583     xmlParseDocument(ctxt);
12584
12585     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
12586     else {
12587        ret = NULL;
12588        xmlFreeDoc(ctxt->myDoc);
12589        ctxt->myDoc = NULL;
12590     }
12591     if (sax != NULL) 
12592         ctxt->sax = NULL;
12593     xmlFreeParserCtxt(ctxt);
12594     
12595     return(ret);
12596 }
12597
12598 /**
12599  * xmlSAXParseMemory:
12600  * @sax:  the SAX handler block
12601  * @buffer:  an pointer to a char array
12602  * @size:  the size of the array
12603  * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
12604  *             documents
12605  *
12606  * parse an XML in-memory block and use the given SAX function block
12607  * to handle the parsing callback. If sax is NULL, fallback to the default
12608  * DOM tree building routines.
12609  * 
12610  * Returns the resulting document tree
12611  */
12612 xmlDocPtr
12613 xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
12614                   int size, int recovery) {
12615     return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
12616 }
12617
12618 /**
12619  * xmlParseMemory:
12620  * @buffer:  an pointer to a char array
12621  * @size:  the size of the array
12622  *
12623  * parse an XML in-memory block and build a tree.
12624  * 
12625  * Returns the resulting document tree
12626  */
12627
12628 xmlDocPtr xmlParseMemory(const char *buffer, int size) {
12629    return(xmlSAXParseMemory(NULL, buffer, size, 0));
12630 }
12631
12632 /**
12633  * xmlRecoverMemory:
12634  * @buffer:  an pointer to a char array
12635  * @size:  the size of the array
12636  *
12637  * parse an XML in-memory block and build a tree.
12638  * In the case the document is not Well Formed, a tree is built anyway
12639  * 
12640  * Returns the resulting document tree
12641  */
12642
12643 xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
12644    return(xmlSAXParseMemory(NULL, buffer, size, 1));
12645 }
12646
12647 /**
12648  * xmlSAXUserParseMemory:
12649  * @sax:  a SAX handler
12650  * @user_data:  The user data returned on SAX callbacks
12651  * @buffer:  an in-memory XML document input
12652  * @size:  the length of the XML document in bytes
12653  *
12654  * A better SAX parsing routine.
12655  * parse an XML in-memory buffer and call the given SAX handler routines.
12656  * 
12657  * Returns 0 in case of success or a error number otherwise
12658  */
12659 int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
12660                           const char *buffer, int size) {
12661     int ret = 0;
12662     xmlParserCtxtPtr ctxt;
12663     xmlSAXHandlerPtr oldsax = NULL;
12664     
12665     if (sax == NULL) return -1;
12666     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
12667     if (ctxt == NULL) return -1;
12668     oldsax = ctxt->sax;
12669     ctxt->sax = sax;
12670     xmlDetectSAX2(ctxt);
12671     if (user_data != NULL)
12672         ctxt->userData = user_data;
12673     
12674     xmlParseDocument(ctxt);
12675     
12676     if (ctxt->wellFormed)
12677         ret = 0;
12678     else {
12679         if (ctxt->errNo != 0)
12680             ret = ctxt->errNo;
12681         else
12682             ret = -1;
12683     }
12684     ctxt->sax = oldsax;
12685     if (ctxt->myDoc != NULL) {
12686         xmlFreeDoc(ctxt->myDoc);
12687         ctxt->myDoc = NULL;
12688     }
12689     xmlFreeParserCtxt(ctxt);
12690     
12691     return ret;
12692 }
12693 #endif /* LIBXML_SAX1_ENABLED */
12694
12695 /**
12696  * xmlCreateDocParserCtxt:
12697  * @cur:  a pointer to an array of xmlChar
12698  *
12699  * Creates a parser context for an XML in-memory document.
12700  *
12701  * Returns the new parser context or NULL
12702  */
12703 xmlParserCtxtPtr
12704 xmlCreateDocParserCtxt(const xmlChar *cur) {
12705     int len;
12706
12707     if (cur == NULL)
12708         return(NULL);
12709     len = xmlStrlen(cur);
12710     return(xmlCreateMemoryParserCtxt((const char *)cur, len));
12711 }
12712
12713 #ifdef LIBXML_SAX1_ENABLED
12714 /**
12715  * xmlSAXParseDoc:
12716  * @sax:  the SAX handler block
12717  * @cur:  a pointer to an array of xmlChar
12718  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
12719  *             documents
12720  *
12721  * parse an XML in-memory document and build a tree.
12722  * It use the given SAX function block to handle the parsing callback.
12723  * If sax is NULL, fallback to the default DOM tree building routines.
12724  * 
12725  * Returns the resulting document tree
12726  */
12727
12728 xmlDocPtr
12729 xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
12730     xmlDocPtr ret;
12731     xmlParserCtxtPtr ctxt;
12732     xmlSAXHandlerPtr oldsax = NULL;
12733
12734     if (cur == NULL) return(NULL);
12735
12736
12737     ctxt = xmlCreateDocParserCtxt(cur);
12738     if (ctxt == NULL) return(NULL);
12739     if (sax != NULL) { 
12740         oldsax = ctxt->sax;
12741         ctxt->sax = sax;
12742         ctxt->userData = NULL;
12743     }
12744     xmlDetectSAX2(ctxt);
12745
12746     xmlParseDocument(ctxt);
12747     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
12748     else {
12749        ret = NULL;
12750        xmlFreeDoc(ctxt->myDoc);
12751        ctxt->myDoc = NULL;
12752     }
12753     if (sax != NULL)
12754         ctxt->sax = oldsax;
12755     xmlFreeParserCtxt(ctxt);
12756     
12757     return(ret);
12758 }
12759
12760 /**
12761  * xmlParseDoc:
12762  * @cur:  a pointer to an array of xmlChar
12763  *
12764  * parse an XML in-memory document and build a tree.
12765  * 
12766  * Returns the resulting document tree
12767  */
12768
12769 xmlDocPtr
12770 xmlParseDoc(const xmlChar *cur) {
12771     return(xmlSAXParseDoc(NULL, cur, 0));
12772 }
12773 #endif /* LIBXML_SAX1_ENABLED */
12774
12775 #ifdef LIBXML_LEGACY_ENABLED
12776 /************************************************************************
12777  *                                                                      *
12778  *      Specific function to keep track of entities references          *
12779  *      and used by the XSLT debugger                                   *
12780  *                                                                      *
12781  ************************************************************************/
12782
12783 static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
12784
12785 /**
12786  * xmlAddEntityReference:
12787  * @ent : A valid entity
12788  * @firstNode : A valid first node for children of entity
12789  * @lastNode : A valid last node of children entity 
12790  *
12791  * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
12792  */
12793 static void
12794 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
12795                       xmlNodePtr lastNode)
12796 {
12797     if (xmlEntityRefFunc != NULL) {
12798         (*xmlEntityRefFunc) (ent, firstNode, lastNode);
12799     }
12800 }
12801
12802
12803 /**
12804  * xmlSetEntityReferenceFunc:
12805  * @func: A valid function
12806  *
12807  * Set the function to call call back when a xml reference has been made
12808  */
12809 void
12810 xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
12811 {
12812     xmlEntityRefFunc = func;
12813 }
12814 #endif /* LIBXML_LEGACY_ENABLED */
12815
12816 /************************************************************************
12817  *                                                                      *
12818  *                              Miscellaneous                           *
12819  *                                                                      *
12820  ************************************************************************/
12821
12822 #ifdef LIBXML_XPATH_ENABLED
12823 #include <libxml/xpath.h>
12824 #endif
12825
12826 extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
12827 static int xmlParserInitialized = 0;
12828
12829 /**
12830  * xmlInitParser:
12831  *
12832  * Initialization function for the XML parser.
12833  * This is not reentrant. Call once before processing in case of
12834  * use in multithreaded programs.
12835  */
12836
12837 void
12838 xmlInitParser(void) {
12839     if (xmlParserInitialized != 0)
12840         return;
12841
12842     if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
12843         (xmlGenericError == NULL))
12844         initGenericErrorDefaultFunc(NULL);
12845     xmlInitGlobals();
12846     xmlInitThreads();
12847     xmlInitMemory();
12848     xmlInitCharEncodingHandlers();
12849     xmlDefaultSAXHandlerInit();
12850     xmlRegisterDefaultInputCallbacks();
12851 #ifdef LIBXML_OUTPUT_ENABLED
12852     xmlRegisterDefaultOutputCallbacks();
12853 #endif /* LIBXML_OUTPUT_ENABLED */
12854 #ifdef LIBXML_HTML_ENABLED
12855     htmlInitAutoClose();
12856     htmlDefaultSAXHandlerInit();
12857 #endif
12858 #ifdef LIBXML_XPATH_ENABLED
12859     xmlXPathInit();
12860 #endif
12861     xmlParserInitialized = 1;
12862 }
12863
12864 /**
12865  * xmlCleanupParser:
12866  *
12867  * Cleanup function for the XML library. It tries to reclaim all
12868  * parsing related global memory allocated for the library processing.
12869  * It doesn't deallocate any document related memory. Calling this
12870  * function should not prevent reusing the library but one should
12871  * call xmlCleanupParser() only when the process has
12872  * finished using the library or XML document built with it.
12873  */
12874
12875 void
12876 xmlCleanupParser(void) {
12877     if (!xmlParserInitialized)
12878         return;
12879
12880     xmlCleanupCharEncodingHandlers();
12881 #ifdef LIBXML_CATALOG_ENABLED
12882     xmlCatalogCleanup();
12883 #endif
12884     xmlDictCleanup();
12885     xmlCleanupInputCallbacks();
12886 #ifdef LIBXML_OUTPUT_ENABLED
12887     xmlCleanupOutputCallbacks();
12888 #endif
12889 #ifdef LIBXML_SCHEMAS_ENABLED
12890     xmlSchemaCleanupTypes();
12891     xmlRelaxNGCleanupTypes();
12892 #endif
12893     xmlCleanupGlobals();
12894     xmlResetLastError();
12895     xmlCleanupThreads(); /* must be last if called not from the main thread */
12896     xmlCleanupMemory();
12897     xmlParserInitialized = 0;
12898 }
12899
12900 /************************************************************************
12901  *                                                                      *
12902  *      New set (2.6.0) of simpler and more flexible APIs               *
12903  *                                                                      *
12904  ************************************************************************/
12905
12906 /**
12907  * DICT_FREE:
12908  * @str:  a string
12909  *
12910  * Free a string if it is not owned by the "dict" dictionnary in the
12911  * current scope
12912  */
12913 #define DICT_FREE(str)                                          \
12914         if ((str) && ((!dict) ||                                \
12915             (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
12916             xmlFree((char *)(str));
12917
12918 /**
12919  * xmlCtxtReset:
12920  * @ctxt: an XML parser context
12921  *
12922  * Reset a parser context
12923  */
12924 void
12925 xmlCtxtReset(xmlParserCtxtPtr ctxt)
12926 {
12927     xmlParserInputPtr input;
12928     xmlDictPtr dict;
12929     
12930     if (ctxt == NULL)
12931         return;
12932
12933     dict = ctxt->dict;
12934
12935     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
12936         xmlFreeInputStream(input);
12937     }
12938     ctxt->inputNr = 0;
12939     ctxt->input = NULL;
12940
12941     ctxt->spaceNr = 0;
12942     ctxt->spaceTab[0] = -1;
12943     ctxt->space = &ctxt->spaceTab[0];
12944
12945
12946     ctxt->nodeNr = 0;
12947     ctxt->node = NULL;
12948
12949     ctxt->nameNr = 0;
12950     ctxt->name = NULL;
12951
12952     DICT_FREE(ctxt->version);
12953     ctxt->version = NULL;
12954     DICT_FREE(ctxt->encoding);
12955     ctxt->encoding = NULL;
12956     DICT_FREE(ctxt->directory);
12957     ctxt->directory = NULL;
12958     DICT_FREE(ctxt->extSubURI);
12959     ctxt->extSubURI = NULL;
12960     DICT_FREE(ctxt->extSubSystem);
12961     ctxt->extSubSystem = NULL;
12962     if (ctxt->myDoc != NULL)
12963         xmlFreeDoc(ctxt->myDoc);
12964     ctxt->myDoc = NULL;
12965
12966     ctxt->standalone = -1;
12967     ctxt->hasExternalSubset = 0;
12968     ctxt->hasPErefs = 0;
12969     ctxt->html = 0;
12970     ctxt->external = 0;
12971     ctxt->instate = XML_PARSER_START;
12972     ctxt->token = 0;
12973
12974     ctxt->wellFormed = 1;
12975     ctxt->nsWellFormed = 1;
12976     ctxt->disableSAX = 0;
12977     ctxt->valid = 1;
12978 #if 0
12979     ctxt->vctxt.userData = ctxt;
12980     ctxt->vctxt.error = xmlParserValidityError;
12981     ctxt->vctxt.warning = xmlParserValidityWarning;
12982 #endif
12983     ctxt->record_info = 0;
12984     ctxt->nbChars = 0;
12985     ctxt->checkIndex = 0;
12986     ctxt->inSubset = 0;
12987     ctxt->errNo = XML_ERR_OK;
12988     ctxt->depth = 0;
12989     ctxt->charset = XML_CHAR_ENCODING_UTF8;
12990     ctxt->catalogs = NULL;
12991     xmlInitNodeInfoSeq(&ctxt->node_seq);
12992
12993     if (ctxt->attsDefault != NULL) {
12994         xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
12995         ctxt->attsDefault = NULL;
12996     }
12997     if (ctxt->attsSpecial != NULL) {
12998         xmlHashFree(ctxt->attsSpecial, NULL);
12999         ctxt->attsSpecial = NULL;
13000     }
13001
13002 #ifdef LIBXML_CATALOG_ENABLED
13003     if (ctxt->catalogs != NULL)
13004         xmlCatalogFreeLocal(ctxt->catalogs);
13005 #endif
13006     if (ctxt->lastError.code != XML_ERR_OK)
13007         xmlResetError(&ctxt->lastError);
13008 }
13009
13010 /**
13011  * xmlCtxtResetPush:
13012  * @ctxt: an XML parser context
13013  * @chunk:  a pointer to an array of chars
13014  * @size:  number of chars in the array
13015  * @filename:  an optional file name or URI
13016  * @encoding:  the document encoding, or NULL
13017  *
13018  * Reset a push parser context
13019  *
13020  * Returns 0 in case of success and 1 in case of error
13021  */
13022 int
13023 xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
13024                  int size, const char *filename, const char *encoding)
13025 {
13026     xmlParserInputPtr inputStream;
13027     xmlParserInputBufferPtr buf;
13028     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
13029
13030     if (ctxt == NULL)
13031         return(1);
13032
13033     if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
13034         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
13035
13036     buf = xmlAllocParserInputBuffer(enc);
13037     if (buf == NULL)
13038         return(1);
13039
13040     if (ctxt == NULL) {
13041         xmlFreeParserInputBuffer(buf);
13042         return(1);
13043     }
13044
13045     xmlCtxtReset(ctxt);
13046
13047     if (ctxt->pushTab == NULL) {
13048         ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
13049                                             sizeof(xmlChar *));
13050         if (ctxt->pushTab == NULL) {
13051             xmlErrMemory(ctxt, NULL);
13052             xmlFreeParserInputBuffer(buf);
13053             return(1);
13054         }
13055     }
13056
13057     if (filename == NULL) {
13058         ctxt->directory = NULL;
13059     } else {
13060         ctxt->directory = xmlParserGetDirectory(filename);
13061     }
13062
13063     inputStream = xmlNewInputStream(ctxt);
13064     if (inputStream == NULL) {
13065         xmlFreeParserInputBuffer(buf);
13066         return(1);
13067     }
13068
13069     if (filename == NULL)
13070         inputStream->filename = NULL;
13071     else
13072         inputStream->filename = (char *)
13073             xmlCanonicPath((const xmlChar *) filename);
13074     inputStream->buf = buf;
13075     inputStream->base = inputStream->buf->buffer->content;
13076     inputStream->cur = inputStream->buf->buffer->content;
13077     inputStream->end =
13078         &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
13079
13080     inputPush(ctxt, inputStream);
13081
13082     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
13083         (ctxt->input->buf != NULL)) {
13084         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
13085         int cur = ctxt->input->cur - ctxt->input->base;
13086
13087         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
13088
13089         ctxt->input->base = ctxt->input->buf->buffer->content + base;
13090         ctxt->input->cur = ctxt->input->base + cur;
13091         ctxt->input->end =
13092             &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->
13093                                                use];
13094 #ifdef DEBUG_PUSH
13095         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
13096 #endif
13097     }
13098
13099     if (encoding != NULL) {
13100         xmlCharEncodingHandlerPtr hdlr;
13101
13102         hdlr = xmlFindCharEncodingHandler(encoding);
13103         if (hdlr != NULL) {
13104             xmlSwitchToEncoding(ctxt, hdlr);
13105         } else {
13106             xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
13107                               "Unsupported encoding %s\n", BAD_CAST encoding);
13108         }
13109     } else if (enc != XML_CHAR_ENCODING_NONE) {
13110         xmlSwitchEncoding(ctxt, enc);
13111     }
13112
13113     return(0);
13114 }
13115
13116 /**
13117  * xmlCtxtUseOptions:
13118  * @ctxt: an XML parser context
13119  * @options:  a combination of xmlParserOption
13120  *
13121  * Applies the options to the parser context
13122  *
13123  * Returns 0 in case of success, the set of unknown or unimplemented options
13124  *         in case of error.
13125  */
13126 int
13127 xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
13128 {
13129     if (ctxt == NULL)
13130         return(-1);
13131     if (options & XML_PARSE_RECOVER) {
13132         ctxt->recovery = 1;
13133         options -= XML_PARSE_RECOVER;
13134     } else
13135         ctxt->recovery = 0;
13136     if (options & XML_PARSE_DTDLOAD) {
13137         ctxt->loadsubset = XML_DETECT_IDS;
13138         options -= XML_PARSE_DTDLOAD;
13139     } else
13140         ctxt->loadsubset = 0;
13141     if (options & XML_PARSE_DTDATTR) {
13142         ctxt->loadsubset |= XML_COMPLETE_ATTRS;
13143         options -= XML_PARSE_DTDATTR;
13144     }
13145     if (options & XML_PARSE_NOENT) {
13146         ctxt->replaceEntities = 1;
13147         /* ctxt->loadsubset |= XML_DETECT_IDS; */
13148         options -= XML_PARSE_NOENT;
13149     } else
13150         ctxt->replaceEntities = 0;
13151     if (options & XML_PARSE_PEDANTIC) {
13152         ctxt->pedantic = 1;
13153         options -= XML_PARSE_PEDANTIC;
13154     } else
13155         ctxt->pedantic = 0;
13156     if (options & XML_PARSE_NOBLANKS) {
13157         ctxt->keepBlanks = 0;
13158         ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
13159         options -= XML_PARSE_NOBLANKS;
13160     } else
13161         ctxt->keepBlanks = 1;
13162     if (options & XML_PARSE_DTDVALID) {
13163         ctxt->validate = 1;
13164         if (options & XML_PARSE_NOWARNING)
13165             ctxt->vctxt.warning = NULL;
13166         if (options & XML_PARSE_NOERROR)
13167             ctxt->vctxt.error = NULL;
13168         options -= XML_PARSE_DTDVALID;
13169     } else
13170         ctxt->validate = 0;
13171     if (options & XML_PARSE_NOWARNING) {
13172         ctxt->sax->warning = NULL;
13173         options -= XML_PARSE_NOWARNING;
13174     }
13175     if (options & XML_PARSE_NOERROR) {
13176         ctxt->sax->error = NULL;
13177         ctxt->sax->fatalError = NULL;
13178         options -= XML_PARSE_NOERROR;
13179     }
13180 #ifdef LIBXML_SAX1_ENABLED
13181     if (options & XML_PARSE_SAX1) {
13182         ctxt->sax->startElement = xmlSAX2StartElement;
13183         ctxt->sax->endElement = xmlSAX2EndElement;
13184         ctxt->sax->startElementNs = NULL;
13185         ctxt->sax->endElementNs = NULL;
13186         ctxt->sax->initialized = 1;
13187         options -= XML_PARSE_SAX1;
13188     }
13189 #endif /* LIBXML_SAX1_ENABLED */
13190     if (options & XML_PARSE_NODICT) {
13191         ctxt->dictNames = 0;
13192         options -= XML_PARSE_NODICT;
13193     } else {
13194         ctxt->dictNames = 1;
13195     }
13196     if (options & XML_PARSE_NOCDATA) {
13197         ctxt->sax->cdataBlock = NULL;
13198         options -= XML_PARSE_NOCDATA;
13199     }
13200     if (options & XML_PARSE_NSCLEAN) {
13201         ctxt->options |= XML_PARSE_NSCLEAN;
13202         options -= XML_PARSE_NSCLEAN;
13203     }
13204     if (options & XML_PARSE_NONET) {
13205         ctxt->options |= XML_PARSE_NONET;
13206         options -= XML_PARSE_NONET;
13207     }
13208     if (options & XML_PARSE_COMPACT) {
13209         ctxt->options |= XML_PARSE_COMPACT;
13210         options -= XML_PARSE_COMPACT;
13211     }
13212     ctxt->linenumbers = 1;
13213     return (options);
13214 }
13215
13216 /**
13217  * xmlDoRead:
13218  * @ctxt:  an XML parser context
13219  * @URL:  the base URL to use for the document
13220  * @encoding:  the document encoding, or NULL
13221  * @options:  a combination of xmlParserOption
13222  * @reuse:  keep the context for reuse
13223  *
13224  * Common front-end for the xmlRead functions
13225  * 
13226  * Returns the resulting document tree or NULL
13227  */
13228 static xmlDocPtr
13229 xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
13230           int options, int reuse)
13231 {
13232     xmlDocPtr ret;
13233     
13234     xmlCtxtUseOptions(ctxt, options);
13235     if (encoding != NULL) {
13236         xmlCharEncodingHandlerPtr hdlr;
13237
13238         hdlr = xmlFindCharEncodingHandler(encoding);
13239         if (hdlr != NULL)
13240             xmlSwitchToEncoding(ctxt, hdlr);
13241     }
13242     if ((URL != NULL) && (ctxt->input != NULL) &&
13243         (ctxt->input->filename == NULL))
13244         ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
13245     xmlParseDocument(ctxt);
13246     if ((ctxt->wellFormed) || ctxt->recovery)
13247         ret = ctxt->myDoc;
13248     else {
13249         ret = NULL;
13250         if (ctxt->myDoc != NULL) {
13251             xmlFreeDoc(ctxt->myDoc);
13252         }
13253     }
13254     ctxt->myDoc = NULL;
13255     if (!reuse) {
13256         xmlFreeParserCtxt(ctxt);
13257     }
13258
13259     return (ret);
13260 }
13261
13262 /**
13263  * xmlReadDoc:
13264  * @cur:  a pointer to a zero terminated string
13265  * @URL:  the base URL to use for the document
13266  * @encoding:  the document encoding, or NULL
13267  * @options:  a combination of xmlParserOption
13268  *
13269  * parse an XML in-memory document and build a tree.
13270  * 
13271  * Returns the resulting document tree
13272  */
13273 xmlDocPtr
13274 xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
13275 {
13276     xmlParserCtxtPtr ctxt;
13277
13278     if (cur == NULL)
13279         return (NULL);
13280
13281     ctxt = xmlCreateDocParserCtxt(cur);
13282     if (ctxt == NULL)
13283         return (NULL);
13284     return (xmlDoRead(ctxt, URL, encoding, options, 0));
13285 }
13286
13287 /**
13288  * xmlReadFile:
13289  * @filename:  a file or URL
13290  * @encoding:  the document encoding, or NULL
13291  * @options:  a combination of xmlParserOption
13292  *
13293  * parse an XML file from the filesystem or the network.
13294  * 
13295  * Returns the resulting document tree
13296  */
13297 xmlDocPtr
13298 xmlReadFile(const char *filename, const char *encoding, int options)
13299 {
13300     xmlParserCtxtPtr ctxt;
13301
13302     ctxt = xmlCreateURLParserCtxt(filename, options);
13303     if (ctxt == NULL)
13304         return (NULL);
13305     return (xmlDoRead(ctxt, NULL, encoding, options, 0));
13306 }
13307
13308 /**
13309  * xmlReadMemory:
13310  * @buffer:  a pointer to a char array
13311  * @size:  the size of the array
13312  * @URL:  the base URL to use for the document
13313  * @encoding:  the document encoding, or NULL
13314  * @options:  a combination of xmlParserOption
13315  *
13316  * parse an XML in-memory document and build a tree.
13317  * 
13318  * Returns the resulting document tree
13319  */
13320 xmlDocPtr
13321 xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
13322 {
13323     xmlParserCtxtPtr ctxt;
13324
13325     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
13326     if (ctxt == NULL)
13327         return (NULL);
13328     return (xmlDoRead(ctxt, URL, encoding, options, 0));
13329 }
13330
13331 /**
13332  * xmlReadFd:
13333  * @fd:  an open file descriptor
13334  * @URL:  the base URL to use for the document
13335  * @encoding:  the document encoding, or NULL
13336  * @options:  a combination of xmlParserOption
13337  *
13338  * parse an XML from a file descriptor and build a tree.
13339  * NOTE that the file descriptor will not be closed when the
13340  *      reader is closed or reset.
13341  * 
13342  * Returns the resulting document tree
13343  */
13344 xmlDocPtr
13345 xmlReadFd(int fd, const char *URL, const char *encoding, int options)
13346 {
13347     xmlParserCtxtPtr ctxt;
13348     xmlParserInputBufferPtr input;
13349     xmlParserInputPtr stream;
13350
13351     if (fd < 0)
13352         return (NULL);
13353
13354     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
13355     if (input == NULL)
13356         return (NULL);
13357     input->closecallback = NULL;
13358     ctxt = xmlNewParserCtxt();
13359     if (ctxt == NULL) {
13360         xmlFreeParserInputBuffer(input);
13361         return (NULL);
13362     }
13363     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
13364     if (stream == NULL) {
13365         xmlFreeParserInputBuffer(input);
13366         xmlFreeParserCtxt(ctxt);
13367         return (NULL);
13368     }
13369     inputPush(ctxt, stream);
13370     return (xmlDoRead(ctxt, URL, encoding, options, 0));
13371 }
13372
13373 /**
13374  * xmlReadIO:
13375  * @ioread:  an I/O read function
13376  * @ioclose:  an I/O close function
13377  * @ioctx:  an I/O handler
13378  * @URL:  the base URL to use for the document
13379  * @encoding:  the document encoding, or NULL
13380  * @options:  a combination of xmlParserOption
13381  *
13382  * parse an XML document from I/O functions and source and build a tree.
13383  * 
13384  * Returns the resulting document tree
13385  */
13386 xmlDocPtr
13387 xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
13388           void *ioctx, const char *URL, const char *encoding, int options)
13389 {
13390     xmlParserCtxtPtr ctxt;
13391     xmlParserInputBufferPtr input;
13392     xmlParserInputPtr stream;
13393
13394     if (ioread == NULL)
13395         return (NULL);
13396
13397     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
13398                                          XML_CHAR_ENCODING_NONE);
13399     if (input == NULL)
13400         return (NULL);
13401     ctxt = xmlNewParserCtxt();
13402     if (ctxt == NULL) {
13403         xmlFreeParserInputBuffer(input);
13404         return (NULL);
13405     }
13406     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
13407     if (stream == NULL) {
13408         xmlFreeParserInputBuffer(input);
13409         xmlFreeParserCtxt(ctxt);
13410         return (NULL);
13411     }
13412     inputPush(ctxt, stream);
13413     return (xmlDoRead(ctxt, URL, encoding, options, 0));
13414 }
13415
13416 /**
13417  * xmlCtxtReadDoc:
13418  * @ctxt:  an XML parser context
13419  * @cur:  a pointer to a zero terminated string
13420  * @URL:  the base URL to use for the document
13421  * @encoding:  the document encoding, or NULL
13422  * @options:  a combination of xmlParserOption
13423  *
13424  * parse an XML in-memory document and build a tree.
13425  * This reuses the existing @ctxt parser context
13426  * 
13427  * Returns the resulting document tree
13428  */
13429 xmlDocPtr
13430 xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
13431                const char *URL, const char *encoding, int options)
13432 {
13433     xmlParserInputPtr stream;
13434
13435     if (cur == NULL)
13436         return (NULL);
13437     if (ctxt == NULL)
13438         return (NULL);
13439
13440     xmlCtxtReset(ctxt);
13441
13442     stream = xmlNewStringInputStream(ctxt, cur);
13443     if (stream == NULL) {
13444         return (NULL);
13445     }
13446     inputPush(ctxt, stream);
13447     return (xmlDoRead(ctxt, URL, encoding, options, 1));
13448 }
13449
13450 /**
13451  * xmlCtxtReadFile:
13452  * @ctxt:  an XML parser context
13453  * @filename:  a file or URL
13454  * @encoding:  the document encoding, or NULL
13455  * @options:  a combination of xmlParserOption
13456  *
13457  * parse an XML file from the filesystem or the network.
13458  * This reuses the existing @ctxt parser context
13459  * 
13460  * Returns the resulting document tree
13461  */
13462 xmlDocPtr
13463 xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
13464                 const char *encoding, int options)
13465 {
13466     xmlParserInputPtr stream;
13467
13468     if (filename == NULL)
13469         return (NULL);
13470     if (ctxt == NULL)
13471         return (NULL);
13472
13473     xmlCtxtReset(ctxt);
13474
13475     stream = xmlLoadExternalEntity(filename, NULL, ctxt);
13476     if (stream == NULL) {
13477         return (NULL);
13478     }
13479     inputPush(ctxt, stream);
13480     return (xmlDoRead(ctxt, NULL, encoding, options, 1));
13481 }
13482
13483 /**
13484  * xmlCtxtReadMemory:
13485  * @ctxt:  an XML parser context
13486  * @buffer:  a pointer to a char array
13487  * @size:  the size of the array
13488  * @URL:  the base URL to use for the document
13489  * @encoding:  the document encoding, or NULL
13490  * @options:  a combination of xmlParserOption
13491  *
13492  * parse an XML in-memory document and build a tree.
13493  * This reuses the existing @ctxt parser context
13494  * 
13495  * Returns the resulting document tree
13496  */
13497 xmlDocPtr
13498 xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
13499                   const char *URL, const char *encoding, int options)
13500 {
13501     xmlParserInputBufferPtr input;
13502     xmlParserInputPtr stream;
13503
13504     if (ctxt == NULL)
13505         return (NULL);
13506     if (buffer == NULL)
13507         return (NULL);
13508
13509     xmlCtxtReset(ctxt);
13510
13511     input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
13512     if (input == NULL) {
13513         return(NULL);
13514     }
13515
13516     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
13517     if (stream == NULL) {
13518         xmlFreeParserInputBuffer(input);
13519         return(NULL);
13520     }
13521
13522     inputPush(ctxt, stream);
13523     return (xmlDoRead(ctxt, URL, encoding, options, 1));
13524 }
13525
13526 /**
13527  * xmlCtxtReadFd:
13528  * @ctxt:  an XML parser context
13529  * @fd:  an open file descriptor
13530  * @URL:  the base URL to use for the document
13531  * @encoding:  the document encoding, or NULL
13532  * @options:  a combination of xmlParserOption
13533  *
13534  * parse an XML from a file descriptor and build a tree.
13535  * This reuses the existing @ctxt parser context
13536  * NOTE that the file descriptor will not be closed when the
13537  *      reader is closed or reset.
13538  * 
13539  * Returns the resulting document tree
13540  */
13541 xmlDocPtr
13542 xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
13543               const char *URL, const char *encoding, int options)
13544 {
13545     xmlParserInputBufferPtr input;
13546     xmlParserInputPtr stream;
13547
13548     if (fd < 0)
13549         return (NULL);
13550     if (ctxt == NULL)
13551         return (NULL);
13552
13553     xmlCtxtReset(ctxt);
13554
13555
13556     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
13557     if (input == NULL)
13558         return (NULL);
13559     input->closecallback = NULL;
13560     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
13561     if (stream == NULL) {
13562         xmlFreeParserInputBuffer(input);
13563         return (NULL);
13564     }
13565     inputPush(ctxt, stream);
13566     return (xmlDoRead(ctxt, URL, encoding, options, 1));
13567 }
13568
13569 /**
13570  * xmlCtxtReadIO:
13571  * @ctxt:  an XML parser context
13572  * @ioread:  an I/O read function
13573  * @ioclose:  an I/O close function
13574  * @ioctx:  an I/O handler
13575  * @URL:  the base URL to use for the document
13576  * @encoding:  the document encoding, or NULL
13577  * @options:  a combination of xmlParserOption
13578  *
13579  * parse an XML document from I/O functions and source and build a tree.
13580  * This reuses the existing @ctxt parser context
13581  * 
13582  * Returns the resulting document tree
13583  */
13584 xmlDocPtr
13585 xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
13586               xmlInputCloseCallback ioclose, void *ioctx,
13587               const char *URL,
13588               const char *encoding, int options)
13589 {
13590     xmlParserInputBufferPtr input;
13591     xmlParserInputPtr stream;
13592
13593     if (ioread == NULL)
13594         return (NULL);
13595     if (ctxt == NULL)
13596         return (NULL);
13597
13598     xmlCtxtReset(ctxt);
13599
13600     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
13601                                          XML_CHAR_ENCODING_NONE);
13602     if (input == NULL)
13603         return (NULL);
13604     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
13605     if (stream == NULL) {
13606         xmlFreeParserInputBuffer(input);
13607         return (NULL);
13608     }
13609     inputPush(ctxt, stream);
13610     return (xmlDoRead(ctxt, URL, encoding, options, 1));
13611 }
13612
13613 #define bottom_parser
13614 #include "elfgcchack.h"