- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / libxml / src / 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 static void
84 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
85
86 static xmlParserCtxtPtr
87 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
88                           const xmlChar *base, xmlParserCtxtPtr pctx);
89
90 /************************************************************************
91  *                                                                      *
92  *      Arbitrary limits set in the parser. See XML_PARSE_HUGE          *
93  *                                                                      *
94  ************************************************************************/
95
96 #define XML_PARSER_BIG_ENTITY 1000
97 #define XML_PARSER_LOT_ENTITY 5000
98
99 /*
100  * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
101  *    replacement over the size in byte of the input indicates that you have
102  *    and eponential behaviour. A value of 10 correspond to at least 3 entity
103  *    replacement per byte of input.
104  */
105 #define XML_PARSER_NON_LINEAR 10
106
107 /*
108  * xmlParserEntityCheck
109  *
110  * Function to check non-linear entity expansion behaviour
111  * This is here to detect and stop exponential linear entity expansion
112  * This is not a limitation of the parser but a safety
113  * boundary feature. It can be disabled with the XML_PARSE_HUGE
114  * parser option.
115  */
116 static int
117 xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long size,
118                      xmlEntityPtr ent)
119 {
120     unsigned long consumed = 0;
121
122     if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
123         return (0);
124     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
125         return (1);
126     if (size != 0) {
127         /*
128          * Do the check based on the replacement size of the entity
129          */
130         if (size < XML_PARSER_BIG_ENTITY)
131             return(0);
132
133         /*
134          * A limit on the amount of text data reasonably used
135          */
136         if (ctxt->input != NULL) {
137             consumed = ctxt->input->consumed +
138                 (ctxt->input->cur - ctxt->input->base);
139         }
140         consumed += ctxt->sizeentities;
141
142         if ((size < XML_PARSER_NON_LINEAR * consumed) &&
143             (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
144             return (0);
145     } else if (ent != NULL) {
146         /*
147          * use the number of parsed entities in the replacement
148          */
149         size = ent->checked;
150
151         /*
152          * The amount of data parsed counting entities size only once
153          */
154         if (ctxt->input != NULL) {
155             consumed = ctxt->input->consumed +
156                 (ctxt->input->cur - ctxt->input->base);
157         }
158         consumed += ctxt->sizeentities;
159
160         /*
161          * Check the density of entities for the amount of data
162          * knowing an entity reference will take at least 3 bytes
163          */
164         if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
165             return (0);
166     } else {
167         /*
168          * strange we got no data for checking just return
169          */
170         return (0);
171     }
172
173     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
174     return (1);
175 }
176
177 /**
178  * xmlParserMaxDepth:
179  *
180  * arbitrary depth limit for the XML documents that we allow to
181  * process. This is not a limitation of the parser but a safety
182  * boundary feature. It can be disabled with the XML_PARSE_HUGE
183  * parser option.
184  */
185 unsigned int xmlParserMaxDepth = 256;
186
187
188
189 #define SAX2 1
190 #define XML_PARSER_BIG_BUFFER_SIZE 300
191 #define XML_PARSER_BUFFER_SIZE 100
192 #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
193
194 /*
195  * List of XML prefixed PI allowed by W3C specs
196  */
197
198 static const char *xmlW3CPIs[] = {
199     "xml-stylesheet",
200     NULL
201 };
202
203
204 /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
205 static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
206                                               const xmlChar **str);
207
208 static xmlParserErrors
209 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
210                       xmlSAXHandlerPtr sax,
211                       void *user_data, int depth, const xmlChar *URL,
212                       const xmlChar *ID, xmlNodePtr *list);
213
214 static int
215 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
216                           const char *encoding);
217 #ifdef LIBXML_LEGACY_ENABLED
218 static void
219 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
220                       xmlNodePtr lastNode);
221 #endif /* LIBXML_LEGACY_ENABLED */
222
223 static xmlParserErrors
224 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
225                       const xmlChar *string, void *user_data, xmlNodePtr *lst);
226
227 static int
228 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
229
230 /************************************************************************
231  *                                                                      *
232  *              Some factorized error routines                          *
233  *                                                                      *
234  ************************************************************************/
235
236 /**
237  * xmlErrAttributeDup:
238  * @ctxt:  an XML parser context
239  * @prefix:  the attribute prefix
240  * @localname:  the attribute localname
241  *
242  * Handle a redefinition of attribute error
243  */
244 static void
245 xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
246                    const xmlChar * localname)
247 {
248     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
249         (ctxt->instate == XML_PARSER_EOF))
250         return;
251     if (ctxt != NULL)
252         ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
253
254     if (prefix == NULL)
255         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
256                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
257                         (const char *) localname, NULL, NULL, 0, 0,
258                         "Attribute %s redefined\n", localname);
259     else
260         __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
261                         XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
262                         (const char *) prefix, (const char *) localname,
263                         NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
264                         localname);
265     if (ctxt != NULL) {
266         ctxt->wellFormed = 0;
267         if (ctxt->recovery == 0)
268             ctxt->disableSAX = 1;
269     }
270 }
271
272 /**
273  * xmlFatalErr:
274  * @ctxt:  an XML parser context
275  * @error:  the error number
276  * @extra:  extra information string
277  *
278  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
279  */
280 static void
281 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
282 {
283     const char *errmsg;
284
285     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
286         (ctxt->instate == XML_PARSER_EOF))
287         return;
288     switch (error) {
289         case XML_ERR_INVALID_HEX_CHARREF:
290             errmsg = "CharRef: invalid hexadecimal value\n";
291             break;
292         case XML_ERR_INVALID_DEC_CHARREF:
293             errmsg = "CharRef: invalid decimal value\n";
294             break;
295         case XML_ERR_INVALID_CHARREF:
296             errmsg = "CharRef: invalid value\n";
297             break;
298         case XML_ERR_INTERNAL_ERROR:
299             errmsg = "internal error";
300             break;
301         case XML_ERR_PEREF_AT_EOF:
302             errmsg = "PEReference at end of document\n";
303             break;
304         case XML_ERR_PEREF_IN_PROLOG:
305             errmsg = "PEReference in prolog\n";
306             break;
307         case XML_ERR_PEREF_IN_EPILOG:
308             errmsg = "PEReference in epilog\n";
309             break;
310         case XML_ERR_PEREF_NO_NAME:
311             errmsg = "PEReference: no name\n";
312             break;
313         case XML_ERR_PEREF_SEMICOL_MISSING:
314             errmsg = "PEReference: expecting ';'\n";
315             break;
316         case XML_ERR_ENTITY_LOOP:
317             errmsg = "Detected an entity reference loop\n";
318             break;
319         case XML_ERR_ENTITY_NOT_STARTED:
320             errmsg = "EntityValue: \" or ' expected\n";
321             break;
322         case XML_ERR_ENTITY_PE_INTERNAL:
323             errmsg = "PEReferences forbidden in internal subset\n";
324             break;
325         case XML_ERR_ENTITY_NOT_FINISHED:
326             errmsg = "EntityValue: \" or ' expected\n";
327             break;
328         case XML_ERR_ATTRIBUTE_NOT_STARTED:
329             errmsg = "AttValue: \" or ' expected\n";
330             break;
331         case XML_ERR_LT_IN_ATTRIBUTE:
332             errmsg = "Unescaped '<' not allowed in attributes values\n";
333             break;
334         case XML_ERR_LITERAL_NOT_STARTED:
335             errmsg = "SystemLiteral \" or ' expected\n";
336             break;
337         case XML_ERR_LITERAL_NOT_FINISHED:
338             errmsg = "Unfinished System or Public ID \" or ' expected\n";
339             break;
340         case XML_ERR_MISPLACED_CDATA_END:
341             errmsg = "Sequence ']]>' not allowed in content\n";
342             break;
343         case XML_ERR_URI_REQUIRED:
344             errmsg = "SYSTEM or PUBLIC, the URI is missing\n";
345             break;
346         case XML_ERR_PUBID_REQUIRED:
347             errmsg = "PUBLIC, the Public Identifier is missing\n";
348             break;
349         case XML_ERR_HYPHEN_IN_COMMENT:
350             errmsg = "Comment must not contain '--' (double-hyphen)\n";
351             break;
352         case XML_ERR_PI_NOT_STARTED:
353             errmsg = "xmlParsePI : no target name\n";
354             break;
355         case XML_ERR_RESERVED_XML_NAME:
356             errmsg = "Invalid PI name\n";
357             break;
358         case XML_ERR_NOTATION_NOT_STARTED:
359             errmsg = "NOTATION: Name expected here\n";
360             break;
361         case XML_ERR_NOTATION_NOT_FINISHED:
362             errmsg = "'>' required to close NOTATION declaration\n";
363             break;
364         case XML_ERR_VALUE_REQUIRED:
365             errmsg = "Entity value required\n";
366             break;
367         case XML_ERR_URI_FRAGMENT:
368             errmsg = "Fragment not allowed";
369             break;
370         case XML_ERR_ATTLIST_NOT_STARTED:
371             errmsg = "'(' required to start ATTLIST enumeration\n";
372             break;
373         case XML_ERR_NMTOKEN_REQUIRED:
374             errmsg = "NmToken expected in ATTLIST enumeration\n";
375             break;
376         case XML_ERR_ATTLIST_NOT_FINISHED:
377             errmsg = "')' required to finish ATTLIST enumeration\n";
378             break;
379         case XML_ERR_MIXED_NOT_STARTED:
380             errmsg = "MixedContentDecl : '|' or ')*' expected\n";
381             break;
382         case XML_ERR_PCDATA_REQUIRED:
383             errmsg = "MixedContentDecl : '#PCDATA' expected\n";
384             break;
385         case XML_ERR_ELEMCONTENT_NOT_STARTED:
386             errmsg = "ContentDecl : Name or '(' expected\n";
387             break;
388         case XML_ERR_ELEMCONTENT_NOT_FINISHED:
389             errmsg = "ContentDecl : ',' '|' or ')' expected\n";
390             break;
391         case XML_ERR_PEREF_IN_INT_SUBSET:
392             errmsg =
393                 "PEReference: forbidden within markup decl in internal subset\n";
394             break;
395         case XML_ERR_GT_REQUIRED:
396             errmsg = "expected '>'\n";
397             break;
398         case XML_ERR_CONDSEC_INVALID:
399             errmsg = "XML conditional section '[' expected\n";
400             break;
401         case XML_ERR_EXT_SUBSET_NOT_FINISHED:
402             errmsg = "Content error in the external subset\n";
403             break;
404         case XML_ERR_CONDSEC_INVALID_KEYWORD:
405             errmsg =
406                 "conditional section INCLUDE or IGNORE keyword expected\n";
407             break;
408         case XML_ERR_CONDSEC_NOT_FINISHED:
409             errmsg = "XML conditional section not closed\n";
410             break;
411         case XML_ERR_XMLDECL_NOT_STARTED:
412             errmsg = "Text declaration '<?xml' required\n";
413             break;
414         case XML_ERR_XMLDECL_NOT_FINISHED:
415             errmsg = "parsing XML declaration: '?>' expected\n";
416             break;
417         case XML_ERR_EXT_ENTITY_STANDALONE:
418             errmsg = "external parsed entities cannot be standalone\n";
419             break;
420         case XML_ERR_ENTITYREF_SEMICOL_MISSING:
421             errmsg = "EntityRef: expecting ';'\n";
422             break;
423         case XML_ERR_DOCTYPE_NOT_FINISHED:
424             errmsg = "DOCTYPE improperly terminated\n";
425             break;
426         case XML_ERR_LTSLASH_REQUIRED:
427             errmsg = "EndTag: '</' not found\n";
428             break;
429         case XML_ERR_EQUAL_REQUIRED:
430             errmsg = "expected '='\n";
431             break;
432         case XML_ERR_STRING_NOT_CLOSED:
433             errmsg = "String not closed expecting \" or '\n";
434             break;
435         case XML_ERR_STRING_NOT_STARTED:
436             errmsg = "String not started expecting ' or \"\n";
437             break;
438         case XML_ERR_ENCODING_NAME:
439             errmsg = "Invalid XML encoding name\n";
440             break;
441         case XML_ERR_STANDALONE_VALUE:
442             errmsg = "standalone accepts only 'yes' or 'no'\n";
443             break;
444         case XML_ERR_DOCUMENT_EMPTY:
445             errmsg = "Document is empty\n";
446             break;
447         case XML_ERR_DOCUMENT_END:
448             errmsg = "Extra content at the end of the document\n";
449             break;
450         case XML_ERR_NOT_WELL_BALANCED:
451             errmsg = "chunk is not well balanced\n";
452             break;
453         case XML_ERR_EXTRA_CONTENT:
454             errmsg = "extra content at the end of well balanced chunk\n";
455             break;
456         case XML_ERR_VERSION_MISSING:
457             errmsg = "Malformed declaration expecting version\n";
458             break;
459 #if 0
460         case:
461             errmsg = "\n";
462             break;
463 #endif
464         default:
465             errmsg = "Unregistered error message\n";
466     }
467     if (ctxt != NULL)
468         ctxt->errNo = error;
469     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
470                     XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, errmsg,
471                     info);
472     if (ctxt != NULL) {
473         ctxt->wellFormed = 0;
474         if (ctxt->recovery == 0)
475             ctxt->disableSAX = 1;
476     }
477 }
478
479 /**
480  * xmlFatalErrMsg:
481  * @ctxt:  an XML parser context
482  * @error:  the error number
483  * @msg:  the error message
484  *
485  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
486  */
487 static void
488 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
489                const char *msg)
490 {
491     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
492         (ctxt->instate == XML_PARSER_EOF))
493         return;
494     if (ctxt != NULL)
495         ctxt->errNo = error;
496     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
497                     XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
498     if (ctxt != NULL) {
499         ctxt->wellFormed = 0;
500         if (ctxt->recovery == 0)
501             ctxt->disableSAX = 1;
502     }
503 }
504
505 /**
506  * xmlWarningMsg:
507  * @ctxt:  an XML parser context
508  * @error:  the error number
509  * @msg:  the error message
510  * @str1:  extra data
511  * @str2:  extra data
512  *
513  * Handle a warning.
514  */
515 static void
516 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
517               const char *msg, const xmlChar *str1, const xmlChar *str2)
518 {
519     xmlStructuredErrorFunc schannel = NULL;
520
521     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
522         (ctxt->instate == XML_PARSER_EOF))
523         return;
524     if ((ctxt != NULL) && (ctxt->sax != NULL) &&
525         (ctxt->sax->initialized == XML_SAX2_MAGIC))
526         schannel = ctxt->sax->serror;
527     if (ctxt != NULL) {
528         __xmlRaiseError(schannel,
529                     (ctxt->sax) ? ctxt->sax->warning : NULL,
530                     ctxt->userData,
531                     ctxt, NULL, XML_FROM_PARSER, error,
532                     XML_ERR_WARNING, NULL, 0,
533                     (const char *) str1, (const char *) str2, NULL, 0, 0,
534                     msg, (const char *) str1, (const char *) str2);
535     } else {
536         __xmlRaiseError(schannel, NULL, NULL,
537                     ctxt, NULL, XML_FROM_PARSER, error,
538                     XML_ERR_WARNING, NULL, 0,
539                     (const char *) str1, (const char *) str2, NULL, 0, 0,
540                     msg, (const char *) str1, (const char *) str2);
541     }
542 }
543
544 /**
545  * xmlValidityError:
546  * @ctxt:  an XML parser context
547  * @error:  the error number
548  * @msg:  the error message
549  * @str1:  extra data
550  *
551  * Handle a validity error.
552  */
553 static void
554 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
555               const char *msg, const xmlChar *str1, const xmlChar *str2)
556 {
557     xmlStructuredErrorFunc schannel = NULL;
558
559     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
560         (ctxt->instate == XML_PARSER_EOF))
561         return;
562     if (ctxt != NULL) {
563         ctxt->errNo = error;
564         if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
565             schannel = ctxt->sax->serror;
566     }
567     if (ctxt != NULL) {
568         __xmlRaiseError(schannel,
569                     ctxt->vctxt.error, ctxt->vctxt.userData,
570                     ctxt, NULL, XML_FROM_DTD, error,
571                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
572                     (const char *) str2, NULL, 0, 0,
573                     msg, (const char *) str1, (const char *) str2);
574         ctxt->valid = 0;
575     } else {
576         __xmlRaiseError(schannel, NULL, NULL,
577                     ctxt, NULL, XML_FROM_DTD, error,
578                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
579                     (const char *) str2, NULL, 0, 0,
580                     msg, (const char *) str1, (const char *) str2);
581     }
582 }
583
584 /**
585  * xmlFatalErrMsgInt:
586  * @ctxt:  an XML parser context
587  * @error:  the error number
588  * @msg:  the error message
589  * @val:  an integer value
590  *
591  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
592  */
593 static void
594 xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
595                   const char *msg, int val)
596 {
597     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
598         (ctxt->instate == XML_PARSER_EOF))
599         return;
600     if (ctxt != NULL)
601         ctxt->errNo = error;
602     __xmlRaiseError(NULL, NULL, NULL,
603                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
604                     NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
605     if (ctxt != NULL) {
606         ctxt->wellFormed = 0;
607         if (ctxt->recovery == 0)
608             ctxt->disableSAX = 1;
609     }
610 }
611
612 /**
613  * xmlFatalErrMsgStrIntStr:
614  * @ctxt:  an XML parser context
615  * @error:  the error number
616  * @msg:  the error message
617  * @str1:  an string info
618  * @val:  an integer value
619  * @str2:  an string info
620  *
621  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
622  */
623 static void
624 xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
625                   const char *msg, const xmlChar *str1, int val, 
626                   const xmlChar *str2)
627 {
628     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
629         (ctxt->instate == XML_PARSER_EOF))
630         return;
631     if (ctxt != NULL)
632         ctxt->errNo = error;
633     __xmlRaiseError(NULL, NULL, NULL,
634                     ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
635                     NULL, 0, (const char *) str1, (const char *) str2,
636                     NULL, val, 0, msg, str1, val, str2);
637     if (ctxt != NULL) {
638         ctxt->wellFormed = 0;
639         if (ctxt->recovery == 0)
640             ctxt->disableSAX = 1;
641     }
642 }
643
644 /**
645  * xmlFatalErrMsgStr:
646  * @ctxt:  an XML parser context
647  * @error:  the error number
648  * @msg:  the error message
649  * @val:  a string value
650  *
651  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
652  */
653 static void
654 xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
655                   const char *msg, const xmlChar * val)
656 {
657     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
658         (ctxt->instate == XML_PARSER_EOF))
659         return;
660     if (ctxt != NULL)
661         ctxt->errNo = error;
662     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
663                     XML_FROM_PARSER, error, XML_ERR_FATAL,
664                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
665                     val);
666     if (ctxt != NULL) {
667         ctxt->wellFormed = 0;
668         if (ctxt->recovery == 0)
669             ctxt->disableSAX = 1;
670     }
671 }
672
673 /**
674  * xmlErrMsgStr:
675  * @ctxt:  an XML parser context
676  * @error:  the error number
677  * @msg:  the error message
678  * @val:  a string value
679  *
680  * Handle a non fatal parser error
681  */
682 static void
683 xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
684                   const char *msg, const xmlChar * val)
685 {
686     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
687         (ctxt->instate == XML_PARSER_EOF))
688         return;
689     if (ctxt != NULL)
690         ctxt->errNo = error;
691     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
692                     XML_FROM_PARSER, error, XML_ERR_ERROR,
693                     NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
694                     val);
695 }
696
697 /**
698  * xmlNsErr:
699  * @ctxt:  an XML parser context
700  * @error:  the error number
701  * @msg:  the message
702  * @info1:  extra information string
703  * @info2:  extra information string
704  *
705  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
706  */
707 static void
708 xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
709          const char *msg,
710          const xmlChar * info1, const xmlChar * info2,
711          const xmlChar * info3)
712 {
713     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
714         (ctxt->instate == XML_PARSER_EOF))
715         return;
716     if (ctxt != NULL)
717         ctxt->errNo = error;
718     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
719                     XML_ERR_ERROR, NULL, 0, (const char *) info1,
720                     (const char *) info2, (const char *) info3, 0, 0, msg,
721                     info1, info2, info3);
722     if (ctxt != NULL)
723         ctxt->nsWellFormed = 0;
724 }
725
726 /**
727  * xmlNsWarn
728  * @ctxt:  an XML parser context
729  * @error:  the error number
730  * @msg:  the message
731  * @info1:  extra information string
732  * @info2:  extra information string
733  *
734  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
735  */
736 static void
737 xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
738          const char *msg,
739          const xmlChar * info1, const xmlChar * info2,
740          const xmlChar * info3)
741 {
742     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
743         (ctxt->instate == XML_PARSER_EOF))
744         return;
745     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
746                     XML_ERR_WARNING, NULL, 0, (const char *) info1,
747                     (const char *) info2, (const char *) info3, 0, 0, msg,
748                     info1, info2, info3);
749 }
750
751 /************************************************************************
752  *                                                                      *
753  *              Library wide options                                    *
754  *                                                                      *
755  ************************************************************************/
756
757 /**
758   * xmlHasFeature:
759   * @feature: the feature to be examined
760   *
761   * Examines if the library has been compiled with a given feature.
762   *
763   * Returns a non-zero value if the feature exist, otherwise zero.
764   * Returns zero (0) if the feature does not exist or an unknown
765   * unknown feature is requested, non-zero otherwise.
766   */
767 int
768 xmlHasFeature(xmlFeature feature)
769 {
770     switch (feature) {
771         case XML_WITH_THREAD:
772 #ifdef LIBXML_THREAD_ENABLED
773             return(1);
774 #else
775             return(0);
776 #endif
777         case XML_WITH_TREE:
778 #ifdef LIBXML_TREE_ENABLED
779             return(1);
780 #else
781             return(0);
782 #endif
783         case XML_WITH_OUTPUT:
784 #ifdef LIBXML_OUTPUT_ENABLED
785             return(1);
786 #else
787             return(0);
788 #endif
789         case XML_WITH_PUSH:
790 #ifdef LIBXML_PUSH_ENABLED
791             return(1);
792 #else
793             return(0);
794 #endif
795         case XML_WITH_READER:
796 #ifdef LIBXML_READER_ENABLED
797             return(1);
798 #else
799             return(0);
800 #endif
801         case XML_WITH_PATTERN:
802 #ifdef LIBXML_PATTERN_ENABLED
803             return(1);
804 #else
805             return(0);
806 #endif
807         case XML_WITH_WRITER:
808 #ifdef LIBXML_WRITER_ENABLED
809             return(1);
810 #else
811             return(0);
812 #endif
813         case XML_WITH_SAX1:
814 #ifdef LIBXML_SAX1_ENABLED
815             return(1);
816 #else
817             return(0);
818 #endif
819         case XML_WITH_FTP:
820 #ifdef LIBXML_FTP_ENABLED
821             return(1);
822 #else
823             return(0);
824 #endif
825         case XML_WITH_HTTP:
826 #ifdef LIBXML_HTTP_ENABLED
827             return(1);
828 #else
829             return(0);
830 #endif
831         case XML_WITH_VALID:
832 #ifdef LIBXML_VALID_ENABLED
833             return(1);
834 #else
835             return(0);
836 #endif
837         case XML_WITH_HTML:
838 #ifdef LIBXML_HTML_ENABLED
839             return(1);
840 #else
841             return(0);
842 #endif
843         case XML_WITH_LEGACY:
844 #ifdef LIBXML_LEGACY_ENABLED
845             return(1);
846 #else
847             return(0);
848 #endif
849         case XML_WITH_C14N:
850 #ifdef LIBXML_C14N_ENABLED
851             return(1);
852 #else
853             return(0);
854 #endif
855         case XML_WITH_CATALOG:
856 #ifdef LIBXML_CATALOG_ENABLED
857             return(1);
858 #else
859             return(0);
860 #endif
861         case XML_WITH_XPATH:
862 #ifdef LIBXML_XPATH_ENABLED
863             return(1);
864 #else
865             return(0);
866 #endif
867         case XML_WITH_XPTR:
868 #ifdef LIBXML_XPTR_ENABLED
869             return(1);
870 #else
871             return(0);
872 #endif
873         case XML_WITH_XINCLUDE:
874 #ifdef LIBXML_XINCLUDE_ENABLED
875             return(1);
876 #else
877             return(0);
878 #endif
879         case XML_WITH_ICONV:
880 #ifdef LIBXML_ICONV_ENABLED
881             return(1);
882 #else
883             return(0);
884 #endif
885         case XML_WITH_ISO8859X:
886 #ifdef LIBXML_ISO8859X_ENABLED
887             return(1);
888 #else
889             return(0);
890 #endif
891         case XML_WITH_UNICODE:
892 #ifdef LIBXML_UNICODE_ENABLED
893             return(1);
894 #else
895             return(0);
896 #endif
897         case XML_WITH_REGEXP:
898 #ifdef LIBXML_REGEXP_ENABLED
899             return(1);
900 #else
901             return(0);
902 #endif
903         case XML_WITH_AUTOMATA:
904 #ifdef LIBXML_AUTOMATA_ENABLED
905             return(1);
906 #else
907             return(0);
908 #endif
909         case XML_WITH_EXPR:
910 #ifdef LIBXML_EXPR_ENABLED
911             return(1);
912 #else
913             return(0);
914 #endif
915         case XML_WITH_SCHEMAS:
916 #ifdef LIBXML_SCHEMAS_ENABLED
917             return(1);
918 #else
919             return(0);
920 #endif
921         case XML_WITH_SCHEMATRON:
922 #ifdef LIBXML_SCHEMATRON_ENABLED
923             return(1);
924 #else
925             return(0);
926 #endif
927         case XML_WITH_MODULES:
928 #ifdef LIBXML_MODULES_ENABLED
929             return(1);
930 #else
931             return(0);
932 #endif
933         case XML_WITH_DEBUG:
934 #ifdef LIBXML_DEBUG_ENABLED
935             return(1);
936 #else
937             return(0);
938 #endif
939         case XML_WITH_DEBUG_MEM:
940 #ifdef DEBUG_MEMORY_LOCATION
941             return(1);
942 #else
943             return(0);
944 #endif
945         case XML_WITH_DEBUG_RUN:
946 #ifdef LIBXML_DEBUG_RUNTIME
947             return(1);
948 #else
949             return(0);
950 #endif
951         case XML_WITH_ZLIB:
952 #ifdef LIBXML_ZLIB_ENABLED
953             return(1);
954 #else
955             return(0);
956 #endif
957         case XML_WITH_ICU:
958 #ifdef LIBXML_ICU_ENABLED
959             return(1);
960 #else
961             return(0);
962 #endif
963         default:
964             break;
965      }
966      return(0);
967 }
968
969 /************************************************************************
970  *                                                                      *
971  *              SAX2 defaulted attributes handling                      *
972  *                                                                      *
973  ************************************************************************/
974
975 /**
976  * xmlDetectSAX2:
977  * @ctxt:  an XML parser context
978  *
979  * Do the SAX2 detection and specific intialization
980  */
981 static void
982 xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
983     if (ctxt == NULL) return;
984 #ifdef LIBXML_SAX1_ENABLED
985     if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
986         ((ctxt->sax->startElementNs != NULL) ||
987          (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
988 #else
989     ctxt->sax2 = 1;
990 #endif /* LIBXML_SAX1_ENABLED */
991
992     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
993     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
994     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
995     if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) || 
996                 (ctxt->str_xml_ns == NULL)) {
997         xmlErrMemory(ctxt, NULL);
998     }
999 }
1000
1001 typedef struct _xmlDefAttrs xmlDefAttrs;
1002 typedef xmlDefAttrs *xmlDefAttrsPtr;
1003 struct _xmlDefAttrs {
1004     int nbAttrs;        /* number of defaulted attributes on that element */
1005     int maxAttrs;       /* the size of the array */
1006     const xmlChar *values[5]; /* array of localname/prefix/values/external */
1007 };
1008
1009 /**
1010  * xmlAttrNormalizeSpace:
1011  * @src: the source string
1012  * @dst: the target string
1013  *
1014  * Normalize the space in non CDATA attribute values:
1015  * If the attribute type is not CDATA, then the XML processor MUST further
1016  * process the normalized attribute value by discarding any leading and
1017  * trailing space (#x20) characters, and by replacing sequences of space
1018  * (#x20) characters by a single space (#x20) character.
1019  * Note that the size of dst need to be at least src, and if one doesn't need
1020  * to preserve dst (and it doesn't come from a dictionary or read-only) then
1021  * passing src as dst is just fine.
1022  *
1023  * Returns a pointer to the normalized value (dst) or NULL if no conversion
1024  *         is needed.
1025  */
1026 static xmlChar *
1027 xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
1028 {
1029     if ((src == NULL) || (dst == NULL))
1030         return(NULL);
1031
1032     while (*src == 0x20) src++;
1033     while (*src != 0) {
1034         if (*src == 0x20) {
1035             while (*src == 0x20) src++;
1036             if (*src != 0)
1037                 *dst++ = 0x20;
1038         } else {
1039             *dst++ = *src++;
1040         }
1041     }
1042     *dst = 0;
1043     if (dst == src)
1044        return(NULL);
1045     return(dst);
1046 }
1047
1048 /**
1049  * xmlAttrNormalizeSpace2:
1050  * @src: the source string
1051  *
1052  * Normalize the space in non CDATA attribute values, a slightly more complex
1053  * front end to avoid allocation problems when running on attribute values
1054  * coming from the input.
1055  *
1056  * Returns a pointer to the normalized value (dst) or NULL if no conversion
1057  *         is needed.
1058  */
1059 static const xmlChar *
1060 xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
1061 {
1062     int i;
1063     int remove_head = 0;
1064     int need_realloc = 0;
1065     const xmlChar *cur;
1066
1067     if ((ctxt == NULL) || (src == NULL) || (len == NULL))
1068         return(NULL);
1069     i = *len;
1070     if (i <= 0)
1071         return(NULL);
1072
1073     cur = src;
1074     while (*cur == 0x20) {
1075         cur++;
1076         remove_head++;
1077     }
1078     while (*cur != 0) {
1079         if (*cur == 0x20) {
1080             cur++;
1081             if ((*cur == 0x20) || (*cur == 0)) {
1082                 need_realloc = 1;
1083                 break;
1084             }
1085         } else
1086             cur++;
1087     }
1088     if (need_realloc) {
1089         xmlChar *ret;
1090
1091         ret = xmlStrndup(src + remove_head, i - remove_head + 1);
1092         if (ret == NULL) {
1093             xmlErrMemory(ctxt, NULL);
1094             return(NULL);
1095         }
1096         xmlAttrNormalizeSpace(ret, ret);
1097         *len = (int) strlen((const char *)ret);
1098         return(ret);
1099     } else if (remove_head) {
1100         *len -= remove_head;
1101         memmove(src, src + remove_head, 1 + *len);
1102         return(src);
1103     }
1104     return(NULL);
1105 }
1106
1107 /**
1108  * xmlAddDefAttrs:
1109  * @ctxt:  an XML parser context
1110  * @fullname:  the element fullname
1111  * @fullattr:  the attribute fullname
1112  * @value:  the attribute value
1113  *
1114  * Add a defaulted attribute for an element
1115  */
1116 static void
1117 xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
1118                const xmlChar *fullname,
1119                const xmlChar *fullattr,
1120                const xmlChar *value) {
1121     xmlDefAttrsPtr defaults;
1122     int len;
1123     const xmlChar *name;
1124     const xmlChar *prefix;
1125
1126     /*
1127      * Allows to detect attribute redefinitions
1128      */
1129     if (ctxt->attsSpecial != NULL) {
1130         if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1131             return;
1132     }
1133
1134     if (ctxt->attsDefault == NULL) {
1135         ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
1136         if (ctxt->attsDefault == NULL)
1137             goto mem_error;
1138     }
1139
1140     /*
1141      * split the element name into prefix:localname , the string found
1142      * are within the DTD and then not associated to namespace names.
1143      */
1144     name = xmlSplitQName3(fullname, &len);
1145     if (name == NULL) {
1146         name = xmlDictLookup(ctxt->dict, fullname, -1);
1147         prefix = NULL;
1148     } else {
1149         name = xmlDictLookup(ctxt->dict, name, -1);
1150         prefix = xmlDictLookup(ctxt->dict, fullname, len);
1151     }
1152
1153     /*
1154      * make sure there is some storage
1155      */
1156     defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
1157     if (defaults == NULL) {
1158         defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
1159                            (4 * 5) * sizeof(const xmlChar *));
1160         if (defaults == NULL)
1161             goto mem_error;
1162         defaults->nbAttrs = 0;
1163         defaults->maxAttrs = 4;
1164         if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1165                                 defaults, NULL) < 0) {
1166             xmlFree(defaults);
1167             goto mem_error;
1168         }
1169     } else if (defaults->nbAttrs >= defaults->maxAttrs) {
1170         xmlDefAttrsPtr temp;
1171
1172         temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
1173                        (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
1174         if (temp == NULL)
1175             goto mem_error;
1176         defaults = temp;
1177         defaults->maxAttrs *= 2;
1178         if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1179                                 defaults, NULL) < 0) {
1180             xmlFree(defaults);
1181             goto mem_error;
1182         }
1183     }
1184
1185     /*
1186      * Split the element name into prefix:localname , the string found
1187      * are within the DTD and hen not associated to namespace names.
1188      */
1189     name = xmlSplitQName3(fullattr, &len);
1190     if (name == NULL) {
1191         name = xmlDictLookup(ctxt->dict, fullattr, -1);
1192         prefix = NULL;
1193     } else {
1194         name = xmlDictLookup(ctxt->dict, name, -1);
1195         prefix = xmlDictLookup(ctxt->dict, fullattr, len);
1196     }
1197
1198     defaults->values[5 * defaults->nbAttrs] = name;
1199     defaults->values[5 * defaults->nbAttrs + 1] = prefix;
1200     /* intern the string and precompute the end */
1201     len = xmlStrlen(value);
1202     value = xmlDictLookup(ctxt->dict, value, len);
1203     defaults->values[5 * defaults->nbAttrs + 2] = value;
1204     defaults->values[5 * defaults->nbAttrs + 3] = value + len;
1205     if (ctxt->external)
1206         defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
1207     else
1208         defaults->values[5 * defaults->nbAttrs + 4] = NULL;
1209     defaults->nbAttrs++;
1210
1211     return;
1212
1213 mem_error:
1214     xmlErrMemory(ctxt, NULL);
1215     return;
1216 }
1217
1218 /**
1219  * xmlAddSpecialAttr:
1220  * @ctxt:  an XML parser context
1221  * @fullname:  the element fullname
1222  * @fullattr:  the attribute fullname
1223  * @type:  the attribute type
1224  *
1225  * Register this attribute type
1226  */
1227 static void
1228 xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
1229                   const xmlChar *fullname,
1230                   const xmlChar *fullattr,
1231                   int type)
1232 {
1233     if (ctxt->attsSpecial == NULL) {
1234         ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
1235         if (ctxt->attsSpecial == NULL)
1236             goto mem_error;
1237     }
1238
1239     if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1240         return;
1241
1242     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
1243                      (void *) (long) type);
1244     return;
1245
1246 mem_error:
1247     xmlErrMemory(ctxt, NULL);
1248     return;
1249 }
1250
1251 /**
1252  * xmlCleanSpecialAttrCallback:
1253  *
1254  * Removes CDATA attributes from the special attribute table
1255  */
1256 static void
1257 xmlCleanSpecialAttrCallback(void *payload, void *data,
1258                             const xmlChar *fullname, const xmlChar *fullattr,
1259                             const xmlChar *unused ATTRIBUTE_UNUSED) {
1260     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
1261
1262     if (((long) payload) == XML_ATTRIBUTE_CDATA) {
1263         xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
1264     }
1265 }
1266
1267 /**
1268  * xmlCleanSpecialAttr:
1269  * @ctxt:  an XML parser context
1270  *
1271  * Trim the list of attributes defined to remove all those of type
1272  * CDATA as they are not special. This call should be done when finishing
1273  * to parse the DTD and before starting to parse the document root.
1274  */
1275 static void
1276 xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
1277 {
1278     if (ctxt->attsSpecial == NULL)
1279         return;
1280
1281     xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
1282
1283     if (xmlHashSize(ctxt->attsSpecial) == 0) {
1284         xmlHashFree(ctxt->attsSpecial, NULL);
1285         ctxt->attsSpecial = NULL;
1286     }
1287     return;
1288 }
1289
1290 /**
1291  * xmlCheckLanguageID:
1292  * @lang:  pointer to the string value
1293  *
1294  * Checks that the value conforms to the LanguageID production:
1295  *
1296  * NOTE: this is somewhat deprecated, those productions were removed from
1297  *       the XML Second edition.
1298  *
1299  * [33] LanguageID ::= Langcode ('-' Subcode)*
1300  * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
1301  * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
1302  * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
1303  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
1304  * [38] Subcode ::= ([a-z] | [A-Z])+
1305  *
1306  * Returns 1 if correct 0 otherwise
1307  **/
1308 int
1309 xmlCheckLanguageID(const xmlChar * lang)
1310 {
1311     const xmlChar *cur = lang;
1312
1313     if (cur == NULL)
1314         return (0);
1315     if (((cur[0] == 'i') && (cur[1] == '-')) ||
1316         ((cur[0] == 'I') && (cur[1] == '-'))) {
1317         /*
1318          * IANA code
1319          */
1320         cur += 2;
1321         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
1322                ((cur[0] >= 'a') && (cur[0] <= 'z')))
1323             cur++;
1324     } else if (((cur[0] == 'x') && (cur[1] == '-')) ||
1325                ((cur[0] == 'X') && (cur[1] == '-'))) {
1326         /*
1327          * User code
1328          */
1329         cur += 2;
1330         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
1331                ((cur[0] >= 'a') && (cur[0] <= 'z')))
1332             cur++;
1333     } else if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1334                ((cur[0] >= 'a') && (cur[0] <= 'z'))) {
1335         /*
1336          * ISO639
1337          */
1338         cur++;
1339         if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1340             ((cur[0] >= 'a') && (cur[0] <= 'z')))
1341             cur++;
1342         else
1343             return (0);
1344     } else
1345         return (0);
1346     while (cur[0] != 0) {       /* non input consuming */
1347         if (cur[0] != '-')
1348             return (0);
1349         cur++;
1350         if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1351             ((cur[0] >= 'a') && (cur[0] <= 'z')))
1352             cur++;
1353         else
1354             return (0);
1355         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||  /* non input consuming */
1356                ((cur[0] >= 'a') && (cur[0] <= 'z')))
1357             cur++;
1358     }
1359     return (1);
1360 }
1361
1362 /************************************************************************
1363  *                                                                      *
1364  *              Parser stacks related functions and macros              *
1365  *                                                                      *
1366  ************************************************************************/
1367
1368 static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
1369                                             const xmlChar ** str);
1370
1371 #ifdef SAX2
1372 /**
1373  * nsPush:
1374  * @ctxt:  an XML parser context
1375  * @prefix:  the namespace prefix or NULL
1376  * @URL:  the namespace name
1377  *
1378  * Pushes a new parser namespace on top of the ns stack
1379  *
1380  * Returns -1 in case of error, -2 if the namespace should be discarded
1381  *         and the index in the stack otherwise.
1382  */
1383 static int
1384 nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
1385 {
1386     if (ctxt->options & XML_PARSE_NSCLEAN) {
1387         int i;
1388         for (i = 0;i < ctxt->nsNr;i += 2) {
1389             if (ctxt->nsTab[i] == prefix) {
1390                 /* in scope */
1391                 if (ctxt->nsTab[i + 1] == URL)
1392                     return(-2);
1393                 /* out of scope keep it */
1394                 break;
1395             }
1396         }
1397     }
1398     if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
1399         ctxt->nsMax = 10;
1400         ctxt->nsNr = 0;
1401         ctxt->nsTab = (const xmlChar **)
1402                       xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
1403         if (ctxt->nsTab == NULL) {
1404             xmlErrMemory(ctxt, NULL);
1405             ctxt->nsMax = 0;
1406             return (-1);
1407         }
1408     } else if (ctxt->nsNr >= ctxt->nsMax) {
1409         const xmlChar ** tmp;
1410         ctxt->nsMax *= 2;
1411         tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
1412                                     ctxt->nsMax * sizeof(ctxt->nsTab[0]));
1413         if (tmp == NULL) {
1414             xmlErrMemory(ctxt, NULL);
1415             ctxt->nsMax /= 2;
1416             return (-1);
1417         }
1418         ctxt->nsTab = tmp;
1419     }
1420     ctxt->nsTab[ctxt->nsNr++] = prefix;
1421     ctxt->nsTab[ctxt->nsNr++] = URL;
1422     return (ctxt->nsNr);
1423 }
1424 /**
1425  * nsPop:
1426  * @ctxt: an XML parser context
1427  * @nr:  the number to pop
1428  *
1429  * Pops the top @nr parser prefix/namespace from the ns stack
1430  *
1431  * Returns the number of namespaces removed
1432  */
1433 static int
1434 nsPop(xmlParserCtxtPtr ctxt, int nr)
1435 {
1436     int i;
1437
1438     if (ctxt->nsTab == NULL) return(0);
1439     if (ctxt->nsNr < nr) {
1440         xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
1441         nr = ctxt->nsNr;
1442     }
1443     if (ctxt->nsNr <= 0)
1444         return (0);
1445
1446     for (i = 0;i < nr;i++) {
1447          ctxt->nsNr--;
1448          ctxt->nsTab[ctxt->nsNr] = NULL;
1449     }
1450     return(nr);
1451 }
1452 #endif
1453
1454 static int
1455 xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
1456     const xmlChar **atts;
1457     int *attallocs;
1458     int maxatts;
1459
1460     if (ctxt->atts == NULL) {
1461         maxatts = 55; /* allow for 10 attrs by default */
1462         atts = (const xmlChar **)
1463                xmlMalloc(maxatts * sizeof(xmlChar *));
1464         if (atts == NULL) goto mem_error;
1465         ctxt->atts = atts;
1466         attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
1467         if (attallocs == NULL) goto mem_error;
1468         ctxt->attallocs = attallocs;
1469         ctxt->maxatts = maxatts;
1470     } else if (nr + 5 > ctxt->maxatts) {
1471         maxatts = (nr + 5) * 2;
1472         atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
1473                                      maxatts * sizeof(const xmlChar *));
1474         if (atts == NULL) goto mem_error;
1475         ctxt->atts = atts;
1476         attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
1477                                      (maxatts / 5) * sizeof(int));
1478         if (attallocs == NULL) goto mem_error;
1479         ctxt->attallocs = attallocs;
1480         ctxt->maxatts = maxatts;
1481     }
1482     return(ctxt->maxatts);
1483 mem_error:
1484     xmlErrMemory(ctxt, NULL);
1485     return(-1);
1486 }
1487
1488 /**
1489  * inputPush:
1490  * @ctxt:  an XML parser context
1491  * @value:  the parser input
1492  *
1493  * Pushes a new parser input on top of the input stack
1494  *
1495  * Returns -1 in case of error, the index in the stack otherwise
1496  */
1497 int
1498 inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
1499 {
1500     if ((ctxt == NULL) || (value == NULL))
1501         return(-1);
1502     if (ctxt->inputNr >= ctxt->inputMax) {
1503         ctxt->inputMax *= 2;
1504         ctxt->inputTab =
1505             (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
1506                                              ctxt->inputMax *
1507                                              sizeof(ctxt->inputTab[0]));
1508         if (ctxt->inputTab == NULL) {
1509             xmlErrMemory(ctxt, NULL);
1510             xmlFreeInputStream(value);
1511             ctxt->inputMax /= 2;
1512             value = NULL;
1513             return (-1);
1514         }
1515     }
1516     ctxt->inputTab[ctxt->inputNr] = value;
1517     ctxt->input = value;
1518     return (ctxt->inputNr++);
1519 }
1520 /**
1521  * inputPop:
1522  * @ctxt: an XML parser context
1523  *
1524  * Pops the top parser input from the input stack
1525  *
1526  * Returns the input just removed
1527  */
1528 xmlParserInputPtr
1529 inputPop(xmlParserCtxtPtr ctxt)
1530 {
1531     xmlParserInputPtr ret;
1532
1533     if (ctxt == NULL)
1534         return(NULL);
1535     if (ctxt->inputNr <= 0)
1536         return (NULL);
1537     ctxt->inputNr--;
1538     if (ctxt->inputNr > 0)
1539         ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
1540     else
1541         ctxt->input = NULL;
1542     ret = ctxt->inputTab[ctxt->inputNr];
1543     ctxt->inputTab[ctxt->inputNr] = NULL;
1544     return (ret);
1545 }
1546 /**
1547  * nodePush:
1548  * @ctxt:  an XML parser context
1549  * @value:  the element node
1550  *
1551  * Pushes a new element node on top of the node stack
1552  *
1553  * Returns -1 in case of error, the index in the stack otherwise
1554  */
1555 int
1556 nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
1557 {
1558     if (ctxt == NULL) return(0);
1559     if (ctxt->nodeNr >= ctxt->nodeMax) {
1560         xmlNodePtr *tmp;
1561
1562         tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
1563                                       ctxt->nodeMax * 2 *
1564                                       sizeof(ctxt->nodeTab[0]));
1565         if (tmp == NULL) {
1566             xmlErrMemory(ctxt, NULL);
1567             return (-1);
1568         }
1569         ctxt->nodeTab = tmp;
1570         ctxt->nodeMax *= 2;
1571     }
1572     if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
1573         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
1574         xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
1575                  "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
1576                           xmlParserMaxDepth);
1577         ctxt->instate = XML_PARSER_EOF;
1578         return(-1);
1579     }
1580     ctxt->nodeTab[ctxt->nodeNr] = value;
1581     ctxt->node = value;
1582     return (ctxt->nodeNr++);
1583 }
1584
1585 /**
1586  * nodePop:
1587  * @ctxt: an XML parser context
1588  *
1589  * Pops the top element node from the node stack
1590  *
1591  * Returns the node just removed
1592  */
1593 xmlNodePtr
1594 nodePop(xmlParserCtxtPtr ctxt)
1595 {
1596     xmlNodePtr ret;
1597
1598     if (ctxt == NULL) return(NULL);
1599     if (ctxt->nodeNr <= 0)
1600         return (NULL);
1601     ctxt->nodeNr--;
1602     if (ctxt->nodeNr > 0)
1603         ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
1604     else
1605         ctxt->node = NULL;
1606     ret = ctxt->nodeTab[ctxt->nodeNr];
1607     ctxt->nodeTab[ctxt->nodeNr] = NULL;
1608     return (ret);
1609 }
1610
1611 #ifdef LIBXML_PUSH_ENABLED
1612 /**
1613  * nameNsPush:
1614  * @ctxt:  an XML parser context
1615  * @value:  the element name
1616  * @prefix:  the element prefix
1617  * @URI:  the element namespace name
1618  *
1619  * Pushes a new element name/prefix/URL on top of the name stack
1620  *
1621  * Returns -1 in case of error, the index in the stack otherwise
1622  */
1623 static int
1624 nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
1625            const xmlChar *prefix, const xmlChar *URI, int nsNr)
1626 {
1627     if (ctxt->nameNr >= ctxt->nameMax) {
1628         const xmlChar * *tmp;
1629         void **tmp2;
1630         ctxt->nameMax *= 2;
1631         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1632                                     ctxt->nameMax *
1633                                     sizeof(ctxt->nameTab[0]));
1634         if (tmp == NULL) {
1635             ctxt->nameMax /= 2;
1636             goto mem_error;
1637         }
1638         ctxt->nameTab = tmp;
1639         tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
1640                                     ctxt->nameMax * 3 *
1641                                     sizeof(ctxt->pushTab[0]));
1642         if (tmp2 == NULL) {
1643             ctxt->nameMax /= 2;
1644             goto mem_error;
1645         }
1646         ctxt->pushTab = tmp2;
1647     }
1648     ctxt->nameTab[ctxt->nameNr] = value;
1649     ctxt->name = value;
1650     ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
1651     ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
1652     ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
1653     return (ctxt->nameNr++);
1654 mem_error:
1655     xmlErrMemory(ctxt, NULL);
1656     return (-1);
1657 }
1658 /**
1659  * nameNsPop:
1660  * @ctxt: an XML parser context
1661  *
1662  * Pops the top element/prefix/URI name from the name stack
1663  *
1664  * Returns the name just removed
1665  */
1666 static const xmlChar *
1667 nameNsPop(xmlParserCtxtPtr ctxt)
1668 {
1669     const xmlChar *ret;
1670
1671     if (ctxt->nameNr <= 0)
1672         return (NULL);
1673     ctxt->nameNr--;
1674     if (ctxt->nameNr > 0)
1675         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1676     else
1677         ctxt->name = NULL;
1678     ret = ctxt->nameTab[ctxt->nameNr];
1679     ctxt->nameTab[ctxt->nameNr] = NULL;
1680     return (ret);
1681 }
1682 #endif /* LIBXML_PUSH_ENABLED */
1683
1684 /**
1685  * namePush:
1686  * @ctxt:  an XML parser context
1687  * @value:  the element name
1688  *
1689  * Pushes a new element name on top of the name stack
1690  *
1691  * Returns -1 in case of error, the index in the stack otherwise
1692  */
1693 int
1694 namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
1695 {
1696     if (ctxt == NULL) return (-1);
1697
1698     if (ctxt->nameNr >= ctxt->nameMax) {
1699         const xmlChar * *tmp;
1700         ctxt->nameMax *= 2;
1701         tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1702                                     ctxt->nameMax *
1703                                     sizeof(ctxt->nameTab[0]));
1704         if (tmp == NULL) {
1705             ctxt->nameMax /= 2;
1706             goto mem_error;
1707         }
1708         ctxt->nameTab = tmp;
1709     }
1710     ctxt->nameTab[ctxt->nameNr] = value;
1711     ctxt->name = value;
1712     return (ctxt->nameNr++);
1713 mem_error:
1714     xmlErrMemory(ctxt, NULL);
1715     return (-1);
1716 }
1717 /**
1718  * namePop:
1719  * @ctxt: an XML parser context
1720  *
1721  * Pops the top element name from the name stack
1722  *
1723  * Returns the name just removed
1724  */
1725 const xmlChar *
1726 namePop(xmlParserCtxtPtr ctxt)
1727 {
1728     const xmlChar *ret;
1729
1730     if ((ctxt == NULL) || (ctxt->nameNr <= 0))
1731         return (NULL);
1732     ctxt->nameNr--;
1733     if (ctxt->nameNr > 0)
1734         ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1735     else
1736         ctxt->name = NULL;
1737     ret = ctxt->nameTab[ctxt->nameNr];
1738     ctxt->nameTab[ctxt->nameNr] = NULL;
1739     return (ret);
1740 }
1741
1742 static int spacePush(xmlParserCtxtPtr ctxt, int val) {
1743     if (ctxt->spaceNr >= ctxt->spaceMax) {
1744         int *tmp;
1745
1746         ctxt->spaceMax *= 2;
1747         tmp = (int *) xmlRealloc(ctxt->spaceTab,
1748                                  ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
1749         if (tmp == NULL) {
1750             xmlErrMemory(ctxt, NULL);
1751             ctxt->spaceMax /=2;
1752             return(-1);
1753         }
1754         ctxt->spaceTab = tmp;
1755     }
1756     ctxt->spaceTab[ctxt->spaceNr] = val;
1757     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
1758     return(ctxt->spaceNr++);
1759 }
1760
1761 static int spacePop(xmlParserCtxtPtr ctxt) {
1762     int ret;
1763     if (ctxt->spaceNr <= 0) return(0);
1764     ctxt->spaceNr--;
1765     if (ctxt->spaceNr > 0)
1766         ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
1767     else
1768         ctxt->space = &ctxt->spaceTab[0];
1769     ret = ctxt->spaceTab[ctxt->spaceNr];
1770     ctxt->spaceTab[ctxt->spaceNr] = -1;
1771     return(ret);
1772 }
1773
1774 /*
1775  * Macros for accessing the content. Those should be used only by the parser,
1776  * and not exported.
1777  *
1778  * Dirty macros, i.e. one often need to make assumption on the context to
1779  * use them
1780  *
1781  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
1782  *           To be used with extreme caution since operations consuming
1783  *           characters may move the input buffer to a different location !
1784  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
1785  *           This should be used internally by the parser
1786  *           only to compare to ASCII values otherwise it would break when
1787  *           running with UTF-8 encoding.
1788  *   RAW     same as CUR but in the input buffer, bypass any token
1789  *           extraction that may have been done
1790  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
1791  *           to compare on ASCII based substring.
1792  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
1793  *           strings without newlines within the parser.
1794  *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII 
1795  *           defined char within the parser.
1796  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
1797  *
1798  *   NEXT    Skip to the next character, this does the proper decoding
1799  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
1800  *   NEXTL(l) Skip the current unicode character of l xmlChars long.
1801  *   CUR_CHAR(l) returns the current unicode character (int), set l
1802  *           to the number of xmlChars used for the encoding [0-5].
1803  *   CUR_SCHAR  same but operate on a string instead of the context
1804  *   COPY_BUF  copy the current unicode char to the target buffer, increment
1805  *            the index
1806  *   GROW, SHRINK  handling of input buffers
1807  */
1808
1809 #define RAW (*ctxt->input->cur)
1810 #define CUR (*ctxt->input->cur)
1811 #define NXT(val) ctxt->input->cur[(val)]
1812 #define CUR_PTR ctxt->input->cur
1813
1814 #define CMP4( s, c1, c2, c3, c4 ) \
1815   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
1816     ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
1817 #define CMP5( s, c1, c2, c3, c4, c5 ) \
1818   ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
1819 #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
1820   ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
1821 #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
1822   ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
1823 #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
1824   ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
1825 #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
1826   ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
1827     ((unsigned char *) s)[ 8 ] == c9 )
1828 #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
1829   ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
1830     ((unsigned char *) s)[ 9 ] == c10 )
1831
1832 #define SKIP(val) do {                                                  \
1833     ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);                   \
1834     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
1835     if ((*ctxt->input->cur == 0) &&                                     \
1836         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))            \
1837             xmlPopInput(ctxt);                                          \
1838   } while (0)
1839
1840 #define SKIPL(val) do {                                                 \
1841     int skipl;                                                          \
1842     for(skipl=0; skipl<val; skipl++) {                                  \
1843         if (*(ctxt->input->cur) == '\n') {                              \
1844         ctxt->input->line++; ctxt->input->col = 1;                      \
1845         } else ctxt->input->col++;                                      \
1846         ctxt->nbChars++;                                                \
1847         ctxt->input->cur++;                                             \
1848     }                                                                   \
1849     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
1850     if ((*ctxt->input->cur == 0) &&                                     \
1851         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))            \
1852             xmlPopInput(ctxt);                                          \
1853   } while (0)
1854
1855 #define SHRINK if ((ctxt->progressive == 0) &&                          \
1856                    (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
1857                    (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
1858         xmlSHRINK (ctxt);
1859
1860 static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
1861     xmlParserInputShrink(ctxt->input);
1862     if ((*ctxt->input->cur == 0) &&
1863         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
1864             xmlPopInput(ctxt);
1865   }
1866
1867 #define GROW if ((ctxt->progressive == 0) &&                            \
1868                  (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))   \
1869         xmlGROW (ctxt);
1870
1871 static void xmlGROW (xmlParserCtxtPtr ctxt) {
1872     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
1873     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
1874         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
1875             xmlPopInput(ctxt);
1876 }
1877
1878 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
1879
1880 #define NEXT xmlNextChar(ctxt)
1881
1882 #define NEXT1 {                                                         \
1883         ctxt->input->col++;                                             \
1884         ctxt->input->cur++;                                             \
1885         ctxt->nbChars++;                                                \
1886         if (*ctxt->input->cur == 0)                                     \
1887             xmlParserInputGrow(ctxt->input, INPUT_CHUNK);               \
1888     }
1889
1890 #define NEXTL(l) do {                                                   \
1891     if (*(ctxt->input->cur) == '\n') {                                  \
1892         ctxt->input->line++; ctxt->input->col = 1;                      \
1893     } else ctxt->input->col++;                                          \
1894     ctxt->input->cur += l;                              \
1895     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
1896   } while (0)
1897
1898 #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
1899 #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
1900
1901 #define COPY_BUF(l,b,i,v)                                               \
1902     if (l == 1) b[i++] = (xmlChar) v;                                   \
1903     else i += xmlCopyCharMultiByte(&b[i],v)
1904
1905 /**
1906  * xmlSkipBlankChars:
1907  * @ctxt:  the XML parser context
1908  *
1909  * skip all blanks character found at that point in the input streams.
1910  * It pops up finished entities in the process if allowable at that point.
1911  *
1912  * Returns the number of space chars skipped
1913  */
1914
1915 int
1916 xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
1917     int res = 0;
1918
1919     /*
1920      * It's Okay to use CUR/NEXT here since all the blanks are on
1921      * the ASCII range.
1922      */
1923     if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
1924         const xmlChar *cur;
1925         /*
1926          * if we are in the document content, go really fast
1927          */
1928         cur = ctxt->input->cur;
1929         while (IS_BLANK_CH(*cur)) {
1930             if (*cur == '\n') {
1931                 ctxt->input->line++; ctxt->input->col = 1;
1932             }
1933             cur++;
1934             res++;
1935             if (*cur == 0) {
1936                 ctxt->input->cur = cur;
1937                 xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
1938                 cur = ctxt->input->cur;
1939             }
1940         }
1941         ctxt->input->cur = cur;
1942     } else {
1943         int cur;
1944         do {
1945             cur = CUR;
1946             while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
1947                 NEXT;
1948                 cur = CUR;
1949                 res++;
1950             }
1951             while ((cur == 0) && (ctxt->inputNr > 1) &&
1952                    (ctxt->instate != XML_PARSER_COMMENT)) {
1953                 xmlPopInput(ctxt);
1954                 cur = CUR;
1955             }
1956             /*
1957              * Need to handle support of entities branching here
1958              */
1959             if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
1960         } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
1961     }
1962     return(res);
1963 }
1964
1965 /************************************************************************
1966  *                                                                      *
1967  *              Commodity functions to handle entities                  *
1968  *                                                                      *
1969  ************************************************************************/
1970
1971 /**
1972  * xmlPopInput:
1973  * @ctxt:  an XML parser context
1974  *
1975  * xmlPopInput: the current input pointed by ctxt->input came to an end
1976  *          pop it and return the next char.
1977  *
1978  * Returns the current xmlChar in the parser context
1979  */
1980 xmlChar
1981 xmlPopInput(xmlParserCtxtPtr ctxt) {
1982     if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
1983     if (xmlParserDebugEntities)
1984         xmlGenericError(xmlGenericErrorContext,
1985                 "Popping input %d\n", ctxt->inputNr);
1986     xmlFreeInputStream(inputPop(ctxt));
1987     if ((*ctxt->input->cur == 0) &&
1988         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
1989             return(xmlPopInput(ctxt));
1990     return(CUR);
1991 }
1992
1993 /**
1994  * xmlPushInput:
1995  * @ctxt:  an XML parser context
1996  * @input:  an XML parser input fragment (entity, XML fragment ...).
1997  *
1998  * xmlPushInput: switch to a new input stream which is stacked on top
1999  *               of the previous one(s).
2000  * Returns -1 in case of error or the index in the input stack
2001  */
2002 int
2003 xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
2004     int ret;
2005     if (input == NULL) return(-1);
2006
2007     if (xmlParserDebugEntities) {
2008         if ((ctxt->input != NULL) && (ctxt->input->filename))
2009             xmlGenericError(xmlGenericErrorContext,
2010                     "%s(%d): ", ctxt->input->filename,
2011                     ctxt->input->line);
2012         xmlGenericError(xmlGenericErrorContext,
2013                 "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
2014     }
2015     ret = inputPush(ctxt, input);
2016     if (ctxt->instate == XML_PARSER_EOF)
2017         return(-1);
2018     GROW;
2019     return(ret);
2020 }
2021
2022 /**
2023  * xmlParseCharRef:
2024  * @ctxt:  an XML parser context
2025  *
2026  * parse Reference declarations
2027  *
2028  * [66] CharRef ::= '&#' [0-9]+ ';' |
2029  *                  '&#x' [0-9a-fA-F]+ ';'
2030  *
2031  * [ WFC: Legal Character ]
2032  * Characters referred to using character references must match the
2033  * production for Char. 
2034  *
2035  * Returns the value parsed (as an int), 0 in case of error
2036  */
2037 int
2038 xmlParseCharRef(xmlParserCtxtPtr ctxt) {
2039     unsigned int val = 0;
2040     int count = 0;
2041     unsigned int outofrange = 0;
2042
2043     /*
2044      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
2045      */
2046     if ((RAW == '&') && (NXT(1) == '#') &&
2047         (NXT(2) == 'x')) {
2048         SKIP(3);
2049         GROW;
2050         while (RAW != ';') { /* loop blocked by count */
2051             if (count++ > 20) {
2052                 count = 0;
2053                 GROW;
2054                 if (ctxt->instate == XML_PARSER_EOF)
2055                     return(0);
2056             }
2057             if ((RAW >= '0') && (RAW <= '9')) 
2058                 val = val * 16 + (CUR - '0');
2059             else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
2060                 val = val * 16 + (CUR - 'a') + 10;
2061             else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
2062                 val = val * 16 + (CUR - 'A') + 10;
2063             else {
2064                 xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2065                 val = 0;
2066                 break;
2067             }
2068             if (val > 0x10FFFF)
2069                 outofrange = val;
2070
2071             NEXT;
2072             count++;
2073         }
2074         if (RAW == ';') {
2075             /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2076             ctxt->input->col++;
2077             ctxt->nbChars ++;
2078             ctxt->input->cur++;
2079         }
2080     } else if  ((RAW == '&') && (NXT(1) == '#')) {
2081         SKIP(2);
2082         GROW;
2083         while (RAW != ';') { /* loop blocked by count */
2084             if (count++ > 20) {
2085                 count = 0;
2086                 GROW;
2087                 if (ctxt->instate == XML_PARSER_EOF)
2088                     return(0);
2089             }
2090             if ((RAW >= '0') && (RAW <= '9')) 
2091                 val = val * 10 + (CUR - '0');
2092             else {
2093                 xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2094                 val = 0;
2095                 break;
2096             }
2097             if (val > 0x10FFFF)
2098                 outofrange = val;
2099
2100             NEXT;
2101             count++;
2102         }
2103         if (RAW == ';') {
2104             /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2105             ctxt->input->col++;
2106             ctxt->nbChars ++;
2107             ctxt->input->cur++;
2108         }
2109     } else {
2110         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2111     }
2112
2113     /*
2114      * [ WFC: Legal Character ]
2115      * Characters referred to using character references must match the
2116      * production for Char. 
2117      */
2118     if ((IS_CHAR(val) && (outofrange == 0))) {
2119         return(val);
2120     } else {
2121         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2122                           "xmlParseCharRef: invalid xmlChar value %d\n",
2123                           val);
2124     }
2125     return(0);
2126 }
2127
2128 /**
2129  * xmlParseStringCharRef:
2130  * @ctxt:  an XML parser context
2131  * @str:  a pointer to an index in the string
2132  *
2133  * parse Reference declarations, variant parsing from a string rather
2134  * than an an input flow.
2135  *
2136  * [66] CharRef ::= '&#' [0-9]+ ';' |
2137  *                  '&#x' [0-9a-fA-F]+ ';'
2138  *
2139  * [ WFC: Legal Character ]
2140  * Characters referred to using character references must match the
2141  * production for Char. 
2142  *
2143  * Returns the value parsed (as an int), 0 in case of error, str will be
2144  *         updated to the current value of the index
2145  */
2146 static int
2147 xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
2148     const xmlChar *ptr;
2149     xmlChar cur;
2150     unsigned int val = 0;
2151     unsigned int outofrange = 0;
2152
2153     if ((str == NULL) || (*str == NULL)) return(0);
2154     ptr = *str;
2155     cur = *ptr;
2156     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
2157         ptr += 3;
2158         cur = *ptr;
2159         while (cur != ';') { /* Non input consuming loop */
2160             if ((cur >= '0') && (cur <= '9')) 
2161                 val = val * 16 + (cur - '0');
2162             else if ((cur >= 'a') && (cur <= 'f'))
2163                 val = val * 16 + (cur - 'a') + 10;
2164             else if ((cur >= 'A') && (cur <= 'F'))
2165                 val = val * 16 + (cur - 'A') + 10;
2166             else {
2167                 xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2168                 val = 0;
2169                 break;
2170             }
2171             if (val > 0x10FFFF)
2172                 outofrange = val;
2173
2174             ptr++;
2175             cur = *ptr;
2176         }
2177         if (cur == ';')
2178             ptr++;
2179     } else if  ((cur == '&') && (ptr[1] == '#')){
2180         ptr += 2;
2181         cur = *ptr;
2182         while (cur != ';') { /* Non input consuming loops */
2183             if ((cur >= '0') && (cur <= '9')) 
2184                 val = val * 10 + (cur - '0');
2185             else {
2186                 xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2187                 val = 0;
2188                 break;
2189             }
2190             if (val > 0x10FFFF)
2191                 outofrange = val;
2192
2193             ptr++;
2194             cur = *ptr;
2195         }
2196         if (cur == ';')
2197             ptr++;
2198     } else {
2199         xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2200         return(0);
2201     }
2202     *str = ptr;
2203
2204     /*
2205      * [ WFC: Legal Character ]
2206      * Characters referred to using character references must match the
2207      * production for Char. 
2208      */
2209     if ((IS_CHAR(val) && (outofrange == 0))) {
2210         return(val);
2211     } else {
2212         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2213                           "xmlParseStringCharRef: invalid xmlChar value %d\n",
2214                           val);
2215     }
2216     return(0);
2217 }
2218
2219 /**
2220  * xmlNewBlanksWrapperInputStream:
2221  * @ctxt:  an XML parser context
2222  * @entity:  an Entity pointer
2223  *
2224  * Create a new input stream for wrapping
2225  * blanks around a PEReference
2226  *
2227  * Returns the new input stream or NULL
2228  */
2229  
2230 static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
2231  
2232 static xmlParserInputPtr
2233 xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
2234     xmlParserInputPtr input;
2235     xmlChar *buffer;
2236     size_t length;
2237     if (entity == NULL) {
2238         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
2239                     "xmlNewBlanksWrapperInputStream entity\n");
2240         return(NULL);
2241     }
2242     if (xmlParserDebugEntities)
2243         xmlGenericError(xmlGenericErrorContext,
2244                 "new blanks wrapper for entity: %s\n", entity->name);
2245     input = xmlNewInputStream(ctxt);
2246     if (input == NULL) {
2247         return(NULL);
2248     }
2249     length = xmlStrlen(entity->name) + 5;
2250     buffer = xmlMallocAtomic(length);
2251     if (buffer == NULL) {
2252         xmlErrMemory(ctxt, NULL);
2253         xmlFree(input);
2254         return(NULL);
2255     }
2256     buffer [0] = ' ';
2257     buffer [1] = '%';
2258     buffer [length-3] = ';';
2259     buffer [length-2] = ' ';
2260     buffer [length-1] = 0;
2261     memcpy(buffer + 2, entity->name, length - 5);
2262     input->free = deallocblankswrapper;
2263     input->base = buffer;
2264     input->cur = buffer;
2265     input->length = length;
2266     input->end = &buffer[length];
2267     return(input);
2268 }
2269
2270 /**
2271  * xmlParserHandlePEReference:
2272  * @ctxt:  the parser context
2273  * 
2274  * [69] PEReference ::= '%' Name ';'
2275  *
2276  * [ WFC: No Recursion ]
2277  * A parsed entity must not contain a recursive
2278  * reference to itself, either directly or indirectly. 
2279  *
2280  * [ WFC: Entity Declared ]
2281  * In a document without any DTD, a document with only an internal DTD
2282  * subset which contains no parameter entity references, or a document
2283  * with "standalone='yes'", ...  ... The declaration of a parameter
2284  * entity must precede any reference to it...
2285  *
2286  * [ VC: Entity Declared ]
2287  * In a document with an external subset or external parameter entities
2288  * with "standalone='no'", ...  ... The declaration of a parameter entity
2289  * must precede any reference to it...
2290  *
2291  * [ WFC: In DTD ]
2292  * Parameter-entity references may only appear in the DTD.
2293  * NOTE: misleading but this is handled.
2294  *
2295  * A PEReference may have been detected in the current input stream
2296  * the handling is done accordingly to 
2297  *      http://www.w3.org/TR/REC-xml#entproc
2298  * i.e. 
2299  *   - Included in literal in entity values
2300  *   - Included as Parameter Entity reference within DTDs
2301  */
2302 void
2303 xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
2304     const xmlChar *name;
2305     xmlEntityPtr entity = NULL;
2306     xmlParserInputPtr input;
2307
2308     if (RAW != '%') return;
2309     switch(ctxt->instate) {
2310         case XML_PARSER_CDATA_SECTION:
2311             return;
2312         case XML_PARSER_COMMENT:
2313             return;
2314         case XML_PARSER_START_TAG:
2315             return;
2316         case XML_PARSER_END_TAG:
2317             return;
2318         case XML_PARSER_EOF:
2319             xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
2320             return;
2321         case XML_PARSER_PROLOG:
2322         case XML_PARSER_START:
2323         case XML_PARSER_MISC:
2324             xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
2325             return;
2326         case XML_PARSER_ENTITY_DECL:
2327         case XML_PARSER_CONTENT:
2328         case XML_PARSER_ATTRIBUTE_VALUE:
2329         case XML_PARSER_PI:
2330         case XML_PARSER_SYSTEM_LITERAL:
2331         case XML_PARSER_PUBLIC_LITERAL:
2332             /* we just ignore it there */
2333             return;
2334         case XML_PARSER_EPILOG:
2335             xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
2336             return;
2337         case XML_PARSER_ENTITY_VALUE:
2338             /*
2339              * NOTE: in the case of entity values, we don't do the
2340              *       substitution here since we need the literal
2341              *       entity value to be able to save the internal
2342              *       subset of the document.
2343              *       This will be handled by xmlStringDecodeEntities
2344              */
2345             return;
2346         case XML_PARSER_DTD:
2347             /*
2348              * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
2349              * In the internal DTD subset, parameter-entity references
2350              * can occur only where markup declarations can occur, not
2351              * within markup declarations.
2352              * In that case this is handled in xmlParseMarkupDecl
2353              */
2354             if ((ctxt->external == 0) && (ctxt->inputNr == 1))
2355                 return;
2356             if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
2357                 return;
2358             break;
2359         case XML_PARSER_IGNORE:
2360             return;
2361     }
2362
2363     NEXT;
2364     name = xmlParseName(ctxt);
2365     if (xmlParserDebugEntities)
2366         xmlGenericError(xmlGenericErrorContext,
2367                 "PEReference: %s\n", name);
2368     if (name == NULL) {
2369         xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
2370     } else {
2371         if (RAW == ';') {
2372             NEXT;
2373             if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
2374                 entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
2375             if (ctxt->instate == XML_PARSER_EOF)
2376                 return;
2377             if (entity == NULL) {
2378                 
2379                 /*
2380                  * [ WFC: Entity Declared ]
2381                  * In a document without any DTD, a document with only an
2382                  * internal DTD subset which contains no parameter entity
2383                  * references, or a document with "standalone='yes'", ...
2384                  * ... The declaration of a parameter entity must precede
2385                  * any reference to it...
2386                  */
2387                 if ((ctxt->standalone == 1) ||
2388                     ((ctxt->hasExternalSubset == 0) &&
2389                      (ctxt->hasPErefs == 0))) {
2390                     xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
2391                          "PEReference: %%%s; not found\n", name);
2392                 } else {
2393                     /*
2394                      * [ VC: Entity Declared ]
2395                      * In a document with an external subset or external
2396                      * parameter entities with "standalone='no'", ...
2397                      * ... The declaration of a parameter entity must precede
2398                      * any reference to it...
2399                      */
2400                     if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
2401                         xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
2402                                          "PEReference: %%%s; not found\n",
2403                                          name, NULL);
2404                     } else 
2405                         xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
2406                                       "PEReference: %%%s; not found\n",
2407                                       name, NULL);
2408                     ctxt->valid = 0;
2409                 }
2410             } else if (ctxt->input->free != deallocblankswrapper) {
2411                     input = xmlNewBlanksWrapperInputStream(ctxt, entity);
2412                     if (xmlPushInput(ctxt, input) < 0)
2413                         return;
2414             } else {
2415                 if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
2416                     (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
2417                     xmlChar start[4];
2418                     xmlCharEncoding enc;
2419
2420                     /*
2421                      * handle the extra spaces added before and after
2422                      * c.f. http://www.w3.org/TR/REC-xml#as-PE
2423                      * this is done independently.
2424                      */
2425                     input = xmlNewEntityInputStream(ctxt, entity);
2426                     if (xmlPushInput(ctxt, input) < 0)
2427                         return;
2428
2429                     /* 
2430                      * Get the 4 first bytes and decode the charset
2431                      * if enc != XML_CHAR_ENCODING_NONE
2432                      * plug some encoding conversion routines.
2433                      * Note that, since we may have some non-UTF8
2434                      * encoding (like UTF16, bug 135229), the 'length'
2435                      * is not known, but we can calculate based upon
2436                      * the amount of data in the buffer.
2437                      */
2438                     GROW
2439                     if (ctxt->instate == XML_PARSER_EOF)
2440                         return;
2441                     if ((ctxt->input->end - ctxt->input->cur)>=4) {
2442                         start[0] = RAW;
2443                         start[1] = NXT(1);
2444                         start[2] = NXT(2);
2445                         start[3] = NXT(3);
2446                         enc = xmlDetectCharEncoding(start, 4);
2447                         if (enc != XML_CHAR_ENCODING_NONE) {
2448                             xmlSwitchEncoding(ctxt, enc);
2449                         }
2450                     }
2451
2452                     if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
2453                         (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
2454                         (IS_BLANK_CH(NXT(5)))) {
2455                         xmlParseTextDecl(ctxt);
2456                     }
2457                 } else {
2458                     xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
2459                              "PEReference: %s is not a parameter entity\n",
2460                                       name);
2461                 }
2462             }
2463         } else {
2464             xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
2465         }
2466     }
2467 }
2468
2469 /*
2470  * Macro used to grow the current buffer.
2471  */
2472 #define growBuffer(buffer, n) {                                         \
2473     xmlChar *tmp;                                                       \
2474     buffer##_size *= 2;                                                 \
2475     buffer##_size += n;                                                 \
2476     tmp = (xmlChar *)                                                   \
2477                 xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));    \
2478     if (tmp == NULL) goto mem_error;                                    \
2479     buffer = tmp;                                                       \
2480 }
2481
2482 /**
2483  * xmlStringLenDecodeEntities:
2484  * @ctxt:  the parser context
2485  * @str:  the input string
2486  * @len: the string length
2487  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2488  * @end:  an end marker xmlChar, 0 if none
2489  * @end2:  an end marker xmlChar, 0 if none
2490  * @end3:  an end marker xmlChar, 0 if none
2491  * 
2492  * Takes a entity string content and process to do the adequate substitutions.
2493  *
2494  * [67] Reference ::= EntityRef | CharRef
2495  *
2496  * [69] PEReference ::= '%' Name ';'
2497  *
2498  * Returns A newly allocated string with the substitution done. The caller
2499  *      must deallocate it !
2500  */
2501 xmlChar *
2502 xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2503                       int what, xmlChar end, xmlChar  end2, xmlChar end3) {
2504     xmlChar *buffer = NULL;
2505     int buffer_size = 0;
2506
2507     xmlChar *current = NULL;
2508     xmlChar *rep = NULL;
2509     const xmlChar *last;
2510     xmlEntityPtr ent;
2511     int c,l;
2512     int nbchars = 0;
2513
2514     if ((ctxt == NULL) || (str == NULL) || (len < 0))
2515         return(NULL);
2516     last = str + len;
2517
2518     if (((ctxt->depth > 40) &&
2519          ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2520         (ctxt->depth > 1024)) {
2521         xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2522         return(NULL);
2523     }
2524
2525     /*
2526      * allocate a translation buffer.
2527      */
2528     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
2529     buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
2530     if (buffer == NULL) goto mem_error;
2531
2532     /*
2533      * OK loop until we reach one of the ending char or a size limit.
2534      * we are operating on already parsed values.
2535      */
2536     if (str < last)
2537         c = CUR_SCHAR(str, l);
2538     else
2539         c = 0;
2540     while ((c != 0) && (c != end) && /* non input consuming loop */
2541            (c != end2) && (c != end3)) {
2542
2543         if (c == 0) break;
2544         if ((c == '&') && (str[1] == '#')) {
2545             int val = xmlParseStringCharRef(ctxt, &str);
2546             if (val != 0) {
2547                 COPY_BUF(0,buffer,nbchars,val);
2548             }
2549             if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
2550                 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2551             }
2552         } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
2553             if (xmlParserDebugEntities)
2554                 xmlGenericError(xmlGenericErrorContext,
2555                         "String decoding Entity Reference: %.30s\n",
2556                         str);
2557             ent = xmlParseStringEntityRef(ctxt, &str);
2558             if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
2559                 (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
2560                 goto int_error;
2561             if (ent != NULL)
2562                 ctxt->nbentities += ent->checked;
2563             if ((ent != NULL) &&
2564                 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
2565                 if (ent->content != NULL) {
2566                     COPY_BUF(0,buffer,nbchars,ent->content[0]);
2567                     if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
2568                         growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2569                     }
2570                 } else {
2571                     xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
2572                             "predefined entity has no content\n");
2573                 }
2574             } else if ((ent != NULL) && (ent->content != NULL)) {
2575                 ctxt->depth++;
2576                 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2577                                               0, 0, 0);
2578                 ctxt->depth--;
2579
2580                 if (rep != NULL) {
2581                     current = rep;
2582                     while (*current != 0) { /* non input consuming loop */
2583                         buffer[nbchars++] = *current++;
2584                         if (nbchars >
2585                             buffer_size - XML_PARSER_BUFFER_SIZE) {
2586                             if (xmlParserEntityCheck(ctxt, nbchars, ent))
2587                                 goto int_error;
2588                             growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2589                         }
2590                     }
2591                     xmlFree(rep);
2592                     rep = NULL;
2593                 }
2594             } else if (ent != NULL) {
2595                 int i = xmlStrlen(ent->name);
2596                 const xmlChar *cur = ent->name;
2597
2598                 buffer[nbchars++] = '&';
2599                 if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
2600                     growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
2601                 }
2602                 for (;i > 0;i--)
2603                     buffer[nbchars++] = *cur++;
2604                 buffer[nbchars++] = ';';
2605             }
2606         } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
2607             if (xmlParserDebugEntities)
2608                 xmlGenericError(xmlGenericErrorContext,
2609                         "String decoding PE Reference: %.30s\n", str);
2610             ent = xmlParseStringPEReference(ctxt, &str);
2611             if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
2612                 goto int_error;
2613             if (ent != NULL)
2614                 ctxt->nbentities += ent->checked;
2615             if (ent != NULL) {
2616                 if (ent->content == NULL) {
2617                     xmlLoadEntityContent(ctxt, ent);
2618                 }
2619                 ctxt->depth++;
2620                 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2621                                               0, 0, 0);
2622                 ctxt->depth--;
2623                 if (rep != NULL) {
2624                     current = rep;
2625                     while (*current != 0) { /* non input consuming loop */
2626                         buffer[nbchars++] = *current++;
2627                         if (nbchars >
2628                             buffer_size - XML_PARSER_BUFFER_SIZE) {
2629                             if (xmlParserEntityCheck(ctxt, nbchars, ent))
2630                                 goto int_error;
2631                             growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2632                         }
2633                     }
2634                     xmlFree(rep);
2635                     rep = NULL;
2636                 }
2637             }
2638         } else {
2639             COPY_BUF(l,buffer,nbchars,c);
2640             str += l;
2641             if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
2642               growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2643             }
2644         }
2645         if (str < last)
2646             c = CUR_SCHAR(str, l);
2647         else
2648             c = 0;
2649     }
2650     buffer[nbchars] = 0;
2651     return(buffer);
2652
2653 mem_error:
2654     xmlErrMemory(ctxt, NULL);
2655 int_error:
2656     if (rep != NULL)
2657         xmlFree(rep);
2658     if (buffer != NULL)
2659         xmlFree(buffer);
2660     return(NULL);
2661 }
2662
2663 /**
2664  * xmlStringDecodeEntities:
2665  * @ctxt:  the parser context
2666  * @str:  the input string
2667  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2668  * @end:  an end marker xmlChar, 0 if none
2669  * @end2:  an end marker xmlChar, 0 if none
2670  * @end3:  an end marker xmlChar, 0 if none
2671  * 
2672  * Takes a entity string content and process to do the adequate substitutions.
2673  *
2674  * [67] Reference ::= EntityRef | CharRef
2675  *
2676  * [69] PEReference ::= '%' Name ';'
2677  *
2678  * Returns A newly allocated string with the substitution done. The caller
2679  *      must deallocate it !
2680  */
2681 xmlChar *
2682 xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
2683                         xmlChar end, xmlChar  end2, xmlChar end3) {
2684     if ((ctxt == NULL) || (str == NULL)) return(NULL);
2685     return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
2686            end, end2, end3));
2687 }
2688
2689 /************************************************************************
2690  *                                                                      *
2691  *              Commodity functions, cleanup needed ?                   *
2692  *                                                                      *
2693  ************************************************************************/
2694
2695 /**
2696  * areBlanks:
2697  * @ctxt:  an XML parser context
2698  * @str:  a xmlChar *
2699  * @len:  the size of @str
2700  * @blank_chars: we know the chars are blanks
2701  *
2702  * Is this a sequence of blank chars that one can ignore ?
2703  *
2704  * Returns 1 if ignorable 0 otherwise.
2705  */
2706
2707 static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2708                      int blank_chars) {
2709     int i, ret;
2710     xmlNodePtr lastChild;
2711
2712     /*
2713      * Don't spend time trying to differentiate them, the same callback is
2714      * used !
2715      */
2716     if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
2717         return(0);
2718
2719     /*
2720      * Check for xml:space value.
2721      */
2722     if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
2723         (*(ctxt->space) == -2))
2724         return(0);
2725
2726     /*
2727      * Check that the string is made of blanks
2728      */
2729     if (blank_chars == 0) {
2730         for (i = 0;i < len;i++)
2731             if (!(IS_BLANK_CH(str[i]))) return(0);
2732     }
2733
2734     /*
2735      * Look if the element is mixed content in the DTD if available
2736      */
2737     if (ctxt->node == NULL) return(0);
2738     if (ctxt->myDoc != NULL) {
2739         ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
2740         if (ret == 0) return(1);
2741         if (ret == 1) return(0);
2742     }
2743
2744     /*
2745      * Otherwise, heuristic :-\
2746      */
2747     if ((RAW != '<') && (RAW != 0xD)) return(0);
2748     if ((ctxt->node->children == NULL) &&
2749         (RAW == '<') && (NXT(1) == '/')) return(0);
2750
2751     lastChild = xmlGetLastChild(ctxt->node);
2752     if (lastChild == NULL) {
2753         if ((ctxt->node->type != XML_ELEMENT_NODE) &&
2754             (ctxt->node->content != NULL)) return(0);
2755     } else if (xmlNodeIsText(lastChild))
2756         return(0);
2757     else if ((ctxt->node->children != NULL) &&
2758              (xmlNodeIsText(ctxt->node->children)))
2759         return(0);
2760     return(1);
2761 }
2762
2763 /************************************************************************
2764  *                                                                      *
2765  *              Extra stuff for namespace support                       *
2766  *      Relates to http://www.w3.org/TR/WD-xml-names                    *
2767  *                                                                      *
2768  ************************************************************************/
2769
2770 /**
2771  * xmlSplitQName:
2772  * @ctxt:  an XML parser context
2773  * @name:  an XML parser context
2774  * @prefix:  a xmlChar **
2775  *
2776  * parse an UTF8 encoded XML qualified name string
2777  *
2778  * [NS 5] QName ::= (Prefix ':')? LocalPart
2779  *
2780  * [NS 6] Prefix ::= NCName
2781  *
2782  * [NS 7] LocalPart ::= NCName
2783  *
2784  * Returns the local part, and prefix is updated
2785  *   to get the Prefix if any.
2786  */
2787
2788 xmlChar *
2789 xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
2790     xmlChar buf[XML_MAX_NAMELEN + 5];
2791     xmlChar *buffer = NULL;
2792     int len = 0;
2793     int max = XML_MAX_NAMELEN;
2794     xmlChar *ret = NULL;
2795     const xmlChar *cur = name;
2796     int c;
2797
2798     if (prefix == NULL) return(NULL);
2799     *prefix = NULL;
2800
2801     if (cur == NULL) return(NULL);
2802
2803 #ifndef XML_XML_NAMESPACE
2804     /* xml: prefix is not really a namespace */
2805     if ((cur[0] == 'x') && (cur[1] == 'm') &&
2806         (cur[2] == 'l') && (cur[3] == ':'))
2807         return(xmlStrdup(name));
2808 #endif
2809
2810     /* nasty but well=formed */
2811     if (cur[0] == ':')
2812         return(xmlStrdup(name));
2813
2814     c = *cur++;
2815     while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
2816         buf[len++] = c;
2817         c = *cur++;
2818     }
2819     if (len >= max) {
2820         /*
2821          * Okay someone managed to make a huge name, so he's ready to pay
2822          * for the processing speed.
2823          */
2824         max = len * 2;
2825
2826         buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
2827         if (buffer == NULL) {
2828             xmlErrMemory(ctxt, NULL);
2829             return(NULL);
2830         }
2831         memcpy(buffer, buf, len);
2832         while ((c != 0) && (c != ':')) { /* tested bigname.xml */
2833             if (len + 10 > max) {
2834                 xmlChar *tmp;
2835
2836                 max *= 2;
2837                 tmp = (xmlChar *) xmlRealloc(buffer,
2838                                                 max * sizeof(xmlChar));
2839                 if (tmp == NULL) {
2840                     xmlFree(buffer);
2841                     xmlErrMemory(ctxt, NULL);
2842                     return(NULL);
2843                 }
2844                 buffer = tmp;
2845             }
2846             buffer[len++] = c;
2847             c = *cur++;
2848         }
2849         buffer[len] = 0;
2850     }
2851
2852     if ((c == ':') && (*cur == 0)) {
2853         if (buffer != NULL)
2854             xmlFree(buffer);
2855         *prefix = NULL;
2856         return(xmlStrdup(name));
2857     }
2858
2859     if (buffer == NULL)
2860         ret = xmlStrndup(buf, len);
2861     else {
2862         ret = buffer;
2863         buffer = NULL;
2864         max = XML_MAX_NAMELEN;
2865     }
2866
2867
2868     if (c == ':') {
2869         c = *cur;
2870         *prefix = ret;
2871         if (c == 0) {
2872             return(xmlStrndup(BAD_CAST "", 0));
2873         }
2874         len = 0;
2875
2876         /*
2877          * Check that the first character is proper to start
2878          * a new name
2879          */
2880         if (!(((c >= 0x61) && (c <= 0x7A)) ||
2881               ((c >= 0x41) && (c <= 0x5A)) ||
2882               (c == '_') || (c == ':'))) {
2883             int l;
2884             int first = CUR_SCHAR(cur, l);
2885
2886             if (!IS_LETTER(first) && (first != '_')) {
2887                 xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
2888                             "Name %s is not XML Namespace compliant\n",
2889                                   name);
2890             }
2891         }
2892         cur++;
2893
2894         while ((c != 0) && (len < max)) { /* tested bigname2.xml */
2895             buf[len++] = c;
2896             c = *cur++;
2897         }
2898         if (len >= max) {
2899             /*
2900              * Okay someone managed to make a huge name, so he's ready to pay
2901              * for the processing speed.
2902              */
2903             max = len * 2;
2904
2905             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
2906             if (buffer == NULL) {
2907                 xmlErrMemory(ctxt, NULL);
2908                 return(NULL);
2909             }
2910             memcpy(buffer, buf, len);
2911             while (c != 0) { /* tested bigname2.xml */
2912                 if (len + 10 > max) {
2913                     xmlChar *tmp;
2914
2915                     max *= 2;
2916                     tmp = (xmlChar *) xmlRealloc(buffer,
2917                                                     max * sizeof(xmlChar));
2918                     if (tmp == NULL) {
2919                         xmlErrMemory(ctxt, NULL);
2920                         xmlFree(buffer);
2921                         return(NULL);
2922                     }
2923                     buffer = tmp;
2924                 }
2925                 buffer[len++] = c;
2926                 c = *cur++;
2927             }
2928             buffer[len] = 0;
2929         }
2930
2931         if (buffer == NULL)
2932             ret = xmlStrndup(buf, len);
2933         else {
2934             ret = buffer;
2935         }
2936     }
2937
2938     return(ret);
2939 }
2940
2941 /************************************************************************
2942  *                                                                      *
2943  *                      The parser itself                               *
2944  *      Relates to http://www.w3.org/TR/REC-xml                         *
2945  *                                                                      *
2946  ************************************************************************/
2947
2948 /************************************************************************
2949  *                                                                      *
2950  *      Routines to parse Name, NCName and NmToken                      *
2951  *                                                                      *
2952  ************************************************************************/
2953 #ifdef DEBUG
2954 static unsigned long nbParseName = 0;
2955 static unsigned long nbParseNmToken = 0;
2956 static unsigned long nbParseNCName = 0;
2957 static unsigned long nbParseNCNameComplex = 0;
2958 static unsigned long nbParseNameComplex = 0;
2959 static unsigned long nbParseStringName = 0;
2960 #endif
2961
2962 /*
2963  * The two following functions are related to the change of accepted
2964  * characters for Name and NmToken in the Revision 5 of XML-1.0
2965  * They correspond to the modified production [4] and the new production [4a]
2966  * changes in that revision. Also note that the macros used for the
2967  * productions Letter, Digit, CombiningChar and Extender are not needed
2968  * anymore.
2969  * We still keep compatibility to pre-revision5 parsing semantic if the
2970  * new XML_PARSE_OLD10 option is given to the parser.
2971  */
2972 static int
2973 xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
2974     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
2975         /*
2976          * Use the new checks of production [4] [4a] amd [5] of the
2977          * Update 5 of XML-1.0
2978          */
2979         if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
2980             (((c >= 'a') && (c <= 'z')) ||
2981              ((c >= 'A') && (c <= 'Z')) ||
2982              (c == '_') || (c == ':') ||
2983              ((c >= 0xC0) && (c <= 0xD6)) ||
2984              ((c >= 0xD8) && (c <= 0xF6)) ||
2985              ((c >= 0xF8) && (c <= 0x2FF)) ||
2986              ((c >= 0x370) && (c <= 0x37D)) ||
2987              ((c >= 0x37F) && (c <= 0x1FFF)) ||
2988              ((c >= 0x200C) && (c <= 0x200D)) ||
2989              ((c >= 0x2070) && (c <= 0x218F)) ||
2990              ((c >= 0x2C00) && (c <= 0x2FEF)) ||
2991              ((c >= 0x3001) && (c <= 0xD7FF)) ||
2992              ((c >= 0xF900) && (c <= 0xFDCF)) ||
2993              ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
2994              ((c >= 0x10000) && (c <= 0xEFFFF))))
2995             return(1);
2996     } else {
2997         if (IS_LETTER(c) || (c == '_') || (c == ':'))
2998             return(1);
2999     }
3000     return(0);
3001 }
3002
3003 static int
3004 xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
3005     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3006         /*
3007          * Use the new checks of production [4] [4a] amd [5] of the
3008          * Update 5 of XML-1.0
3009          */
3010         if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3011             (((c >= 'a') && (c <= 'z')) ||
3012              ((c >= 'A') && (c <= 'Z')) ||
3013              ((c >= '0') && (c <= '9')) || /* !start */
3014              (c == '_') || (c == ':') ||
3015              (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3016              ((c >= 0xC0) && (c <= 0xD6)) ||
3017              ((c >= 0xD8) && (c <= 0xF6)) ||
3018              ((c >= 0xF8) && (c <= 0x2FF)) ||
3019              ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3020              ((c >= 0x370) && (c <= 0x37D)) ||
3021              ((c >= 0x37F) && (c <= 0x1FFF)) ||
3022              ((c >= 0x200C) && (c <= 0x200D)) ||
3023              ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3024              ((c >= 0x2070) && (c <= 0x218F)) ||
3025              ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3026              ((c >= 0x3001) && (c <= 0xD7FF)) ||
3027              ((c >= 0xF900) && (c <= 0xFDCF)) ||
3028              ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3029              ((c >= 0x10000) && (c <= 0xEFFFF))))
3030              return(1);
3031     } else {
3032         if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3033             (c == '.') || (c == '-') ||
3034             (c == '_') || (c == ':') || 
3035             (IS_COMBINING(c)) ||
3036             (IS_EXTENDER(c)))
3037             return(1);
3038     }
3039     return(0);
3040 }
3041
3042 static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
3043                                           int *len, int *alloc, int normalize);
3044
3045 static const xmlChar *
3046 xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
3047     int len = 0, l;
3048     int c;
3049     int count = 0;
3050
3051 #ifdef DEBUG
3052     nbParseNameComplex++;
3053 #endif
3054
3055     /*
3056      * Handler for more complex cases
3057      */
3058     GROW;
3059     if (ctxt->instate == XML_PARSER_EOF)
3060         return(NULL);
3061     c = CUR_CHAR(l);
3062     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3063         /*
3064          * Use the new checks of production [4] [4a] amd [5] of the
3065          * Update 5 of XML-1.0
3066          */
3067         if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3068             (!(((c >= 'a') && (c <= 'z')) ||
3069                ((c >= 'A') && (c <= 'Z')) ||
3070                (c == '_') || (c == ':') ||
3071                ((c >= 0xC0) && (c <= 0xD6)) ||
3072                ((c >= 0xD8) && (c <= 0xF6)) ||
3073                ((c >= 0xF8) && (c <= 0x2FF)) ||
3074                ((c >= 0x370) && (c <= 0x37D)) ||
3075                ((c >= 0x37F) && (c <= 0x1FFF)) ||
3076                ((c >= 0x200C) && (c <= 0x200D)) ||
3077                ((c >= 0x2070) && (c <= 0x218F)) ||
3078                ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3079                ((c >= 0x3001) && (c <= 0xD7FF)) ||
3080                ((c >= 0xF900) && (c <= 0xFDCF)) ||
3081                ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3082                ((c >= 0x10000) && (c <= 0xEFFFF))))) {
3083             return(NULL);
3084         }
3085         len += l;
3086         NEXTL(l);
3087         c = CUR_CHAR(l);
3088         while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3089                (((c >= 'a') && (c <= 'z')) ||
3090                 ((c >= 'A') && (c <= 'Z')) ||
3091                 ((c >= '0') && (c <= '9')) || /* !start */
3092                 (c == '_') || (c == ':') ||
3093                 (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3094                 ((c >= 0xC0) && (c <= 0xD6)) ||
3095                 ((c >= 0xD8) && (c <= 0xF6)) ||
3096                 ((c >= 0xF8) && (c <= 0x2FF)) ||
3097                 ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3098                 ((c >= 0x370) && (c <= 0x37D)) ||
3099                 ((c >= 0x37F) && (c <= 0x1FFF)) ||
3100                 ((c >= 0x200C) && (c <= 0x200D)) ||
3101                 ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3102                 ((c >= 0x2070) && (c <= 0x218F)) ||
3103                 ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3104                 ((c >= 0x3001) && (c <= 0xD7FF)) ||
3105                 ((c >= 0xF900) && (c <= 0xFDCF)) ||
3106                 ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3107                 ((c >= 0x10000) && (c <= 0xEFFFF))
3108                 )) {
3109             if (count++ > 100) {
3110                 count = 0;
3111                 GROW;
3112                 if (ctxt->instate == XML_PARSER_EOF)
3113                     return(NULL);
3114             }
3115             len += l;
3116             NEXTL(l);
3117             c = CUR_CHAR(l);
3118         }
3119     } else {
3120         if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3121             (!IS_LETTER(c) && (c != '_') &&
3122              (c != ':'))) {
3123             return(NULL);
3124         }
3125         len += l;
3126         NEXTL(l);
3127         c = CUR_CHAR(l);
3128
3129         while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3130                ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3131                 (c == '.') || (c == '-') ||
3132                 (c == '_') || (c == ':') || 
3133                 (IS_COMBINING(c)) ||
3134                 (IS_EXTENDER(c)))) {
3135             if (count++ > 100) {
3136                 count = 0;
3137                 GROW;
3138                 if (ctxt->instate == XML_PARSER_EOF)
3139                     return(NULL);
3140             }
3141             len += l;
3142             NEXTL(l);
3143             c = CUR_CHAR(l);
3144         }
3145     }
3146     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
3147         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
3148     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3149 }
3150
3151 /**
3152  * xmlParseName:
3153  * @ctxt:  an XML parser context
3154  *
3155  * parse an XML name.
3156  *
3157  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3158  *                  CombiningChar | Extender
3159  *
3160  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3161  *
3162  * [6] Names ::= Name (#x20 Name)*
3163  *
3164  * Returns the Name parsed or NULL
3165  */
3166
3167 const xmlChar *
3168 xmlParseName(xmlParserCtxtPtr ctxt) {
3169     const xmlChar *in;
3170     const xmlChar *ret;
3171     int count = 0;
3172
3173     GROW;
3174
3175 #ifdef DEBUG
3176     nbParseName++;
3177 #endif
3178
3179     /*
3180      * Accelerator for simple ASCII names
3181      */
3182     in = ctxt->input->cur;
3183     if (((*in >= 0x61) && (*in <= 0x7A)) ||
3184         ((*in >= 0x41) && (*in <= 0x5A)) ||
3185         (*in == '_') || (*in == ':')) {
3186         in++;
3187         while (((*in >= 0x61) && (*in <= 0x7A)) ||
3188                ((*in >= 0x41) && (*in <= 0x5A)) ||
3189                ((*in >= 0x30) && (*in <= 0x39)) ||
3190                (*in == '_') || (*in == '-') ||
3191                (*in == ':') || (*in == '.'))
3192             in++;
3193         if ((*in > 0) && (*in < 0x80)) {
3194             count = in - ctxt->input->cur;
3195             ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3196             ctxt->input->cur = in;
3197             ctxt->nbChars += count;
3198             ctxt->input->col += count;
3199             if (ret == NULL)
3200                 xmlErrMemory(ctxt, NULL);
3201             return(ret);
3202         }
3203     }
3204     /* accelerator for special cases */
3205     return(xmlParseNameComplex(ctxt));
3206 }
3207
3208 static const xmlChar *
3209 xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
3210     int len = 0, l;
3211     int c;
3212     int count = 0;
3213
3214 #ifdef DEBUG
3215     nbParseNCNameComplex++;
3216 #endif
3217
3218     /*
3219      * Handler for more complex cases
3220      */
3221     GROW;
3222     c = CUR_CHAR(l);
3223     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3224         (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
3225         return(NULL);
3226     }
3227
3228     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3229            (xmlIsNameChar(ctxt, c) && (c != ':'))) {
3230         if (count++ > 100) {
3231             count = 0;
3232             GROW;
3233             if (ctxt->instate == XML_PARSER_EOF)
3234                 return(NULL);
3235         }
3236         len += l;
3237         NEXTL(l);
3238         c = CUR_CHAR(l);
3239     }
3240     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3241 }
3242
3243 /**
3244  * xmlParseNCName:
3245  * @ctxt:  an XML parser context
3246  * @len:  lenght of the string parsed
3247  *
3248  * parse an XML name.
3249  *
3250  * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
3251  *                      CombiningChar | Extender
3252  *
3253  * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
3254  *
3255  * Returns the Name parsed or NULL
3256  */
3257
3258 static const xmlChar *
3259 xmlParseNCName(xmlParserCtxtPtr ctxt) {
3260     const xmlChar *in;
3261     const xmlChar *ret;
3262     int count = 0;
3263
3264 #ifdef DEBUG
3265     nbParseNCName++;
3266 #endif
3267
3268     /*
3269      * Accelerator for simple ASCII names
3270      */
3271     in = ctxt->input->cur;
3272     if (((*in >= 0x61) && (*in <= 0x7A)) ||
3273         ((*in >= 0x41) && (*in <= 0x5A)) ||
3274         (*in == '_')) {
3275         in++;
3276         while (((*in >= 0x61) && (*in <= 0x7A)) ||
3277                ((*in >= 0x41) && (*in <= 0x5A)) ||
3278                ((*in >= 0x30) && (*in <= 0x39)) ||
3279                (*in == '_') || (*in == '-') ||
3280                (*in == '.'))
3281             in++;
3282         if ((*in > 0) && (*in < 0x80)) {
3283             count = in - ctxt->input->cur;
3284             ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3285             ctxt->input->cur = in;
3286             ctxt->nbChars += count;
3287             ctxt->input->col += count;
3288             if (ret == NULL) {
3289                 xmlErrMemory(ctxt, NULL);
3290             }
3291             return(ret);
3292         }
3293     }
3294     return(xmlParseNCNameComplex(ctxt));
3295 }
3296
3297 /**
3298  * xmlParseNameAndCompare:
3299  * @ctxt:  an XML parser context
3300  *
3301  * parse an XML name and compares for match
3302  * (specialized for endtag parsing)
3303  *
3304  * Returns NULL for an illegal name, (xmlChar*) 1 for success
3305  * and the name for mismatch
3306  */
3307
3308 static const xmlChar *
3309 xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
3310     register const xmlChar *cmp = other;
3311     register const xmlChar *in;
3312     const xmlChar *ret;
3313
3314     GROW;
3315     if (ctxt->instate == XML_PARSER_EOF)
3316         return(NULL);
3317
3318     in = ctxt->input->cur;
3319     while (*in != 0 && *in == *cmp) {
3320         ++in;
3321         ++cmp;
3322         ctxt->input->col++;
3323     }
3324     if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
3325         /* success */
3326         ctxt->input->cur = in;
3327         return (const xmlChar*) 1;
3328     }
3329     /* failure (or end of input buffer), check with full function */
3330     ret = xmlParseName (ctxt);
3331     /* strings coming from the dictionnary direct compare possible */
3332     if (ret == other) {
3333         return (const xmlChar*) 1;
3334     }
3335     return ret;
3336 }
3337
3338 /**
3339  * xmlParseStringName:
3340  * @ctxt:  an XML parser context
3341  * @str:  a pointer to the string pointer (IN/OUT)
3342  *
3343  * parse an XML name.
3344  *
3345  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3346  *                  CombiningChar | Extender
3347  *
3348  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3349  *
3350  * [6] Names ::= Name (#x20 Name)*
3351  *
3352  * Returns the Name parsed or NULL. The @str pointer 
3353  * is updated to the current location in the string.
3354  */
3355
3356 static xmlChar *
3357 xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
3358     xmlChar buf[XML_MAX_NAMELEN + 5];
3359     const xmlChar *cur = *str;
3360     int len = 0, l;
3361     int c;
3362
3363 #ifdef DEBUG
3364     nbParseStringName++;
3365 #endif
3366
3367     c = CUR_SCHAR(cur, l);
3368     if (!xmlIsNameStartChar(ctxt, c)) {
3369         return(NULL);
3370     }
3371
3372     COPY_BUF(l,buf,len,c);
3373     cur += l;
3374     c = CUR_SCHAR(cur, l);
3375     while (xmlIsNameChar(ctxt, c)) {
3376         COPY_BUF(l,buf,len,c);
3377         cur += l;
3378         c = CUR_SCHAR(cur, l);
3379         if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
3380             /*
3381              * Okay someone managed to make a huge name, so he's ready to pay
3382              * for the processing speed.
3383              */
3384             xmlChar *buffer;
3385             int max = len * 2;
3386
3387             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3388             if (buffer == NULL) {
3389                 xmlErrMemory(ctxt, NULL);
3390                 return(NULL);
3391             }
3392             memcpy(buffer, buf, len);
3393             while (xmlIsNameChar(ctxt, c)) {
3394                 if (len + 10 > max) {
3395                     xmlChar *tmp;
3396                     max *= 2;
3397                     tmp = (xmlChar *) xmlRealloc(buffer,
3398                                                     max * sizeof(xmlChar));
3399                     if (tmp == NULL) {
3400                         xmlErrMemory(ctxt, NULL);
3401                         xmlFree(buffer);
3402                         return(NULL);
3403                     }
3404                     buffer = tmp;
3405                 }
3406                 COPY_BUF(l,buffer,len,c);
3407                 cur += l;
3408                 c = CUR_SCHAR(cur, l);
3409             }
3410             buffer[len] = 0;
3411             *str = cur;
3412             return(buffer);
3413         }
3414     }
3415     *str = cur;
3416     return(xmlStrndup(buf, len));
3417 }
3418
3419 /**
3420  * xmlParseNmtoken:
3421  * @ctxt:  an XML parser context
3422  *
3423  * parse an XML Nmtoken.
3424  *
3425  * [7] Nmtoken ::= (NameChar)+
3426  *
3427  * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
3428  *
3429  * Returns the Nmtoken parsed or NULL
3430  */
3431
3432 xmlChar *
3433 xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
3434     xmlChar buf[XML_MAX_NAMELEN + 5];
3435     int len = 0, l;
3436     int c;
3437     int count = 0;
3438
3439 #ifdef DEBUG
3440     nbParseNmToken++;
3441 #endif
3442
3443     GROW;
3444     if (ctxt->instate == XML_PARSER_EOF)
3445         return(NULL);
3446     c = CUR_CHAR(l);
3447
3448     while (xmlIsNameChar(ctxt, c)) {
3449         if (count++ > 100) {
3450             count = 0;
3451             GROW;
3452         }
3453         COPY_BUF(l,buf,len,c);
3454         NEXTL(l);
3455         c = CUR_CHAR(l);
3456         if (len >= XML_MAX_NAMELEN) {
3457             /*
3458              * Okay someone managed to make a huge token, so he's ready to pay
3459              * for the processing speed.
3460              */
3461             xmlChar *buffer;
3462             int max = len * 2;
3463
3464             buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3465             if (buffer == NULL) {
3466                 xmlErrMemory(ctxt, NULL);
3467                 return(NULL);
3468             }
3469             memcpy(buffer, buf, len);
3470             while (xmlIsNameChar(ctxt, c)) {
3471                 if (count++ > 100) {
3472                     count = 0;
3473                     GROW;
3474                     if (ctxt->instate == XML_PARSER_EOF) {
3475                         xmlFree(buffer);
3476                         return(NULL);
3477                     }
3478                 }
3479                 if (len + 10 > max) {
3480                     xmlChar *tmp;
3481
3482                     max *= 2;
3483                     tmp = (xmlChar *) xmlRealloc(buffer,
3484                                                     max * sizeof(xmlChar));
3485                     if (tmp == NULL) {
3486                         xmlErrMemory(ctxt, NULL);
3487                         xmlFree(buffer);
3488                         return(NULL);
3489                     }
3490                     buffer = tmp;
3491                 }
3492                 COPY_BUF(l,buffer,len,c);
3493                 NEXTL(l);
3494                 c = CUR_CHAR(l);
3495             }
3496             buffer[len] = 0;
3497             return(buffer);
3498         }
3499     }
3500     if (len == 0)
3501         return(NULL);
3502     return(xmlStrndup(buf, len));
3503 }
3504
3505 /**
3506  * xmlParseEntityValue:
3507  * @ctxt:  an XML parser context
3508  * @orig:  if non-NULL store a copy of the original entity value
3509  *
3510  * parse a value for ENTITY declarations
3511  *
3512  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
3513  *                     "'" ([^%&'] | PEReference | Reference)* "'"
3514  *
3515  * Returns the EntityValue parsed with reference substituted or NULL
3516  */
3517
3518 xmlChar *
3519 xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
3520     xmlChar *buf = NULL;
3521     int len = 0;
3522     int size = XML_PARSER_BUFFER_SIZE;
3523     int c, l;
3524     xmlChar stop;
3525     xmlChar *ret = NULL;
3526     const xmlChar *cur = NULL;
3527     xmlParserInputPtr input;
3528
3529     if (RAW == '"') stop = '"';
3530     else if (RAW == '\'') stop = '\'';
3531     else {
3532         xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
3533         return(NULL);
3534     }
3535     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3536     if (buf == NULL) {
3537         xmlErrMemory(ctxt, NULL);
3538         return(NULL);
3539     }
3540
3541     /*
3542      * The content of the entity definition is copied in a buffer.
3543      */
3544
3545     ctxt->instate = XML_PARSER_ENTITY_VALUE;
3546     input = ctxt->input;
3547     GROW;
3548     if (ctxt->instate == XML_PARSER_EOF) {
3549         xmlFree(buf);
3550         return(NULL);
3551     }
3552     NEXT;
3553     c = CUR_CHAR(l);
3554     /*
3555      * NOTE: 4.4.5 Included in Literal
3556      * When a parameter entity reference appears in a literal entity
3557      * value, ... a single or double quote character in the replacement
3558      * text is always treated as a normal data character and will not
3559      * terminate the literal. 
3560      * In practice it means we stop the loop only when back at parsing
3561      * the initial entity and the quote is found
3562      */
3563     while (((IS_CHAR(c)) && ((c != stop) || /* checked */
3564             (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
3565         if (len + 5 >= size) {
3566             xmlChar *tmp;
3567
3568             size *= 2;
3569             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
3570             if (tmp == NULL) {
3571                 xmlErrMemory(ctxt, NULL);
3572                 xmlFree(buf);
3573                 return(NULL);
3574             }
3575             buf = tmp;
3576         }
3577         COPY_BUF(l,buf,len,c);
3578         NEXTL(l);
3579         /*
3580          * Pop-up of finished entities.
3581          */
3582         while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
3583             xmlPopInput(ctxt);
3584
3585         GROW;
3586         c = CUR_CHAR(l);
3587         if (c == 0) {
3588             GROW;
3589             c = CUR_CHAR(l);
3590         }
3591     }
3592     buf[len] = 0;
3593     if (ctxt->instate == XML_PARSER_EOF) {
3594         xmlFree(buf);
3595         return(NULL);
3596     }
3597
3598     /*
3599      * Raise problem w.r.t. '&' and '%' being used in non-entities
3600      * reference constructs. Note Charref will be handled in
3601      * xmlStringDecodeEntities()
3602      */
3603     cur = buf;
3604     while (*cur != 0) { /* non input consuming */
3605         if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
3606             xmlChar *name;
3607             xmlChar tmp = *cur;
3608
3609             cur++;
3610             name = xmlParseStringName(ctxt, &cur);
3611             if ((name == NULL) || (*cur != ';')) {
3612                 xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
3613             "EntityValue: '%c' forbidden except for entities references\n",
3614                                   tmp);
3615             }
3616             if ((tmp == '%') && (ctxt->inSubset == 1) &&
3617                 (ctxt->inputNr == 1)) {
3618                 xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
3619             }
3620             if (name != NULL)
3621                 xmlFree(name);
3622             if (*cur == 0)
3623                 break;
3624         }
3625         cur++;
3626     }
3627
3628     /*
3629      * Then PEReference entities are substituted.
3630      */
3631     if (c != stop) {
3632         xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
3633         xmlFree(buf);
3634     } else {
3635         NEXT;
3636         /*
3637          * NOTE: 4.4.7 Bypassed
3638          * When a general entity reference appears in the EntityValue in
3639          * an entity declaration, it is bypassed and left as is.
3640          * so XML_SUBSTITUTE_REF is not set here.
3641          */
3642         ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
3643                                       0, 0, 0);
3644         if (orig != NULL)
3645             *orig = buf;
3646         else
3647             xmlFree(buf);
3648     }
3649
3650     return(ret);
3651 }
3652
3653 /**
3654  * xmlParseAttValueComplex:
3655  * @ctxt:  an XML parser context
3656  * @len:   the resulting attribute len
3657  * @normalize:  wether to apply the inner normalization
3658  *
3659  * parse a value for an attribute, this is the fallback function
3660  * of xmlParseAttValue() when the attribute parsing requires handling
3661  * of non-ASCII characters, or normalization compaction.
3662  *
3663  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
3664  */
3665 static xmlChar *
3666 xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
3667     xmlChar limit = 0;
3668     xmlChar *buf = NULL;
3669     xmlChar *rep = NULL;
3670     int len = 0;
3671     int buf_size = 0;
3672     int c, l, in_space = 0;
3673     xmlChar *current = NULL;
3674     xmlEntityPtr ent;
3675
3676     if (NXT(0) == '"') {
3677         ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3678         limit = '"';
3679         NEXT;
3680     } else if (NXT(0) == '\'') {
3681         limit = '\'';
3682         ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3683         NEXT;
3684     } else {
3685         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
3686         return(NULL);
3687     }
3688
3689     /*
3690      * allocate a translation buffer.
3691      */
3692     buf_size = XML_PARSER_BUFFER_SIZE;
3693     buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
3694     if (buf == NULL) goto mem_error;
3695
3696     /*
3697      * OK loop until we reach one of the ending char or a size limit.
3698      */
3699     c = CUR_CHAR(l);
3700     while (((NXT(0) != limit) && /* checked */
3701             (IS_CHAR(c)) && (c != '<')) &&
3702             (ctxt->instate != XML_PARSER_EOF)) {
3703         if (c == 0) break;
3704         if (c == '&') {
3705             in_space = 0;
3706             if (NXT(1) == '#') {
3707                 int val = xmlParseCharRef(ctxt);
3708
3709                 if (val == '&') {
3710                     if (ctxt->replaceEntities) {
3711                         if (len > buf_size - 10) {
3712                             growBuffer(buf, 10);
3713                         }
3714                         buf[len++] = '&';
3715                     } else {
3716                         /*
3717                          * The reparsing will be done in xmlStringGetNodeList()
3718                          * called by the attribute() function in SAX.c
3719                          */
3720                         if (len > buf_size - 10) {
3721                             growBuffer(buf, 10);
3722                         }
3723                         buf[len++] = '&';
3724                         buf[len++] = '#';
3725                         buf[len++] = '3';
3726                         buf[len++] = '8';
3727                         buf[len++] = ';';
3728                     }
3729                 } else if (val != 0) {
3730                     if (len > buf_size - 10) {
3731                         growBuffer(buf, 10);
3732                     }
3733                     len += xmlCopyChar(0, &buf[len], val);
3734                 }
3735             } else {
3736                 ent = xmlParseEntityRef(ctxt);
3737                 ctxt->nbentities++;
3738                 if (ent != NULL)
3739                     ctxt->nbentities += ent->owner;
3740                 if ((ent != NULL) &&
3741                     (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
3742                     if (len > buf_size - 10) {
3743                         growBuffer(buf, 10);
3744                     }
3745                     if ((ctxt->replaceEntities == 0) &&
3746                         (ent->content[0] == '&')) {
3747                         buf[len++] = '&';
3748                         buf[len++] = '#';
3749                         buf[len++] = '3';
3750                         buf[len++] = '8';
3751                         buf[len++] = ';';
3752                     } else {
3753                         buf[len++] = ent->content[0];
3754                     }
3755                 } else if ((ent != NULL) && 
3756                            (ctxt->replaceEntities != 0)) {
3757                     if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
3758                         rep = xmlStringDecodeEntities(ctxt, ent->content,
3759                                                       XML_SUBSTITUTE_REF,
3760                                                       0, 0, 0);
3761                         if (rep != NULL) {
3762                             current = rep;
3763                             while (*current != 0) { /* non input consuming */
3764                                 if ((*current == 0xD) || (*current == 0xA) ||
3765                                     (*current == 0x9)) {
3766                                     buf[len++] = 0x20;
3767                                     current++;
3768                                 } else
3769                                     buf[len++] = *current++;
3770                                 if (len > buf_size - 10) {
3771                                     growBuffer(buf, 10);
3772                                 }
3773                             }
3774                             xmlFree(rep);
3775                             rep = NULL;
3776                         }
3777                     } else {
3778                         if (len > buf_size - 10) {
3779                             growBuffer(buf, 10);
3780                         }
3781                         if (ent->content != NULL)
3782                             buf[len++] = ent->content[0];
3783                     }
3784                 } else if (ent != NULL) {
3785                     int i = xmlStrlen(ent->name);
3786                     const xmlChar *cur = ent->name;
3787
3788                     /*
3789                      * This may look absurd but is needed to detect
3790                      * entities problems
3791                      */
3792                     if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
3793                         (ent->content != NULL)) {
3794                         rep = xmlStringDecodeEntities(ctxt, ent->content,
3795                                                   XML_SUBSTITUTE_REF, 0, 0, 0);
3796                         if (rep != NULL) {
3797                             xmlFree(rep);
3798                             rep = NULL;
3799                         }
3800                     }
3801
3802                     /*
3803                      * Just output the reference
3804                      */
3805                     buf[len++] = '&';
3806                     while (len > buf_size - i - 10) {
3807                         growBuffer(buf, i + 10);
3808                     }
3809                     for (;i > 0;i--)
3810                         buf[len++] = *cur++;
3811                     buf[len++] = ';';
3812                 }
3813             }
3814         } else {
3815             if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
3816                 if ((len != 0) || (!normalize)) {
3817                     if ((!normalize) || (!in_space)) {
3818                         COPY_BUF(l,buf,len,0x20);
3819                         while (len > buf_size - 10) {
3820                             growBuffer(buf, 10);
3821                         }
3822                     }
3823                     in_space = 1;
3824                 }
3825             } else {
3826                 in_space = 0;
3827                 COPY_BUF(l,buf,len,c);
3828                 if (len > buf_size - 10) {
3829                     growBuffer(buf, 10);
3830                 }
3831             }
3832             NEXTL(l);
3833         }
3834         GROW;
3835         c = CUR_CHAR(l);
3836     }
3837     if (ctxt->instate == XML_PARSER_EOF)
3838         goto error;
3839
3840     if ((in_space) && (normalize)) {
3841         while ((len > 0) && (buf[len - 1] == 0x20)) len--;
3842     }
3843     buf[len] = 0;
3844     if (RAW == '<') {
3845         xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
3846     } else if (RAW != limit) {
3847         if ((c != 0) && (!IS_CHAR(c))) {
3848             xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
3849                            "invalid character in attribute value\n");
3850         } else {
3851             xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
3852                            "AttValue: ' expected\n");
3853         }
3854     } else
3855         NEXT;
3856     if (attlen != NULL) *attlen = len;
3857     return(buf);
3858
3859 mem_error:
3860     xmlErrMemory(ctxt, NULL);
3861 error:
3862     if (buf != NULL)
3863         xmlFree(buf);
3864     if (rep != NULL)
3865         xmlFree(rep);
3866     return(NULL);
3867 }
3868
3869 /**
3870  * xmlParseAttValue:
3871  * @ctxt:  an XML parser context
3872  *
3873  * parse a value for an attribute
3874  * Note: the parser won't do substitution of entities here, this
3875  * will be handled later in xmlStringGetNodeList
3876  *
3877  * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
3878  *                   "'" ([^<&'] | Reference)* "'"
3879  *
3880  * 3.3.3 Attribute-Value Normalization:
3881  * Before the value of an attribute is passed to the application or
3882  * checked for validity, the XML processor must normalize it as follows: 
3883  * - a character reference is processed by appending the referenced
3884  *   character to the attribute value
3885  * - an entity reference is processed by recursively processing the
3886  *   replacement text of the entity 
3887  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
3888  *   appending #x20 to the normalized value, except that only a single
3889  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
3890  *   parsed entity or the literal entity value of an internal parsed entity 
3891  * - other characters are processed by appending them to the normalized value 
3892  * If the declared value is not CDATA, then the XML processor must further
3893  * process the normalized attribute value by discarding any leading and
3894  * trailing space (#x20) characters, and by replacing sequences of space
3895  * (#x20) characters by a single space (#x20) character.  
3896  * All attributes for which no declaration has been read should be treated
3897  * by a non-validating parser as if declared CDATA.
3898  *
3899  * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
3900  */
3901
3902
3903 xmlChar *
3904 xmlParseAttValue(xmlParserCtxtPtr ctxt) {
3905     if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
3906     return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
3907 }
3908
3909 /**
3910  * xmlParseSystemLiteral:
3911  * @ctxt:  an XML parser context
3912  * 
3913  * parse an XML Literal
3914  *
3915  * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
3916  *
3917  * Returns the SystemLiteral parsed or NULL
3918  */
3919
3920 xmlChar *
3921 xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
3922     xmlChar *buf = NULL;
3923     int len = 0;
3924     int size = XML_PARSER_BUFFER_SIZE;
3925     int cur, l;
3926     xmlChar stop;
3927     int state = ctxt->instate;
3928     int count = 0;
3929
3930     SHRINK;
3931     if (RAW == '"') {
3932         NEXT;
3933         stop = '"';
3934     } else if (RAW == '\'') {
3935         NEXT;
3936         stop = '\'';
3937     } else {
3938         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
3939         return(NULL);
3940     }
3941     
3942     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3943     if (buf == NULL) {
3944         xmlErrMemory(ctxt, NULL);
3945         return(NULL);
3946     }
3947     ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
3948     cur = CUR_CHAR(l);
3949     while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
3950         if (len + 5 >= size) {
3951             xmlChar *tmp;
3952
3953             size *= 2;
3954             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
3955             if (tmp == NULL) {
3956                 xmlFree(buf);
3957                 xmlErrMemory(ctxt, NULL);
3958                 ctxt->instate = (xmlParserInputState) state;
3959                 return(NULL);
3960             }
3961             buf = tmp;
3962         }
3963         count++;
3964         if (count > 50) {
3965             GROW;
3966             count = 0;
3967             if (ctxt->instate == XML_PARSER_EOF) {
3968                 xmlFree(buf);
3969                 return(NULL);
3970             }
3971         }
3972         COPY_BUF(l,buf,len,cur);
3973         NEXTL(l);
3974         cur = CUR_CHAR(l);
3975         if (cur == 0) {
3976             GROW;
3977             SHRINK;
3978             cur = CUR_CHAR(l);
3979         }
3980     }
3981     buf[len] = 0;
3982     ctxt->instate = (xmlParserInputState) state;
3983     if (!IS_CHAR(cur)) {
3984         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
3985     } else {
3986         NEXT;
3987     }
3988     return(buf);
3989 }
3990
3991 /**
3992  * xmlParsePubidLiteral:
3993  * @ctxt:  an XML parser context
3994  *
3995  * parse an XML public literal
3996  *
3997  * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
3998  *
3999  * Returns the PubidLiteral parsed or NULL.
4000  */
4001
4002 xmlChar *
4003 xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
4004     xmlChar *buf = NULL;
4005     int len = 0;
4006     int size = XML_PARSER_BUFFER_SIZE;
4007     xmlChar cur;
4008     xmlChar stop;
4009     int count = 0;
4010     xmlParserInputState oldstate = ctxt->instate;
4011
4012     SHRINK;
4013     if (RAW == '"') {
4014         NEXT;
4015         stop = '"';
4016     } else if (RAW == '\'') {
4017         NEXT;
4018         stop = '\'';
4019     } else {
4020         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4021         return(NULL);
4022     }
4023     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4024     if (buf == NULL) {
4025         xmlErrMemory(ctxt, NULL);
4026         return(NULL);
4027     }
4028     ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
4029     cur = CUR;
4030     while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
4031         if (len + 1 >= size) {
4032             xmlChar *tmp;
4033
4034             size *= 2;
4035             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4036             if (tmp == NULL) {
4037                 xmlErrMemory(ctxt, NULL);
4038                 xmlFree(buf);
4039                 return(NULL);
4040             }
4041             buf = tmp;
4042         }
4043         buf[len++] = cur;
4044         count++;
4045         if (count > 50) {
4046             GROW;
4047             count = 0;
4048             if (ctxt->instate == XML_PARSER_EOF) {
4049                 xmlFree(buf);
4050                 return(NULL);
4051             }
4052         }
4053         NEXT;
4054         cur = CUR;
4055         if (cur == 0) {
4056             GROW;
4057             SHRINK;
4058             cur = CUR;
4059         }
4060     }
4061     buf[len] = 0;
4062     if (cur != stop) {
4063         xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4064     } else {
4065         NEXT;
4066     }
4067     ctxt->instate = oldstate;
4068     return(buf);
4069 }
4070
4071 static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
4072
4073 /*
4074  * used for the test in the inner loop of the char data testing
4075  */
4076 static const unsigned char test_char_data[256] = {
4077     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4078     0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
4079     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4080     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4081     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
4082     0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
4083     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
4084     0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
4085     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
4086     0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
4087     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
4088     0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
4089     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
4090     0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
4091     0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
4092     0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
4093     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
4094     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4095     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4096     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4097     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4098     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4099     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4100     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4101     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4102     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4103     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4104     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4105     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4106     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4107     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4108     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4109 };
4110
4111 /**
4112  * xmlParseCharData:
4113  * @ctxt:  an XML parser context
4114  * @cdata:  int indicating whether we are within a CDATA section
4115  *
4116  * parse a CharData section.
4117  * if we are within a CDATA section ']]>' marks an end of section.
4118  *
4119  * The right angle bracket (>) may be represented using the string "&gt;",
4120  * and must, for compatibility, be escaped using "&gt;" or a character
4121  * reference when it appears in the string "]]>" in content, when that
4122  * string is not marking the end of a CDATA section. 
4123  *
4124  * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
4125  */
4126
4127 void
4128 xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
4129     const xmlChar *in;
4130     int nbchar = 0;
4131     int line = ctxt->input->line;
4132     int col = ctxt->input->col;
4133     int ccol;
4134
4135     SHRINK;
4136     GROW;
4137     /*
4138      * Accelerated common case where input don't need to be
4139      * modified before passing it to the handler.
4140      */
4141     if (!cdata) {
4142         in = ctxt->input->cur;
4143         do {
4144 get_more_space:
4145             while (*in == 0x20) { in++; ctxt->input->col++; }
4146             if (*in == 0xA) {
4147                 do {
4148                     ctxt->input->line++; ctxt->input->col = 1;
4149                     in++;
4150                 } while (*in == 0xA);
4151                 goto get_more_space;
4152             }
4153             if (*in == '<') {
4154                 nbchar = in - ctxt->input->cur;
4155                 if (nbchar > 0) {
4156                     const xmlChar *tmp = ctxt->input->cur;
4157                     ctxt->input->cur = in;
4158
4159                     if ((ctxt->sax != NULL) &&
4160                         (ctxt->sax->ignorableWhitespace !=
4161                          ctxt->sax->characters)) {
4162                         if (areBlanks(ctxt, tmp, nbchar, 1)) {
4163                             if (ctxt->sax->ignorableWhitespace != NULL)
4164                                 ctxt->sax->ignorableWhitespace(ctxt->userData,
4165                                                        tmp, nbchar);
4166                         } else {
4167                             if (ctxt->sax->characters != NULL)
4168                                 ctxt->sax->characters(ctxt->userData,
4169                                                       tmp, nbchar);
4170                             if (*ctxt->space == -1)
4171                                 *ctxt->space = -2;
4172                         }
4173                     } else if ((ctxt->sax != NULL) &&
4174                                (ctxt->sax->characters != NULL)) {
4175                         ctxt->sax->characters(ctxt->userData,
4176                                               tmp, nbchar);
4177                     }
4178                 }
4179                 return;
4180             }
4181
4182 get_more:
4183             ccol = ctxt->input->col;
4184             while (test_char_data[*in]) {
4185                 in++;
4186                 ccol++;
4187             }
4188             ctxt->input->col = ccol;
4189             if (*in == 0xA) {
4190                 do {
4191                     ctxt->input->line++; ctxt->input->col = 1;
4192                     in++;
4193                 } while (*in == 0xA);
4194                 goto get_more;
4195             }
4196             if (*in == ']') {
4197                 if ((in[1] == ']') && (in[2] == '>')) {
4198                     xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4199                     ctxt->input->cur = in;
4200                     return;
4201                 }
4202                 in++;
4203                 ctxt->input->col++;
4204                 goto get_more;
4205             }
4206             nbchar = in - ctxt->input->cur;
4207             if (nbchar > 0) {
4208                 if ((ctxt->sax != NULL) &&
4209                     (ctxt->sax->ignorableWhitespace !=
4210                      ctxt->sax->characters) &&
4211                     (IS_BLANK_CH(*ctxt->input->cur))) {
4212                     const xmlChar *tmp = ctxt->input->cur;
4213                     ctxt->input->cur = in;
4214
4215                     if (areBlanks(ctxt, tmp, nbchar, 0)) {
4216                         if (ctxt->sax->ignorableWhitespace != NULL)
4217                             ctxt->sax->ignorableWhitespace(ctxt->userData,
4218                                                            tmp, nbchar);
4219                     } else {
4220                         if (ctxt->sax->characters != NULL)
4221                             ctxt->sax->characters(ctxt->userData,
4222                                                   tmp, nbchar);
4223                         if (*ctxt->space == -1)
4224                             *ctxt->space = -2;
4225                     }
4226                     line = ctxt->input->line;
4227                     col = ctxt->input->col;
4228                 } else if (ctxt->sax != NULL) {
4229                     if (ctxt->sax->characters != NULL)
4230                         ctxt->sax->characters(ctxt->userData,
4231                                               ctxt->input->cur, nbchar);
4232                     line = ctxt->input->line;
4233                     col = ctxt->input->col;
4234                 }
4235                 /* something really bad happened in the SAX callback */
4236                 if (ctxt->instate != XML_PARSER_CONTENT)
4237                     return;
4238             }
4239             ctxt->input->cur = in;
4240             if (*in == 0xD) {
4241                 in++;
4242                 if (*in == 0xA) {
4243                     ctxt->input->cur = in;
4244                     in++;
4245                     ctxt->input->line++; ctxt->input->col = 1;
4246                     continue; /* while */
4247                 }
4248                 in--;
4249             }
4250             if (*in == '<') {
4251                 return;
4252             }
4253             if (*in == '&') {
4254                 return;
4255             }
4256             SHRINK;
4257             GROW;
4258             if (ctxt->instate == XML_PARSER_EOF)
4259                 return;
4260             in = ctxt->input->cur;
4261         } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
4262         nbchar = 0;
4263     }
4264     ctxt->input->line = line;
4265     ctxt->input->col = col;
4266     xmlParseCharDataComplex(ctxt, cdata);
4267 }
4268
4269 /**
4270  * xmlParseCharDataComplex:
4271  * @ctxt:  an XML parser context
4272  * @cdata:  int indicating whether we are within a CDATA section
4273  *
4274  * parse a CharData section.this is the fallback function
4275  * of xmlParseCharData() when the parsing requires handling
4276  * of non-ASCII characters.
4277  */
4278 static void
4279 xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
4280     xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
4281     int nbchar = 0;
4282     int cur, l;
4283     int count = 0;
4284
4285     SHRINK;
4286     GROW;
4287     cur = CUR_CHAR(l);
4288     while ((cur != '<') && /* checked */
4289            (cur != '&') && 
4290            (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
4291         if ((cur == ']') && (NXT(1) == ']') &&
4292             (NXT(2) == '>')) {
4293             if (cdata) break;
4294             else {
4295                 xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4296             }
4297         }
4298         COPY_BUF(l,buf,nbchar,cur);
4299         if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
4300             buf[nbchar] = 0;
4301
4302             /*
4303              * OK the segment is to be consumed as chars.
4304              */
4305             if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4306                 if (areBlanks(ctxt, buf, nbchar, 0)) {
4307                     if (ctxt->sax->ignorableWhitespace != NULL)
4308                         ctxt->sax->ignorableWhitespace(ctxt->userData,
4309                                                        buf, nbchar);
4310                 } else {
4311                     if (ctxt->sax->characters != NULL)
4312                         ctxt->sax->characters(ctxt->userData, buf, nbchar);
4313                     if ((ctxt->sax->characters !=
4314                          ctxt->sax->ignorableWhitespace) &&
4315                         (*ctxt->space == -1))
4316                         *ctxt->space = -2;
4317                 }
4318             }
4319             nbchar = 0;
4320             /* something really bad happened in the SAX callback */
4321             if (ctxt->instate != XML_PARSER_CONTENT)
4322                 return;
4323         }
4324         count++;
4325         if (count > 50) {
4326             GROW;
4327             count = 0;
4328             if (ctxt->instate == XML_PARSER_EOF)
4329                 return;
4330         }
4331         NEXTL(l);
4332         cur = CUR_CHAR(l);
4333     }
4334     if (nbchar != 0) {
4335         buf[nbchar] = 0;
4336         /*
4337          * OK the segment is to be consumed as chars.
4338          */
4339         if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4340             if (areBlanks(ctxt, buf, nbchar, 0)) {
4341                 if (ctxt->sax->ignorableWhitespace != NULL)
4342                     ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
4343             } else {
4344                 if (ctxt->sax->characters != NULL)
4345                     ctxt->sax->characters(ctxt->userData, buf, nbchar);
4346                 if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
4347                     (*ctxt->space == -1))
4348                     *ctxt->space = -2;
4349             }
4350         }
4351     }
4352     if ((cur != 0) && (!IS_CHAR(cur))) {
4353         /* Generate the error and skip the offending character */
4354         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4355                           "PCDATA invalid Char value %d\n",
4356                           cur);
4357         NEXTL(l);
4358     }
4359 }
4360
4361 /**
4362  * xmlParseExternalID:
4363  * @ctxt:  an XML parser context
4364  * @publicID:  a xmlChar** receiving PubidLiteral
4365  * @strict: indicate whether we should restrict parsing to only
4366  *          production [75], see NOTE below
4367  *
4368  * Parse an External ID or a Public ID
4369  *
4370  * NOTE: Productions [75] and [83] interact badly since [75] can generate
4371  *       'PUBLIC' S PubidLiteral S SystemLiteral
4372  *
4373  * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
4374  *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
4375  *
4376  * [83] PublicID ::= 'PUBLIC' S PubidLiteral
4377  *
4378  * Returns the function returns SystemLiteral and in the second
4379  *                case publicID receives PubidLiteral, is strict is off
4380  *                it is possible to return NULL and have publicID set.
4381  */
4382
4383 xmlChar *
4384 xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
4385     xmlChar *URI = NULL;
4386
4387     SHRINK;
4388
4389     *publicID = NULL;
4390     if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
4391         SKIP(6);
4392         if (!IS_BLANK_CH(CUR)) {
4393             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4394                            "Space required after 'SYSTEM'\n");
4395         }
4396         SKIP_BLANKS;
4397         URI = xmlParseSystemLiteral(ctxt);
4398         if (URI == NULL) {
4399             xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4400         }
4401     } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
4402         SKIP(6);
4403         if (!IS_BLANK_CH(CUR)) {
4404             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4405                     "Space required after 'PUBLIC'\n");
4406         }
4407         SKIP_BLANKS;
4408         *publicID = xmlParsePubidLiteral(ctxt);
4409         if (*publicID == NULL) {
4410             xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
4411         }
4412         if (strict) {
4413             /*
4414              * We don't handle [83] so "S SystemLiteral" is required.
4415              */
4416             if (!IS_BLANK_CH(CUR)) {
4417                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4418                         "Space required after the Public Identifier\n");
4419             }
4420         } else {
4421             /*
4422              * We handle [83] so we return immediately, if 
4423              * "S SystemLiteral" is not detected. From a purely parsing
4424              * point of view that's a nice mess.
4425              */
4426             const xmlChar *ptr;
4427             GROW;
4428
4429             ptr = CUR_PTR;
4430             if (!IS_BLANK_CH(*ptr)) return(NULL);
4431             
4432             while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
4433             if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
4434         }
4435         SKIP_BLANKS;
4436         URI = xmlParseSystemLiteral(ctxt);
4437         if (URI == NULL) {
4438             xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4439         }
4440     }
4441     return(URI);
4442 }
4443
4444 /**
4445  * xmlParseCommentComplex:
4446  * @ctxt:  an XML parser context
4447  * @buf:  the already parsed part of the buffer
4448  * @len:  number of bytes filles in the buffer
4449  * @size:  allocated size of the buffer
4450  *
4451  * Skip an XML (SGML) comment <!-- .... -->
4452  *  The spec says that "For compatibility, the string "--" (double-hyphen)
4453  *  must not occur within comments. "
4454  * This is the slow routine in case the accelerator for ascii didn't work
4455  *
4456  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4457  */
4458 static void
4459 xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, int len, int size) {
4460     int q, ql;
4461     int r, rl;
4462     int cur, l;
4463     int count = 0;
4464     int inputid;
4465
4466     inputid = ctxt->input->id;
4467
4468     if (buf == NULL) {
4469         len = 0;
4470         size = XML_PARSER_BUFFER_SIZE;
4471         buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4472         if (buf == NULL) {
4473             xmlErrMemory(ctxt, NULL);
4474             return;
4475         }
4476     }
4477     GROW;       /* Assure there's enough input data */
4478     q = CUR_CHAR(ql);
4479     if (q == 0)
4480         goto not_terminated;
4481     if (!IS_CHAR(q)) {
4482         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4483                           "xmlParseComment: invalid xmlChar value %d\n",
4484                           q);
4485         xmlFree (buf);
4486         return;
4487     }
4488     NEXTL(ql);
4489     r = CUR_CHAR(rl);
4490     if (r == 0)
4491         goto not_terminated;
4492     if (!IS_CHAR(r)) {
4493         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4494                           "xmlParseComment: invalid xmlChar value %d\n",
4495                           q);
4496         xmlFree (buf);
4497         return;
4498     }
4499     NEXTL(rl);
4500     cur = CUR_CHAR(l);
4501     if (cur == 0)
4502         goto not_terminated;
4503     while (IS_CHAR(cur) && /* checked */
4504            ((cur != '>') ||
4505             (r != '-') || (q != '-'))) {
4506         if ((r == '-') && (q == '-')) {
4507             xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
4508         }
4509         if (len + 5 >= size) {
4510             xmlChar *new_buf;
4511             size *= 2;
4512             new_buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4513             if (new_buf == NULL) {
4514                 xmlFree (buf);
4515                 xmlErrMemory(ctxt, NULL);
4516                 return;
4517             }
4518             buf = new_buf;
4519         }
4520         COPY_BUF(ql,buf,len,q);
4521         q = r;
4522         ql = rl;
4523         r = cur;
4524         rl = l;
4525
4526         count++;
4527         if (count > 50) {
4528             GROW;
4529             count = 0;
4530             if (ctxt->instate == XML_PARSER_EOF) {
4531                 xmlFree(buf);
4532                 return;
4533             }
4534         }
4535         NEXTL(l);
4536         cur = CUR_CHAR(l);
4537         if (cur == 0) {
4538             SHRINK;
4539             GROW;
4540             cur = CUR_CHAR(l);
4541         }
4542     }
4543     buf[len] = 0;
4544     if (cur == 0) {
4545         xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4546                              "Comment not terminated \n<!--%.50s\n", buf);
4547     } else if (!IS_CHAR(cur)) {
4548         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4549                           "xmlParseComment: invalid xmlChar value %d\n",
4550                           cur);
4551     } else {
4552         if (inputid != ctxt->input->id) {
4553             xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4554                 "Comment doesn't start and stop in the same entity\n");
4555         }
4556         NEXT;
4557         if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4558             (!ctxt->disableSAX))
4559             ctxt->sax->comment(ctxt->userData, buf);
4560     }
4561     xmlFree(buf);
4562     return;
4563 not_terminated:
4564     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4565                          "Comment not terminated\n", NULL);
4566     xmlFree(buf);
4567     return;
4568 }
4569
4570 /**
4571  * xmlParseComment:
4572  * @ctxt:  an XML parser context
4573  *
4574  * Skip an XML (SGML) comment <!-- .... -->
4575  *  The spec says that "For compatibility, the string "--" (double-hyphen)
4576  *  must not occur within comments. "
4577  *
4578  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4579  */
4580 void
4581 xmlParseComment(xmlParserCtxtPtr ctxt) {
4582     xmlChar *buf = NULL;
4583     int size = XML_PARSER_BUFFER_SIZE;
4584     int len = 0;
4585     xmlParserInputState state;
4586     const xmlChar *in;
4587     int nbchar = 0, ccol;
4588     int inputid;
4589
4590     /*
4591      * Check that there is a comment right here.
4592      */
4593     if ((RAW != '<') || (NXT(1) != '!') ||
4594         (NXT(2) != '-') || (NXT(3) != '-')) return;
4595     state = ctxt->instate;
4596     ctxt->instate = XML_PARSER_COMMENT;
4597     inputid = ctxt->input->id;
4598     SKIP(4);
4599     SHRINK;
4600     GROW;
4601
4602     /*
4603      * Accelerated common case where input don't need to be
4604      * modified before passing it to the handler.
4605      */
4606     in = ctxt->input->cur;
4607     do {
4608         if (*in == 0xA) {
4609             do {
4610                 ctxt->input->line++; ctxt->input->col = 1;
4611                 in++;
4612             } while (*in == 0xA);
4613         }
4614 get_more:
4615         ccol = ctxt->input->col;
4616         while (((*in > '-') && (*in <= 0x7F)) ||
4617                ((*in >= 0x20) && (*in < '-')) ||
4618                (*in == 0x09)) {
4619                     in++;
4620                     ccol++;
4621         }
4622         ctxt->input->col = ccol;
4623         if (*in == 0xA) {
4624             do {
4625                 ctxt->input->line++; ctxt->input->col = 1;
4626                 in++;
4627             } while (*in == 0xA);
4628             goto get_more;
4629         }
4630         nbchar = in - ctxt->input->cur;
4631         /*
4632          * save current set of data
4633          */
4634         if (nbchar > 0) {
4635             if ((ctxt->sax != NULL) &&
4636                 (ctxt->sax->comment != NULL)) {
4637                 if (buf == NULL) {
4638                     if ((*in == '-') && (in[1] == '-'))
4639                         size = nbchar + 1;
4640                     else
4641                         size = XML_PARSER_BUFFER_SIZE + nbchar;
4642                     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4643                     if (buf == NULL) {
4644                         xmlErrMemory(ctxt, NULL);
4645                         ctxt->instate = state;
4646                         return;
4647                     }
4648                     len = 0;
4649                 } else if (len + nbchar + 1 >= size) {
4650                     xmlChar *new_buf;
4651                     size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
4652                     new_buf = (xmlChar *) xmlRealloc(buf,
4653                                                      size * sizeof(xmlChar));
4654                     if (new_buf == NULL) {
4655                         xmlFree (buf);
4656                         xmlErrMemory(ctxt, NULL);
4657                         ctxt->instate = state;
4658                         return;
4659                     }
4660                     buf = new_buf;
4661                 }
4662                 memcpy(&buf[len], ctxt->input->cur, nbchar);
4663                 len += nbchar;
4664                 buf[len] = 0;
4665             }
4666         }
4667         ctxt->input->cur = in;
4668         if (*in == 0xA) {
4669             in++;
4670             ctxt->input->line++; ctxt->input->col = 1;
4671         }
4672         if (*in == 0xD) {
4673             in++;
4674             if (*in == 0xA) {
4675                 ctxt->input->cur = in;
4676                 in++;
4677                 ctxt->input->line++; ctxt->input->col = 1;
4678                 continue; /* while */
4679             }
4680             in--;
4681         }
4682         SHRINK;
4683         GROW;
4684         if (ctxt->instate == XML_PARSER_EOF) {
4685             xmlFree(buf);
4686             return;
4687         }
4688         in = ctxt->input->cur;
4689         if (*in == '-') {
4690             if (in[1] == '-') {
4691                 if (in[2] == '>') {
4692                     if (ctxt->input->id != inputid) {
4693                         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4694                         "comment doesn't start and stop in the same entity\n");
4695                     }
4696                     SKIP(3);
4697                     if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4698                         (!ctxt->disableSAX)) {
4699                         if (buf != NULL)
4700                             ctxt->sax->comment(ctxt->userData, buf);
4701                         else
4702                             ctxt->sax->comment(ctxt->userData, BAD_CAST "");
4703                     }
4704                     if (buf != NULL)
4705                         xmlFree(buf);
4706                     if (ctxt->instate != XML_PARSER_EOF)
4707                         ctxt->instate = state;
4708                     return;
4709                 }
4710                 if (buf != NULL)
4711                     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4712                                       "Comment not terminated \n<!--%.50s\n",
4713                                       buf);
4714                 else
4715                     xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4716                                       "Comment not terminated \n", NULL);
4717                 in++;
4718                 ctxt->input->col++;
4719             }
4720             in++;
4721             ctxt->input->col++;
4722             goto get_more;
4723         }
4724     } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
4725     xmlParseCommentComplex(ctxt, buf, len, size);
4726     ctxt->instate = state;
4727     return;
4728 }
4729
4730
4731 /**
4732  * xmlParsePITarget:
4733  * @ctxt:  an XML parser context
4734  * 
4735  * parse the name of a PI
4736  *
4737  * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
4738  *
4739  * Returns the PITarget name or NULL
4740  */
4741
4742 const xmlChar *
4743 xmlParsePITarget(xmlParserCtxtPtr ctxt) {
4744     const xmlChar *name;
4745
4746     name = xmlParseName(ctxt);
4747     if ((name != NULL) &&
4748         ((name[0] == 'x') || (name[0] == 'X')) &&
4749         ((name[1] == 'm') || (name[1] == 'M')) &&
4750         ((name[2] == 'l') || (name[2] == 'L'))) {
4751         int i;
4752         if ((name[0] == 'x') && (name[1] == 'm') &&
4753             (name[2] == 'l') && (name[3] == 0)) {
4754             xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
4755                  "XML declaration allowed only at the start of the document\n");
4756             return(name);
4757         } else if (name[3] == 0) {
4758             xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
4759             return(name);
4760         }
4761         for (i = 0;;i++) {
4762             if (xmlW3CPIs[i] == NULL) break;
4763             if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
4764                 return(name);
4765         }
4766         xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
4767                       "xmlParsePITarget: invalid name prefix 'xml'\n",
4768                       NULL, NULL);
4769     }
4770     if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
4771         xmlNsErr(ctxt, XML_NS_ERR_COLON, 
4772                  "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
4773     }
4774     return(name);
4775 }
4776
4777 #ifdef LIBXML_CATALOG_ENABLED
4778 /**
4779  * xmlParseCatalogPI:
4780  * @ctxt:  an XML parser context
4781  * @catalog:  the PI value string
4782  * 
4783  * parse an XML Catalog Processing Instruction.
4784  *
4785  * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
4786  *
4787  * Occurs only if allowed by the user and if happening in the Misc
4788  * part of the document before any doctype informations
4789  * This will add the given catalog to the parsing context in order
4790  * to be used if there is a resolution need further down in the document
4791  */
4792
4793 static void
4794 xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
4795     xmlChar *URL = NULL;
4796     const xmlChar *tmp, *base;
4797     xmlChar marker;
4798
4799     tmp = catalog;
4800     while (IS_BLANK_CH(*tmp)) tmp++;
4801     if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
4802         goto error;
4803     tmp += 7;
4804     while (IS_BLANK_CH(*tmp)) tmp++;
4805     if (*tmp != '=') {
4806         return;
4807     }
4808     tmp++;
4809     while (IS_BLANK_CH(*tmp)) tmp++;
4810     marker = *tmp;
4811     if ((marker != '\'') && (marker != '"'))
4812         goto error;
4813     tmp++;
4814     base = tmp;
4815     while ((*tmp != 0) && (*tmp != marker)) tmp++;
4816     if (*tmp == 0)
4817         goto error;
4818     URL = xmlStrndup(base, tmp - base);
4819     tmp++;
4820     while (IS_BLANK_CH(*tmp)) tmp++;
4821     if (*tmp != 0)
4822         goto error;
4823
4824     if (URL != NULL) {
4825         ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
4826         xmlFree(URL);
4827     }
4828     return;
4829
4830 error:
4831     xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
4832                   "Catalog PI syntax error: %s\n",
4833                   catalog, NULL);
4834     if (URL != NULL)
4835         xmlFree(URL);
4836 }
4837 #endif
4838
4839 /**
4840  * xmlParsePI:
4841  * @ctxt:  an XML parser context
4842  * 
4843  * parse an XML Processing Instruction.
4844  *
4845  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
4846  *
4847  * The processing is transfered to SAX once parsed.
4848  */
4849
4850 void
4851 xmlParsePI(xmlParserCtxtPtr ctxt) {
4852     xmlChar *buf = NULL;
4853     int len = 0;
4854     int size = XML_PARSER_BUFFER_SIZE;
4855     int cur, l;
4856     const xmlChar *target;
4857     xmlParserInputState state;
4858     int count = 0;
4859
4860     if ((RAW == '<') && (NXT(1) == '?')) {
4861         xmlParserInputPtr input = ctxt->input;
4862         state = ctxt->instate;
4863         ctxt->instate = XML_PARSER_PI;
4864         /*
4865          * this is a Processing Instruction.
4866          */
4867         SKIP(2);
4868         SHRINK;
4869
4870         /*
4871          * Parse the target name and check for special support like
4872          * namespace.
4873          */
4874         target = xmlParsePITarget(ctxt);
4875         if (target != NULL) {
4876             if ((RAW == '?') && (NXT(1) == '>')) {
4877                 if (input != ctxt->input) {
4878                     xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4879             "PI declaration doesn't start and stop in the same entity\n");
4880                 }
4881                 SKIP(2);
4882
4883                 /*
4884                  * SAX: PI detected.
4885                  */
4886                 if ((ctxt->sax) && (!ctxt->disableSAX) &&
4887                     (ctxt->sax->processingInstruction != NULL))
4888                     ctxt->sax->processingInstruction(ctxt->userData,
4889                                                      target, NULL);
4890                 if (ctxt->instate != XML_PARSER_EOF)
4891                     ctxt->instate = state;
4892                 return;
4893             }
4894             buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4895             if (buf == NULL) {
4896                 xmlErrMemory(ctxt, NULL);
4897                 ctxt->instate = state;
4898                 return;
4899             }
4900             cur = CUR;
4901             if (!IS_BLANK(cur)) {
4902                 xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
4903                           "ParsePI: PI %s space expected\n", target);
4904             }
4905             SKIP_BLANKS;
4906             cur = CUR_CHAR(l);
4907             while (IS_CHAR(cur) && /* checked */
4908                    ((cur != '?') || (NXT(1) != '>'))) {
4909                 if (len + 5 >= size) {
4910                     xmlChar *tmp;
4911
4912                     size *= 2;
4913                     tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4914                     if (tmp == NULL) {
4915                         xmlErrMemory(ctxt, NULL);
4916                         xmlFree(buf);
4917                         ctxt->instate = state;
4918                         return;
4919                     }
4920                     buf = tmp;
4921                 }
4922                 count++;
4923                 if (count > 50) {
4924                     GROW;
4925                     if (ctxt->instate == XML_PARSER_EOF) {
4926                         xmlFree(buf);
4927                         return;
4928                     }
4929                     count = 0;
4930                 }
4931                 COPY_BUF(l,buf,len,cur);
4932                 NEXTL(l);
4933                 cur = CUR_CHAR(l);
4934                 if (cur == 0) {
4935                     SHRINK;
4936                     GROW;
4937                     cur = CUR_CHAR(l);
4938                 }
4939             }
4940             buf[len] = 0;
4941             if (cur != '?') {
4942                 xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
4943                       "ParsePI: PI %s never end ...\n", target);
4944             } else {
4945                 if (input != ctxt->input) {
4946                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4947             "PI declaration doesn't start and stop in the same entity\n");
4948                 }
4949                 SKIP(2);
4950
4951 #ifdef LIBXML_CATALOG_ENABLED
4952                 if (((state == XML_PARSER_MISC) ||
4953                      (state == XML_PARSER_START)) &&
4954                     (xmlStrEqual(target, XML_CATALOG_PI))) {
4955                     xmlCatalogAllow allow = xmlCatalogGetDefaults();
4956                     if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
4957                         (allow == XML_CATA_ALLOW_ALL))
4958                         xmlParseCatalogPI(ctxt, buf);
4959                 }
4960 #endif
4961
4962
4963                 /*
4964                  * SAX: PI detected.
4965                  */
4966                 if ((ctxt->sax) && (!ctxt->disableSAX) &&
4967                     (ctxt->sax->processingInstruction != NULL))
4968                     ctxt->sax->processingInstruction(ctxt->userData,
4969                                                      target, buf);
4970             }
4971             xmlFree(buf);
4972         } else {
4973             xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
4974         }
4975         if (ctxt->instate != XML_PARSER_EOF)
4976             ctxt->instate = state;
4977     }
4978 }
4979
4980 /**
4981  * xmlParseNotationDecl:
4982  * @ctxt:  an XML parser context
4983  *
4984  * parse a notation declaration
4985  *
4986  * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
4987  *
4988  * Hence there is actually 3 choices:
4989  *     'PUBLIC' S PubidLiteral
4990  *     'PUBLIC' S PubidLiteral S SystemLiteral
4991  * and 'SYSTEM' S SystemLiteral
4992  *
4993  * See the NOTE on xmlParseExternalID().
4994  */
4995
4996 void
4997 xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
4998     const xmlChar *name;
4999     xmlChar *Pubid;
5000     xmlChar *Systemid;
5001     
5002     if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5003         xmlParserInputPtr input = ctxt->input;
5004         SHRINK;
5005         SKIP(10);
5006         if (!IS_BLANK_CH(CUR)) {
5007             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5008                            "Space required after '<!NOTATION'\n");
5009             return;
5010         }
5011         SKIP_BLANKS;
5012
5013         name = xmlParseName(ctxt);
5014         if (name == NULL) {
5015             xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5016             return;
5017         }
5018         if (!IS_BLANK_CH(CUR)) {
5019             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5020                      "Space required after the NOTATION name'\n");
5021             return;
5022         }
5023         if (xmlStrchr(name, ':') != NULL) {
5024             xmlNsErr(ctxt, XML_NS_ERR_COLON, 
5025                      "colon are forbidden from notation names '%s'\n",
5026                      name, NULL, NULL);
5027         }
5028         SKIP_BLANKS;
5029
5030         /*
5031          * Parse the IDs.
5032          */
5033         Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
5034         SKIP_BLANKS;
5035
5036         if (RAW == '>') {
5037             if (input != ctxt->input) {
5038                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5039         "Notation declaration doesn't start and stop in the same entity\n");
5040             }
5041             NEXT;
5042             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5043                 (ctxt->sax->notationDecl != NULL))
5044                 ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
5045         } else {
5046             xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5047         }
5048         if (Systemid != NULL) xmlFree(Systemid);
5049         if (Pubid != NULL) xmlFree(Pubid);
5050     }
5051 }
5052
5053 /**
5054  * xmlParseEntityDecl:
5055  * @ctxt:  an XML parser context
5056  *
5057  * parse <!ENTITY declarations
5058  *
5059  * [70] EntityDecl ::= GEDecl | PEDecl
5060  *
5061  * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
5062  *
5063  * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
5064  *
5065  * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
5066  *
5067  * [74] PEDef ::= EntityValue | ExternalID
5068  *
5069  * [76] NDataDecl ::= S 'NDATA' S Name
5070  *
5071  * [ VC: Notation Declared ]
5072  * The Name must match the declared name of a notation.
5073  */
5074
5075 void
5076 xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
5077     const xmlChar *name = NULL;
5078     xmlChar *value = NULL;
5079     xmlChar *URI = NULL, *literal = NULL;
5080     const xmlChar *ndata = NULL;
5081     int isParameter = 0;
5082     xmlChar *orig = NULL;
5083     int skipped;
5084     
5085     /* GROW; done in the caller */
5086     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
5087         xmlParserInputPtr input = ctxt->input;
5088         SHRINK;
5089         SKIP(8);
5090         skipped = SKIP_BLANKS;
5091         if (skipped == 0) {
5092             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5093                            "Space required after '<!ENTITY'\n");
5094         }
5095
5096         if (RAW == '%') {
5097             NEXT;
5098             skipped = SKIP_BLANKS;
5099             if (skipped == 0) {
5100                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5101                                "Space required after '%'\n");
5102             }
5103             isParameter = 1;
5104         }
5105
5106         name = xmlParseName(ctxt);
5107         if (name == NULL) {
5108             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5109                            "xmlParseEntityDecl: no name\n");
5110             return;
5111         }
5112         if (xmlStrchr(name, ':') != NULL) {
5113             xmlNsErr(ctxt, XML_NS_ERR_COLON, 
5114                      "colon are forbidden from entities names '%s'\n",
5115                      name, NULL, NULL);
5116         }
5117         skipped = SKIP_BLANKS;
5118         if (skipped == 0) {
5119             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5120                            "Space required after the entity name\n");
5121         }
5122
5123         ctxt->instate = XML_PARSER_ENTITY_DECL;
5124         /*
5125          * handle the various case of definitions...
5126          */
5127         if (isParameter) {
5128             if ((RAW == '"') || (RAW == '\'')) {
5129                 value = xmlParseEntityValue(ctxt, &orig);
5130                 if (value) {
5131                     if ((ctxt->sax != NULL) &&
5132                         (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5133                         ctxt->sax->entityDecl(ctxt->userData, name,
5134                                     XML_INTERNAL_PARAMETER_ENTITY,
5135                                     NULL, NULL, value);
5136                 }
5137             } else {
5138                 URI = xmlParseExternalID(ctxt, &literal, 1);
5139                 if ((URI == NULL) && (literal == NULL)) {
5140                     xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5141                 }
5142                 if (URI) {
5143                     xmlURIPtr uri;
5144
5145                     uri = xmlParseURI((const char *) URI);
5146                     if (uri == NULL) {
5147                         xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5148                                      "Invalid URI: %s\n", URI);
5149                         /*
5150                          * This really ought to be a well formedness error
5151                          * but the XML Core WG decided otherwise c.f. issue
5152                          * E26 of the XML erratas.
5153                          */
5154                     } else {
5155                         if (uri->fragment != NULL) {
5156                             /*
5157                              * Okay this is foolish to block those but not
5158                              * invalid URIs.
5159                              */
5160                             xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5161                         } else {
5162                             if ((ctxt->sax != NULL) &&
5163                                 (!ctxt->disableSAX) &&
5164                                 (ctxt->sax->entityDecl != NULL))
5165                                 ctxt->sax->entityDecl(ctxt->userData, name,
5166                                             XML_EXTERNAL_PARAMETER_ENTITY,
5167                                             literal, URI, NULL);
5168                         }
5169                         xmlFreeURI(uri);
5170                     }
5171                 }
5172             }
5173         } else {
5174             if ((RAW == '"') || (RAW == '\'')) {
5175                 value = xmlParseEntityValue(ctxt, &orig);
5176                 if ((ctxt->sax != NULL) &&
5177                     (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5178                     ctxt->sax->entityDecl(ctxt->userData, name,
5179                                 XML_INTERNAL_GENERAL_ENTITY,
5180                                 NULL, NULL, value);
5181                 /*
5182                  * For expat compatibility in SAX mode.
5183                  */
5184                 if ((ctxt->myDoc == NULL) ||
5185                     (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
5186                     if (ctxt->myDoc == NULL) {
5187                         ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5188                         if (ctxt->myDoc == NULL) {
5189                             xmlErrMemory(ctxt, "New Doc failed");
5190                             return;
5191                         }
5192                         ctxt->myDoc->properties = XML_DOC_INTERNAL;
5193                     }
5194                     if (ctxt->myDoc->intSubset == NULL)
5195                         ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5196                                             BAD_CAST "fake", NULL, NULL);
5197
5198                     xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
5199                                       NULL, NULL, value);
5200                 }
5201             } else {
5202                 URI = xmlParseExternalID(ctxt, &literal, 1);
5203                 if ((URI == NULL) && (literal == NULL)) {
5204                     xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5205                 }
5206                 if (URI) {
5207                     xmlURIPtr uri;
5208
5209                     uri = xmlParseURI((const char *)URI);
5210                     if (uri == NULL) {
5211                         xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5212                                      "Invalid URI: %s\n", URI);
5213                         /*
5214                          * This really ought to be a well formedness error
5215                          * but the XML Core WG decided otherwise c.f. issue
5216                          * E26 of the XML erratas.
5217                          */
5218                     } else {
5219                         if (uri->fragment != NULL) {
5220                             /*
5221                              * Okay this is foolish to block those but not
5222                              * invalid URIs.
5223                              */
5224                             xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5225                         }
5226                         xmlFreeURI(uri);
5227                     }
5228                 }
5229                 if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
5230                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5231                                    "Space required before 'NDATA'\n");
5232                 }
5233                 SKIP_BLANKS;
5234                 if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
5235                     SKIP(5);
5236                     if (!IS_BLANK_CH(CUR)) {
5237                         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5238                                        "Space required after 'NDATA'\n");
5239                     }
5240                     SKIP_BLANKS;
5241                     ndata = xmlParseName(ctxt);
5242                     if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5243                         (ctxt->sax->unparsedEntityDecl != NULL))
5244                         ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
5245                                     literal, URI, ndata);
5246                 } else {
5247                     if ((ctxt->sax != NULL) &&
5248                         (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5249                         ctxt->sax->entityDecl(ctxt->userData, name,
5250                                     XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5251                                     literal, URI, NULL);
5252                     /*
5253                      * For expat compatibility in SAX mode.
5254                      * assuming the entity repalcement was asked for
5255                      */
5256                     if ((ctxt->replaceEntities != 0) &&
5257                         ((ctxt->myDoc == NULL) ||
5258                         (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
5259                         if (ctxt->myDoc == NULL) {
5260                             ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5261                             if (ctxt->myDoc == NULL) {
5262                                 xmlErrMemory(ctxt, "New Doc failed");
5263                                 return;
5264                             }
5265                             ctxt->myDoc->properties = XML_DOC_INTERNAL;
5266                         }
5267
5268                         if (ctxt->myDoc->intSubset == NULL)
5269                             ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5270                                                 BAD_CAST "fake", NULL, NULL);
5271                         xmlSAX2EntityDecl(ctxt, name,
5272                                           XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5273                                           literal, URI, NULL);
5274                     }
5275                 }
5276             }
5277         }
5278         if (ctxt->instate == XML_PARSER_EOF)
5279             return;
5280         SKIP_BLANKS;
5281         if (RAW != '>') {
5282             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
5283                     "xmlParseEntityDecl: entity %s not terminated\n", name);
5284         } else {
5285             if (input != ctxt->input) {
5286                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5287         "Entity declaration doesn't start and stop in the same entity\n");
5288             }
5289             NEXT;
5290         }
5291         if (orig != NULL) {
5292             /*
5293              * Ugly mechanism to save the raw entity value.
5294              */
5295             xmlEntityPtr cur = NULL;
5296
5297             if (isParameter) {
5298                 if ((ctxt->sax != NULL) &&
5299                     (ctxt->sax->getParameterEntity != NULL))
5300                     cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
5301             } else {
5302                 if ((ctxt->sax != NULL) &&
5303                     (ctxt->sax->getEntity != NULL))
5304                     cur = ctxt->sax->getEntity(ctxt->userData, name);
5305                 if ((cur == NULL) && (ctxt->userData==ctxt)) {
5306                     cur = xmlSAX2GetEntity(ctxt, name);
5307                 }
5308             }
5309             if (cur != NULL) {
5310                 if (cur->orig != NULL)
5311                     xmlFree(orig);
5312                 else
5313                     cur->orig = orig;
5314             } else
5315                 xmlFree(orig);
5316         }
5317         if (value != NULL) xmlFree(value);
5318         if (URI != NULL) xmlFree(URI);
5319         if (literal != NULL) xmlFree(literal);
5320     }
5321 }
5322
5323 /**
5324  * xmlParseDefaultDecl:
5325  * @ctxt:  an XML parser context
5326  * @value:  Receive a possible fixed default value for the attribute
5327  *
5328  * Parse an attribute default declaration
5329  *
5330  * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
5331  *
5332  * [ VC: Required Attribute ]
5333  * if the default declaration is the keyword #REQUIRED, then the
5334  * attribute must be specified for all elements of the type in the
5335  * attribute-list declaration.
5336  *
5337  * [ VC: Attribute Default Legal ]
5338  * The declared default value must meet the lexical constraints of
5339  * the declared attribute type c.f. xmlValidateAttributeDecl()
5340  *
5341  * [ VC: Fixed Attribute Default ]
5342  * if an attribute has a default value declared with the #FIXED
5343  * keyword, instances of that attribute must match the default value. 
5344  *
5345  * [ WFC: No < in Attribute Values ]
5346  * handled in xmlParseAttValue()
5347  *
5348  * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
5349  *          or XML_ATTRIBUTE_FIXED. 
5350  */
5351
5352 int
5353 xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
5354     int val;
5355     xmlChar *ret;
5356
5357     *value = NULL;
5358     if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
5359         SKIP(9);
5360         return(XML_ATTRIBUTE_REQUIRED);
5361     }
5362     if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
5363         SKIP(8);
5364         return(XML_ATTRIBUTE_IMPLIED);
5365     }
5366     val = XML_ATTRIBUTE_NONE;
5367     if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
5368         SKIP(6);
5369         val = XML_ATTRIBUTE_FIXED;
5370         if (!IS_BLANK_CH(CUR)) {
5371             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5372                            "Space required after '#FIXED'\n");
5373         }
5374         SKIP_BLANKS;
5375     }
5376     ret = xmlParseAttValue(ctxt);
5377     ctxt->instate = XML_PARSER_DTD;
5378     if (ret == NULL) {
5379         xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
5380                        "Attribute default value declaration error\n");
5381     } else
5382         *value = ret;
5383     return(val);
5384 }
5385
5386 /**
5387  * xmlParseNotationType:
5388  * @ctxt:  an XML parser context
5389  *
5390  * parse an Notation attribute type.
5391  *
5392  * Note: the leading 'NOTATION' S part has already being parsed...
5393  *
5394  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5395  *
5396  * [ VC: Notation Attributes ]
5397  * Values of this type must match one of the notation names included
5398  * in the declaration; all notation names in the declaration must be declared. 
5399  *
5400  * Returns: the notation attribute tree built while parsing
5401  */
5402
5403 xmlEnumerationPtr
5404 xmlParseNotationType(xmlParserCtxtPtr ctxt) {
5405     const xmlChar *name;
5406     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5407
5408     if (RAW != '(') {
5409         xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5410         return(NULL);
5411     }
5412     SHRINK;
5413     do {
5414         NEXT;
5415         SKIP_BLANKS;
5416         name = xmlParseName(ctxt);
5417         if (name == NULL) {
5418             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5419                            "Name expected in NOTATION declaration\n");
5420             xmlFreeEnumeration(ret);
5421             return(NULL);
5422         }
5423         tmp = ret;
5424         while (tmp != NULL) {
5425             if (xmlStrEqual(name, tmp->name)) {
5426                 xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5427           "standalone: attribute notation value token %s duplicated\n",
5428                                  name, NULL);
5429                 if (!xmlDictOwns(ctxt->dict, name))
5430                     xmlFree((xmlChar *) name);
5431                 break;
5432             }
5433             tmp = tmp->next;
5434         }
5435         if (tmp == NULL) {
5436             cur = xmlCreateEnumeration(name);
5437             if (cur == NULL) {
5438                 xmlFreeEnumeration(ret);
5439                 return(NULL);
5440             }
5441             if (last == NULL) ret = last = cur;
5442             else {
5443                 last->next = cur;
5444                 last = cur;
5445             }
5446         }
5447         SKIP_BLANKS;
5448     } while (RAW == '|');
5449     if (RAW != ')') {
5450         xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5451         xmlFreeEnumeration(ret);
5452         return(NULL);
5453     }
5454     NEXT;
5455     return(ret);
5456 }
5457
5458 /**
5459  * xmlParseEnumerationType:
5460  * @ctxt:  an XML parser context
5461  *
5462  * parse an Enumeration attribute type.
5463  *
5464  * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
5465  *
5466  * [ VC: Enumeration ]
5467  * Values of this type must match one of the Nmtoken tokens in
5468  * the declaration
5469  *
5470  * Returns: the enumeration attribute tree built while parsing
5471  */
5472
5473 xmlEnumerationPtr
5474 xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
5475     xmlChar *name;
5476     xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5477
5478     if (RAW != '(') {
5479         xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
5480         return(NULL);
5481     }
5482     SHRINK;
5483     do {
5484         NEXT;
5485         SKIP_BLANKS;
5486         name = xmlParseNmtoken(ctxt);
5487         if (name == NULL) {
5488             xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
5489             return(ret);
5490         }
5491         tmp = ret;
5492         while (tmp != NULL) {
5493             if (xmlStrEqual(name, tmp->name)) {
5494                 xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5495           "standalone: attribute enumeration value token %s duplicated\n",
5496                                  name, NULL);
5497                 if (!xmlDictOwns(ctxt->dict, name))
5498                     xmlFree(name);
5499                 break;
5500             }
5501             tmp = tmp->next;
5502         }
5503         if (tmp == NULL) {
5504             cur = xmlCreateEnumeration(name);
5505             if (!xmlDictOwns(ctxt->dict, name))
5506                 xmlFree(name);
5507             if (cur == NULL) {
5508                 xmlFreeEnumeration(ret);
5509                 return(NULL);
5510             }
5511             if (last == NULL) ret = last = cur;
5512             else {
5513                 last->next = cur;
5514                 last = cur;
5515             }
5516         }
5517         SKIP_BLANKS;
5518     } while (RAW == '|');
5519     if (RAW != ')') {
5520         xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
5521         return(ret);
5522     }
5523     NEXT;
5524     return(ret);
5525 }
5526
5527 /**
5528  * xmlParseEnumeratedType:
5529  * @ctxt:  an XML parser context
5530  * @tree:  the enumeration tree built while parsing
5531  *
5532  * parse an Enumerated attribute type.
5533  *
5534  * [57] EnumeratedType ::= NotationType | Enumeration
5535  *
5536  * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5537  *
5538  *
5539  * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
5540  */
5541
5542 int
5543 xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5544     if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5545         SKIP(8);
5546         if (!IS_BLANK_CH(CUR)) {
5547             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5548                            "Space required after 'NOTATION'\n");
5549             return(0);
5550         }
5551         SKIP_BLANKS;
5552         *tree = xmlParseNotationType(ctxt);
5553         if (*tree == NULL) return(0);
5554         return(XML_ATTRIBUTE_NOTATION);
5555     }
5556     *tree = xmlParseEnumerationType(ctxt);
5557     if (*tree == NULL) return(0);
5558     return(XML_ATTRIBUTE_ENUMERATION);
5559 }
5560
5561 /**
5562  * xmlParseAttributeType:
5563  * @ctxt:  an XML parser context
5564  * @tree:  the enumeration tree built while parsing
5565  *
5566  * parse the Attribute list def for an element
5567  *
5568  * [54] AttType ::= StringType | TokenizedType | EnumeratedType
5569  *
5570  * [55] StringType ::= 'CDATA'
5571  *
5572  * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
5573  *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
5574  *
5575  * Validity constraints for attribute values syntax are checked in
5576  * xmlValidateAttributeValue()
5577  *
5578  * [ VC: ID ]
5579  * Values of type ID must match the Name production. A name must not
5580  * appear more than once in an XML document as a value of this type;
5581  * i.e., ID values must uniquely identify the elements which bear them.
5582  *
5583  * [ VC: One ID per Element Type ]
5584  * No element type may have more than one ID attribute specified.
5585  *
5586  * [ VC: ID Attribute Default ]
5587  * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
5588  *
5589  * [ VC: IDREF ]
5590  * Values of type IDREF must match the Name production, and values
5591  * of type IDREFS must match Names; each IDREF Name must match the value
5592  * of an ID attribute on some element in the XML document; i.e. IDREF
5593  * values must match the value of some ID attribute.
5594  *
5595  * [ VC: Entity Name ]
5596  * Values of type ENTITY must match the Name production, values
5597  * of type ENTITIES must match Names; each Entity Name must match the
5598  * name of an unparsed entity declared in the DTD.  
5599  *
5600  * [ VC: Name Token ]
5601  * Values of type NMTOKEN must match the Nmtoken production; values
5602  * of type NMTOKENS must match Nmtokens. 
5603  *
5604  * Returns the attribute type
5605  */
5606 int 
5607 xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5608     SHRINK;
5609     if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
5610         SKIP(5);
5611         return(XML_ATTRIBUTE_CDATA);
5612      } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
5613         SKIP(6);
5614         return(XML_ATTRIBUTE_IDREFS);
5615      } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
5616         SKIP(5);
5617         return(XML_ATTRIBUTE_IDREF);
5618      } else if ((RAW == 'I') && (NXT(1) == 'D')) {
5619         SKIP(2);
5620         return(XML_ATTRIBUTE_ID);
5621      } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
5622         SKIP(6);
5623         return(XML_ATTRIBUTE_ENTITY);
5624      } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
5625         SKIP(8);
5626         return(XML_ATTRIBUTE_ENTITIES);
5627      } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
5628         SKIP(8);
5629         return(XML_ATTRIBUTE_NMTOKENS);
5630      } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
5631         SKIP(7);
5632         return(XML_ATTRIBUTE_NMTOKEN);
5633      }
5634      return(xmlParseEnumeratedType(ctxt, tree));
5635 }
5636
5637 /**
5638  * xmlParseAttributeListDecl:
5639  * @ctxt:  an XML parser context
5640  *
5641  * : parse the Attribute list def for an element
5642  *
5643  * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
5644  *
5645  * [53] AttDef ::= S Name S AttType S DefaultDecl
5646  *
5647  */
5648 void
5649 xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
5650     const xmlChar *elemName;
5651     const xmlChar *attrName;
5652     xmlEnumerationPtr tree;
5653
5654     if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
5655         xmlParserInputPtr input = ctxt->input;
5656
5657         SKIP(9);
5658         if (!IS_BLANK_CH(CUR)) {
5659             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5660                                  "Space required after '<!ATTLIST'\n");
5661         }
5662         SKIP_BLANKS;
5663         elemName = xmlParseName(ctxt);
5664         if (elemName == NULL) {
5665             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5666                            "ATTLIST: no name for Element\n");
5667             return;
5668         }
5669         SKIP_BLANKS;
5670         GROW;
5671         while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
5672             const xmlChar *check = CUR_PTR;
5673             int type;
5674             int def;
5675             xmlChar *defaultValue = NULL;
5676
5677             GROW;
5678             tree = NULL;
5679             attrName = xmlParseName(ctxt);
5680             if (attrName == NULL) {
5681                 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5682                                "ATTLIST: no name for Attribute\n");
5683                 break;
5684             }
5685             GROW;
5686             if (!IS_BLANK_CH(CUR)) {
5687                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5688                         "Space required after the attribute name\n");
5689                 break;
5690             }
5691             SKIP_BLANKS;
5692
5693             type = xmlParseAttributeType(ctxt, &tree);
5694             if (type <= 0) {
5695                 break;
5696             }
5697
5698             GROW;
5699             if (!IS_BLANK_CH(CUR)) {
5700                 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5701                                "Space required after the attribute type\n");
5702                 if (tree != NULL)
5703                     xmlFreeEnumeration(tree);
5704                 break;
5705             }
5706             SKIP_BLANKS;
5707
5708             def = xmlParseDefaultDecl(ctxt, &defaultValue);
5709             if (def <= 0) {
5710                 if (defaultValue != NULL)
5711                     xmlFree(defaultValue);
5712                 if (tree != NULL)
5713                     xmlFreeEnumeration(tree);
5714                 break;
5715             }
5716             if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
5717                 xmlAttrNormalizeSpace(defaultValue, defaultValue);
5718
5719             GROW;
5720             if (RAW != '>') {
5721                 if (!IS_BLANK_CH(CUR)) {
5722                     xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5723                         "Space required after the attribute default value\n");
5724                     if (defaultValue != NULL)
5725                         xmlFree(defaultValue);
5726                     if (tree != NULL)
5727                         xmlFreeEnumeration(tree);
5728                     break;
5729                 }
5730                 SKIP_BLANKS;
5731             }
5732             if (check == CUR_PTR) {
5733                 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
5734                             "in xmlParseAttributeListDecl\n");
5735                 if (defaultValue != NULL)
5736                     xmlFree(defaultValue);
5737                 if (tree != NULL)
5738                     xmlFreeEnumeration(tree);
5739                 break;
5740             }
5741             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5742                 (ctxt->sax->attributeDecl != NULL))
5743                 ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
5744                                 type, def, defaultValue, tree);
5745             else if (tree != NULL)
5746                 xmlFreeEnumeration(tree);
5747
5748             if ((ctxt->sax2) && (defaultValue != NULL) &&
5749                 (def != XML_ATTRIBUTE_IMPLIED) && 
5750                 (def != XML_ATTRIBUTE_REQUIRED)) {
5751                 xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
5752             }
5753             if (ctxt->sax2) {
5754                 xmlAddSpecialAttr(ctxt, elemName, attrName, type);
5755             }
5756             if (defaultValue != NULL)
5757                 xmlFree(defaultValue);
5758             GROW;
5759         }
5760         if (RAW == '>') {
5761             if (input != ctxt->input) {
5762                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
5763     "Attribute list declaration doesn't start and stop in the same entity\n",
5764                                  NULL, NULL);
5765             }
5766             NEXT;
5767         }
5768     }
5769 }
5770
5771 /**
5772  * xmlParseElementMixedContentDecl:
5773  * @ctxt:  an XML parser context
5774  * @inputchk:  the input used for the current entity, needed for boundary checks
5775  *
5776  * parse the declaration for a Mixed Element content
5777  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
5778  * 
5779  * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
5780  *                '(' S? '#PCDATA' S? ')'
5781  *
5782  * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
5783  *
5784  * [ VC: No Duplicate Types ]
5785  * The same name must not appear more than once in a single
5786  * mixed-content declaration. 
5787  *
5788  * returns: the list of the xmlElementContentPtr describing the element choices
5789  */
5790 xmlElementContentPtr
5791 xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
5792     xmlElementContentPtr ret = NULL, cur = NULL, n;
5793     const xmlChar *elem = NULL;
5794
5795     GROW;
5796     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
5797         SKIP(7);
5798         SKIP_BLANKS;
5799         SHRINK;
5800         if (RAW == ')') {
5801             if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
5802                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
5803 "Element content declaration doesn't start and stop in the same entity\n",
5804                                  NULL, NULL);
5805             }
5806             NEXT;
5807             ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
5808             if (ret == NULL)
5809                 return(NULL);
5810             if (RAW == '*') {
5811                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
5812                 NEXT;
5813             }
5814             return(ret);
5815         }
5816         if ((RAW == '(') || (RAW == '|')) {
5817             ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
5818             if (ret == NULL) return(NULL);
5819         }
5820         while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
5821             NEXT;
5822             if (elem == NULL) {
5823                 ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
5824                 if (ret == NULL) return(NULL);
5825                 ret->c1 = cur;
5826                 if (cur != NULL)
5827                     cur->parent = ret;
5828                 cur = ret;
5829             } else {
5830                 n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
5831                 if (n == NULL) return(NULL);
5832                 n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
5833                 if (n->c1 != NULL)
5834                     n->c1->parent = n;
5835                 cur->c2 = n;
5836                 if (n != NULL)
5837                     n->parent = cur;
5838                 cur = n;
5839             }
5840             SKIP_BLANKS;
5841             elem = xmlParseName(ctxt);
5842             if (elem == NULL) {
5843                 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5844                         "xmlParseElementMixedContentDecl : Name expected\n");
5845                 xmlFreeDocElementContent(ctxt->myDoc, cur);
5846                 return(NULL);
5847             }
5848             SKIP_BLANKS;
5849             GROW;
5850         }
5851         if ((RAW == ')') && (NXT(1) == '*')) {
5852             if (elem != NULL) {
5853                 cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
5854                                                XML_ELEMENT_CONTENT_ELEMENT);
5855                 if (cur->c2 != NULL)
5856                     cur->c2->parent = cur;
5857             }
5858             if (ret != NULL)
5859                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
5860             if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
5861                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
5862 "Element content declaration doesn't start and stop in the same entity\n",
5863                                  NULL, NULL);
5864             }
5865             SKIP(2);
5866         } else {
5867             xmlFreeDocElementContent(ctxt->myDoc, ret);
5868             xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
5869             return(NULL);
5870         }
5871
5872     } else {
5873         xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
5874     }
5875     return(ret);
5876 }
5877
5878 /**
5879  * xmlParseElementChildrenContentDeclPriv:
5880  * @ctxt:  an XML parser context
5881  * @inputchk:  the input used for the current entity, needed for boundary checks
5882  * @depth: the level of recursion
5883  *
5884  * parse the declaration for a Mixed Element content
5885  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
5886  * 
5887  *
5888  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
5889  *
5890  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
5891  *
5892  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
5893  *
5894  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
5895  *
5896  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
5897  * TODO Parameter-entity replacement text must be properly nested
5898  *      with parenthesized groups. That is to say, if either of the
5899  *      opening or closing parentheses in a choice, seq, or Mixed
5900  *      construct is contained in the replacement text for a parameter
5901  *      entity, both must be contained in the same replacement text. For
5902  *      interoperability, if a parameter-entity reference appears in a
5903  *      choice, seq, or Mixed construct, its replacement text should not
5904  *      be empty, and neither the first nor last non-blank character of
5905  *      the replacement text should be a connector (| or ,).
5906  *
5907  * Returns the tree of xmlElementContentPtr describing the element 
5908  *          hierarchy.
5909  */
5910 static xmlElementContentPtr
5911 xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
5912                                        int depth) {
5913     xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
5914     const xmlChar *elem;
5915     xmlChar type = 0;
5916
5917     if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
5918         (depth >  2048)) {
5919         xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
5920 "xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
5921                           depth);
5922         return(NULL);
5923     }
5924     SKIP_BLANKS;
5925     GROW;
5926     if (RAW == '(') {
5927         int inputid = ctxt->input->id;
5928
5929         /* Recurse on first child */
5930         NEXT;
5931         SKIP_BLANKS;
5932         cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
5933                                                            depth + 1);
5934         SKIP_BLANKS;
5935         GROW;
5936     } else {
5937         elem = xmlParseName(ctxt);
5938         if (elem == NULL) {
5939             xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
5940             return(NULL);
5941         }
5942         cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
5943         if (cur == NULL) {
5944             xmlErrMemory(ctxt, NULL);
5945             return(NULL);
5946         }
5947         GROW;
5948         if (RAW == '?') {
5949             cur->ocur = XML_ELEMENT_CONTENT_OPT;
5950             NEXT;
5951         } else if (RAW == '*') {
5952             cur->ocur = XML_ELEMENT_CONTENT_MULT;
5953             NEXT;
5954         } else if (RAW == '+') {
5955             cur->ocur = XML_ELEMENT_CONTENT_PLUS;
5956             NEXT;
5957         } else {
5958             cur->ocur = XML_ELEMENT_CONTENT_ONCE;
5959         }
5960         GROW;
5961     }
5962     SKIP_BLANKS;
5963     SHRINK;
5964     while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
5965         /*
5966          * Each loop we parse one separator and one element.
5967          */
5968         if (RAW == ',') {
5969             if (type == 0) type = CUR;
5970
5971             /*
5972              * Detect "Name | Name , Name" error
5973              */
5974             else if (type != CUR) {
5975                 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
5976                     "xmlParseElementChildrenContentDecl : '%c' expected\n",
5977                                   type);
5978                 if ((last != NULL) && (last != ret))
5979                     xmlFreeDocElementContent(ctxt->myDoc, last);
5980                 if (ret != NULL)
5981                     xmlFreeDocElementContent(ctxt->myDoc, ret);
5982                 return(NULL);
5983             }
5984             NEXT;
5985
5986             op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
5987             if (op == NULL) {
5988                 if ((last != NULL) && (last != ret))
5989                     xmlFreeDocElementContent(ctxt->myDoc, last);
5990                 xmlFreeDocElementContent(ctxt->myDoc, ret);
5991                 return(NULL);
5992             }
5993             if (last == NULL) {
5994                 op->c1 = ret;
5995                 if (ret != NULL)
5996                     ret->parent = op;
5997                 ret = cur = op;
5998             } else {
5999                 cur->c2 = op;
6000                 if (op != NULL)
6001                     op->parent = cur;
6002                 op->c1 = last;
6003                 if (last != NULL)
6004                     last->parent = op;
6005                 cur =op;
6006                 last = NULL;
6007             }
6008         } else if (RAW == '|') {
6009             if (type == 0) type = CUR;
6010
6011             /*
6012              * Detect "Name , Name | Name" error
6013              */
6014             else if (type != CUR) {
6015                 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6016                     "xmlParseElementChildrenContentDecl : '%c' expected\n",
6017                                   type);
6018                 if ((last != NULL) && (last != ret))
6019                     xmlFreeDocElementContent(ctxt->myDoc, last);
6020                 if (ret != NULL)
6021                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6022                 return(NULL);
6023             }
6024             NEXT;
6025
6026             op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6027             if (op == NULL) {
6028                 if ((last != NULL) && (last != ret))
6029                     xmlFreeDocElementContent(ctxt->myDoc, last);
6030                 if (ret != NULL)
6031                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6032                 return(NULL);
6033             }
6034             if (last == NULL) {
6035                 op->c1 = ret;
6036                 if (ret != NULL)
6037                     ret->parent = op;
6038                 ret = cur = op;
6039             } else {
6040                 cur->c2 = op;
6041                 if (op != NULL)
6042                     op->parent = cur;
6043                 op->c1 = last;
6044                 if (last != NULL)
6045                     last->parent = op;
6046                 cur =op;
6047                 last = NULL;
6048             }
6049         } else {
6050             xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
6051             if ((last != NULL) && (last != ret))
6052                 xmlFreeDocElementContent(ctxt->myDoc, last);
6053             if (ret != NULL)
6054                 xmlFreeDocElementContent(ctxt->myDoc, ret);
6055             return(NULL);
6056         }
6057         GROW;
6058         SKIP_BLANKS;
6059         GROW;
6060         if (RAW == '(') {
6061             int inputid = ctxt->input->id;
6062             /* Recurse on second child */
6063             NEXT;
6064             SKIP_BLANKS;
6065             last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6066                                                           depth + 1);
6067             SKIP_BLANKS;
6068         } else {
6069             elem = xmlParseName(ctxt);
6070             if (elem == NULL) {
6071                 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6072                 if (ret != NULL)
6073                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6074                 return(NULL);
6075             }
6076             last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6077             if (last == NULL) {
6078                 if (ret != NULL)
6079                     xmlFreeDocElementContent(ctxt->myDoc, ret);
6080                 return(NULL);
6081             }
6082             if (RAW == '?') {
6083                 last->ocur = XML_ELEMENT_CONTENT_OPT;
6084                 NEXT;
6085             } else if (RAW == '*') {
6086                 last->ocur = XML_ELEMENT_CONTENT_MULT;
6087                 NEXT;
6088             } else if (RAW == '+') {
6089                 last->ocur = XML_ELEMENT_CONTENT_PLUS;
6090                 NEXT;
6091             } else {
6092                 last->ocur = XML_ELEMENT_CONTENT_ONCE;
6093             }
6094         }
6095         SKIP_BLANKS;
6096         GROW;
6097     }
6098     if ((cur != NULL) && (last != NULL)) {
6099         cur->c2 = last;
6100         if (last != NULL)
6101             last->parent = cur;
6102     }
6103     if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
6104         xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6105 "Element content declaration doesn't start and stop in the same entity\n",
6106                          NULL, NULL);
6107     }
6108     NEXT;
6109     if (RAW == '?') {
6110         if (ret != NULL) {
6111             if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
6112                 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6113                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6114             else
6115                 ret->ocur = XML_ELEMENT_CONTENT_OPT;
6116         }
6117         NEXT;
6118     } else if (RAW == '*') {
6119         if (ret != NULL) {
6120             ret->ocur = XML_ELEMENT_CONTENT_MULT;
6121             cur = ret;
6122             /*
6123              * Some normalization:
6124              * (a | b* | c?)* == (a | b | c)*
6125              */
6126             while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6127                 if ((cur->c1 != NULL) &&
6128                     ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6129                      (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
6130                     cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6131                 if ((cur->c2 != NULL) &&
6132                     ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6133                      (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
6134                     cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6135                 cur = cur->c2;
6136             }
6137         }
6138         NEXT;
6139     } else if (RAW == '+') {
6140         if (ret != NULL) {
6141             int found = 0;
6142
6143             if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
6144                 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6145                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6146             else
6147                 ret->ocur = XML_ELEMENT_CONTENT_PLUS;
6148             /*
6149              * Some normalization:
6150              * (a | b*)+ == (a | b)*
6151              * (a | b?)+ == (a | b)*
6152              */
6153             while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6154                 if ((cur->c1 != NULL) &&
6155                     ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6156                      (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
6157                     cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6158                     found = 1;
6159                 }
6160                 if ((cur->c2 != NULL) &&
6161                     ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6162                      (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
6163                     cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6164                     found = 1;
6165                 }
6166                 cur = cur->c2;
6167             }
6168             if (found)
6169                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
6170         }
6171         NEXT;
6172     }
6173     return(ret);
6174 }
6175
6176 /**
6177  * xmlParseElementChildrenContentDecl:
6178  * @ctxt:  an XML parser context
6179  * @inputchk:  the input used for the current entity, needed for boundary checks
6180  *
6181  * parse the declaration for a Mixed Element content
6182  * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6183  *
6184  * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6185  *
6186  * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6187  *
6188  * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6189  *
6190  * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6191  *
6192  * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6193  * TODO Parameter-entity replacement text must be properly nested
6194  *      with parenthesized groups. That is to say, if either of the
6195  *      opening or closing parentheses in a choice, seq, or Mixed
6196  *      construct is contained in the replacement text for a parameter
6197  *      entity, both must be contained in the same replacement text. For
6198  *      interoperability, if a parameter-entity reference appears in a
6199  *      choice, seq, or Mixed construct, its replacement text should not
6200  *      be empty, and neither the first nor last non-blank character of
6201  *      the replacement text should be a connector (| or ,).
6202  *
6203  * Returns the tree of xmlElementContentPtr describing the element
6204  *          hierarchy.
6205  */
6206 xmlElementContentPtr
6207 xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6208     /* stub left for API/ABI compat */
6209     return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
6210 }
6211
6212 /**
6213  * xmlParseElementContentDecl:
6214  * @ctxt:  an XML parser context
6215  * @name:  the name of the element being defined.
6216  * @result:  the Element Content pointer will be stored here if any
6217  *
6218  * parse the declaration for an Element content either Mixed or Children,
6219  * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
6220  * 
6221  * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
6222  *
6223  * returns: the type of element content XML_ELEMENT_TYPE_xxx
6224  */
6225
6226 int
6227 xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
6228                            xmlElementContentPtr *result) {
6229
6230     xmlElementContentPtr tree = NULL;
6231     int inputid = ctxt->input->id;
6232     int res;
6233
6234     *result = NULL;
6235
6236     if (RAW != '(') {
6237         xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6238                 "xmlParseElementContentDecl : %s '(' expected\n", name);
6239         return(-1);
6240     }
6241     NEXT;
6242     GROW;
6243     if (ctxt->instate == XML_PARSER_EOF)
6244         return(-1);
6245     SKIP_BLANKS;
6246     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6247         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
6248         res = XML_ELEMENT_TYPE_MIXED;
6249     } else {
6250         tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
6251         res = XML_ELEMENT_TYPE_ELEMENT;
6252     }
6253     SKIP_BLANKS;
6254     *result = tree;
6255     return(res);
6256 }
6257
6258 /**
6259  * xmlParseElementDecl:
6260  * @ctxt:  an XML parser context
6261  *
6262  * parse an Element declaration.
6263  *
6264  * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
6265  *
6266  * [ VC: Unique Element Type Declaration ]
6267  * No element type may be declared more than once
6268  *
6269  * Returns the type of the element, or -1 in case of error
6270  */
6271 int
6272 xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
6273     const xmlChar *name;
6274     int ret = -1;
6275     xmlElementContentPtr content  = NULL;
6276
6277     /* GROW; done in the caller */
6278     if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
6279         xmlParserInputPtr input = ctxt->input;
6280
6281         SKIP(9);
6282         if (!IS_BLANK_CH(CUR)) {
6283             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6284                            "Space required after 'ELEMENT'\n");
6285         }
6286         SKIP_BLANKS;
6287         name = xmlParseName(ctxt);
6288         if (name == NULL) {
6289             xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6290                            "xmlParseElementDecl: no name for Element\n");
6291             return(-1);
6292         }
6293         while ((RAW == 0) && (ctxt->inputNr > 1))
6294             xmlPopInput(ctxt);
6295         if (!IS_BLANK_CH(CUR)) {
6296             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6297                            "Space required after the element name\n");
6298         }
6299         SKIP_BLANKS;
6300         if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
6301             SKIP(5);
6302             /*
6303              * Element must always be empty.
6304              */
6305             ret = XML_ELEMENT_TYPE_EMPTY;
6306         } else if ((RAW == 'A') && (NXT(1) == 'N') &&
6307                    (NXT(2) == 'Y')) {
6308             SKIP(3);
6309             /*
6310              * Element is a generic container.
6311              */
6312             ret = XML_ELEMENT_TYPE_ANY;
6313         } else if (RAW == '(') {
6314             ret = xmlParseElementContentDecl(ctxt, name, &content);
6315         } else {
6316             /*
6317              * [ WFC: PEs in Internal Subset ] error handling.
6318              */
6319             if ((RAW == '%') && (ctxt->external == 0) &&
6320                 (ctxt->inputNr == 1)) {
6321                 xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
6322           "PEReference: forbidden within markup decl in internal subset\n");
6323             } else {
6324                 xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6325                       "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
6326             }
6327             return(-1);
6328         }
6329
6330         SKIP_BLANKS;
6331         /*
6332          * Pop-up of finished entities.
6333          */
6334         while ((RAW == 0) && (ctxt->inputNr > 1))
6335             xmlPopInput(ctxt);
6336         SKIP_BLANKS;
6337
6338         if (RAW != '>') {
6339             xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
6340             if (content != NULL) {
6341                 xmlFreeDocElementContent(ctxt->myDoc, content);
6342             }
6343         } else {
6344             if (input != ctxt->input) {
6345                 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6346     "Element declaration doesn't start and stop in the same entity\n");
6347             }
6348                 
6349             NEXT;
6350             if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6351                 (ctxt->sax->elementDecl != NULL)) {
6352                 if (content != NULL)
6353                     content->parent = NULL;
6354                 ctxt->sax->elementDecl(ctxt->userData, name, ret,
6355                                        content);
6356                 if ((content != NULL) && (content->parent == NULL)) {
6357                     /*
6358                      * this is a trick: if xmlAddElementDecl is called,
6359                      * instead of copying the full tree it is plugged directly
6360                      * if called from the parser. Avoid duplicating the 
6361                      * interfaces or change the API/ABI
6362                      */
6363                     xmlFreeDocElementContent(ctxt->myDoc, content);
6364                 }
6365             } else if (content != NULL) {
6366                 xmlFreeDocElementContent(ctxt->myDoc, content);
6367             }
6368         }
6369     }
6370     return(ret);
6371 }
6372
6373 /**
6374  * xmlParseConditionalSections
6375  * @ctxt:  an XML parser context
6376  *
6377  * [61] conditionalSect ::= includeSect | ignoreSect 
6378  * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>' 
6379  * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
6380  * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
6381  * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
6382  */
6383
6384 static void
6385 xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
6386     int id = ctxt->input->id;
6387
6388     SKIP(3);
6389     SKIP_BLANKS;
6390     if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
6391         SKIP(7);
6392         SKIP_BLANKS;
6393         if (RAW != '[') {
6394             xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6395         } else {
6396             if (ctxt->input->id != id) {
6397                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6398             "All markup of the conditional section is not in the same entity\n",
6399                                      NULL, NULL);
6400             }
6401             NEXT;
6402         }
6403         if (xmlParserDebugEntities) {
6404             if ((ctxt->input != NULL) && (ctxt->input->filename))
6405                 xmlGenericError(xmlGenericErrorContext,
6406                         "%s(%d): ", ctxt->input->filename,
6407                         ctxt->input->line);
6408             xmlGenericError(xmlGenericErrorContext,
6409                     "Entering INCLUDE Conditional Section\n");
6410         }
6411
6412         while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
6413                 (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
6414             const xmlChar *check = CUR_PTR;
6415             unsigned int cons = ctxt->input->consumed;
6416
6417             if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6418                 xmlParseConditionalSections(ctxt);
6419             } else if (IS_BLANK_CH(CUR)) {
6420                 NEXT;
6421             } else if (RAW == '%') {
6422                 xmlParsePEReference(ctxt);
6423             } else
6424                 xmlParseMarkupDecl(ctxt);
6425
6426             /*
6427              * Pop-up of finished entities.
6428              */
6429             while ((RAW == 0) && (ctxt->inputNr > 1))
6430                 xmlPopInput(ctxt);
6431
6432             if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
6433                 xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6434                 break;
6435             }
6436         }
6437         if (xmlParserDebugEntities) {
6438             if ((ctxt->input != NULL) && (ctxt->input->filename))
6439                 xmlGenericError(xmlGenericErrorContext,
6440                         "%s(%d): ", ctxt->input->filename,
6441                         ctxt->input->line);
6442             xmlGenericError(xmlGenericErrorContext,
6443                     "Leaving INCLUDE Conditional Section\n");
6444         }
6445
6446     } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
6447         int state;
6448         xmlParserInputState instate;
6449         int depth = 0;
6450
6451         SKIP(6);
6452         SKIP_BLANKS;
6453         if (RAW != '[') {
6454             xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6455         } else {
6456             if (ctxt->input->id != id) {
6457                 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6458             "All markup of the conditional section is not in the same entity\n",
6459                                      NULL, NULL);
6460             }
6461             NEXT;
6462         }
6463         if (xmlParserDebugEntities) {
6464             if ((ctxt->input != NULL) && (ctxt->input->filename))
6465                 xmlGenericError(xmlGenericErrorContext,
6466                         "%s(%d): ", ctxt->input->filename,
6467                         ctxt->input->line);
6468             xmlGenericError(xmlGenericErrorContext,
6469                     "Entering IGNORE Conditional Section\n");
6470         }
6471
6472         /*
6473          * Parse up to the end of the conditional section
6474          * But disable SAX event generating DTD building in the meantime
6475          */
6476         state = ctxt->disableSAX;
6477         instate = ctxt->instate;
6478         if (ctxt->recovery == 0) ctxt->disableSAX = 1;
6479         ctxt->instate = XML_PARSER_IGNORE;
6480
6481         while (((depth >= 0) && (RAW != 0)) &&
6482                (ctxt->instate != XML_PARSER_EOF)) {
6483           if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6484             depth++;
6485             SKIP(3);
6486             continue;
6487           }
6488           if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
6489             if (--depth >= 0) SKIP(3);
6490             continue;
6491           }
6492           NEXT;
6493           continue;
6494         }
6495
6496         ctxt->disableSAX = state;
6497         ctxt->instate = instate;
6498
6499         if (xmlParserDebugEntities) {
6500             if ((ctxt->input != NULL) && (ctxt->input->filename))
6501                 xmlGenericError(xmlGenericErrorContext,
6502                         "%s(%d): ", ctxt->input->filename,
6503                         ctxt->input->line);
6504             xmlGenericError(xmlGenericErrorContext,
6505                     "Leaving IGNORE Conditional Section\n");
6506         }
6507
6508     } else {
6509         xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
6510     }
6511
6512     if (RAW == 0)
6513         SHRINK;
6514
6515     if (RAW == 0) {
6516         xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
6517     } else {
6518         if (ctxt->input->id != id) {
6519             xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6520         "All markup of the conditional section is not in the same entity\n",
6521                                  NULL, NULL);
6522         }
6523         SKIP(3);
6524     }
6525 }
6526
6527 /**
6528  * xmlParseMarkupDecl:
6529  * @ctxt:  an XML parser context
6530  * 
6531  * parse Markup declarations
6532  *
6533  * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
6534  *                     NotationDecl | PI | Comment
6535  *
6536  * [ VC: Proper Declaration/PE Nesting ]
6537  * Parameter-entity replacement text must be properly nested with
6538  * markup declarations. That is to say, if either the first character
6539  * or the last character of a markup declaration (markupdecl above) is
6540  * contained in the replacement text for a parameter-entity reference,
6541  * both must be contained in the same replacement text.
6542  *
6543  * [ WFC: PEs in Internal Subset ]
6544  * In the internal DTD subset, parameter-entity references can occur
6545  * only where markup declarations can occur, not within markup declarations.
6546  * (This does not apply to references that occur in external parameter
6547  * entities or to the external subset.) 
6548  */
6549 void
6550 xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
6551     GROW;
6552     if (CUR == '<') {
6553         if (NXT(1) == '!') {
6554             switch (NXT(2)) {
6555                 case 'E':
6556                     if (NXT(3) == 'L')
6557                         xmlParseElementDecl(ctxt);
6558                     else if (NXT(3) == 'N')
6559                         xmlParseEntityDecl(ctxt);
6560                     break;
6561                 case 'A':
6562                     xmlParseAttributeListDecl(ctxt);
6563                     break;
6564                 case 'N':
6565                     xmlParseNotationDecl(ctxt);
6566                     break;
6567                 case '-':
6568                     xmlParseComment(ctxt);
6569                     break;
6570                 default:
6571                     /* there is an error but it will be detected later */
6572                     break;
6573             }
6574         } else if (NXT(1) == '?') {
6575             xmlParsePI(ctxt);
6576         }
6577     }
6578     /*
6579      * This is only for internal subset. On external entities,
6580      * the replacement is done before parsing stage
6581      */
6582     if ((ctxt->external == 0) && (ctxt->inputNr == 1))
6583         xmlParsePEReference(ctxt);
6584
6585     /*
6586      * Conditional sections are allowed from entities included
6587      * by PE References in the internal subset.
6588      */
6589     if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
6590         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6591             xmlParseConditionalSections(ctxt);
6592         }
6593     }
6594
6595     ctxt->instate = XML_PARSER_DTD;
6596 }
6597
6598 /**
6599  * xmlParseTextDecl:
6600  * @ctxt:  an XML parser context
6601  *
6602  * parse an XML declaration header for external entities
6603  *
6604  * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
6605  */
6606
6607 void
6608 xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
6609     xmlChar *version;
6610     const xmlChar *encoding;
6611
6612     /*
6613      * We know that '<?xml' is here.
6614      */
6615     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
6616         SKIP(5);
6617     } else {
6618         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
6619         return;
6620     }
6621
6622     if (!IS_BLANK_CH(CUR)) {
6623         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6624                        "Space needed after '<?xml'\n");
6625     }
6626     SKIP_BLANKS;
6627
6628     /*
6629      * We may have the VersionInfo here.
6630      */
6631     version = xmlParseVersionInfo(ctxt);
6632     if (version == NULL)
6633         version = xmlCharStrdup(XML_DEFAULT_VERSION);
6634     else {
6635         if (!IS_BLANK_CH(CUR)) {
6636             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6637                            "Space needed here\n");
6638         }
6639     }
6640     ctxt->input->version = version;
6641
6642     /*
6643      * We must have the encoding declaration
6644      */
6645     encoding = xmlParseEncodingDecl(ctxt);
6646     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
6647         /*
6648          * The XML REC instructs us to stop parsing right here
6649          */
6650         return;
6651     }
6652     if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
6653         xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
6654                        "Missing encoding in text declaration\n");
6655     }
6656
6657     SKIP_BLANKS;
6658     if ((RAW == '?') && (NXT(1) == '>')) {
6659         SKIP(2);
6660     } else if (RAW == '>') {
6661         /* Deprecated old WD ... */
6662         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
6663         NEXT;
6664     } else {
6665         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
6666         MOVETO_ENDTAG(CUR_PTR);
6667         NEXT;
6668     }
6669 }
6670
6671 /**
6672  * xmlParseExternalSubset:
6673  * @ctxt:  an XML parser context
6674  * @ExternalID: the external identifier
6675  * @SystemID: the system identifier (or URL)
6676  * 
6677  * parse Markup declarations from an external subset
6678  *
6679  * [30] extSubset ::= textDecl? extSubsetDecl
6680  *
6681  * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
6682  */
6683 void
6684 xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
6685                        const xmlChar *SystemID) {
6686     xmlDetectSAX2(ctxt);
6687     GROW;
6688
6689     if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
6690         (ctxt->input->end - ctxt->input->cur >= 4)) {
6691         xmlChar start[4];
6692         xmlCharEncoding enc;
6693
6694         start[0] = RAW;
6695         start[1] = NXT(1);
6696         start[2] = NXT(2);
6697         start[3] = NXT(3);
6698         enc = xmlDetectCharEncoding(start, 4);
6699         if (enc != XML_CHAR_ENCODING_NONE)
6700             xmlSwitchEncoding(ctxt, enc);
6701     }
6702
6703     if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
6704         xmlParseTextDecl(ctxt);
6705         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
6706             /*
6707              * The XML REC instructs us to stop parsing right here
6708              */
6709             ctxt->instate = XML_PARSER_EOF;
6710             return;
6711         }
6712     }
6713     if (ctxt->myDoc == NULL) {
6714         ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
6715         if (ctxt->myDoc == NULL) {
6716             xmlErrMemory(ctxt, "New Doc failed");
6717             return;
6718         }
6719         ctxt->myDoc->properties = XML_DOC_INTERNAL;
6720     }
6721     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
6722         xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
6723
6724     ctxt->instate = XML_PARSER_DTD;
6725     ctxt->external = 1;
6726     while (((RAW == '<') && (NXT(1) == '?')) ||
6727            ((RAW == '<') && (NXT(1) == '!')) ||
6728            (RAW == '%') || IS_BLANK_CH(CUR)) {
6729         const xmlChar *check = CUR_PTR;
6730         unsigned int cons = ctxt->input->consumed;
6731
6732         GROW;
6733         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6734             xmlParseConditionalSections(ctxt);
6735         } else if (IS_BLANK_CH(CUR)) {
6736             NEXT;
6737         } else if (RAW == '%') {
6738             xmlParsePEReference(ctxt);
6739         } else
6740             xmlParseMarkupDecl(ctxt);
6741
6742         /*
6743          * Pop-up of finished entities.
6744          */
6745         while ((RAW == 0) && (ctxt->inputNr > 1))
6746             xmlPopInput(ctxt);
6747
6748         if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
6749             xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6750             break;
6751         }
6752     }
6753
6754     if (RAW != 0) {
6755         xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6756     }
6757
6758 }
6759
6760 /**
6761  * xmlParseReference:
6762  * @ctxt:  an XML parser context
6763  *
6764  * parse and handle entity references in content, depending on the SAX
6765  * interface, this may end-up in a call to character() if this is a
6766  * CharRef, a predefined entity, if there is no reference() callback.
6767  * or if the parser was asked to switch to that mode.
6768  *
6769  * [67] Reference ::= EntityRef | CharRef
6770  */
6771 void
6772 xmlParseReference(xmlParserCtxtPtr ctxt) {
6773     xmlEntityPtr ent;
6774     xmlChar *val;
6775     int was_checked;
6776     xmlNodePtr list = NULL;
6777     xmlParserErrors ret = XML_ERR_OK;
6778
6779
6780     if (RAW != '&')
6781         return;
6782
6783     /*
6784      * Simple case of a CharRef
6785      */
6786     if (NXT(1) == '#') {
6787         int i = 0;
6788         xmlChar out[10];
6789         int hex = NXT(2);
6790         int value = xmlParseCharRef(ctxt);
6791
6792         if (value == 0)
6793             return;
6794         if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
6795             /*
6796              * So we are using non-UTF-8 buffers
6797              * Check that the char fit on 8bits, if not
6798              * generate a CharRef.
6799              */
6800             if (value <= 0xFF) {
6801                 out[0] = value;
6802                 out[1] = 0;
6803                 if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
6804                     (!ctxt->disableSAX))
6805                     ctxt->sax->characters(ctxt->userData, out, 1);
6806             } else {
6807                 if ((hex == 'x') || (hex == 'X'))
6808                     snprintf((char *)out, sizeof(out), "#x%X", value);
6809                 else
6810                     snprintf((char *)out, sizeof(out), "#%d", value);
6811                 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
6812                     (!ctxt->disableSAX))
6813                     ctxt->sax->reference(ctxt->userData, out);
6814             }
6815         } else {
6816             /*
6817              * Just encode the value in UTF-8
6818              */
6819             COPY_BUF(0 ,out, i, value);
6820             out[i] = 0;
6821             if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
6822                 (!ctxt->disableSAX))
6823                 ctxt->sax->characters(ctxt->userData, out, i);
6824         }
6825         return;
6826     }
6827
6828     /*
6829      * We are seeing an entity reference
6830      */
6831     ent = xmlParseEntityRef(ctxt);
6832     if (ent == NULL) return;
6833     if (!ctxt->wellFormed)
6834         return;
6835     was_checked = ent->checked;
6836
6837     /* special case of predefined entities */
6838     if ((ent->name == NULL) ||
6839         (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
6840         val = ent->content;
6841         if (val == NULL) return;
6842         /*
6843          * inline the entity.
6844          */
6845         if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
6846             (!ctxt->disableSAX))
6847             ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
6848         return;
6849     }
6850
6851     /*
6852      * The first reference to the entity trigger a parsing phase
6853      * where the ent->children is filled with the result from
6854      * the parsing.
6855      */
6856     if (ent->checked == 0) {
6857         unsigned long oldnbent = ctxt->nbentities;
6858
6859         /*
6860          * This is a bit hackish but this seems the best
6861          * way to make sure both SAX and DOM entity support
6862          * behaves okay.
6863          */
6864         void *user_data;
6865         if (ctxt->userData == ctxt)
6866             user_data = NULL;
6867         else
6868             user_data = ctxt->userData;
6869
6870         /*
6871          * Check that this entity is well formed
6872          * 4.3.2: An internal general parsed entity is well-formed
6873          * if its replacement text matches the production labeled
6874          * content.
6875          */
6876         if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
6877             ctxt->depth++;
6878             ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
6879                                                       user_data, &list);
6880             ctxt->depth--;
6881
6882         } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
6883             ctxt->depth++;
6884             ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
6885                                            user_data, ctxt->depth, ent->URI,
6886                                            ent->ExternalID, &list);
6887             ctxt->depth--;
6888         } else {
6889             ret = XML_ERR_ENTITY_PE_INTERNAL;
6890             xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
6891                          "invalid entity type found\n", NULL);
6892         }
6893
6894         /*
6895          * Store the number of entities needing parsing for this entity
6896          * content and do checkings
6897          */
6898         ent->checked = ctxt->nbentities - oldnbent;
6899         if (ret == XML_ERR_ENTITY_LOOP) {
6900             xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
6901             xmlFreeNodeList(list);
6902             return;
6903         }
6904         if (xmlParserEntityCheck(ctxt, 0, ent)) {
6905             xmlFreeNodeList(list);
6906             return;
6907         }
6908
6909         if ((ret == XML_ERR_OK) && (list != NULL)) {
6910             if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
6911              (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
6912                 (ent->children == NULL)) {
6913                 ent->children = list;
6914                 if (ctxt->replaceEntities) {
6915                     /*
6916                      * Prune it directly in the generated document
6917                      * except for single text nodes.
6918                      */
6919                     if (((list->type == XML_TEXT_NODE) &&
6920                          (list->next == NULL)) ||
6921                         (ctxt->parseMode == XML_PARSE_READER)) {
6922                         list->parent = (xmlNodePtr) ent;
6923                         list = NULL;
6924                         ent->owner = 1;
6925                     } else {
6926                         ent->owner = 0;
6927                         while (list != NULL) {
6928                             list->parent = (xmlNodePtr) ctxt->node;
6929                             list->doc = ctxt->myDoc;
6930                             if (list->next == NULL)
6931                                 ent->last = list;
6932                             list = list->next;
6933                         }
6934                         list = ent->children;
6935 #ifdef LIBXML_LEGACY_ENABLED
6936                         if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
6937                           xmlAddEntityReference(ent, list, NULL);
6938 #endif /* LIBXML_LEGACY_ENABLED */
6939                     }
6940                 } else {
6941                     ent->owner = 1;
6942                     while (list != NULL) {
6943                         list->parent = (xmlNodePtr) ent;
6944                         if (list->next == NULL)
6945                             ent->last = list;
6946                         list = list->next;
6947                     }
6948                 }
6949             } else {
6950                 xmlFreeNodeList(list);
6951                 list = NULL;
6952             }
6953         } else if ((ret != XML_ERR_OK) &&
6954                    (ret != XML_WAR_UNDECLARED_ENTITY)) {
6955             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
6956                      "Entity '%s' failed to parse\n", ent->name);
6957         } else if (list != NULL) {
6958             xmlFreeNodeList(list);
6959             list = NULL;
6960         }
6961         if (ent->checked == 0)
6962             ent->checked = 1;
6963     } else if (ent->checked != 1) {
6964         ctxt->nbentities += ent->checked;
6965     }
6966
6967     /*
6968      * Now that the entity content has been gathered
6969      * provide it to the application, this can take different forms based
6970      * on the parsing modes.
6971      */
6972     if (ent->children == NULL) {
6973         /*
6974          * Probably running in SAX mode and the callbacks don't
6975          * build the entity content. So unless we already went
6976          * though parsing for first checking go though the entity
6977          * content to generate callbacks associated to the entity
6978          */
6979         if (was_checked != 0) {
6980             void *user_data;
6981             /*
6982              * This is a bit hackish but this seems the best
6983              * way to make sure both SAX and DOM entity support
6984              * behaves okay.
6985              */
6986             if (ctxt->userData == ctxt)
6987                 user_data = NULL;
6988             else
6989                 user_data = ctxt->userData;
6990
6991             if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
6992                 ctxt->depth++;
6993                 ret = xmlParseBalancedChunkMemoryInternal(ctxt,
6994                                    ent->content, user_data, NULL);
6995                 ctxt->depth--;
6996             } else if (ent->etype ==
6997                        XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
6998                 ctxt->depth++;
6999                 ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
7000                            ctxt->sax, user_data, ctxt->depth,
7001                            ent->URI, ent->ExternalID, NULL);
7002                 ctxt->depth--;
7003             } else {
7004                 ret = XML_ERR_ENTITY_PE_INTERNAL;
7005                 xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7006                              "invalid entity type found\n", NULL);
7007             }
7008             if (ret == XML_ERR_ENTITY_LOOP) {
7009                 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7010                 return;
7011             }
7012         }
7013         if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7014             (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7015             /*
7016              * Entity reference callback comes second, it's somewhat
7017              * superfluous but a compatibility to historical behaviour
7018              */
7019             ctxt->sax->reference(ctxt->userData, ent->name);
7020         }
7021         return;
7022     }
7023
7024     /*
7025      * If we didn't get any children for the entity being built
7026      */
7027     if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7028         (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7029         /*
7030          * Create a node.
7031          */
7032         ctxt->sax->reference(ctxt->userData, ent->name);
7033         return;
7034     }
7035
7036     if ((ctxt->replaceEntities) || (ent->children == NULL))  {
7037         /*
7038          * There is a problem on the handling of _private for entities
7039          * (bug 155816): Should we copy the content of the field from
7040          * the entity (possibly overwriting some value set by the user
7041          * when a copy is created), should we leave it alone, or should
7042          * we try to take care of different situations?  The problem
7043          * is exacerbated by the usage of this field by the xmlReader.
7044          * To fix this bug, we look at _private on the created node
7045          * and, if it's NULL, we copy in whatever was in the entity.
7046          * If it's not NULL we leave it alone.  This is somewhat of a
7047          * hack - maybe we should have further tests to determine
7048          * what to do.
7049          */
7050         if ((ctxt->node != NULL) && (ent->children != NULL)) {
7051             /*
7052              * Seems we are generating the DOM content, do
7053              * a simple tree copy for all references except the first
7054              * In the first occurrence list contains the replacement.
7055              * progressive == 2 means we are operating on the Reader
7056              * and since nodes are discarded we must copy all the time.
7057              */
7058             if (((list == NULL) && (ent->owner == 0)) ||
7059                 (ctxt->parseMode == XML_PARSE_READER)) {
7060                 xmlNodePtr nw = NULL, cur, firstChild = NULL;
7061
7062                 /*
7063                  * when operating on a reader, the entities definitions
7064                  * are always owning the entities subtree.
7065                 if (ctxt->parseMode == XML_PARSE_READER)
7066                     ent->owner = 1;
7067                  */
7068
7069                 cur = ent->children;
7070                 while (cur != NULL) {
7071                     nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7072                     if (nw != NULL) {
7073                         if (nw->_private == NULL)
7074                             nw->_private = cur->_private;
7075                         if (firstChild == NULL){
7076                             firstChild = nw;
7077                         }
7078                         nw = xmlAddChild(ctxt->node, nw);
7079                     }
7080                     if (cur == ent->last) {
7081                         /*
7082                          * needed to detect some strange empty
7083                          * node cases in the reader tests
7084                          */
7085                         if ((ctxt->parseMode == XML_PARSE_READER) &&
7086                             (nw != NULL) &&
7087                             (nw->type == XML_ELEMENT_NODE) &&
7088                             (nw->children == NULL))
7089                             nw->extra = 1;
7090
7091                         break;
7092                     }
7093                     cur = cur->next;
7094                 }
7095 #ifdef LIBXML_LEGACY_ENABLED
7096                 if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7097                   xmlAddEntityReference(ent, firstChild, nw);
7098 #endif /* LIBXML_LEGACY_ENABLED */
7099             } else if (list == NULL) {
7100                 xmlNodePtr nw = NULL, cur, next, last,
7101                            firstChild = NULL;
7102                 /*
7103                  * Copy the entity child list and make it the new
7104                  * entity child list. The goal is to make sure any
7105                  * ID or REF referenced will be the one from the
7106                  * document content and not the entity copy.
7107                  */
7108                 cur = ent->children;
7109                 ent->children = NULL;
7110                 last = ent->last;
7111                 ent->last = NULL;
7112                 while (cur != NULL) {
7113                     next = cur->next;
7114                     cur->next = NULL;
7115                     cur->parent = NULL;
7116                     nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7117                     if (nw != NULL) {
7118                         if (nw->_private == NULL)
7119                             nw->_private = cur->_private;
7120                         if (firstChild == NULL){
7121                             firstChild = cur;
7122                         }
7123                         xmlAddChild((xmlNodePtr) ent, nw);
7124                         xmlAddChild(ctxt->node, cur);
7125                     }
7126                     if (cur == last)
7127                         break;
7128                     cur = next;
7129                 }
7130                 if (ent->owner == 0)
7131                     ent->owner = 1;
7132 #ifdef LIBXML_LEGACY_ENABLED
7133                 if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7134                   xmlAddEntityReference(ent, firstChild, nw);
7135 #endif /* LIBXML_LEGACY_ENABLED */
7136             } else {
7137                 const xmlChar *nbktext;
7138
7139                 /*
7140                  * the name change is to avoid coalescing of the
7141                  * node with a possible previous text one which
7142                  * would make ent->children a dangling pointer
7143                  */
7144                 nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
7145                                         -1);
7146                 if (ent->children->type == XML_TEXT_NODE)
7147                     ent->children->name = nbktext;
7148                 if ((ent->last != ent->children) &&
7149                     (ent->last->type == XML_TEXT_NODE))
7150                     ent->last->name = nbktext;
7151                 xmlAddChildList(ctxt->node, ent->children);
7152             }
7153
7154             /*
7155              * This is to avoid a nasty side effect, see
7156              * characters() in SAX.c
7157              */
7158             ctxt->nodemem = 0;
7159             ctxt->nodelen = 0;
7160             return;
7161         }
7162     }
7163 }
7164
7165 /**
7166  * xmlParseEntityRef:
7167  * @ctxt:  an XML parser context
7168  *
7169  * parse ENTITY references declarations
7170  *
7171  * [68] EntityRef ::= '&' Name ';'
7172  *
7173  * [ WFC: Entity Declared ]
7174  * In a document without any DTD, a document with only an internal DTD
7175  * subset which contains no parameter entity references, or a document
7176  * with "standalone='yes'", the Name given in the entity reference
7177  * must match that in an entity declaration, except that well-formed
7178  * documents need not declare any of the following entities: amp, lt,
7179  * gt, apos, quot.  The declaration of a parameter entity must precede
7180  * any reference to it.  Similarly, the declaration of a general entity
7181  * must precede any reference to it which appears in a default value in an
7182  * attribute-list declaration. Note that if entities are declared in the
7183  * external subset or in external parameter entities, a non-validating
7184  * processor is not obligated to read and process their declarations;
7185  * for such documents, the rule that an entity must be declared is a
7186  * well-formedness constraint only if standalone='yes'.
7187  *
7188  * [ WFC: Parsed Entity ]
7189  * An entity reference must not contain the name of an unparsed entity
7190  *
7191  * Returns the xmlEntityPtr if found, or NULL otherwise.
7192  */
7193 xmlEntityPtr
7194 xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
7195     const xmlChar *name;
7196     xmlEntityPtr ent = NULL;
7197
7198     GROW;
7199     if (ctxt->instate == XML_PARSER_EOF)
7200         return(NULL);
7201
7202     if (RAW != '&')
7203         return(NULL);
7204     NEXT;
7205     name = xmlParseName(ctxt);
7206     if (name == NULL) {
7207         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7208                        "xmlParseEntityRef: no name\n");
7209         return(NULL);
7210     }
7211     if (RAW != ';') {
7212         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7213         return(NULL);
7214     }
7215     NEXT;
7216
7217     /*
7218      * Predefined entites override any extra definition
7219      */
7220     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7221         ent = xmlGetPredefinedEntity(name);
7222         if (ent != NULL)
7223             return(ent);
7224     }
7225
7226     /*
7227      * Increate the number of entity references parsed
7228      */
7229     ctxt->nbentities++;
7230
7231     /*
7232      * Ask first SAX for entity resolution, otherwise try the
7233      * entities which may have stored in the parser context.
7234      */
7235     if (ctxt->sax != NULL) {
7236         if (ctxt->sax->getEntity != NULL)
7237             ent = ctxt->sax->getEntity(ctxt->userData, name);
7238         if ((ctxt->wellFormed == 1 ) && (ent == NULL) && 
7239             (ctxt->options & XML_PARSE_OLDSAX))
7240             ent = xmlGetPredefinedEntity(name);
7241         if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7242             (ctxt->userData==ctxt)) {
7243             ent = xmlSAX2GetEntity(ctxt, name);
7244         }
7245     }
7246     if (ctxt->instate == XML_PARSER_EOF)
7247         return(NULL);
7248     /*
7249      * [ WFC: Entity Declared ]
7250      * In a document without any DTD, a document with only an
7251      * internal DTD subset which contains no parameter entity
7252      * references, or a document with "standalone='yes'", the
7253      * Name given in the entity reference must match that in an
7254      * entity declaration, except that well-formed documents
7255      * need not declare any of the following entities: amp, lt,
7256      * gt, apos, quot.
7257      * The declaration of a parameter entity must precede any
7258      * reference to it.
7259      * Similarly, the declaration of a general entity must
7260      * precede any reference to it which appears in a default
7261      * value in an attribute-list declaration. Note that if
7262      * entities are declared in the external subset or in
7263      * external parameter entities, a non-validating processor
7264      * is not obligated to read and process their declarations;
7265      * for such documents, the rule that an entity must be
7266      * declared is a well-formedness constraint only if
7267      * standalone='yes'.
7268      */
7269     if (ent == NULL) {
7270         if ((ctxt->standalone == 1) ||
7271             ((ctxt->hasExternalSubset == 0) &&
7272              (ctxt->hasPErefs == 0))) {
7273             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7274                      "Entity '%s' not defined\n", name);
7275         } else {
7276             xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7277                      "Entity '%s' not defined\n", name);
7278             if ((ctxt->inSubset == 0) &&
7279                 (ctxt->sax != NULL) &&
7280                 (ctxt->sax->reference != NULL)) {
7281                 ctxt->sax->reference(ctxt->userData, name);
7282             }
7283         }
7284         ctxt->valid = 0;
7285     }
7286
7287     /*
7288      * [ WFC: Parsed Entity ]
7289      * An entity reference must not contain the name of an
7290      * unparsed entity
7291      */
7292     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7293         xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7294                  "Entity reference to unparsed entity %s\n", name);
7295     }
7296
7297     /*
7298      * [ WFC: No External Entity References ]
7299      * Attribute values cannot contain direct or indirect
7300      * entity references to external entities.
7301      */
7302     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7303              (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7304         xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7305              "Attribute references external entity '%s'\n", name);
7306     }
7307     /*
7308      * [ WFC: No < in Attribute Values ]
7309      * The replacement text of any entity referred to directly or
7310      * indirectly in an attribute value (other than "&lt;") must
7311      * not contain a <. 
7312      */
7313     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7314              (ent != NULL) && (ent->content != NULL) &&
7315              (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
7316              (xmlStrchr(ent->content, '<'))) {
7317         xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7318     "'<' in entity '%s' is not allowed in attributes values\n", name);
7319     }
7320
7321     /*
7322      * Internal check, no parameter entities here ...
7323      */
7324     else {
7325         switch (ent->etype) {
7326             case XML_INTERNAL_PARAMETER_ENTITY:
7327             case XML_EXTERNAL_PARAMETER_ENTITY:
7328             xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7329              "Attempt to reference the parameter entity '%s'\n",
7330                               name);
7331             break;
7332             default:
7333             break;
7334         }
7335     }
7336
7337     /*
7338      * [ WFC: No Recursion ]
7339      * A parsed entity must not contain a recursive reference
7340      * to itself, either directly or indirectly. 
7341      * Done somewhere else
7342      */
7343     return(ent);
7344 }
7345
7346 /**
7347  * xmlParseStringEntityRef:
7348  * @ctxt:  an XML parser context
7349  * @str:  a pointer to an index in the string
7350  *
7351  * parse ENTITY references declarations, but this version parses it from
7352  * a string value.
7353  *
7354  * [68] EntityRef ::= '&' Name ';'
7355  *
7356  * [ WFC: Entity Declared ]
7357  * In a document without any DTD, a document with only an internal DTD
7358  * subset which contains no parameter entity references, or a document
7359  * with "standalone='yes'", the Name given in the entity reference
7360  * must match that in an entity declaration, except that well-formed
7361  * documents need not declare any of the following entities: amp, lt,
7362  * gt, apos, quot.  The declaration of a parameter entity must precede
7363  * any reference to it.  Similarly, the declaration of a general entity
7364  * must precede any reference to it which appears in a default value in an
7365  * attribute-list declaration. Note that if entities are declared in the
7366  * external subset or in external parameter entities, a non-validating
7367  * processor is not obligated to read and process their declarations;
7368  * for such documents, the rule that an entity must be declared is a
7369  * well-formedness constraint only if standalone='yes'.
7370  *
7371  * [ WFC: Parsed Entity ]
7372  * An entity reference must not contain the name of an unparsed entity
7373  *
7374  * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
7375  * is updated to the current location in the string.
7376  */
7377 static xmlEntityPtr
7378 xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
7379     xmlChar *name;
7380     const xmlChar *ptr;
7381     xmlChar cur;
7382     xmlEntityPtr ent = NULL;
7383
7384     if ((str == NULL) || (*str == NULL))
7385         return(NULL);
7386     ptr = *str;
7387     cur = *ptr;
7388     if (cur != '&')
7389         return(NULL);
7390
7391     ptr++;
7392     name = xmlParseStringName(ctxt, &ptr);
7393     if (name == NULL) {
7394         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7395                        "xmlParseStringEntityRef: no name\n");
7396         *str = ptr;
7397         return(NULL);
7398     }
7399     if (*ptr != ';') {
7400         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7401         xmlFree(name);
7402         *str = ptr;
7403         return(NULL);
7404     }
7405     ptr++;
7406
7407
7408     /*
7409      * Predefined entites override any extra definition
7410      */
7411     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7412         ent = xmlGetPredefinedEntity(name);
7413         if (ent != NULL) {
7414             xmlFree(name);
7415             *str = ptr;
7416             return(ent);
7417         }
7418     }
7419
7420     /*
7421      * Increate the number of entity references parsed
7422      */
7423     ctxt->nbentities++;
7424
7425     /*
7426      * Ask first SAX for entity resolution, otherwise try the
7427      * entities which may have stored in the parser context.
7428      */
7429     if (ctxt->sax != NULL) {
7430         if (ctxt->sax->getEntity != NULL)
7431             ent = ctxt->sax->getEntity(ctxt->userData, name);
7432         if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
7433             ent = xmlGetPredefinedEntity(name);
7434         if ((ent == NULL) && (ctxt->userData==ctxt)) {
7435             ent = xmlSAX2GetEntity(ctxt, name);
7436         }
7437     }
7438     if (ctxt->instate == XML_PARSER_EOF) {
7439         xmlFree(name);
7440         return(NULL);
7441     }
7442
7443     /*
7444      * [ WFC: Entity Declared ]
7445      * In a document without any DTD, a document with only an
7446      * internal DTD subset which contains no parameter entity
7447      * references, or a document with "standalone='yes'", the
7448      * Name given in the entity reference must match that in an
7449      * entity declaration, except that well-formed documents
7450      * need not declare any of the following entities: amp, lt,
7451      * gt, apos, quot.
7452      * The declaration of a parameter entity must precede any
7453      * reference to it.
7454      * Similarly, the declaration of a general entity must
7455      * precede any reference to it which appears in a default
7456      * value in an attribute-list declaration. Note that if
7457      * entities are declared in the external subset or in
7458      * external parameter entities, a non-validating processor
7459      * is not obligated to read and process their declarations;
7460      * for such documents, the rule that an entity must be
7461      * declared is a well-formedness constraint only if
7462      * standalone='yes'. 
7463      */
7464     if (ent == NULL) {
7465         if ((ctxt->standalone == 1) ||
7466             ((ctxt->hasExternalSubset == 0) &&
7467              (ctxt->hasPErefs == 0))) {
7468             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7469                      "Entity '%s' not defined\n", name);
7470         } else {
7471             xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7472                           "Entity '%s' not defined\n",
7473                           name);
7474         }
7475         /* TODO ? check regressions ctxt->valid = 0; */
7476     }
7477
7478     /*
7479      * [ WFC: Parsed Entity ]
7480      * An entity reference must not contain the name of an
7481      * unparsed entity
7482      */
7483     else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7484         xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7485                  "Entity reference to unparsed entity %s\n", name);
7486     }
7487
7488     /*
7489      * [ WFC: No External Entity References ]
7490      * Attribute values cannot contain direct or indirect
7491      * entity references to external entities.
7492      */
7493     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7494              (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7495         xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7496          "Attribute references external entity '%s'\n", name);
7497     }
7498     /*
7499      * [ WFC: No < in Attribute Values ]
7500      * The replacement text of any entity referred to directly or
7501      * indirectly in an attribute value (other than "&lt;") must
7502      * not contain a <.
7503      */
7504     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7505              (ent != NULL) && (ent->content != NULL) &&
7506              (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
7507              (xmlStrchr(ent->content, '<'))) {
7508         xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7509      "'<' in entity '%s' is not allowed in attributes values\n",
7510                           name);
7511     }
7512
7513     /*
7514      * Internal check, no parameter entities here ...
7515      */
7516     else {
7517         switch (ent->etype) {
7518             case XML_INTERNAL_PARAMETER_ENTITY:
7519             case XML_EXTERNAL_PARAMETER_ENTITY:
7520                 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7521              "Attempt to reference the parameter entity '%s'\n",
7522                                   name);
7523             break;
7524             default:
7525             break;
7526         }
7527     }
7528
7529     /*
7530      * [ WFC: No Recursion ]
7531      * A parsed entity must not contain a recursive reference
7532      * to itself, either directly or indirectly.
7533      * Done somewhere else
7534      */
7535
7536     xmlFree(name);
7537     *str = ptr;
7538     return(ent);
7539 }
7540
7541 /**
7542  * xmlParsePEReference:
7543  * @ctxt:  an XML parser context
7544  *
7545  * parse PEReference declarations
7546  * The entity content is handled directly by pushing it's content as
7547  * a new input stream.
7548  *
7549  * [69] PEReference ::= '%' Name ';'
7550  *
7551  * [ WFC: No Recursion ]
7552  * A parsed entity must not contain a recursive
7553  * reference to itself, either directly or indirectly. 
7554  *
7555  * [ WFC: Entity Declared ]
7556  * In a document without any DTD, a document with only an internal DTD
7557  * subset which contains no parameter entity references, or a document
7558  * with "standalone='yes'", ...  ... The declaration of a parameter
7559  * entity must precede any reference to it...
7560  *
7561  * [ VC: Entity Declared ]
7562  * In a document with an external subset or external parameter entities
7563  * with "standalone='no'", ...  ... The declaration of a parameter entity
7564  * must precede any reference to it...
7565  *
7566  * [ WFC: In DTD ]
7567  * Parameter-entity references may only appear in the DTD.
7568  * NOTE: misleading but this is handled.
7569  */
7570 void
7571 xmlParsePEReference(xmlParserCtxtPtr ctxt)
7572 {
7573     const xmlChar *name;
7574     xmlEntityPtr entity = NULL;
7575     xmlParserInputPtr input;
7576
7577     if (RAW != '%')
7578         return;
7579     NEXT;
7580     name = xmlParseName(ctxt);
7581     if (name == NULL) {
7582         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7583                        "xmlParsePEReference: no name\n");
7584         return;
7585     }
7586     if (RAW != ';') {
7587         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7588         return;
7589     }
7590
7591     NEXT;
7592
7593     /*
7594      * Increate the number of entity references parsed
7595      */
7596     ctxt->nbentities++;
7597
7598     /*
7599      * Request the entity from SAX
7600      */
7601     if ((ctxt->sax != NULL) &&
7602         (ctxt->sax->getParameterEntity != NULL))
7603         entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
7604     if (ctxt->instate == XML_PARSER_EOF)
7605         return;
7606     if (entity == NULL) {
7607         /*
7608          * [ WFC: Entity Declared ]
7609          * In a document without any DTD, a document with only an
7610          * internal DTD subset which contains no parameter entity
7611          * references, or a document with "standalone='yes'", ...
7612          * ... The declaration of a parameter entity must precede
7613          * any reference to it...
7614          */
7615         if ((ctxt->standalone == 1) ||
7616             ((ctxt->hasExternalSubset == 0) &&
7617              (ctxt->hasPErefs == 0))) {
7618             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7619                               "PEReference: %%%s; not found\n",
7620                               name);
7621         } else {
7622             /*
7623              * [ VC: Entity Declared ]
7624              * In a document with an external subset or external
7625              * parameter entities with "standalone='no'", ...
7626              * ... The declaration of a parameter entity must
7627              * precede any reference to it...
7628              */
7629             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7630                           "PEReference: %%%s; not found\n",
7631                           name, NULL);
7632             ctxt->valid = 0;
7633         }
7634     } else {
7635         /*
7636          * Internal checking in case the entity quest barfed
7637          */
7638         if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
7639             (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
7640             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7641                   "Internal: %%%s; is not a parameter entity\n",
7642                           name, NULL);
7643         } else if (ctxt->input->free != deallocblankswrapper) {
7644             input = xmlNewBlanksWrapperInputStream(ctxt, entity);
7645             if (xmlPushInput(ctxt, input) < 0)
7646                 return;
7647         } else {
7648             /*
7649              * TODO !!!
7650              * handle the extra spaces added before and after
7651              * c.f. http://www.w3.org/TR/REC-xml#as-PE
7652              */
7653             input = xmlNewEntityInputStream(ctxt, entity);
7654             if (xmlPushInput(ctxt, input) < 0)
7655                 return;
7656             if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
7657                 (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
7658                 (IS_BLANK_CH(NXT(5)))) {
7659                 xmlParseTextDecl(ctxt);
7660                 if (ctxt->errNo ==
7661                     XML_ERR_UNSUPPORTED_ENCODING) {
7662                     /*
7663                      * The XML REC instructs us to stop parsing
7664                      * right here
7665                      */
7666                     ctxt->instate = XML_PARSER_EOF;
7667                     return;
7668                 }
7669             }
7670         }
7671     }
7672     ctxt->hasPErefs = 1;
7673 }
7674
7675 /**
7676  * xmlLoadEntityContent:
7677  * @ctxt:  an XML parser context
7678  * @entity: an unloaded system entity
7679  *
7680  * Load the original content of the given system entity from the
7681  * ExternalID/SystemID given. This is to be used for Included in Literal
7682  * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
7683  *
7684  * Returns 0 in case of success and -1 in case of failure
7685  */
7686 static int
7687 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
7688     xmlParserInputPtr input;
7689     xmlBufferPtr buf;
7690     int l, c;
7691     int count = 0;
7692
7693     if ((ctxt == NULL) || (entity == NULL) ||
7694         ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
7695          (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
7696         (entity->content != NULL)) {
7697         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
7698                     "xmlLoadEntityContent parameter error");
7699         return(-1);
7700     }
7701
7702     if (xmlParserDebugEntities)
7703         xmlGenericError(xmlGenericErrorContext,
7704                 "Reading %s entity content input\n", entity->name);
7705
7706     buf = xmlBufferCreate();
7707     if (buf == NULL) {
7708         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
7709                     "xmlLoadEntityContent parameter error");
7710         return(-1);
7711     }
7712
7713     input = xmlNewEntityInputStream(ctxt, entity);
7714     if (input == NULL) {
7715         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
7716                     "xmlLoadEntityContent input error");
7717         xmlBufferFree(buf);
7718         return(-1);
7719     }
7720
7721     /*
7722      * Push the entity as the current input, read char by char
7723      * saving to the buffer until the end of the entity or an error
7724      */
7725     if (xmlPushInput(ctxt, input) < 0) {
7726         xmlBufferFree(buf);
7727         return(-1);
7728     }
7729
7730     GROW;
7731     c = CUR_CHAR(l);
7732     while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
7733            (IS_CHAR(c))) {
7734         xmlBufferAdd(buf, ctxt->input->cur, l);
7735         if (count++ > 100) {
7736             count = 0;
7737             GROW;
7738             if (ctxt->instate == XML_PARSER_EOF) {
7739                 xmlBufferFree(buf);
7740                 return(-1);
7741             }
7742         }
7743         NEXTL(l);
7744         c = CUR_CHAR(l);
7745     }
7746
7747     if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
7748         xmlPopInput(ctxt);
7749     } else if (!IS_CHAR(c)) {
7750         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
7751                           "xmlLoadEntityContent: invalid char value %d\n",
7752                           c);
7753         xmlBufferFree(buf);
7754         return(-1);
7755     }
7756     entity->content = buf->content;
7757     buf->content = NULL;
7758     xmlBufferFree(buf);
7759
7760     return(0);
7761 }
7762
7763 /**
7764  * xmlParseStringPEReference:
7765  * @ctxt:  an XML parser context
7766  * @str:  a pointer to an index in the string
7767  *
7768  * parse PEReference declarations
7769  *
7770  * [69] PEReference ::= '%' Name ';'
7771  *
7772  * [ WFC: No Recursion ]
7773  * A parsed entity must not contain a recursive
7774  * reference to itself, either directly or indirectly.
7775  *
7776  * [ WFC: Entity Declared ]
7777  * In a document without any DTD, a document with only an internal DTD
7778  * subset which contains no parameter entity references, or a document
7779  * with "standalone='yes'", ...  ... The declaration of a parameter
7780  * entity must precede any reference to it...
7781  *
7782  * [ VC: Entity Declared ]
7783  * In a document with an external subset or external parameter entities
7784  * with "standalone='no'", ...  ... The declaration of a parameter entity
7785  * must precede any reference to it...
7786  *
7787  * [ WFC: In DTD ]
7788  * Parameter-entity references may only appear in the DTD.
7789  * NOTE: misleading but this is handled.
7790  *
7791  * Returns the string of the entity content.
7792  *         str is updated to the current value of the index
7793  */
7794 static xmlEntityPtr
7795 xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
7796     const xmlChar *ptr;
7797     xmlChar cur;
7798     xmlChar *name;
7799     xmlEntityPtr entity = NULL;
7800
7801     if ((str == NULL) || (*str == NULL)) return(NULL);
7802     ptr = *str;
7803     cur = *ptr;
7804     if (cur != '%')
7805         return(NULL);
7806     ptr++;
7807     name = xmlParseStringName(ctxt, &ptr);
7808     if (name == NULL) {
7809         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7810                        "xmlParseStringPEReference: no name\n");
7811         *str = ptr;
7812         return(NULL);
7813     }
7814     cur = *ptr;
7815     if (cur != ';') {
7816         xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7817         xmlFree(name);
7818         *str = ptr;
7819         return(NULL);
7820     }
7821     ptr++;
7822
7823     /*
7824      * Increate the number of entity references parsed
7825      */
7826     ctxt->nbentities++;
7827
7828     /*
7829      * Request the entity from SAX
7830      */
7831     if ((ctxt->sax != NULL) &&
7832         (ctxt->sax->getParameterEntity != NULL))
7833         entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
7834     if (ctxt->instate == XML_PARSER_EOF) {
7835         xmlFree(name);
7836         return(NULL);
7837     }
7838     if (entity == NULL) {
7839         /*
7840          * [ WFC: Entity Declared ]
7841          * In a document without any DTD, a document with only an
7842          * internal DTD subset which contains no parameter entity
7843          * references, or a document with "standalone='yes'", ...
7844          * ... The declaration of a parameter entity must precede
7845          * any reference to it...
7846          */
7847         if ((ctxt->standalone == 1) ||
7848             ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
7849             xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7850                  "PEReference: %%%s; not found\n", name);
7851         } else {
7852             /*
7853              * [ VC: Entity Declared ]
7854              * In a document with an external subset or external
7855              * parameter entities with "standalone='no'", ...
7856              * ... The declaration of a parameter entity must
7857              * precede any reference to it...
7858              */
7859             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7860                           "PEReference: %%%s; not found\n",
7861                           name, NULL);
7862             ctxt->valid = 0;
7863         }
7864     } else {
7865         /*
7866          * Internal checking in case the entity quest barfed
7867          */
7868         if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
7869             (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
7870             xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7871                           "%%%s; is not a parameter entity\n",
7872                           name, NULL);
7873         }
7874     }
7875     ctxt->hasPErefs = 1;
7876     xmlFree(name);
7877     *str = ptr;
7878     return(entity);
7879 }
7880
7881 /**
7882  * xmlParseDocTypeDecl:
7883  * @ctxt:  an XML parser context
7884  *
7885  * parse a DOCTYPE declaration
7886  *
7887  * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? 
7888  *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
7889  *
7890  * [ VC: Root Element Type ]
7891  * The Name in the document type declaration must match the element
7892  * type of the root element. 
7893  */
7894
7895 void
7896 xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
7897     const xmlChar *name = NULL;
7898     xmlChar *ExternalID = NULL;
7899     xmlChar *URI = NULL;
7900
7901     /*
7902      * We know that '<!DOCTYPE' has been detected.
7903      */
7904     SKIP(9);
7905
7906     SKIP_BLANKS;
7907
7908     /*
7909      * Parse the DOCTYPE name.
7910      */
7911     name = xmlParseName(ctxt);
7912     if (name == NULL) {
7913         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7914                        "xmlParseDocTypeDecl : no DOCTYPE name !\n");
7915     }
7916     ctxt->intSubName = name;
7917
7918     SKIP_BLANKS;
7919
7920     /*
7921      * Check for SystemID and ExternalID
7922      */
7923     URI = xmlParseExternalID(ctxt, &ExternalID, 1);
7924
7925     if ((URI != NULL) || (ExternalID != NULL)) {
7926         ctxt->hasExternalSubset = 1;
7927     }
7928     ctxt->extSubURI = URI;
7929     ctxt->extSubSystem = ExternalID;
7930
7931     SKIP_BLANKS;
7932
7933     /*
7934      * Create and update the internal subset.
7935      */
7936     if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
7937         (!ctxt->disableSAX))
7938         ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
7939     if (ctxt->instate == XML_PARSER_EOF)
7940         return;
7941
7942     /*
7943      * Is there any internal subset declarations ?
7944      * they are handled separately in xmlParseInternalSubset()
7945      */
7946     if (RAW == '[')
7947         return;
7948
7949     /*
7950      * We should be at the end of the DOCTYPE declaration.
7951      */
7952     if (RAW != '>') {
7953         xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
7954     }
7955     NEXT;
7956 }
7957
7958 /**
7959  * xmlParseInternalSubset:
7960  * @ctxt:  an XML parser context
7961  *
7962  * parse the internal subset declaration
7963  *
7964  * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
7965  */
7966
7967 static void
7968 xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
7969     /*
7970      * Is there any DTD definition ?
7971      */
7972     if (RAW == '[') {
7973         ctxt->instate = XML_PARSER_DTD;
7974         NEXT;
7975         /*
7976          * Parse the succession of Markup declarations and 
7977          * PEReferences.
7978          * Subsequence (markupdecl | PEReference | S)*
7979          */
7980         while ((RAW != ']') && (ctxt->instate != XML_PARSER_EOF)) {
7981             const xmlChar *check = CUR_PTR;
7982             unsigned int cons = ctxt->input->consumed;
7983
7984             SKIP_BLANKS;
7985             xmlParseMarkupDecl(ctxt);
7986             xmlParsePEReference(ctxt);
7987
7988             /*
7989              * Pop-up of finished entities.
7990              */
7991             while ((RAW == 0) && (ctxt->inputNr > 1))
7992                 xmlPopInput(ctxt);
7993
7994             if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
7995                 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
7996              "xmlParseInternalSubset: error detected in Markup declaration\n");
7997                 break;
7998             }
7999         }
8000         if (RAW == ']') { 
8001             NEXT;
8002             SKIP_BLANKS;
8003         }
8004     }
8005
8006     /*
8007      * We should be at the end of the DOCTYPE declaration.
8008      */
8009     if (RAW != '>') {
8010         xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8011     }
8012     NEXT;
8013 }
8014
8015 #ifdef LIBXML_SAX1_ENABLED
8016 /**
8017  * xmlParseAttribute:
8018  * @ctxt:  an XML parser context
8019  * @value:  a xmlChar ** used to store the value of the attribute
8020  *
8021  * parse an attribute
8022  *
8023  * [41] Attribute ::= Name Eq AttValue
8024  *
8025  * [ WFC: No External Entity References ]
8026  * Attribute values cannot contain direct or indirect entity references
8027  * to external entities.
8028  *
8029  * [ WFC: No < in Attribute Values ]
8030  * The replacement text of any entity referred to directly or indirectly in
8031  * an attribute value (other than "&lt;") must not contain a <. 
8032  * 
8033  * [ VC: Attribute Value Type ]
8034  * The attribute must have been declared; the value must be of the type
8035  * declared for it.
8036  *
8037  * [25] Eq ::= S? '=' S?
8038  *
8039  * With namespace:
8040  *
8041  * [NS 11] Attribute ::= QName Eq AttValue
8042  *
8043  * Also the case QName == xmlns:??? is handled independently as a namespace
8044  * definition.
8045  *
8046  * Returns the attribute name, and the value in *value.
8047  */
8048
8049 const xmlChar *
8050 xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
8051     const xmlChar *name;
8052     xmlChar *val;
8053
8054     *value = NULL;
8055     GROW;
8056     name = xmlParseName(ctxt);
8057     if (name == NULL) {
8058         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8059                        "error parsing attribute name\n");
8060         return(NULL);
8061     }
8062
8063     /*
8064      * read the value
8065      */
8066     SKIP_BLANKS;
8067     if (RAW == '=') {
8068         NEXT;
8069         SKIP_BLANKS;
8070         val = xmlParseAttValue(ctxt);
8071         ctxt->instate = XML_PARSER_CONTENT;
8072     } else {
8073         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8074                "Specification mandate value for attribute %s\n", name);
8075         return(NULL);
8076     }
8077
8078     /*
8079      * Check that xml:lang conforms to the specification
8080      * No more registered as an error, just generate a warning now
8081      * since this was deprecated in XML second edition
8082      */
8083     if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
8084         if (!xmlCheckLanguageID(val)) {
8085             xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
8086                           "Malformed value for xml:lang : %s\n",
8087                           val, NULL);
8088         }
8089     }
8090
8091     /*
8092      * Check that xml:space conforms to the specification
8093      */
8094     if (xmlStrEqual(name, BAD_CAST "xml:space")) {
8095         if (xmlStrEqual(val, BAD_CAST "default"))
8096             *(ctxt->space) = 0;
8097         else if (xmlStrEqual(val, BAD_CAST "preserve"))
8098             *(ctxt->space) = 1;
8099         else {
8100                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
8101 "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
8102                                  val, NULL);
8103         }
8104     }
8105
8106     *value = val;
8107     return(name);
8108 }
8109
8110 /**
8111  * xmlParseStartTag:
8112  * @ctxt:  an XML parser context
8113  * 
8114  * parse a start of tag either for rule element or
8115  * EmptyElement. In both case we don't parse the tag closing chars.
8116  *
8117  * [40] STag ::= '<' Name (S Attribute)* S? '>'
8118  *
8119  * [ WFC: Unique Att Spec ]
8120  * No attribute name may appear more than once in the same start-tag or
8121  * empty-element tag. 
8122  *
8123  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
8124  *
8125  * [ WFC: Unique Att Spec ]
8126  * No attribute name may appear more than once in the same start-tag or
8127  * empty-element tag. 
8128  *
8129  * With namespace:
8130  *
8131  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
8132  *
8133  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
8134  *
8135  * Returns the element name parsed
8136  */
8137
8138 const xmlChar *
8139 xmlParseStartTag(xmlParserCtxtPtr ctxt) {
8140     const xmlChar *name;
8141     const xmlChar *attname;
8142     xmlChar *attvalue;
8143     const xmlChar **atts = ctxt->atts;
8144     int nbatts = 0;
8145     int maxatts = ctxt->maxatts;
8146     int i;
8147
8148     if (RAW != '<') return(NULL);
8149     NEXT1;
8150
8151     name = xmlParseName(ctxt);
8152     if (name == NULL) {
8153         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8154              "xmlParseStartTag: invalid element name\n");
8155         return(NULL);
8156     }
8157
8158     /*
8159      * Now parse the attributes, it ends up with the ending
8160      *
8161      * (S Attribute)* S?
8162      */
8163     SKIP_BLANKS;
8164     GROW;
8165
8166     while (((RAW != '>') && 
8167            ((RAW != '/') || (NXT(1) != '>')) &&
8168            (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
8169         const xmlChar *q = CUR_PTR;
8170         unsigned int cons = ctxt->input->consumed;
8171
8172         attname = xmlParseAttribute(ctxt, &attvalue);
8173         if ((attname != NULL) && (attvalue != NULL)) {
8174             /*
8175              * [ WFC: Unique Att Spec ]
8176              * No attribute name may appear more than once in the same
8177              * start-tag or empty-element tag. 
8178              */
8179             for (i = 0; i < nbatts;i += 2) {
8180                 if (xmlStrEqual(atts[i], attname)) {
8181                     xmlErrAttributeDup(ctxt, NULL, attname);
8182                     xmlFree(attvalue);
8183                     goto failed;
8184                 }
8185             }
8186             /*
8187              * Add the pair to atts
8188              */
8189             if (atts == NULL) {
8190                 maxatts = 22; /* allow for 10 attrs by default */
8191                 atts = (const xmlChar **)
8192                        xmlMalloc(maxatts * sizeof(xmlChar *));
8193                 if (atts == NULL) {
8194                     xmlErrMemory(ctxt, NULL);
8195                     if (attvalue != NULL)
8196                         xmlFree(attvalue);
8197                     goto failed;
8198                 }
8199                 ctxt->atts = atts;
8200                 ctxt->maxatts = maxatts;
8201             } else if (nbatts + 4 > maxatts) {
8202                 const xmlChar **n;
8203
8204                 maxatts *= 2;
8205                 n = (const xmlChar **) xmlRealloc((void *) atts,
8206                                              maxatts * sizeof(const xmlChar *));
8207                 if (n == NULL) {
8208                     xmlErrMemory(ctxt, NULL);
8209                     if (attvalue != NULL)
8210                         xmlFree(attvalue);
8211                     goto failed;
8212                 }
8213                 atts = n;
8214                 ctxt->atts = atts;
8215                 ctxt->maxatts = maxatts;
8216             }
8217             atts[nbatts++] = attname;
8218             atts[nbatts++] = attvalue;
8219             atts[nbatts] = NULL;
8220             atts[nbatts + 1] = NULL;
8221         } else {
8222             if (attvalue != NULL)
8223                 xmlFree(attvalue);
8224         }
8225
8226 failed:     
8227
8228         GROW
8229         if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
8230             break;
8231         if (!IS_BLANK_CH(RAW)) {
8232             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
8233                            "attributes construct error\n");
8234         }
8235         SKIP_BLANKS;
8236         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
8237             (attname == NULL) && (attvalue == NULL)) {
8238             xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
8239                            "xmlParseStartTag: problem parsing attributes\n");
8240             break;
8241         }
8242         SHRINK;
8243         GROW;
8244     }
8245
8246     /*
8247      * SAX: Start of Element !
8248      */
8249     if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
8250         (!ctxt->disableSAX)) {
8251         if (nbatts > 0)
8252             ctxt->sax->startElement(ctxt->userData, name, atts);
8253         else
8254             ctxt->sax->startElement(ctxt->userData, name, NULL);
8255     }
8256
8257     if (atts != NULL) {
8258         /* Free only the content strings */
8259         for (i = 1;i < nbatts;i+=2)
8260             if (atts[i] != NULL)
8261                xmlFree((xmlChar *) atts[i]);
8262     }
8263     return(name);
8264 }
8265
8266 /**
8267  * xmlParseEndTag1:
8268  * @ctxt:  an XML parser context
8269  * @line:  line of the start tag
8270  * @nsNr:  number of namespaces on the start tag
8271  *
8272  * parse an end of tag
8273  *
8274  * [42] ETag ::= '</' Name S? '>'
8275  *
8276  * With namespace
8277  *
8278  * [NS 9] ETag ::= '</' QName S? '>'
8279  */
8280
8281 static void
8282 xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
8283     const xmlChar *name;
8284
8285     GROW;
8286     if ((RAW != '<') || (NXT(1) != '/')) {
8287         xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
8288                        "xmlParseEndTag: '</' not found\n");
8289         return;
8290     }
8291     SKIP(2);
8292
8293     name = xmlParseNameAndCompare(ctxt,ctxt->name);
8294
8295     /*
8296      * We should definitely be at the ending "S? '>'" part
8297      */
8298     GROW;
8299     SKIP_BLANKS;
8300     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
8301         xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
8302     } else
8303         NEXT1;
8304
8305     /*
8306      * [ WFC: Element Type Match ]
8307      * The Name in an element's end-tag must match the element type in the
8308      * start-tag. 
8309      *
8310      */
8311     if (name != (xmlChar*)1) {
8312         if (name == NULL) name = BAD_CAST "unparseable";
8313         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
8314                      "Opening and ending tag mismatch: %s line %d and %s\n",
8315                                 ctxt->name, line, name);
8316     }
8317
8318     /*
8319      * SAX: End of Tag
8320      */
8321     if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
8322         (!ctxt->disableSAX))
8323         ctxt->sax->endElement(ctxt->userData, ctxt->name);
8324
8325     namePop(ctxt);
8326     spacePop(ctxt);
8327     return;
8328 }
8329
8330 /**
8331  * xmlParseEndTag:
8332  * @ctxt:  an XML parser context
8333  *
8334  * parse an end of tag
8335  *
8336  * [42] ETag ::= '</' Name S? '>'
8337  *
8338  * With namespace
8339  *
8340  * [NS 9] ETag ::= '</' QName S? '>'
8341  */
8342
8343 void
8344 xmlParseEndTag(xmlParserCtxtPtr ctxt) {
8345     xmlParseEndTag1(ctxt, 0);
8346 }
8347 #endif /* LIBXML_SAX1_ENABLED */
8348
8349 /************************************************************************
8350  *                                                                      *
8351  *                    SAX 2 specific operations                         *
8352  *                                                                      *
8353  ************************************************************************/
8354
8355 /*
8356  * xmlGetNamespace:
8357  * @ctxt:  an XML parser context
8358  * @prefix:  the prefix to lookup
8359  *
8360  * Lookup the namespace name for the @prefix (which ca be NULL)
8361  * The prefix must come from the @ctxt->dict dictionnary
8362  *
8363  * Returns the namespace name or NULL if not bound
8364  */
8365 static const xmlChar *
8366 xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
8367     int i;
8368
8369     if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
8370     for (i = ctxt->nsNr - 2;i >= 0;i-=2)
8371         if (ctxt->nsTab[i] == prefix) {
8372             if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
8373                 return(NULL);
8374             return(ctxt->nsTab[i + 1]);
8375         }
8376     return(NULL);
8377 }
8378
8379 /**
8380  * xmlParseQName:
8381  * @ctxt:  an XML parser context
8382  * @prefix:  pointer to store the prefix part
8383  *
8384  * parse an XML Namespace QName
8385  *
8386  * [6]  QName  ::= (Prefix ':')? LocalPart
8387  * [7]  Prefix  ::= NCName
8388  * [8]  LocalPart  ::= NCName
8389  *
8390  * Returns the Name parsed or NULL
8391  */
8392
8393 static const xmlChar *
8394 xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
8395     const xmlChar *l, *p;
8396
8397     GROW;
8398
8399     l = xmlParseNCName(ctxt);
8400     if (l == NULL) {
8401         if (CUR == ':') {
8402             l = xmlParseName(ctxt);
8403             if (l != NULL) {
8404                 xmlNsErr(ctxt, XML_NS_ERR_QNAME, 
8405                          "Failed to parse QName '%s'\n", l, NULL, NULL);
8406                 *prefix = NULL;
8407                 return(l);
8408             }
8409         }
8410         return(NULL);
8411     }
8412     if (CUR == ':') {
8413         NEXT;
8414         p = l;
8415         l = xmlParseNCName(ctxt);
8416         if (l == NULL) {
8417             xmlChar *tmp;
8418
8419             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8420                      "Failed to parse QName '%s:'\n", p, NULL, NULL);
8421             l = xmlParseNmtoken(ctxt);
8422             if (l == NULL)
8423                 tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
8424             else {
8425                 tmp = xmlBuildQName(l, p, NULL, 0);
8426                 xmlFree((char *)l);
8427             }
8428             p = xmlDictLookup(ctxt->dict, tmp, -1);
8429             if (tmp != NULL) xmlFree(tmp);
8430             *prefix = NULL;
8431             return(p);
8432         }
8433         if (CUR == ':') {
8434             xmlChar *tmp;
8435
8436             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8437                      "Failed to parse QName '%s:%s:'\n", p, l, NULL);
8438             NEXT;
8439             tmp = (xmlChar *) xmlParseName(ctxt);
8440             if (tmp != NULL) {
8441                 tmp = xmlBuildQName(tmp, l, NULL, 0);
8442                 l = xmlDictLookup(ctxt->dict, tmp, -1);
8443                 if (tmp != NULL) xmlFree(tmp);
8444                 *prefix = p;
8445                 return(l);
8446             }
8447             tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
8448             l = xmlDictLookup(ctxt->dict, tmp, -1);
8449             if (tmp != NULL) xmlFree(tmp);
8450             *prefix = p;
8451             return(l);
8452         }
8453         *prefix = p;
8454     } else
8455         *prefix = NULL;
8456     return(l);
8457 }
8458
8459 /**
8460  * xmlParseQNameAndCompare:
8461  * @ctxt:  an XML parser context
8462  * @name:  the localname
8463  * @prefix:  the prefix, if any.
8464  *
8465  * parse an XML name and compares for match
8466  * (specialized for endtag parsing)
8467  *
8468  * Returns NULL for an illegal name, (xmlChar*) 1 for success
8469  * and the name for mismatch
8470  */
8471
8472 static const xmlChar *
8473 xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
8474                         xmlChar const *prefix) {
8475     const xmlChar *cmp;
8476     const xmlChar *in;
8477     const xmlChar *ret;
8478     const xmlChar *prefix2;
8479
8480     if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
8481
8482     GROW;
8483     in = ctxt->input->cur;
8484
8485     cmp = prefix;
8486     while (*in != 0 && *in == *cmp) {
8487         ++in;
8488         ++cmp;
8489     }
8490     if ((*cmp == 0) && (*in == ':')) {
8491         in++;
8492         cmp = name;
8493         while (*in != 0 && *in == *cmp) {
8494             ++in;
8495             ++cmp;
8496         }
8497         if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
8498             /* success */
8499             ctxt->input->cur = in;
8500             return((const xmlChar*) 1);
8501         }
8502     }
8503     /*
8504      * all strings coms from the dictionary, equality can be done directly
8505      */
8506     ret = xmlParseQName (ctxt, &prefix2);
8507     if ((ret == name) && (prefix == prefix2))
8508         return((const xmlChar*) 1);
8509     return ret;
8510 }
8511
8512 /**
8513  * xmlParseAttValueInternal:
8514  * @ctxt:  an XML parser context
8515  * @len:  attribute len result
8516  * @alloc:  whether the attribute was reallocated as a new string
8517  * @normalize:  if 1 then further non-CDATA normalization must be done
8518  *
8519  * parse a value for an attribute.
8520  * NOTE: if no normalization is needed, the routine will return pointers
8521  *       directly from the data buffer.
8522  *
8523  * 3.3.3 Attribute-Value Normalization:
8524  * Before the value of an attribute is passed to the application or
8525  * checked for validity, the XML processor must normalize it as follows: 
8526  * - a character reference is processed by appending the referenced
8527  *   character to the attribute value
8528  * - an entity reference is processed by recursively processing the
8529  *   replacement text of the entity 
8530  * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
8531  *   appending #x20 to the normalized value, except that only a single
8532  *   #x20 is appended for a "#xD#xA" sequence that is part of an external
8533  *   parsed entity or the literal entity value of an internal parsed entity 
8534  * - other characters are processed by appending them to the normalized value 
8535  * If the declared value is not CDATA, then the XML processor must further
8536  * process the normalized attribute value by discarding any leading and
8537  * trailing space (#x20) characters, and by replacing sequences of space
8538  * (#x20) characters by a single space (#x20) character.  
8539  * All attributes for which no declaration has been read should be treated
8540  * by a non-validating parser as if declared CDATA.
8541  *
8542  * Returns the AttValue parsed or NULL. The value has to be freed by the
8543  *     caller if it was copied, this can be detected by val[*len] == 0.
8544  */
8545
8546 static xmlChar *
8547 xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
8548                          int normalize)
8549 {
8550     xmlChar limit = 0;
8551     const xmlChar *in = NULL, *start, *end, *last;
8552     xmlChar *ret = NULL;
8553
8554     GROW;
8555     in = (xmlChar *) CUR_PTR;
8556     if (*in != '"' && *in != '\'') {
8557         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
8558         return (NULL);
8559     }
8560     ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
8561
8562     /*
8563      * try to handle in this routine the most common case where no
8564      * allocation of a new string is required and where content is
8565      * pure ASCII.
8566      */
8567     limit = *in++;
8568     end = ctxt->input->end;
8569     start = in;
8570     if (in >= end) {
8571         const xmlChar *oldbase = ctxt->input->base;
8572         GROW;
8573         if (oldbase != ctxt->input->base) {
8574             long delta = ctxt->input->base - oldbase;
8575             start = start + delta;
8576             in = in + delta;
8577         }
8578         end = ctxt->input->end;
8579     }
8580     if (normalize) {
8581         /*
8582          * Skip any leading spaces
8583          */
8584         while ((in < end) && (*in != limit) && 
8585                ((*in == 0x20) || (*in == 0x9) ||
8586                 (*in == 0xA) || (*in == 0xD))) {
8587             in++;
8588             start = in;
8589             if (in >= end) {
8590                 const xmlChar *oldbase = ctxt->input->base;
8591                 GROW;
8592                 if (ctxt->instate == XML_PARSER_EOF)
8593                     return(NULL);
8594                 if (oldbase != ctxt->input->base) {
8595                     long delta = ctxt->input->base - oldbase;
8596                     start = start + delta;
8597                     in = in + delta;
8598                 }
8599                 end = ctxt->input->end;
8600             }
8601         }
8602         while ((in < end) && (*in != limit) && (*in >= 0x20) &&
8603                (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
8604             if ((*in++ == 0x20) && (*in == 0x20)) break;
8605             if (in >= end) {
8606                 const xmlChar *oldbase = ctxt->input->base;
8607                 GROW;
8608                 if (ctxt->instate == XML_PARSER_EOF)
8609                     return(NULL);
8610                 if (oldbase != ctxt->input->base) {
8611                     long delta = ctxt->input->base - oldbase;
8612                     start = start + delta;
8613                     in = in + delta;
8614                 }
8615                 end = ctxt->input->end;
8616             }
8617         }
8618         last = in;
8619         /*
8620          * skip the trailing blanks
8621          */
8622         while ((last[-1] == 0x20) && (last > start)) last--;
8623         while ((in < end) && (*in != limit) && 
8624                ((*in == 0x20) || (*in == 0x9) ||
8625                 (*in == 0xA) || (*in == 0xD))) {
8626             in++;
8627             if (in >= end) {
8628                 const xmlChar *oldbase = ctxt->input->base;
8629                 GROW;
8630                 if (ctxt->instate == XML_PARSER_EOF)
8631                     return(NULL);
8632                 if (oldbase != ctxt->input->base) {
8633                     long delta = ctxt->input->base - oldbase;
8634                     start = start + delta;
8635                     in = in + delta;
8636                     last = last + delta;
8637                 }
8638                 end = ctxt->input->end;
8639             }
8640         }
8641         if (*in != limit) goto need_complex;
8642     } else {
8643         while ((in < end) && (*in != limit) && (*in >= 0x20) &&
8644                (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
8645             in++;
8646             if (in >= end) {
8647                 const xmlChar *oldbase = ctxt->input->base;
8648                 GROW;
8649                 if (ctxt->instate == XML_PARSER_EOF)
8650                     return(NULL);
8651                 if (oldbase != ctxt->input->base) {
8652                     long delta = ctxt->input->base - oldbase;
8653                     start = start + delta;
8654                     in = in + delta;
8655                 }
8656                 end = ctxt->input->end;
8657             }
8658         }
8659         last = in;
8660         if (*in != limit) goto need_complex;
8661     }
8662     in++;
8663     if (len != NULL) {
8664         *len = last - start;
8665         ret = (xmlChar *) start;
8666     } else {
8667         if (alloc) *alloc = 1;
8668         ret = xmlStrndup(start, last - start);
8669     }
8670     CUR_PTR = in;
8671     if (alloc) *alloc = 0;
8672     return ret;
8673 need_complex:
8674     if (alloc) *alloc = 1;
8675     return xmlParseAttValueComplex(ctxt, len, normalize);
8676 }
8677
8678 /**
8679  * xmlParseAttribute2:
8680  * @ctxt:  an XML parser context
8681  * @pref:  the element prefix
8682  * @elem:  the element name
8683  * @prefix:  a xmlChar ** used to store the value of the attribute prefix
8684  * @value:  a xmlChar ** used to store the value of the attribute
8685  * @len:  an int * to save the length of the attribute
8686  * @alloc:  an int * to indicate if the attribute was allocated
8687  *
8688  * parse an attribute in the new SAX2 framework.
8689  *
8690  * Returns the attribute name, and the value in *value, .
8691  */
8692
8693 static const xmlChar *
8694 xmlParseAttribute2(xmlParserCtxtPtr ctxt,
8695                    const xmlChar * pref, const xmlChar * elem,
8696                    const xmlChar ** prefix, xmlChar ** value,
8697                    int *len, int *alloc)
8698 {
8699     const xmlChar *name;
8700     xmlChar *val, *internal_val = NULL;
8701     int normalize = 0;
8702
8703     *value = NULL;
8704     GROW;
8705     name = xmlParseQName(ctxt, prefix);
8706     if (name == NULL) {
8707         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8708                        "error parsing attribute name\n");
8709         return (NULL);
8710     }
8711
8712     /*
8713      * get the type if needed
8714      */
8715     if (ctxt->attsSpecial != NULL) {
8716         int type;
8717
8718         type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
8719                                             pref, elem, *prefix, name);
8720         if (type != 0)
8721             normalize = 1;
8722     }
8723
8724     /*
8725      * read the value
8726      */
8727     SKIP_BLANKS;
8728     if (RAW == '=') {
8729         NEXT;
8730         SKIP_BLANKS;
8731         val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
8732         if (normalize) {
8733             /*
8734              * Sometimes a second normalisation pass for spaces is needed
8735              * but that only happens if charrefs or entities refernces
8736              * have been used in the attribute value, i.e. the attribute
8737              * value have been extracted in an allocated string already.
8738              */
8739             if (*alloc) {
8740                 const xmlChar *val2;
8741
8742                 val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
8743                 if ((val2 != NULL) && (val2 != val)) {
8744                     xmlFree(val);
8745                     val = (xmlChar *) val2;
8746                 }
8747             }
8748         }
8749         ctxt->instate = XML_PARSER_CONTENT;
8750     } else {
8751         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8752                           "Specification mandate value for attribute %s\n",
8753                           name);
8754         return (NULL);
8755     }
8756
8757     if (*prefix == ctxt->str_xml) {
8758         /*
8759          * Check that xml:lang conforms to the specification
8760          * No more registered as an error, just generate a warning now
8761          * since this was deprecated in XML second edition
8762          */
8763         if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
8764             internal_val = xmlStrndup(val, *len);
8765             if (!xmlCheckLanguageID(internal_val)) {
8766                 xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
8767                               "Malformed value for xml:lang : %s\n",
8768                               internal_val, NULL);
8769             }
8770         }
8771
8772         /*
8773          * Check that xml:space conforms to the specification
8774          */
8775         if (xmlStrEqual(name, BAD_CAST "space")) {
8776             internal_val = xmlStrndup(val, *len);
8777             if (xmlStrEqual(internal_val, BAD_CAST "default"))
8778                 *(ctxt->space) = 0;
8779             else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
8780                 *(ctxt->space) = 1;
8781             else {
8782                 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
8783                               "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
8784                               internal_val, NULL);
8785             }
8786         }
8787         if (internal_val) {
8788             xmlFree(internal_val);
8789         }
8790     }
8791
8792     *value = val;
8793     return (name);
8794 }
8795 /**
8796  * xmlParseStartTag2:
8797  * @ctxt:  an XML parser context
8798  * 
8799  * parse a start of tag either for rule element or
8800  * EmptyElement. In both case we don't parse the tag closing chars.
8801  * This routine is called when running SAX2 parsing
8802  *
8803  * [40] STag ::= '<' Name (S Attribute)* S? '>'
8804  *
8805  * [ WFC: Unique Att Spec ]
8806  * No attribute name may appear more than once in the same start-tag or
8807  * empty-element tag. 
8808  *
8809  * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
8810  *
8811  * [ WFC: Unique Att Spec ]
8812  * No attribute name may appear more than once in the same start-tag or
8813  * empty-element tag. 
8814  *
8815  * With namespace:
8816  *
8817  * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
8818  *
8819  * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
8820  *
8821  * Returns the element name parsed
8822  */
8823
8824 static const xmlChar *
8825 xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
8826                   const xmlChar **URI, int *tlen) {
8827     const xmlChar *localname;
8828     const xmlChar *prefix;
8829     const xmlChar *attname;
8830     const xmlChar *aprefix;
8831     const xmlChar *nsname;
8832     xmlChar *attvalue;
8833     const xmlChar **atts = ctxt->atts;
8834     int maxatts = ctxt->maxatts;
8835     int nratts, nbatts, nbdef;
8836     int i, j, nbNs, attval, oldline, oldcol;
8837     const xmlChar *base;
8838     unsigned long cur;
8839     int nsNr = ctxt->nsNr;
8840
8841     if (RAW != '<') return(NULL);
8842     NEXT1;
8843
8844     /*
8845      * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
8846      *       point since the attribute values may be stored as pointers to
8847      *       the buffer and calling SHRINK would destroy them !
8848      *       The Shrinking is only possible once the full set of attribute
8849      *       callbacks have been done.
8850      */
8851 reparse:
8852     SHRINK;
8853     base = ctxt->input->base;
8854     cur = ctxt->input->cur - ctxt->input->base;
8855     oldline = ctxt->input->line;
8856     oldcol = ctxt->input->col;
8857     nbatts = 0;
8858     nratts = 0;
8859     nbdef = 0;
8860     nbNs = 0;
8861     attval = 0;
8862     /* Forget any namespaces added during an earlier parse of this element. */
8863     ctxt->nsNr = nsNr;
8864
8865     localname = xmlParseQName(ctxt, &prefix);
8866     if (localname == NULL) {
8867         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8868                        "StartTag: invalid element name\n");
8869         return(NULL);
8870     }
8871     *tlen = ctxt->input->cur - ctxt->input->base - cur;
8872
8873     /*
8874      * Now parse the attributes, it ends up with the ending
8875      *
8876      * (S Attribute)* S?
8877      */
8878     SKIP_BLANKS;
8879     GROW;
8880     if (ctxt->input->base != base) goto base_changed;
8881
8882     while (((RAW != '>') && 
8883            ((RAW != '/') || (NXT(1) != '>')) &&
8884            (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
8885         const xmlChar *q = CUR_PTR;
8886         unsigned int cons = ctxt->input->consumed;
8887         int len = -1, alloc = 0;
8888
8889         attname = xmlParseAttribute2(ctxt, prefix, localname,
8890                                      &aprefix, &attvalue, &len, &alloc);
8891         if (ctxt->input->base != base) {
8892             if ((attvalue != NULL) && (alloc != 0))
8893                 xmlFree(attvalue);
8894             attvalue = NULL;
8895             goto base_changed;
8896         }
8897         if ((attname != NULL) && (attvalue != NULL)) {
8898             if (len < 0) len = xmlStrlen(attvalue);
8899             if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
8900                 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
8901                 xmlURIPtr uri;
8902
8903                 if (*URL != 0) {
8904                     uri = xmlParseURI((const char *) URL);
8905                     if (uri == NULL) {
8906                         xmlNsErr(ctxt, XML_WAR_NS_URI,
8907                                  "xmlns: '%s' is not a valid URI\n",
8908                                            URL, NULL, NULL);
8909                     } else {
8910                         if (uri->scheme == NULL) {
8911                             xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
8912                                       "xmlns: URI %s is not absolute\n",
8913                                       URL, NULL, NULL);
8914                         }
8915                         xmlFreeURI(uri);
8916                     }
8917                     if (URL == ctxt->str_xml_ns) {
8918                         if (attname != ctxt->str_xml) {
8919                             xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8920                          "xml namespace URI cannot be the default namespace\n",
8921                                      NULL, NULL, NULL);
8922                         }
8923                         goto skip_default_ns;
8924                     }
8925                     if ((len == 29) &&
8926                         (xmlStrEqual(URL,
8927                                  BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
8928                         xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8929                              "reuse of the xmlns namespace name is forbidden\n",
8930                                  NULL, NULL, NULL);
8931                         goto skip_default_ns;
8932                     }
8933                 }
8934                 /*
8935                  * check that it's not a defined namespace
8936                  */
8937                 for (j = 1;j <= nbNs;j++)
8938                     if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
8939                         break;
8940                 if (j <= nbNs)
8941                     xmlErrAttributeDup(ctxt, NULL, attname);
8942                 else
8943                     if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
8944 skip_default_ns:
8945                 if (alloc != 0) xmlFree(attvalue);
8946                 SKIP_BLANKS;
8947                 continue;
8948             }
8949             if (aprefix == ctxt->str_xmlns) {
8950                 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
8951                 xmlURIPtr uri;
8952
8953                 if (attname == ctxt->str_xml) {
8954                     if (URL != ctxt->str_xml_ns) {
8955                         xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8956                                  "xml namespace prefix mapped to wrong URI\n",
8957                                  NULL, NULL, NULL);
8958                     }
8959                     /*
8960                      * Do not keep a namespace definition node
8961                      */
8962                     goto skip_ns;
8963                 }
8964                 if (URL == ctxt->str_xml_ns) {
8965                     if (attname != ctxt->str_xml) {
8966                         xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8967                                  "xml namespace URI mapped to wrong prefix\n",
8968                                  NULL, NULL, NULL);
8969                     }
8970                     goto skip_ns;
8971                 }
8972                 if (attname == ctxt->str_xmlns) {
8973                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8974                              "redefinition of the xmlns prefix is forbidden\n",
8975                              NULL, NULL, NULL);
8976                     goto skip_ns;
8977                 }
8978                 if ((len == 29) &&
8979                     (xmlStrEqual(URL,
8980                                  BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
8981                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8982                              "reuse of the xmlns namespace name is forbidden\n",
8983                              NULL, NULL, NULL);
8984                     goto skip_ns;
8985                 }
8986                 if ((URL == NULL) || (URL[0] == 0)) {
8987                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
8988                              "xmlns:%s: Empty XML namespace is not allowed\n",
8989                                   attname, NULL, NULL);
8990                     goto skip_ns;
8991                 } else {
8992                     uri = xmlParseURI((const char *) URL);
8993                     if (uri == NULL) {
8994                         xmlNsErr(ctxt, XML_WAR_NS_URI,
8995                              "xmlns:%s: '%s' is not a valid URI\n",
8996                                            attname, URL, NULL);
8997                     } else {
8998                         if ((ctxt->pedantic) && (uri->scheme == NULL)) {
8999                             xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9000                                       "xmlns:%s: URI %s is not absolute\n",
9001                                       attname, URL, NULL);
9002                         }
9003                         xmlFreeURI(uri);
9004                     }
9005                 }
9006
9007                 /*
9008                  * check that it's not a defined namespace
9009                  */
9010                 for (j = 1;j <= nbNs;j++)
9011                     if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9012                         break;
9013                 if (j <= nbNs)
9014                     xmlErrAttributeDup(ctxt, aprefix, attname);
9015                 else
9016                     if (nsPush(ctxt, attname, URL) > 0) nbNs++;
9017 skip_ns:
9018                 if (alloc != 0) xmlFree(attvalue);
9019                 SKIP_BLANKS;
9020                 if (ctxt->input->base != base) goto base_changed;
9021                 continue;
9022             }
9023
9024             /*
9025              * Add the pair to atts
9026              */
9027             if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9028                 if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9029                     if (attvalue[len] == 0)
9030                         xmlFree(attvalue);
9031                     goto failed;
9032                 }
9033                 maxatts = ctxt->maxatts;
9034                 atts = ctxt->atts;
9035             }
9036             ctxt->attallocs[nratts++] = alloc;
9037             atts[nbatts++] = attname;
9038             atts[nbatts++] = aprefix;
9039             atts[nbatts++] = NULL; /* the URI will be fetched later */
9040             atts[nbatts++] = attvalue;
9041             attvalue += len;
9042             atts[nbatts++] = attvalue;
9043             /*
9044              * tag if some deallocation is needed
9045              */
9046             if (alloc != 0) attval = 1;
9047         } else {
9048             if ((attvalue != NULL) && (attvalue[len] == 0))
9049                 xmlFree(attvalue);
9050         }
9051
9052 failed:
9053
9054         GROW
9055         if (ctxt->instate == XML_PARSER_EOF)
9056             break;
9057         if (ctxt->input->base != base) goto base_changed;
9058         if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
9059             break;
9060         if (!IS_BLANK_CH(RAW)) {
9061             xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9062                            "attributes construct error\n");
9063             break;
9064         }
9065         SKIP_BLANKS;
9066         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
9067             (attname == NULL) && (attvalue == NULL)) {
9068             xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9069                  "xmlParseStartTag: problem parsing attributes\n");
9070             break;
9071         }
9072         GROW;
9073         if (ctxt->input->base != base) goto base_changed;
9074     }
9075
9076     /*
9077      * The attributes defaulting
9078      */
9079     if (ctxt->attsDefault != NULL) {
9080         xmlDefAttrsPtr defaults;
9081
9082         defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
9083         if (defaults != NULL) {
9084             for (i = 0;i < defaults->nbAttrs;i++) {
9085                 attname = defaults->values[5 * i];
9086                 aprefix = defaults->values[5 * i + 1];
9087
9088                 /*
9089                  * special work for namespaces defaulted defs
9090                  */
9091                 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9092                     /*
9093                      * check that it's not a defined namespace
9094                      */
9095                     for (j = 1;j <= nbNs;j++)
9096                         if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9097                             break;
9098                     if (j <= nbNs) continue;
9099
9100                     nsname = xmlGetNamespace(ctxt, NULL);
9101                     if (nsname != defaults->values[5 * i + 2]) {
9102                         if (nsPush(ctxt, NULL,
9103                                    defaults->values[5 * i + 2]) > 0)
9104                             nbNs++;
9105                     }
9106                 } else if (aprefix == ctxt->str_xmlns) {
9107                     /*
9108                      * check that it's not a defined namespace
9109                      */
9110                     for (j = 1;j <= nbNs;j++)
9111                         if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9112                             break;
9113                     if (j <= nbNs) continue;
9114
9115                     nsname = xmlGetNamespace(ctxt, attname);
9116                     if (nsname != defaults->values[2]) {
9117                         if (nsPush(ctxt, attname,
9118                                    defaults->values[5 * i + 2]) > 0)
9119                             nbNs++;
9120                     }
9121                 } else {
9122                     /*
9123                      * check that it's not a defined attribute
9124                      */
9125                     for (j = 0;j < nbatts;j+=5) {
9126                         if ((attname == atts[j]) && (aprefix == atts[j+1]))
9127                             break;
9128                     }
9129                     if (j < nbatts) continue;
9130
9131                     if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9132                         if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9133                             return(NULL);
9134                         }
9135                         maxatts = ctxt->maxatts;
9136                         atts = ctxt->atts;
9137                     }
9138                     atts[nbatts++] = attname;
9139                     atts[nbatts++] = aprefix;
9140                     if (aprefix == NULL)
9141                         atts[nbatts++] = NULL;
9142                     else
9143                         atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
9144                     atts[nbatts++] = defaults->values[5 * i + 2];
9145                     atts[nbatts++] = defaults->values[5 * i + 3];
9146                     if ((ctxt->standalone == 1) &&
9147                         (defaults->values[5 * i + 4] != NULL)) {
9148                         xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED, 
9149           "standalone: attribute %s on %s defaulted from external subset\n",
9150                                          attname, localname);
9151                     }
9152                     nbdef++;
9153                 }
9154             }
9155         }
9156     }
9157
9158     /*
9159      * The attributes checkings
9160      */
9161     for (i = 0; i < nbatts;i += 5) {
9162         /*
9163         * The default namespace does not apply to attribute names.
9164         */
9165         if (atts[i + 1] != NULL) {
9166             nsname = xmlGetNamespace(ctxt, atts[i + 1]);
9167             if (nsname == NULL) {
9168                 xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9169                     "Namespace prefix %s for %s on %s is not defined\n",
9170                     atts[i + 1], atts[i], localname);
9171             }
9172             atts[i + 2] = nsname;
9173         } else
9174             nsname = NULL;
9175         /*
9176          * [ WFC: Unique Att Spec ]
9177          * No attribute name may appear more than once in the same
9178          * start-tag or empty-element tag. 
9179          * As extended by the Namespace in XML REC.
9180          */
9181         for (j = 0; j < i;j += 5) {
9182             if (atts[i] == atts[j]) {
9183                 if (atts[i+1] == atts[j+1]) {
9184                     xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
9185                     break;
9186                 }
9187                 if ((nsname != NULL) && (atts[j + 2] == nsname)) {
9188                     xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
9189                              "Namespaced Attribute %s in '%s' redefined\n",
9190                              atts[i], nsname, NULL);
9191                     break;
9192                 }
9193             }
9194         }
9195     }
9196
9197     nsname = xmlGetNamespace(ctxt, prefix);
9198     if ((prefix != NULL) && (nsname == NULL)) {
9199         xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9200                  "Namespace prefix %s on %s is not defined\n",
9201                  prefix, localname, NULL);
9202     }
9203     *pref = prefix;
9204     *URI = nsname;
9205
9206     /*
9207      * SAX: Start of Element !
9208      */
9209     if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
9210         (!ctxt->disableSAX)) {
9211         if (nbNs > 0)
9212             ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9213                           nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
9214                           nbatts / 5, nbdef, atts);
9215         else
9216             ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9217                           nsname, 0, NULL, nbatts / 5, nbdef, atts);
9218     }
9219
9220     /*
9221      * Free up attribute allocated strings if needed
9222      */
9223     if (attval != 0) {
9224         for (i = 3,j = 0; j < nratts;i += 5,j++)
9225             if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9226                 xmlFree((xmlChar *) atts[i]);
9227     }
9228
9229     return(localname);
9230
9231 base_changed:
9232     /*
9233      * the attribute strings are valid iif the base didn't changed
9234      */
9235     if (attval != 0) {
9236         for (i = 3,j = 0; j < nratts;i += 5,j++)
9237             if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9238                 xmlFree((xmlChar *) atts[i]);
9239     }
9240     ctxt->input->cur = ctxt->input->base + cur;
9241     ctxt->input->line = oldline;
9242     ctxt->input->col = oldcol;
9243     if (ctxt->wellFormed == 1) {
9244         goto reparse;
9245     }
9246     return(NULL);
9247 }
9248
9249 /**
9250  * xmlParseEndTag2:
9251  * @ctxt:  an XML parser context
9252  * @line:  line of the start tag
9253  * @nsNr:  number of namespaces on the start tag
9254  *
9255  * parse an end of tag
9256  *
9257  * [42] ETag ::= '</' Name S? '>'
9258  *
9259  * With namespace
9260  *
9261  * [NS 9] ETag ::= '</' QName S? '>'
9262  */
9263
9264 static void
9265 xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
9266                 const xmlChar *URI, int line, int nsNr, int tlen) {
9267     const xmlChar *name;
9268
9269     GROW;
9270     if ((RAW != '<') || (NXT(1) != '/')) {
9271         xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
9272         return;
9273     }
9274     SKIP(2);
9275
9276     if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
9277         if (ctxt->input->cur[tlen] == '>') {
9278             ctxt->input->cur += tlen + 1;
9279             goto done;
9280         }
9281         ctxt->input->cur += tlen;
9282         name = (xmlChar*)1;
9283     } else {
9284         if (prefix == NULL)
9285             name = xmlParseNameAndCompare(ctxt, ctxt->name);
9286         else
9287             name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
9288     }
9289
9290     /*
9291      * We should definitely be at the ending "S? '>'" part
9292      */
9293     GROW;
9294     if (ctxt->instate == XML_PARSER_EOF)
9295         return;
9296     SKIP_BLANKS;
9297     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
9298         xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
9299     } else
9300         NEXT1;
9301
9302     /*
9303      * [ WFC: Element Type Match ]
9304      * The Name in an element's end-tag must match the element type in the
9305      * start-tag. 
9306      *
9307      */
9308     if (name != (xmlChar*)1) {
9309         if (name == NULL) name = BAD_CAST "unparseable";
9310         if ((line == 0) && (ctxt->node != NULL))
9311             line = ctxt->node->line;
9312         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
9313                      "Opening and ending tag mismatch: %s line %d and %s\n",
9314                                 ctxt->name, line, name);
9315     }
9316
9317     /*
9318      * SAX: End of Tag
9319      */
9320 done:
9321     if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9322         (!ctxt->disableSAX))
9323         ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
9324
9325     spacePop(ctxt);
9326     if (nsNr != 0)
9327         nsPop(ctxt, nsNr);
9328     return;
9329 }
9330
9331 /**
9332  * xmlParseCDSect:
9333  * @ctxt:  an XML parser context
9334  * 
9335  * Parse escaped pure raw content.
9336  *
9337  * [18] CDSect ::= CDStart CData CDEnd
9338  *
9339  * [19] CDStart ::= '<![CDATA['
9340  *
9341  * [20] Data ::= (Char* - (Char* ']]>' Char*))
9342  *
9343  * [21] CDEnd ::= ']]>'
9344  */
9345 void
9346 xmlParseCDSect(xmlParserCtxtPtr ctxt) {
9347     xmlChar *buf = NULL;
9348     int len = 0;
9349     int size = XML_PARSER_BUFFER_SIZE;
9350     int r, rl;
9351     int s, sl;
9352     int cur, l;
9353     int count = 0;
9354
9355     /* Check 2.6.0 was NXT(0) not RAW */
9356     if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9357         SKIP(9);
9358     } else
9359         return;
9360
9361     ctxt->instate = XML_PARSER_CDATA_SECTION;
9362     r = CUR_CHAR(rl);
9363     if (!IS_CHAR(r)) {
9364         xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9365         ctxt->instate = XML_PARSER_CONTENT;
9366         return;
9367     }
9368     NEXTL(rl);
9369     s = CUR_CHAR(sl);
9370     if (!IS_CHAR(s)) {
9371         xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9372         ctxt->instate = XML_PARSER_CONTENT;
9373         return;
9374     }
9375     NEXTL(sl);
9376     cur = CUR_CHAR(l);
9377     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
9378     if (buf == NULL) {
9379         xmlErrMemory(ctxt, NULL);
9380         return;
9381     }
9382     while (IS_CHAR(cur) &&
9383            ((r != ']') || (s != ']') || (cur != '>'))) {
9384         if (len + 5 >= size) {
9385             xmlChar *tmp;
9386
9387             size *= 2;
9388             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
9389             if (tmp == NULL) {
9390                 xmlFree(buf);
9391                 xmlErrMemory(ctxt, NULL);
9392                 return;
9393             }
9394             buf = tmp;
9395         }
9396         COPY_BUF(rl,buf,len,r);
9397         r = s;
9398         rl = sl;
9399         s = cur;
9400         sl = l;
9401         count++;
9402         if (count > 50) {
9403             GROW;
9404             if (ctxt->instate == XML_PARSER_EOF) {
9405                 xmlFree(buf);
9406                 return;
9407             }
9408             count = 0;
9409         }
9410         NEXTL(l);
9411         cur = CUR_CHAR(l);
9412     }
9413     buf[len] = 0;
9414     ctxt->instate = XML_PARSER_CONTENT;
9415     if (cur != '>') {
9416         xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9417                              "CData section not finished\n%.50s\n", buf);
9418         xmlFree(buf);
9419         return;
9420     }
9421     NEXTL(l);
9422
9423     /*
9424      * OK the buffer is to be consumed as cdata.
9425      */
9426     if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
9427         if (ctxt->sax->cdataBlock != NULL)
9428             ctxt->sax->cdataBlock(ctxt->userData, buf, len);
9429         else if (ctxt->sax->characters != NULL)
9430             ctxt->sax->characters(ctxt->userData, buf, len);
9431     }
9432     xmlFree(buf);
9433 }
9434
9435 /**
9436  * xmlParseContent:
9437  * @ctxt:  an XML parser context
9438  *
9439  * Parse a content:
9440  *
9441  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
9442  */
9443
9444 void
9445 xmlParseContent(xmlParserCtxtPtr ctxt) {
9446     GROW;
9447     while ((RAW != 0) &&
9448            ((RAW != '<') || (NXT(1) != '/')) &&
9449            (ctxt->instate != XML_PARSER_EOF)) {
9450         const xmlChar *test = CUR_PTR;
9451         unsigned int cons = ctxt->input->consumed;
9452         const xmlChar *cur = ctxt->input->cur;
9453
9454         /*
9455          * First case : a Processing Instruction.
9456          */
9457         if ((*cur == '<') && (cur[1] == '?')) {
9458             xmlParsePI(ctxt);
9459         }
9460
9461         /*
9462          * Second case : a CDSection
9463          */
9464         /* 2.6.0 test was *cur not RAW */
9465         else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9466             xmlParseCDSect(ctxt);
9467         }
9468
9469         /*
9470          * Third case :  a comment
9471          */
9472         else if ((*cur == '<') && (NXT(1) == '!') &&
9473                  (NXT(2) == '-') && (NXT(3) == '-')) {
9474             xmlParseComment(ctxt);
9475             ctxt->instate = XML_PARSER_CONTENT;
9476         }
9477
9478         /*
9479          * Fourth case :  a sub-element.
9480          */
9481         else if (*cur == '<') {
9482             xmlParseElement(ctxt);
9483         }
9484
9485         /*
9486          * Fifth case : a reference. If if has not been resolved,
9487          *    parsing returns it's Name, create the node 
9488          */
9489
9490         else if (*cur == '&') {
9491             xmlParseReference(ctxt);
9492         }
9493
9494         /*
9495          * Last case, text. Note that References are handled directly.
9496          */
9497         else {
9498             xmlParseCharData(ctxt, 0);
9499         }
9500
9501         GROW;
9502         /*
9503          * Pop-up of finished entities.
9504          */
9505         while ((RAW == 0) && (ctxt->inputNr > 1))
9506             xmlPopInput(ctxt);
9507         SHRINK;
9508
9509         if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
9510             xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9511                         "detected an error in element content\n");
9512             ctxt->instate = XML_PARSER_EOF;
9513             break;
9514         }
9515     }
9516 }
9517
9518 /**
9519  * xmlParseElement:
9520  * @ctxt:  an XML parser context
9521  *
9522  * parse an XML element, this is highly recursive
9523  *
9524  * [39] element ::= EmptyElemTag | STag content ETag
9525  *
9526  * [ WFC: Element Type Match ]
9527  * The Name in an element's end-tag must match the element type in the
9528  * start-tag. 
9529  *
9530  */
9531
9532 void
9533 xmlParseElement(xmlParserCtxtPtr ctxt) {
9534     const xmlChar *name;
9535     const xmlChar *prefix = NULL;
9536     const xmlChar *URI = NULL;
9537     xmlParserNodeInfo node_info;
9538     int line, tlen;
9539     xmlNodePtr ret;
9540     int nsNr = ctxt->nsNr;
9541
9542     if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
9543         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9544         xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
9545                  "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
9546                           xmlParserMaxDepth);
9547         ctxt->instate = XML_PARSER_EOF;
9548         return;
9549     }
9550
9551     /* Capture start position */
9552     if (ctxt->record_info) {
9553         node_info.begin_pos = ctxt->input->consumed +
9554                           (CUR_PTR - ctxt->input->base);
9555         node_info.begin_line = ctxt->input->line;
9556     }
9557
9558     if (ctxt->spaceNr == 0)
9559         spacePush(ctxt, -1);
9560     else if (*ctxt->space == -2)
9561         spacePush(ctxt, -1);
9562     else
9563         spacePush(ctxt, *ctxt->space);
9564
9565     line = ctxt->input->line;
9566 #ifdef LIBXML_SAX1_ENABLED
9567     if (ctxt->sax2)
9568 #endif /* LIBXML_SAX1_ENABLED */
9569         name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
9570 #ifdef LIBXML_SAX1_ENABLED
9571     else
9572         name = xmlParseStartTag(ctxt);
9573 #endif /* LIBXML_SAX1_ENABLED */
9574     if (ctxt->instate == XML_PARSER_EOF)
9575         return;
9576     if (name == NULL) {
9577         spacePop(ctxt);
9578         return;
9579     }
9580     namePush(ctxt, name);
9581     ret = ctxt->node;
9582
9583 #ifdef LIBXML_VALID_ENABLED
9584     /*
9585      * [ VC: Root Element Type ]
9586      * The Name in the document type declaration must match the element
9587      * type of the root element. 
9588      */
9589     if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
9590         ctxt->node && (ctxt->node == ctxt->myDoc->children))
9591         ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
9592 #endif /* LIBXML_VALID_ENABLED */
9593
9594     /*
9595      * Check for an Empty Element.
9596      */
9597     if ((RAW == '/') && (NXT(1) == '>')) {
9598         SKIP(2);
9599         if (ctxt->sax2) {
9600             if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9601                 (!ctxt->disableSAX))
9602                 ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
9603 #ifdef LIBXML_SAX1_ENABLED
9604         } else {
9605             if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
9606                 (!ctxt->disableSAX))
9607                 ctxt->sax->endElement(ctxt->userData, name);
9608 #endif /* LIBXML_SAX1_ENABLED */
9609         }
9610         namePop(ctxt);
9611         spacePop(ctxt);
9612         if (nsNr != ctxt->nsNr)
9613             nsPop(ctxt, ctxt->nsNr - nsNr);
9614         if ( ret != NULL && ctxt->record_info ) {
9615            node_info.end_pos = ctxt->input->consumed +
9616                               (CUR_PTR - ctxt->input->base);
9617            node_info.end_line = ctxt->input->line;
9618            node_info.node = ret;
9619            xmlParserAddNodeInfo(ctxt, &node_info);
9620         }
9621         return;
9622     }
9623     if (RAW == '>') {
9624         NEXT1;
9625     } else {
9626         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
9627                      "Couldn't find end of Start Tag %s line %d\n",
9628                                 name, line, NULL);
9629
9630         /*
9631          * end of parsing of this node.
9632          */
9633         nodePop(ctxt);
9634         namePop(ctxt);
9635         spacePop(ctxt);
9636         if (nsNr != ctxt->nsNr)
9637             nsPop(ctxt, ctxt->nsNr - nsNr);
9638
9639         /*
9640          * Capture end position and add node
9641          */
9642         if ( ret != NULL && ctxt->record_info ) {
9643            node_info.end_pos = ctxt->input->consumed +
9644                               (CUR_PTR - ctxt->input->base);
9645            node_info.end_line = ctxt->input->line;
9646            node_info.node = ret;
9647            xmlParserAddNodeInfo(ctxt, &node_info);
9648         }
9649         return;
9650     }
9651
9652     /*
9653      * Parse the content of the element:
9654      */
9655     xmlParseContent(ctxt);
9656     if (ctxt->instate == XML_PARSER_EOF)
9657         return;
9658     if (!IS_BYTE_CHAR(RAW)) {
9659         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
9660          "Premature end of data in tag %s line %d\n",
9661                                 name, line, NULL);
9662
9663         /*
9664          * end of parsing of this node.
9665          */
9666         nodePop(ctxt);
9667         namePop(ctxt);
9668         spacePop(ctxt);
9669         if (nsNr != ctxt->nsNr)
9670             nsPop(ctxt, ctxt->nsNr - nsNr);
9671         return;
9672     }
9673
9674     /*
9675      * parse the end of tag: '</' should be here.
9676      */
9677     if (ctxt->sax2) {
9678         xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
9679         namePop(ctxt);
9680     }
9681 #ifdef LIBXML_SAX1_ENABLED
9682       else
9683         xmlParseEndTag1(ctxt, line);
9684 #endif /* LIBXML_SAX1_ENABLED */
9685
9686     /*
9687      * Capture end position and add node
9688      */
9689     if ( ret != NULL && ctxt->record_info ) {
9690        node_info.end_pos = ctxt->input->consumed +
9691                           (CUR_PTR - ctxt->input->base);
9692        node_info.end_line = ctxt->input->line;
9693        node_info.node = ret;
9694        xmlParserAddNodeInfo(ctxt, &node_info);
9695     }
9696 }
9697
9698 /**
9699  * xmlParseVersionNum:
9700  * @ctxt:  an XML parser context
9701  *
9702  * parse the XML version value.
9703  *
9704  * [26] VersionNum ::= '1.' [0-9]+
9705  *
9706  * In practice allow [0-9].[0-9]+ at that level
9707  *
9708  * Returns the string giving the XML version number, or NULL
9709  */
9710 xmlChar *
9711 xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
9712     xmlChar *buf = NULL;
9713     int len = 0;
9714     int size = 10;
9715     xmlChar cur;
9716
9717     buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
9718     if (buf == NULL) {
9719         xmlErrMemory(ctxt, NULL);
9720         return(NULL);
9721     }
9722     cur = CUR;
9723     if (!((cur >= '0') && (cur <= '9'))) {
9724         xmlFree(buf);
9725         return(NULL);
9726     }
9727     buf[len++] = cur;
9728     NEXT;
9729     cur=CUR;
9730     if (cur != '.') {
9731         xmlFree(buf);
9732         return(NULL);
9733     }
9734     buf[len++] = cur;
9735     NEXT;
9736     cur=CUR;
9737     while ((cur >= '0') && (cur <= '9')) {
9738         if (len + 1 >= size) {
9739             xmlChar *tmp;
9740
9741             size *= 2;
9742             tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
9743             if (tmp == NULL) {
9744                 xmlFree(buf);
9745                 xmlErrMemory(ctxt, NULL);
9746                 return(NULL);
9747             }
9748             buf = tmp;
9749         }
9750         buf[len++] = cur;
9751         NEXT;
9752         cur=CUR;
9753     }
9754     buf[len] = 0;
9755     return(buf);
9756 }
9757
9758 /**
9759  * xmlParseVersionInfo:
9760  * @ctxt:  an XML parser context
9761  *
9762  * parse the XML version.
9763  *
9764  * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
9765  *
9766  * [25] Eq ::= S? '=' S?
9767  *
9768  * Returns the version string, e.g. "1.0"
9769  */
9770
9771 xmlChar *
9772 xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
9773     xmlChar *version = NULL;
9774
9775     if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
9776         SKIP(7);
9777         SKIP_BLANKS;
9778         if (RAW != '=') {
9779             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
9780             return(NULL);
9781         }
9782         NEXT;
9783         SKIP_BLANKS;
9784         if (RAW == '"') {
9785             NEXT;
9786             version = xmlParseVersionNum(ctxt);
9787             if (RAW != '"') {
9788                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
9789             } else
9790                 NEXT;
9791         } else if (RAW == '\''){
9792             NEXT;
9793             version = xmlParseVersionNum(ctxt);
9794             if (RAW != '\'') {
9795                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
9796             } else
9797                 NEXT;
9798         } else {
9799             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
9800         }
9801     }
9802     return(version);
9803 }
9804
9805 /**
9806  * xmlParseEncName:
9807  * @ctxt:  an XML parser context
9808  *
9809  * parse the XML encoding name
9810  *
9811  * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
9812  *
9813  * Returns the encoding name value or NULL
9814  */
9815 xmlChar *
9816 xmlParseEncName(xmlParserCtxtPtr ctxt) {
9817     xmlChar *buf = NULL;
9818     int len = 0;
9819     int size = 10;
9820     xmlChar cur;
9821
9822     cur = CUR;
9823     if (((cur >= 'a') && (cur <= 'z')) ||
9824         ((cur >= 'A') && (cur <= 'Z'))) {
9825         buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
9826         if (buf == NULL) {
9827             xmlErrMemory(ctxt, NULL);
9828             return(NULL);
9829         }
9830
9831         buf[len++] = cur;
9832         NEXT;
9833         cur = CUR;
9834         while (((cur >= 'a') && (cur <= 'z')) ||
9835                ((cur >= 'A') && (cur <= 'Z')) ||
9836                ((cur >= '0') && (cur <= '9')) ||
9837                (cur == '.') || (cur == '_') ||
9838                (cur == '-')) {
9839             if (len + 1 >= size) {
9840                 xmlChar *tmp;
9841
9842                 size *= 2;
9843                 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
9844                 if (tmp == NULL) {
9845                     xmlErrMemory(ctxt, NULL);
9846                     xmlFree(buf);
9847                     return(NULL);
9848                 }
9849                 buf = tmp;
9850             }
9851             buf[len++] = cur;
9852             NEXT;
9853             cur = CUR;
9854             if (cur == 0) {
9855                 SHRINK;
9856                 GROW;
9857                 cur = CUR;
9858             }
9859         }
9860         buf[len] = 0;
9861     } else {
9862         xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
9863     }
9864     return(buf);
9865 }
9866
9867 /**
9868  * xmlParseEncodingDecl:
9869  * @ctxt:  an XML parser context
9870  * 
9871  * parse the XML encoding declaration
9872  *
9873  * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
9874  *
9875  * this setups the conversion filters.
9876  *
9877  * Returns the encoding value or NULL
9878  */
9879
9880 const xmlChar *
9881 xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
9882     xmlChar *encoding = NULL;
9883
9884     SKIP_BLANKS;
9885     if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
9886         SKIP(8);
9887         SKIP_BLANKS;
9888         if (RAW != '=') {
9889             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
9890             return(NULL);
9891         }
9892         NEXT;
9893         SKIP_BLANKS;
9894         if (RAW == '"') {
9895             NEXT;
9896             encoding = xmlParseEncName(ctxt);
9897             if (RAW != '"') {
9898                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
9899             } else
9900                 NEXT;
9901         } else if (RAW == '\''){
9902             NEXT;
9903             encoding = xmlParseEncName(ctxt);
9904             if (RAW != '\'') {
9905                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
9906             } else
9907                 NEXT;
9908         } else {
9909             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
9910         }
9911         /*
9912          * UTF-16 encoding stwich has already taken place at this stage,
9913          * more over the little-endian/big-endian selection is already done
9914          */
9915         if ((encoding != NULL) &&
9916             ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
9917              (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
9918             /*
9919              * If no encoding was passed to the parser, that we are
9920              * using UTF-16 and no decoder is present i.e. the 
9921              * document is apparently UTF-8 compatible, then raise an
9922              * encoding mismatch fatal error
9923              */
9924             if ((ctxt->encoding == NULL) &&
9925                 (ctxt->input->buf != NULL) &&
9926                 (ctxt->input->buf->encoder == NULL)) {
9927                 xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
9928                   "Document labelled UTF-16 but has UTF-8 content\n");
9929             }
9930             if (ctxt->encoding != NULL)
9931                 xmlFree((xmlChar *) ctxt->encoding);
9932             ctxt->encoding = encoding;
9933         }
9934         /*
9935          * UTF-8 encoding is handled natively
9936          */
9937         else if ((encoding != NULL) &&
9938             ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
9939              (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
9940             if (ctxt->encoding != NULL)
9941                 xmlFree((xmlChar *) ctxt->encoding);
9942             ctxt->encoding = encoding;
9943         }
9944         else if (encoding != NULL) {
9945             xmlCharEncodingHandlerPtr handler;
9946
9947             if (ctxt->input->encoding != NULL)
9948                 xmlFree((xmlChar *) ctxt->input->encoding);
9949             ctxt->input->encoding = encoding;
9950
9951             handler = xmlFindCharEncodingHandler((const char *) encoding);
9952             if (handler != NULL) {
9953                 xmlSwitchToEncoding(ctxt, handler);
9954             } else {
9955                 xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
9956                         "Unsupported encoding %s\n", encoding);
9957                 return(NULL);
9958             }
9959         }
9960     }
9961     return(encoding);
9962 }
9963
9964 /**
9965  * xmlParseSDDecl:
9966  * @ctxt:  an XML parser context
9967  *
9968  * parse the XML standalone declaration
9969  *
9970  * [32] SDDecl ::= S 'standalone' Eq
9971  *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"')) 
9972  *
9973  * [ VC: Standalone Document Declaration ]
9974  * TODO The standalone document declaration must have the value "no"
9975  * if any external markup declarations contain declarations of:
9976  *  - attributes with default values, if elements to which these
9977  *    attributes apply appear in the document without specifications
9978  *    of values for these attributes, or
9979  *  - entities (other than amp, lt, gt, apos, quot), if references
9980  *    to those entities appear in the document, or
9981  *  - attributes with values subject to normalization, where the
9982  *    attribute appears in the document with a value which will change
9983  *    as a result of normalization, or
9984  *  - element types with element content, if white space occurs directly
9985  *    within any instance of those types.
9986  *
9987  * Returns:
9988  *   1 if standalone="yes"
9989  *   0 if standalone="no"
9990  *  -2 if standalone attribute is missing or invalid
9991  *        (A standalone value of -2 means that the XML declaration was found,
9992  *         but no value was specified for the standalone attribute).
9993  */
9994
9995 int
9996 xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
9997     int standalone = -2;
9998
9999     SKIP_BLANKS;
10000     if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
10001         SKIP(10);
10002         SKIP_BLANKS;
10003         if (RAW != '=') {
10004             xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10005             return(standalone);
10006         }
10007         NEXT;
10008         SKIP_BLANKS;
10009         if (RAW == '\''){
10010             NEXT;
10011             if ((RAW == 'n') && (NXT(1) == 'o')) {
10012                 standalone = 0;
10013                 SKIP(2);
10014             } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10015                        (NXT(2) == 's')) {
10016                 standalone = 1;
10017                 SKIP(3);
10018             } else {
10019                 xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10020             }
10021             if (RAW != '\'') {
10022                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10023             } else
10024                 NEXT;
10025         } else if (RAW == '"'){
10026             NEXT;
10027             if ((RAW == 'n') && (NXT(1) == 'o')) {
10028                 standalone = 0;
10029                 SKIP(2);
10030             } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10031                        (NXT(2) == 's')) {
10032                 standalone = 1;
10033                 SKIP(3);
10034             } else {
10035                 xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10036             }
10037             if (RAW != '"') {
10038                 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10039             } else
10040                 NEXT;
10041         } else {
10042             xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10043         }
10044     }
10045     return(standalone);
10046 }
10047
10048 /**
10049  * xmlParseXMLDecl:
10050  * @ctxt:  an XML parser context
10051  * 
10052  * parse an XML declaration header
10053  *
10054  * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
10055  */
10056
10057 void
10058 xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
10059     xmlChar *version;
10060
10061     /*
10062      * This value for standalone indicates that the document has an
10063      * XML declaration but it does not have a standalone attribute.
10064      * It will be overwritten later if a standalone attribute is found.
10065      */
10066     ctxt->input->standalone = -2;
10067
10068     /*
10069      * We know that '<?xml' is here.
10070      */
10071     SKIP(5);
10072
10073     if (!IS_BLANK_CH(RAW)) {
10074         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
10075                        "Blank needed after '<?xml'\n");
10076     }
10077     SKIP_BLANKS;
10078
10079     /*
10080      * We must have the VersionInfo here.
10081      */
10082     version = xmlParseVersionInfo(ctxt);
10083     if (version == NULL) {
10084         xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
10085     } else {
10086         if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
10087             /*
10088              * Changed here for XML-1.0 5th edition
10089              */
10090             if (ctxt->options & XML_PARSE_OLD10) {
10091                 xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10092                                   "Unsupported version '%s'\n",
10093                                   version);
10094             } else {
10095                 if ((version[0] == '1') && ((version[1] == '.'))) {
10096                     xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
10097                                   "Unsupported version '%s'\n",
10098                                   version, NULL);
10099                 } else {
10100                     xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10101                                       "Unsupported version '%s'\n",
10102                                       version);
10103                 }
10104             }
10105         }
10106         if (ctxt->version != NULL)
10107             xmlFree((void *) ctxt->version);
10108         ctxt->version = version;
10109     }
10110
10111     /*
10112      * We may have the encoding declaration
10113      */
10114     if (!IS_BLANK_CH(RAW)) {
10115         if ((RAW == '?') && (NXT(1) == '>')) {
10116             SKIP(2);
10117             return;
10118         }
10119         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10120     }
10121     xmlParseEncodingDecl(ctxt);
10122     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10123         /*
10124          * The XML REC instructs us to stop parsing right here
10125          */
10126         return;
10127     }
10128
10129     /*
10130      * We may have the standalone status.
10131      */
10132     if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
10133         if ((RAW == '?') && (NXT(1) == '>')) {
10134             SKIP(2);
10135             return;
10136         }
10137         xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10138     }
10139
10140     /*
10141      * We can grow the input buffer freely at that point
10142      */
10143     GROW;
10144
10145     SKIP_BLANKS;
10146     ctxt->input->standalone = xmlParseSDDecl(ctxt);
10147
10148     SKIP_BLANKS;
10149     if ((RAW == '?') && (NXT(1) == '>')) {
10150         SKIP(2);
10151     } else if (RAW == '>') {
10152         /* Deprecated old WD ... */
10153         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10154         NEXT;
10155     } else {
10156         xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10157         MOVETO_ENDTAG(CUR_PTR);
10158         NEXT;
10159     }
10160 }
10161
10162 /**
10163  * xmlParseMisc:
10164  * @ctxt:  an XML parser context
10165  * 
10166  * parse an XML Misc* optional field.
10167  *
10168  * [27] Misc ::= Comment | PI |  S
10169  */
10170
10171 void
10172 xmlParseMisc(xmlParserCtxtPtr ctxt) {
10173     while ((ctxt->instate != XML_PARSER_EOF) &&
10174            (((RAW == '<') && (NXT(1) == '?')) ||
10175             (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
10176             IS_BLANK_CH(CUR))) {
10177         if ((RAW == '<') && (NXT(1) == '?')) {
10178             xmlParsePI(ctxt);
10179         } else if (IS_BLANK_CH(CUR)) {
10180             NEXT;
10181         } else
10182             xmlParseComment(ctxt);
10183     }
10184 }
10185
10186 /**
10187  * xmlParseDocument:
10188  * @ctxt:  an XML parser context
10189  * 
10190  * parse an XML document (and build a tree if using the standard SAX
10191  * interface).
10192  *
10193  * [1] document ::= prolog element Misc*
10194  *
10195  * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
10196  *
10197  * Returns 0, -1 in case of error. the parser context is augmented
10198  *                as a result of the parsing.
10199  */
10200
10201 int
10202 xmlParseDocument(xmlParserCtxtPtr ctxt) {
10203     xmlChar start[4];
10204     xmlCharEncoding enc;
10205
10206     xmlInitParser();
10207
10208     if ((ctxt == NULL) || (ctxt->input == NULL))
10209         return(-1);
10210
10211     GROW;
10212
10213     /*
10214      * SAX: detecting the level.
10215      */
10216     xmlDetectSAX2(ctxt);
10217
10218     /*
10219      * SAX: beginning of the document processing.
10220      */
10221     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10222         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10223     if (ctxt->instate == XML_PARSER_EOF)
10224         return(-1);
10225
10226     if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
10227         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
10228         /* 
10229          * Get the 4 first bytes and decode the charset
10230          * if enc != XML_CHAR_ENCODING_NONE
10231          * plug some encoding conversion routines.
10232          */
10233         start[0] = RAW;
10234         start[1] = NXT(1);
10235         start[2] = NXT(2);
10236         start[3] = NXT(3);
10237         enc = xmlDetectCharEncoding(&start[0], 4);
10238         if (enc != XML_CHAR_ENCODING_NONE) {
10239             xmlSwitchEncoding(ctxt, enc);
10240         }
10241     }
10242
10243
10244     if (CUR == 0) {
10245         xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10246     }
10247
10248     /*
10249      * Check for the XMLDecl in the Prolog.
10250      * do not GROW here to avoid the detected encoder to decode more
10251      * than just the first line, unless the amount of data is really
10252      * too small to hold "<?xml version="1.0" encoding="foo"
10253      */
10254     if ((ctxt->input->end - ctxt->input->cur) < 35) {
10255        GROW;
10256     }
10257     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10258
10259         /*
10260          * Note that we will switch encoding on the fly.
10261          */
10262         xmlParseXMLDecl(ctxt);
10263         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10264             /*
10265              * The XML REC instructs us to stop parsing right here
10266              */
10267             return(-1);
10268         }
10269         ctxt->standalone = ctxt->input->standalone;
10270         SKIP_BLANKS;
10271     } else {
10272         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10273     }
10274     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10275         ctxt->sax->startDocument(ctxt->userData);
10276     if (ctxt->instate == XML_PARSER_EOF)
10277         return(-1);
10278
10279     /*
10280      * The Misc part of the Prolog
10281      */
10282     GROW;
10283     xmlParseMisc(ctxt);
10284
10285     /*
10286      * Then possibly doc type declaration(s) and more Misc
10287      * (doctypedecl Misc*)?
10288      */
10289     GROW;
10290     if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
10291
10292         ctxt->inSubset = 1;
10293         xmlParseDocTypeDecl(ctxt);
10294         if (RAW == '[') {
10295             ctxt->instate = XML_PARSER_DTD;
10296             xmlParseInternalSubset(ctxt);
10297             if (ctxt->instate == XML_PARSER_EOF)
10298                 return(-1);
10299         }
10300
10301         /*
10302          * Create and update the external subset.
10303          */
10304         ctxt->inSubset = 2;
10305         if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
10306             (!ctxt->disableSAX))
10307             ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
10308                                       ctxt->extSubSystem, ctxt->extSubURI);
10309         if (ctxt->instate == XML_PARSER_EOF)
10310             return(-1);
10311         ctxt->inSubset = 0;
10312
10313         xmlCleanSpecialAttr(ctxt);
10314
10315         ctxt->instate = XML_PARSER_PROLOG;
10316         xmlParseMisc(ctxt);
10317     }
10318
10319     /*
10320      * Time to start parsing the tree itself
10321      */
10322     GROW;
10323     if (RAW != '<') {
10324         xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
10325                        "Start tag expected, '<' not found\n");
10326     } else {
10327         ctxt->instate = XML_PARSER_CONTENT;
10328         xmlParseElement(ctxt);
10329         ctxt->instate = XML_PARSER_EPILOG;
10330
10331
10332         /*
10333          * The Misc part at the end
10334          */
10335         xmlParseMisc(ctxt);
10336
10337         if (RAW != 0) {
10338             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10339         }
10340         ctxt->instate = XML_PARSER_EOF;
10341     }
10342
10343     /*
10344      * SAX: end of the document processing.
10345      */
10346     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10347         ctxt->sax->endDocument(ctxt->userData);
10348
10349     /*
10350      * Remove locally kept entity definitions if the tree was not built
10351      */
10352     if ((ctxt->myDoc != NULL) &&
10353         (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
10354         xmlFreeDoc(ctxt->myDoc);
10355         ctxt->myDoc = NULL;
10356     }
10357
10358     if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
10359         ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
10360         if (ctxt->valid)
10361             ctxt->myDoc->properties |= XML_DOC_DTDVALID;
10362         if (ctxt->nsWellFormed)
10363             ctxt->myDoc->properties |= XML_DOC_NSVALID;
10364         if (ctxt->options & XML_PARSE_OLD10)
10365             ctxt->myDoc->properties |= XML_DOC_OLD10;
10366     }
10367     if (! ctxt->wellFormed) {
10368         ctxt->valid = 0;
10369         return(-1);
10370     }
10371     return(0);
10372 }
10373
10374 /**
10375  * xmlParseExtParsedEnt:
10376  * @ctxt:  an XML parser context
10377  * 
10378  * parse a general parsed entity
10379  * An external general parsed entity is well-formed if it matches the
10380  * production labeled extParsedEnt.
10381  *
10382  * [78] extParsedEnt ::= TextDecl? content
10383  *
10384  * Returns 0, -1 in case of error. the parser context is augmented
10385  *                as a result of the parsing.
10386  */
10387
10388 int
10389 xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
10390     xmlChar start[4];
10391     xmlCharEncoding enc;
10392
10393     if ((ctxt == NULL) || (ctxt->input == NULL))
10394         return(-1);
10395
10396     xmlDefaultSAXHandlerInit();
10397
10398     xmlDetectSAX2(ctxt);
10399
10400     GROW;
10401
10402     /*
10403      * SAX: beginning of the document processing.
10404      */
10405     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10406         ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10407
10408     /* 
10409      * Get the 4 first bytes and decode the charset
10410      * if enc != XML_CHAR_ENCODING_NONE
10411      * plug some encoding conversion routines.
10412      */
10413     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
10414         start[0] = RAW;
10415         start[1] = NXT(1);
10416         start[2] = NXT(2);
10417         start[3] = NXT(3);
10418         enc = xmlDetectCharEncoding(start, 4);
10419         if (enc != XML_CHAR_ENCODING_NONE) {
10420             xmlSwitchEncoding(ctxt, enc);
10421         }
10422     }
10423
10424
10425     if (CUR == 0) {
10426         xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10427     }
10428
10429     /*
10430      * Check for the XMLDecl in the Prolog.
10431      */
10432     GROW;
10433     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10434
10435         /*
10436          * Note that we will switch encoding on the fly.
10437          */
10438         xmlParseXMLDecl(ctxt);
10439         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10440             /*
10441              * The XML REC instructs us to stop parsing right here
10442              */
10443             return(-1);
10444         }
10445         SKIP_BLANKS;
10446     } else {
10447         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10448     }
10449     if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10450         ctxt->sax->startDocument(ctxt->userData);
10451     if (ctxt->instate == XML_PARSER_EOF)
10452         return(-1);
10453
10454     /*
10455      * Doing validity checking on chunk doesn't make sense
10456      */
10457     ctxt->instate = XML_PARSER_CONTENT;
10458     ctxt->validate = 0;
10459     ctxt->loadsubset = 0;
10460     ctxt->depth = 0;
10461
10462     xmlParseContent(ctxt);
10463     if (ctxt->instate == XML_PARSER_EOF)
10464         return(-1);
10465    
10466     if ((RAW == '<') && (NXT(1) == '/')) {
10467         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
10468     } else if (RAW != 0) {
10469         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
10470     }
10471
10472     /*
10473      * SAX: end of the document processing.
10474      */
10475     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10476         ctxt->sax->endDocument(ctxt->userData);
10477
10478     if (! ctxt->wellFormed) return(-1);
10479     return(0);
10480 }
10481
10482 #ifdef LIBXML_PUSH_ENABLED
10483 /************************************************************************
10484  *                                                                      *
10485  *              Progressive parsing interfaces                          *
10486  *                                                                      *
10487  ************************************************************************/
10488
10489 /**
10490  * xmlParseLookupSequence:
10491  * @ctxt:  an XML parser context
10492  * @first:  the first char to lookup
10493  * @next:  the next char to lookup or zero
10494  * @third:  the next char to lookup or zero
10495  *
10496  * Try to find if a sequence (first, next, third) or  just (first next) or
10497  * (first) is available in the input stream.
10498  * This function has a side effect of (possibly) incrementing ctxt->checkIndex
10499  * to avoid rescanning sequences of bytes, it DOES change the state of the
10500  * parser, do not use liberally.
10501  *
10502  * Returns the index to the current parsing point if the full sequence
10503  *      is available, -1 otherwise.
10504  */
10505 static int
10506 xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
10507                        xmlChar next, xmlChar third) {
10508     int base, len;
10509     xmlParserInputPtr in;
10510     const xmlChar *buf;
10511
10512     in = ctxt->input;
10513     if (in == NULL) return(-1);
10514     base = in->cur - in->base;
10515     if (base < 0) return(-1);
10516     if (ctxt->checkIndex > base)
10517         base = ctxt->checkIndex;
10518     if (in->buf == NULL) {
10519         buf = in->base;
10520         len = in->length;
10521     } else {
10522         buf = in->buf->buffer->content;
10523         len = in->buf->buffer->use;
10524     }
10525     /* take into account the sequence length */
10526     if (third) len -= 2;
10527     else if (next) len --;
10528     for (;base < len;base++) {
10529         if (buf[base] == first) {
10530             if (third != 0) {
10531                 if ((buf[base + 1] != next) ||
10532                     (buf[base + 2] != third)) continue;
10533             } else if (next != 0) {
10534                 if (buf[base + 1] != next) continue;
10535             }
10536             ctxt->checkIndex = 0;
10537 #ifdef DEBUG_PUSH
10538             if (next == 0)
10539                 xmlGenericError(xmlGenericErrorContext,
10540                         "PP: lookup '%c' found at %d\n",
10541                         first, base);
10542             else if (third == 0)
10543                 xmlGenericError(xmlGenericErrorContext,
10544                         "PP: lookup '%c%c' found at %d\n",
10545                         first, next, base);
10546             else 
10547                 xmlGenericError(xmlGenericErrorContext,
10548                         "PP: lookup '%c%c%c' found at %d\n",
10549                         first, next, third, base);
10550 #endif
10551             return(base - (in->cur - in->base));
10552         }
10553     }
10554     ctxt->checkIndex = base;
10555 #ifdef DEBUG_PUSH
10556     if (next == 0)
10557         xmlGenericError(xmlGenericErrorContext,
10558                 "PP: lookup '%c' failed\n", first);
10559     else if (third == 0)
10560         xmlGenericError(xmlGenericErrorContext,
10561                 "PP: lookup '%c%c' failed\n", first, next);
10562     else        
10563         xmlGenericError(xmlGenericErrorContext,
10564                 "PP: lookup '%c%c%c' failed\n", first, next, third);
10565 #endif
10566     return(-1);
10567 }
10568
10569 /**
10570  * xmlParseGetLasts:
10571  * @ctxt:  an XML parser context
10572  * @lastlt:  pointer to store the last '<' from the input
10573  * @lastgt:  pointer to store the last '>' from the input
10574  *
10575  * Lookup the last < and > in the current chunk
10576  */
10577 static void
10578 xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
10579                  const xmlChar **lastgt) {
10580     const xmlChar *tmp;
10581
10582     if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
10583         xmlGenericError(xmlGenericErrorContext,
10584                     "Internal error: xmlParseGetLasts\n");
10585         return;
10586     }
10587     if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
10588         tmp = ctxt->input->end;
10589         tmp--;
10590         while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
10591         if (tmp < ctxt->input->base) {
10592             *lastlt = NULL;
10593             *lastgt = NULL;
10594         } else {
10595             *lastlt = tmp;
10596             tmp++;
10597             while ((tmp < ctxt->input->end) && (*tmp != '>')) {
10598                 if (*tmp == '\'') {
10599                     tmp++;
10600                     while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
10601                     if (tmp < ctxt->input->end) tmp++;
10602                 } else if (*tmp == '"') {
10603                     tmp++;
10604                     while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
10605                     if (tmp < ctxt->input->end) tmp++;
10606                 } else
10607                     tmp++;
10608             }
10609             if (tmp < ctxt->input->end)
10610                 *lastgt = tmp;
10611             else {
10612                 tmp = *lastlt;
10613                 tmp--;
10614                 while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
10615                 if (tmp >= ctxt->input->base)
10616                     *lastgt = tmp;
10617                 else
10618                     *lastgt = NULL;
10619             }
10620         }
10621     } else {
10622         *lastlt = NULL;
10623         *lastgt = NULL;
10624     }
10625 }
10626 /**
10627  * xmlCheckCdataPush:
10628  * @cur: pointer to the bock of characters
10629  * @len: length of the block in bytes
10630  *
10631  * Check that the block of characters is okay as SCdata content [20]
10632  *
10633  * Returns the number of bytes to pass if okay, a negative index where an
10634  *         UTF-8 error occured otherwise
10635  */
10636 static int
10637 xmlCheckCdataPush(const xmlChar *utf, int len) {
10638     int ix;
10639     unsigned char c;
10640     int codepoint;
10641
10642     if ((utf == NULL) || (len <= 0))
10643         return(0);
10644     
10645     for (ix = 0; ix < len;) {      /* string is 0-terminated */
10646         c = utf[ix];
10647         if ((c & 0x80) == 0x00) {       /* 1-byte code, starts with 10 */
10648             if (c >= 0x20)
10649                 ix++;
10650             else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
10651                 ix++;
10652             else
10653                 return(-ix);
10654         } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
10655             if (ix + 2 > len) return(ix);
10656             if ((utf[ix+1] & 0xc0 ) != 0x80)
10657                 return(-ix);
10658             codepoint = (utf[ix] & 0x1f) << 6;
10659             codepoint |= utf[ix+1] & 0x3f;
10660             if (!xmlIsCharQ(codepoint))
10661                 return(-ix);
10662             ix += 2;
10663         } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
10664             if (ix + 3 > len) return(ix);
10665             if (((utf[ix+1] & 0xc0) != 0x80) ||
10666                 ((utf[ix+2] & 0xc0) != 0x80))
10667                     return(-ix);
10668             codepoint = (utf[ix] & 0xf) << 12;
10669             codepoint |= (utf[ix+1] & 0x3f) << 6;
10670             codepoint |= utf[ix+2] & 0x3f;
10671             if (!xmlIsCharQ(codepoint))
10672                 return(-ix);
10673             ix += 3;
10674         } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
10675             if (ix + 4 > len) return(ix);
10676             if (((utf[ix+1] & 0xc0) != 0x80) ||
10677                 ((utf[ix+2] & 0xc0) != 0x80) ||
10678                 ((utf[ix+3] & 0xc0) != 0x80))
10679                     return(-ix);
10680             codepoint = (utf[ix] & 0x7) << 18;
10681             codepoint |= (utf[ix+1] & 0x3f) << 12;
10682             codepoint |= (utf[ix+2] & 0x3f) << 6;
10683             codepoint |= utf[ix+3] & 0x3f;
10684             if (!xmlIsCharQ(codepoint))
10685                 return(-ix);
10686             ix += 4;
10687         } else                          /* unknown encoding */
10688             return(-ix);
10689       }
10690       return(ix);
10691 }
10692
10693 /**
10694  * xmlParseTryOrFinish:
10695  * @ctxt:  an XML parser context
10696  * @terminate:  last chunk indicator
10697  *
10698  * Try to progress on parsing
10699  *
10700  * Returns zero if no parsing was possible
10701  */
10702 static int
10703 xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
10704     int ret = 0;
10705     int avail, tlen;
10706     xmlChar cur, next;
10707     const xmlChar *lastlt, *lastgt;
10708
10709     if (ctxt->input == NULL)
10710         return(0);
10711
10712 #ifdef DEBUG_PUSH
10713     switch (ctxt->instate) {
10714         case XML_PARSER_EOF:
10715             xmlGenericError(xmlGenericErrorContext,
10716                     "PP: try EOF\n"); break;
10717         case XML_PARSER_START:
10718             xmlGenericError(xmlGenericErrorContext,
10719                     "PP: try START\n"); break;
10720         case XML_PARSER_MISC:
10721             xmlGenericError(xmlGenericErrorContext,
10722                     "PP: try MISC\n");break;
10723         case XML_PARSER_COMMENT:
10724             xmlGenericError(xmlGenericErrorContext,
10725                     "PP: try COMMENT\n");break;
10726         case XML_PARSER_PROLOG:
10727             xmlGenericError(xmlGenericErrorContext,
10728                     "PP: try PROLOG\n");break;
10729         case XML_PARSER_START_TAG:
10730             xmlGenericError(xmlGenericErrorContext,
10731                     "PP: try START_TAG\n");break;
10732         case XML_PARSER_CONTENT:
10733             xmlGenericError(xmlGenericErrorContext,
10734                     "PP: try CONTENT\n");break;
10735         case XML_PARSER_CDATA_SECTION:
10736             xmlGenericError(xmlGenericErrorContext,
10737                     "PP: try CDATA_SECTION\n");break;
10738         case XML_PARSER_END_TAG:
10739             xmlGenericError(xmlGenericErrorContext,
10740                     "PP: try END_TAG\n");break;
10741         case XML_PARSER_ENTITY_DECL:
10742             xmlGenericError(xmlGenericErrorContext,
10743                     "PP: try ENTITY_DECL\n");break;
10744         case XML_PARSER_ENTITY_VALUE:
10745             xmlGenericError(xmlGenericErrorContext,
10746                     "PP: try ENTITY_VALUE\n");break;
10747         case XML_PARSER_ATTRIBUTE_VALUE:
10748             xmlGenericError(xmlGenericErrorContext,
10749                     "PP: try ATTRIBUTE_VALUE\n");break;
10750         case XML_PARSER_DTD:
10751             xmlGenericError(xmlGenericErrorContext,
10752                     "PP: try DTD\n");break;
10753         case XML_PARSER_EPILOG:
10754             xmlGenericError(xmlGenericErrorContext,
10755                     "PP: try EPILOG\n");break;
10756         case XML_PARSER_PI:
10757             xmlGenericError(xmlGenericErrorContext,
10758                     "PP: try PI\n");break;
10759         case XML_PARSER_IGNORE:
10760             xmlGenericError(xmlGenericErrorContext,
10761                     "PP: try IGNORE\n");break;
10762     }
10763 #endif
10764
10765     if ((ctxt->input != NULL) &&
10766         (ctxt->input->cur - ctxt->input->base > 4096)) {
10767         xmlSHRINK(ctxt);
10768         ctxt->checkIndex = 0;
10769     }
10770     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
10771
10772     while (ctxt->instate != XML_PARSER_EOF) {
10773         if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
10774             return(0);
10775
10776         
10777         /*
10778          * Pop-up of finished entities.
10779          */
10780         while ((RAW == 0) && (ctxt->inputNr > 1))
10781             xmlPopInput(ctxt);
10782
10783         if (ctxt->input == NULL) break;
10784         if (ctxt->input->buf == NULL)
10785             avail = ctxt->input->length -
10786                     (ctxt->input->cur - ctxt->input->base);
10787         else {
10788             /*
10789              * If we are operating on converted input, try to flush
10790              * remainng chars to avoid them stalling in the non-converted
10791              * buffer.
10792              */
10793             if ((ctxt->input->buf->raw != NULL) &&
10794                 (ctxt->input->buf->raw->use > 0)) {
10795                 int base = ctxt->input->base -
10796                            ctxt->input->buf->buffer->content;
10797                 int current = ctxt->input->cur - ctxt->input->base;
10798
10799                 xmlParserInputBufferPush(ctxt->input->buf, 0, "");
10800                 ctxt->input->base = ctxt->input->buf->buffer->content + base;
10801                 ctxt->input->cur = ctxt->input->base + current;
10802                 ctxt->input->end =
10803                     &ctxt->input->buf->buffer->content[
10804                                        ctxt->input->buf->buffer->use];
10805             }
10806             avail = ctxt->input->buf->buffer->use -
10807                     (ctxt->input->cur - ctxt->input->base);
10808         }
10809         if (avail < 1)
10810             goto done;
10811         switch (ctxt->instate) {
10812             case XML_PARSER_EOF:
10813                 /*
10814                  * Document parsing is done !
10815                  */
10816                 goto done;
10817             case XML_PARSER_START:
10818                 if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
10819                     xmlChar start[4];
10820                     xmlCharEncoding enc;
10821
10822                     /*
10823                      * Very first chars read from the document flow.
10824                      */
10825                     if (avail < 4)
10826                         goto done;
10827
10828                     /* 
10829                      * Get the 4 first bytes and decode the charset
10830                      * if enc != XML_CHAR_ENCODING_NONE
10831                      * plug some encoding conversion routines,
10832                      * else xmlSwitchEncoding will set to (default)
10833                      * UTF8.
10834                      */
10835                     start[0] = RAW;
10836                     start[1] = NXT(1);
10837                     start[2] = NXT(2);
10838                     start[3] = NXT(3);
10839                     enc = xmlDetectCharEncoding(start, 4);
10840                     xmlSwitchEncoding(ctxt, enc);
10841                     break;
10842                 }
10843
10844                 if (avail < 2)
10845                     goto done;
10846                 cur = ctxt->input->cur[0];
10847                 next = ctxt->input->cur[1];
10848                 if (cur == 0) {
10849                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10850                         ctxt->sax->setDocumentLocator(ctxt->userData,
10851                                                       &xmlDefaultSAXLocator);
10852                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10853                     ctxt->instate = XML_PARSER_EOF;
10854 #ifdef DEBUG_PUSH
10855                     xmlGenericError(xmlGenericErrorContext,
10856                             "PP: entering EOF\n");
10857 #endif
10858                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10859                         ctxt->sax->endDocument(ctxt->userData);
10860                     goto done;
10861                 }
10862                 if ((cur == '<') && (next == '?')) {
10863                     /* PI or XML decl */
10864                     if (avail < 5) return(ret);
10865                     if ((!terminate) &&
10866                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
10867                         return(ret);
10868                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10869                         ctxt->sax->setDocumentLocator(ctxt->userData,
10870                                                       &xmlDefaultSAXLocator);
10871                     if ((ctxt->input->cur[2] == 'x') &&
10872                         (ctxt->input->cur[3] == 'm') &&
10873                         (ctxt->input->cur[4] == 'l') &&
10874                         (IS_BLANK_CH(ctxt->input->cur[5]))) {
10875                         ret += 5;
10876 #ifdef DEBUG_PUSH
10877                         xmlGenericError(xmlGenericErrorContext,
10878                                 "PP: Parsing XML Decl\n");
10879 #endif
10880                         xmlParseXMLDecl(ctxt);
10881                         if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10882                             /*
10883                              * The XML REC instructs us to stop parsing right
10884                              * here
10885                              */
10886                             ctxt->instate = XML_PARSER_EOF;
10887                             return(0);
10888                         }
10889                         ctxt->standalone = ctxt->input->standalone;
10890                         if ((ctxt->encoding == NULL) &&
10891                             (ctxt->input->encoding != NULL))
10892                             ctxt->encoding = xmlStrdup(ctxt->input->encoding);
10893                         if ((ctxt->sax) && (ctxt->sax->startDocument) &&
10894                             (!ctxt->disableSAX))
10895                             ctxt->sax->startDocument(ctxt->userData);
10896                         ctxt->instate = XML_PARSER_MISC;
10897 #ifdef DEBUG_PUSH
10898                         xmlGenericError(xmlGenericErrorContext,
10899                                 "PP: entering MISC\n");
10900 #endif
10901                     } else {
10902                         ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10903                         if ((ctxt->sax) && (ctxt->sax->startDocument) &&
10904                             (!ctxt->disableSAX))
10905                             ctxt->sax->startDocument(ctxt->userData);
10906                         ctxt->instate = XML_PARSER_MISC;
10907 #ifdef DEBUG_PUSH
10908                         xmlGenericError(xmlGenericErrorContext,
10909                                 "PP: entering MISC\n");
10910 #endif
10911                     }
10912                 } else {
10913                     if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10914                         ctxt->sax->setDocumentLocator(ctxt->userData,
10915                                                       &xmlDefaultSAXLocator);
10916                     ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10917                     if (ctxt->version == NULL) {
10918                         xmlErrMemory(ctxt, NULL);
10919                         break;
10920                     }
10921                     if ((ctxt->sax) && (ctxt->sax->startDocument) &&
10922                         (!ctxt->disableSAX))
10923                         ctxt->sax->startDocument(ctxt->userData);
10924                     ctxt->instate = XML_PARSER_MISC;
10925 #ifdef DEBUG_PUSH
10926                     xmlGenericError(xmlGenericErrorContext,
10927                             "PP: entering MISC\n");
10928 #endif
10929                 }
10930                 break;
10931             case XML_PARSER_START_TAG: {
10932                 const xmlChar *name;
10933                 const xmlChar *prefix = NULL;
10934                 const xmlChar *URI = NULL;
10935                 int nsNr = ctxt->nsNr;
10936
10937                 if ((avail < 2) && (ctxt->inputNr == 1))
10938                     goto done;
10939                 cur = ctxt->input->cur[0];
10940                 if (cur != '<') {
10941                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10942                     ctxt->instate = XML_PARSER_EOF;
10943                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10944                         ctxt->sax->endDocument(ctxt->userData);
10945                     goto done;
10946                 }
10947                 if (!terminate) {
10948                     if (ctxt->progressive) {
10949                         /* > can be found unescaped in attribute values */
10950                         if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
10951                             goto done;
10952                     } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
10953                         goto done;
10954                     }
10955                 }
10956                 if (ctxt->spaceNr == 0)
10957                     spacePush(ctxt, -1);
10958                 else if (*ctxt->space == -2)
10959                     spacePush(ctxt, -1);
10960                 else
10961                     spacePush(ctxt, *ctxt->space);
10962 #ifdef LIBXML_SAX1_ENABLED
10963                 if (ctxt->sax2)
10964 #endif /* LIBXML_SAX1_ENABLED */
10965                     name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
10966 #ifdef LIBXML_SAX1_ENABLED
10967                 else
10968                     name = xmlParseStartTag(ctxt);
10969 #endif /* LIBXML_SAX1_ENABLED */
10970                 if (ctxt->instate == XML_PARSER_EOF)
10971                     goto done;
10972                 if (name == NULL) {
10973                     spacePop(ctxt);
10974                     ctxt->instate = XML_PARSER_EOF;
10975                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10976                         ctxt->sax->endDocument(ctxt->userData);
10977                     goto done;
10978                 }
10979 #ifdef LIBXML_VALID_ENABLED
10980                 /*
10981                  * [ VC: Root Element Type ]
10982                  * The Name in the document type declaration must match
10983                  * the element type of the root element. 
10984                  */
10985                 if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
10986                     ctxt->node && (ctxt->node == ctxt->myDoc->children))
10987                     ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
10988 #endif /* LIBXML_VALID_ENABLED */
10989
10990                 /*
10991                  * Check for an Empty Element.
10992                  */
10993                 if ((RAW == '/') && (NXT(1) == '>')) {
10994                     SKIP(2);
10995
10996                     if (ctxt->sax2) {
10997                         if ((ctxt->sax != NULL) &&
10998                             (ctxt->sax->endElementNs != NULL) &&
10999                             (!ctxt->disableSAX))
11000                             ctxt->sax->endElementNs(ctxt->userData, name,
11001                                                     prefix, URI);
11002                         if (ctxt->nsNr - nsNr > 0)
11003                             nsPop(ctxt, ctxt->nsNr - nsNr);
11004 #ifdef LIBXML_SAX1_ENABLED
11005                     } else {
11006                         if ((ctxt->sax != NULL) &&
11007                             (ctxt->sax->endElement != NULL) &&
11008                             (!ctxt->disableSAX))
11009                             ctxt->sax->endElement(ctxt->userData, name);
11010 #endif /* LIBXML_SAX1_ENABLED */
11011                     }
11012                     if (ctxt->instate == XML_PARSER_EOF)
11013                         goto done;
11014                     spacePop(ctxt);
11015                     if (ctxt->nameNr == 0) {
11016                         ctxt->instate = XML_PARSER_EPILOG;
11017                     } else {
11018                         ctxt->instate = XML_PARSER_CONTENT;
11019                     }
11020                     break;
11021                 }
11022                 if (RAW == '>') {
11023                     NEXT;
11024                 } else {
11025                     xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
11026                                          "Couldn't find end of Start Tag %s\n",
11027                                          name);
11028                     nodePop(ctxt);
11029                     spacePop(ctxt);
11030                 }
11031                 if (ctxt->sax2)
11032                     nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
11033 #ifdef LIBXML_SAX1_ENABLED
11034                 else
11035                     namePush(ctxt, name);
11036 #endif /* LIBXML_SAX1_ENABLED */
11037
11038                 ctxt->instate = XML_PARSER_CONTENT;
11039                 break;
11040             }
11041             case XML_PARSER_CONTENT: {
11042                 const xmlChar *test;
11043                 unsigned int cons;
11044                 if ((avail < 2) && (ctxt->inputNr == 1))
11045                     goto done;
11046                 cur = ctxt->input->cur[0];
11047                 next = ctxt->input->cur[1];
11048
11049                 test = CUR_PTR;
11050                 cons = ctxt->input->consumed;
11051                 if ((cur == '<') && (next == '/')) {
11052                     ctxt->instate = XML_PARSER_END_TAG;
11053                     break;
11054                 } else if ((cur == '<') && (next == '?')) {
11055                     if ((!terminate) &&
11056                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11057                         goto done;
11058                     xmlParsePI(ctxt);
11059                 } else if ((cur == '<') && (next != '!')) {
11060                     ctxt->instate = XML_PARSER_START_TAG;
11061                     break;
11062                 } else if ((cur == '<') && (next == '!') &&
11063                            (ctxt->input->cur[2] == '-') &&
11064                            (ctxt->input->cur[3] == '-')) {
11065                     int term;
11066
11067                     if (avail < 4)
11068                         goto done;
11069                     ctxt->input->cur += 4;
11070                     term = xmlParseLookupSequence(ctxt, '-', '-', '>');
11071                     ctxt->input->cur -= 4;
11072                     if ((!terminate) && (term < 0))
11073                         goto done;
11074                     xmlParseComment(ctxt);
11075                     ctxt->instate = XML_PARSER_CONTENT;
11076                 } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
11077                     (ctxt->input->cur[2] == '[') &&
11078                     (ctxt->input->cur[3] == 'C') &&
11079                     (ctxt->input->cur[4] == 'D') &&
11080                     (ctxt->input->cur[5] == 'A') &&
11081                     (ctxt->input->cur[6] == 'T') &&
11082                     (ctxt->input->cur[7] == 'A') &&
11083                     (ctxt->input->cur[8] == '[')) {
11084                     SKIP(9);
11085                     ctxt->instate = XML_PARSER_CDATA_SECTION;
11086                     break;
11087                 } else if ((cur == '<') && (next == '!') &&
11088                            (avail < 9)) {
11089                     goto done;
11090                 } else if (cur == '&') {
11091                     if ((!terminate) &&
11092                         (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
11093                         goto done;
11094                     xmlParseReference(ctxt);
11095                 } else {
11096                     /* TODO Avoid the extra copy, handle directly !!! */
11097                     /*
11098                      * Goal of the following test is:
11099                      *  - minimize calls to the SAX 'character' callback
11100                      *    when they are mergeable
11101                      *  - handle an problem for isBlank when we only parse
11102                      *    a sequence of blank chars and the next one is
11103                      *    not available to check against '<' presence.
11104                      *  - tries to homogenize the differences in SAX
11105                      *    callbacks between the push and pull versions
11106                      *    of the parser.
11107                      */
11108                     if ((ctxt->inputNr == 1) &&
11109                         (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
11110                         if (!terminate) {
11111                             if (ctxt->progressive) {
11112                                 if ((lastlt == NULL) ||
11113                                     (ctxt->input->cur > lastlt))
11114                                     goto done;
11115                             } else if (xmlParseLookupSequence(ctxt,
11116                                                               '<', 0, 0) < 0) {
11117                                 goto done;
11118                             }
11119                         }
11120                     }
11121                     ctxt->checkIndex = 0;
11122                     xmlParseCharData(ctxt, 0);
11123                 }
11124                 /*
11125                  * Pop-up of finished entities.
11126                  */
11127                 while ((RAW == 0) && (ctxt->inputNr > 1))
11128                     xmlPopInput(ctxt);
11129                 if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
11130                     xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
11131                                 "detected an error in element content\n");
11132                     ctxt->instate = XML_PARSER_EOF;
11133                     break;
11134                 }
11135                 break;
11136             }
11137             case XML_PARSER_END_TAG:
11138                 if (avail < 2)
11139                     goto done;
11140                 if (!terminate) {
11141                     if (ctxt->progressive) {
11142                         /* > can be found unescaped in attribute values */
11143                         if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11144                             goto done;
11145                     } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11146                         goto done;
11147                     }
11148                 }
11149                 if (ctxt->sax2) {
11150                     xmlParseEndTag2(ctxt,
11151                            (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
11152                            (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
11153                        (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
11154                     nameNsPop(ctxt);
11155                 }
11156 #ifdef LIBXML_SAX1_ENABLED
11157                   else
11158                     xmlParseEndTag1(ctxt, 0);
11159 #endif /* LIBXML_SAX1_ENABLED */
11160                 if (ctxt->instate == XML_PARSER_EOF) {
11161                     /* Nothing */
11162                 } else if (ctxt->nameNr == 0) {
11163                     ctxt->instate = XML_PARSER_EPILOG;
11164                 } else {
11165                     ctxt->instate = XML_PARSER_CONTENT;
11166                 }
11167                 break;
11168             case XML_PARSER_CDATA_SECTION: {
11169                 /*
11170                  * The Push mode need to have the SAX callback for 
11171                  * cdataBlock merge back contiguous callbacks.
11172                  */
11173                 int base;
11174
11175                 base = xmlParseLookupSequence(ctxt, ']', ']', '>');
11176                 if (base < 0) {
11177                     if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
11178                         int tmp;
11179
11180                         tmp = xmlCheckCdataPush(ctxt->input->cur, 
11181                                                 XML_PARSER_BIG_BUFFER_SIZE);
11182                         if (tmp < 0) {
11183                             tmp = -tmp;
11184                             ctxt->input->cur += tmp;
11185                             goto encoding_error;
11186                         }
11187                         if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
11188                             if (ctxt->sax->cdataBlock != NULL)
11189                                 ctxt->sax->cdataBlock(ctxt->userData,
11190                                                       ctxt->input->cur, tmp);
11191                             else if (ctxt->sax->characters != NULL)
11192                                 ctxt->sax->characters(ctxt->userData,
11193                                                       ctxt->input->cur, tmp);
11194                         }
11195                         if (ctxt->instate == XML_PARSER_EOF)
11196                             goto done;
11197                         SKIPL(tmp);
11198                         ctxt->checkIndex = 0;
11199                     }
11200                     goto done;
11201                 } else {
11202                     int tmp;
11203
11204                     tmp = xmlCheckCdataPush(ctxt->input->cur, base);
11205                     if ((tmp < 0) || (tmp != base)) {
11206                         tmp = -tmp;
11207                         ctxt->input->cur += tmp;
11208                         goto encoding_error;
11209                     }
11210                     if ((ctxt->sax != NULL) && (base == 0) &&
11211                         (ctxt->sax->cdataBlock != NULL) &&
11212                         (!ctxt->disableSAX)) {
11213                         /*
11214                          * Special case to provide identical behaviour
11215                          * between pull and push parsers on enpty CDATA
11216                          * sections
11217                          */
11218                          if ((ctxt->input->cur - ctxt->input->base >= 9) &&
11219                              (!strncmp((const char *)&ctxt->input->cur[-9],
11220                                        "<![CDATA[", 9)))
11221                              ctxt->sax->cdataBlock(ctxt->userData,
11222                                                    BAD_CAST "", 0);
11223                     } else if ((ctxt->sax != NULL) && (base > 0) &&
11224                         (!ctxt->disableSAX)) {
11225                         if (ctxt->sax->cdataBlock != NULL)
11226                             ctxt->sax->cdataBlock(ctxt->userData,
11227                                                   ctxt->input->cur, base);
11228                         else if (ctxt->sax->characters != NULL)
11229                             ctxt->sax->characters(ctxt->userData,
11230                                                   ctxt->input->cur, base);
11231                     }
11232                     if (ctxt->instate == XML_PARSER_EOF)
11233                         goto done;
11234                     SKIPL(base + 3);
11235                     ctxt->checkIndex = 0;
11236                     ctxt->instate = XML_PARSER_CONTENT;
11237 #ifdef DEBUG_PUSH
11238                     xmlGenericError(xmlGenericErrorContext,
11239                             "PP: entering CONTENT\n");
11240 #endif
11241                 }
11242                 break;
11243             }
11244             case XML_PARSER_MISC:
11245                 SKIP_BLANKS;
11246                 if (ctxt->input->buf == NULL)
11247                     avail = ctxt->input->length -
11248                             (ctxt->input->cur - ctxt->input->base);
11249                 else
11250                     avail = ctxt->input->buf->buffer->use -
11251                             (ctxt->input->cur - ctxt->input->base);
11252                 if (avail < 2)
11253                     goto done;
11254                 cur = ctxt->input->cur[0];
11255                 next = ctxt->input->cur[1];
11256                 if ((cur == '<') && (next == '?')) {
11257                     if ((!terminate) &&
11258                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11259                         goto done;
11260 #ifdef DEBUG_PUSH
11261                     xmlGenericError(xmlGenericErrorContext,
11262                             "PP: Parsing PI\n");
11263 #endif
11264                     xmlParsePI(ctxt);
11265                     if (ctxt->instate == XML_PARSER_EOF)
11266                         goto done;
11267                     ctxt->checkIndex = 0;
11268                 } else if ((cur == '<') && (next == '!') &&
11269                     (ctxt->input->cur[2] == '-') &&
11270                     (ctxt->input->cur[3] == '-')) {
11271                     if ((!terminate) &&
11272                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
11273                         goto done;
11274 #ifdef DEBUG_PUSH
11275                     xmlGenericError(xmlGenericErrorContext,
11276                             "PP: Parsing Comment\n");
11277 #endif
11278                     xmlParseComment(ctxt);
11279                     if (ctxt->instate == XML_PARSER_EOF)
11280                         goto done;
11281                     ctxt->instate = XML_PARSER_MISC;
11282                     ctxt->checkIndex = 0;
11283                 } else if ((cur == '<') && (next == '!') &&
11284                     (ctxt->input->cur[2] == 'D') &&
11285                     (ctxt->input->cur[3] == 'O') &&
11286                     (ctxt->input->cur[4] == 'C') &&
11287                     (ctxt->input->cur[5] == 'T') &&
11288                     (ctxt->input->cur[6] == 'Y') &&
11289                     (ctxt->input->cur[7] == 'P') &&
11290                     (ctxt->input->cur[8] == 'E')) {
11291                     if ((!terminate) &&
11292                         (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
11293                         goto done;
11294 #ifdef DEBUG_PUSH
11295                     xmlGenericError(xmlGenericErrorContext,
11296                             "PP: Parsing internal subset\n");
11297 #endif
11298                     ctxt->inSubset = 1;
11299                     xmlParseDocTypeDecl(ctxt);
11300                     if (ctxt->instate == XML_PARSER_EOF)
11301                         goto done;
11302                     if (RAW == '[') {
11303                         ctxt->instate = XML_PARSER_DTD;
11304 #ifdef DEBUG_PUSH
11305                         xmlGenericError(xmlGenericErrorContext,
11306                                 "PP: entering DTD\n");
11307 #endif
11308                     } else {
11309                         /*
11310                          * Create and update the external subset.
11311                          */
11312                         ctxt->inSubset = 2;
11313                         if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11314                             (ctxt->sax->externalSubset != NULL))
11315                             ctxt->sax->externalSubset(ctxt->userData,
11316                                     ctxt->intSubName, ctxt->extSubSystem,
11317                                     ctxt->extSubURI);
11318                         ctxt->inSubset = 0;
11319                         xmlCleanSpecialAttr(ctxt);
11320                         ctxt->instate = XML_PARSER_PROLOG;
11321 #ifdef DEBUG_PUSH
11322                         xmlGenericError(xmlGenericErrorContext,
11323                                 "PP: entering PROLOG\n");
11324 #endif
11325                     }
11326                 } else if ((cur == '<') && (next == '!') &&
11327                            (avail < 9)) {
11328                     goto done;
11329                 } else {
11330                     ctxt->instate = XML_PARSER_START_TAG;
11331                     ctxt->progressive = 1;
11332                     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11333 #ifdef DEBUG_PUSH
11334                     xmlGenericError(xmlGenericErrorContext,
11335                             "PP: entering START_TAG\n");
11336 #endif
11337                 }
11338                 break;
11339             case XML_PARSER_PROLOG:
11340                 SKIP_BLANKS;
11341                 if (ctxt->input->buf == NULL)
11342                     avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11343                 else
11344                     avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
11345                 if (avail < 2) 
11346                     goto done;
11347                 cur = ctxt->input->cur[0];
11348                 next = ctxt->input->cur[1];
11349                 if ((cur == '<') && (next == '?')) {
11350                     if ((!terminate) &&
11351                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11352                         goto done;
11353 #ifdef DEBUG_PUSH
11354                     xmlGenericError(xmlGenericErrorContext,
11355                             "PP: Parsing PI\n");
11356 #endif
11357                     xmlParsePI(ctxt);
11358                     if (ctxt->instate == XML_PARSER_EOF)
11359                         goto done;
11360                 } else if ((cur == '<') && (next == '!') &&
11361                     (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11362                     if ((!terminate) &&
11363                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
11364                         goto done;
11365 #ifdef DEBUG_PUSH
11366                     xmlGenericError(xmlGenericErrorContext,
11367                             "PP: Parsing Comment\n");
11368 #endif
11369                     xmlParseComment(ctxt);
11370                     if (ctxt->instate == XML_PARSER_EOF)
11371                         goto done;
11372                     ctxt->instate = XML_PARSER_PROLOG;
11373                 } else if ((cur == '<') && (next == '!') &&
11374                            (avail < 4)) {
11375                     goto done;
11376                 } else {
11377                     ctxt->instate = XML_PARSER_START_TAG;
11378                     if (ctxt->progressive == 0)
11379                         ctxt->progressive = 1;
11380                     xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11381 #ifdef DEBUG_PUSH
11382                     xmlGenericError(xmlGenericErrorContext,
11383                             "PP: entering START_TAG\n");
11384 #endif
11385                 }
11386                 break;
11387             case XML_PARSER_EPILOG:
11388                 SKIP_BLANKS;
11389                 if (ctxt->input->buf == NULL)
11390                     avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11391                 else
11392                     avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
11393                 if (avail < 2)
11394                     goto done;
11395                 cur = ctxt->input->cur[0];
11396                 next = ctxt->input->cur[1];
11397                 if ((cur == '<') && (next == '?')) {
11398                     if ((!terminate) &&
11399                         (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11400                         goto done;
11401 #ifdef DEBUG_PUSH
11402                     xmlGenericError(xmlGenericErrorContext,
11403                             "PP: Parsing PI\n");
11404 #endif
11405                     xmlParsePI(ctxt);
11406                     if (ctxt->instate == XML_PARSER_EOF)
11407                         goto done;
11408                     ctxt->instate = XML_PARSER_EPILOG;
11409                 } else if ((cur == '<') && (next == '!') &&
11410                     (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11411                     if ((!terminate) &&
11412                         (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
11413                         goto done;
11414 #ifdef DEBUG_PUSH
11415                     xmlGenericError(xmlGenericErrorContext,
11416                             "PP: Parsing Comment\n");
11417 #endif
11418                     xmlParseComment(ctxt);
11419                     if (ctxt->instate == XML_PARSER_EOF)
11420                         goto done;
11421                     ctxt->instate = XML_PARSER_EPILOG;
11422                 } else if ((cur == '<') && (next == '!') &&
11423                            (avail < 4)) {
11424                     goto done;
11425                 } else {
11426                     xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11427                     ctxt->instate = XML_PARSER_EOF;
11428 #ifdef DEBUG_PUSH
11429                     xmlGenericError(xmlGenericErrorContext,
11430                             "PP: entering EOF\n");
11431 #endif
11432                     if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11433                         ctxt->sax->endDocument(ctxt->userData);
11434                     goto done;
11435                 }
11436                 break;
11437             case XML_PARSER_DTD: {
11438                 /*
11439                  * Sorry but progressive parsing of the internal subset
11440                  * is not expected to be supported. We first check that
11441                  * the full content of the internal subset is available and
11442                  * the parsing is launched only at that point.
11443                  * Internal subset ends up with "']' S? '>'" in an unescaped
11444                  * section and not in a ']]>' sequence which are conditional
11445                  * sections (whoever argued to keep that crap in XML deserve
11446                  * a place in hell !).
11447                  */
11448                 int base, i;
11449                 xmlChar *buf;
11450                 xmlChar quote = 0;
11451
11452                 base = ctxt->input->cur - ctxt->input->base;
11453                 if (base < 0) return(0);
11454                 if (ctxt->checkIndex > base)
11455                     base = ctxt->checkIndex;
11456                 buf = ctxt->input->buf->buffer->content;
11457                 for (;(unsigned int) base < ctxt->input->buf->buffer->use;
11458                      base++) {
11459                     if (quote != 0) {
11460                         if (buf[base] == quote)
11461                             quote = 0;
11462                         continue;    
11463                     }
11464                     if ((quote == 0) && (buf[base] == '<')) {
11465                         int found  = 0;
11466                         /* special handling of comments */
11467                         if (((unsigned int) base + 4 <
11468                              ctxt->input->buf->buffer->use) &&
11469                             (buf[base + 1] == '!') &&
11470                             (buf[base + 2] == '-') &&
11471                             (buf[base + 3] == '-')) {
11472                             for (;(unsigned int) base + 3 <
11473                                   ctxt->input->buf->buffer->use; base++) {
11474                                 if ((buf[base] == '-') &&
11475                                     (buf[base + 1] == '-') &&
11476                                     (buf[base + 2] == '>')) {
11477                                     found = 1;
11478                                     base += 2;
11479                                     break;
11480                                 }
11481                             }
11482                             if (!found) {
11483 #if 0
11484                                 fprintf(stderr, "unfinished comment\n");
11485 #endif
11486                                 break; /* for */
11487                             }
11488                             continue;
11489                         }
11490                     }
11491                     if (buf[base] == '"') {
11492                         quote = '"';
11493                         continue;
11494                     }
11495                     if (buf[base] == '\'') {
11496                         quote = '\'';
11497                         continue;
11498                     }
11499                     if (buf[base] == ']') {
11500 #if 0
11501                         fprintf(stderr, "%c%c%c%c: ", buf[base],
11502                                 buf[base + 1], buf[base + 2], buf[base + 3]);
11503 #endif
11504                         if ((unsigned int) base +1 >=
11505                             ctxt->input->buf->buffer->use)
11506                             break;
11507                         if (buf[base + 1] == ']') {
11508                             /* conditional crap, skip both ']' ! */
11509                             base++;
11510                             continue;
11511                         }
11512                         for (i = 1;
11513                      (unsigned int) base + i < ctxt->input->buf->buffer->use;
11514                              i++) {
11515                             if (buf[base + i] == '>') {
11516 #if 0
11517                                 fprintf(stderr, "found\n");
11518 #endif
11519                                 goto found_end_int_subset;
11520                             }
11521                             if (!IS_BLANK_CH(buf[base + i])) {
11522 #if 0
11523                                 fprintf(stderr, "not found\n");
11524 #endif
11525                                 goto not_end_of_int_subset;
11526                             }
11527                         }
11528 #if 0
11529                         fprintf(stderr, "end of stream\n");
11530 #endif
11531                         break;
11532                         
11533                     }
11534 not_end_of_int_subset:
11535                     continue; /* for */
11536                 }
11537                 /*
11538                  * We didn't found the end of the Internal subset
11539                  */
11540 #ifdef DEBUG_PUSH
11541                 if (next == 0)
11542                     xmlGenericError(xmlGenericErrorContext,
11543                             "PP: lookup of int subset end filed\n");
11544 #endif
11545                 goto done;
11546
11547 found_end_int_subset:
11548                 xmlParseInternalSubset(ctxt);
11549                 if (ctxt->instate == XML_PARSER_EOF)
11550                     goto done;
11551                 ctxt->inSubset = 2;
11552                 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11553                     (ctxt->sax->externalSubset != NULL))
11554                     ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
11555                             ctxt->extSubSystem, ctxt->extSubURI);
11556                 ctxt->inSubset = 0;
11557                 xmlCleanSpecialAttr(ctxt);
11558                 if (ctxt->instate == XML_PARSER_EOF)
11559                     goto done;
11560                 ctxt->instate = XML_PARSER_PROLOG;
11561                 ctxt->checkIndex = 0;
11562 #ifdef DEBUG_PUSH
11563                 xmlGenericError(xmlGenericErrorContext,
11564                         "PP: entering PROLOG\n");
11565 #endif
11566                 break;
11567             }
11568             case XML_PARSER_COMMENT:
11569                 xmlGenericError(xmlGenericErrorContext,
11570                         "PP: internal error, state == COMMENT\n");
11571                 ctxt->instate = XML_PARSER_CONTENT;
11572 #ifdef DEBUG_PUSH
11573                 xmlGenericError(xmlGenericErrorContext,
11574                         "PP: entering CONTENT\n");
11575 #endif
11576                 break;
11577             case XML_PARSER_IGNORE:
11578                 xmlGenericError(xmlGenericErrorContext,
11579                         "PP: internal error, state == IGNORE");
11580                 ctxt->instate = XML_PARSER_DTD;
11581 #ifdef DEBUG_PUSH
11582                 xmlGenericError(xmlGenericErrorContext,
11583                         "PP: entering DTD\n");
11584 #endif
11585                 break;
11586             case XML_PARSER_PI:
11587                 xmlGenericError(xmlGenericErrorContext,
11588                         "PP: internal error, state == PI\n");
11589                 ctxt->instate = XML_PARSER_CONTENT;
11590 #ifdef DEBUG_PUSH
11591                 xmlGenericError(xmlGenericErrorContext,
11592                         "PP: entering CONTENT\n");
11593 #endif
11594                 break;
11595             case XML_PARSER_ENTITY_DECL:
11596                 xmlGenericError(xmlGenericErrorContext,
11597                         "PP: internal error, state == ENTITY_DECL\n");
11598                 ctxt->instate = XML_PARSER_DTD;
11599 #ifdef DEBUG_PUSH
11600                 xmlGenericError(xmlGenericErrorContext,
11601                         "PP: entering DTD\n");
11602 #endif
11603                 break;
11604             case XML_PARSER_ENTITY_VALUE:
11605                 xmlGenericError(xmlGenericErrorContext,
11606                         "PP: internal error, state == ENTITY_VALUE\n");
11607                 ctxt->instate = XML_PARSER_CONTENT;
11608 #ifdef DEBUG_PUSH
11609                 xmlGenericError(xmlGenericErrorContext,
11610                         "PP: entering DTD\n");
11611 #endif
11612                 break;
11613             case XML_PARSER_ATTRIBUTE_VALUE:
11614                 xmlGenericError(xmlGenericErrorContext,
11615                         "PP: internal error, state == ATTRIBUTE_VALUE\n");
11616                 ctxt->instate = XML_PARSER_START_TAG;
11617 #ifdef DEBUG_PUSH
11618                 xmlGenericError(xmlGenericErrorContext,
11619                         "PP: entering START_TAG\n");
11620 #endif
11621                 break;
11622             case XML_PARSER_SYSTEM_LITERAL:
11623                 xmlGenericError(xmlGenericErrorContext,
11624                         "PP: internal error, state == SYSTEM_LITERAL\n");
11625                 ctxt->instate = XML_PARSER_START_TAG;
11626 #ifdef DEBUG_PUSH
11627                 xmlGenericError(xmlGenericErrorContext,
11628                         "PP: entering START_TAG\n");
11629 #endif
11630                 break;
11631             case XML_PARSER_PUBLIC_LITERAL:
11632                 xmlGenericError(xmlGenericErrorContext,
11633                         "PP: internal error, state == PUBLIC_LITERAL\n");
11634                 ctxt->instate = XML_PARSER_START_TAG;
11635 #ifdef DEBUG_PUSH
11636                 xmlGenericError(xmlGenericErrorContext,
11637                         "PP: entering START_TAG\n");
11638 #endif
11639                 break;
11640         }
11641     }
11642 done:    
11643 #ifdef DEBUG_PUSH
11644     xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
11645 #endif
11646     return(ret);
11647 encoding_error:
11648     {
11649         char buffer[150];
11650
11651         snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
11652                         ctxt->input->cur[0], ctxt->input->cur[1],
11653                         ctxt->input->cur[2], ctxt->input->cur[3]);
11654         __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
11655                      "Input is not proper UTF-8, indicate encoding !\n%s",
11656                      BAD_CAST buffer, NULL);
11657     }
11658     return(0);
11659 }
11660
11661 /**
11662  * xmlParseChunk:
11663  * @ctxt:  an XML parser context
11664  * @chunk:  an char array
11665  * @size:  the size in byte of the chunk
11666  * @terminate:  last chunk indicator
11667  *
11668  * Parse a Chunk of memory
11669  *
11670  * Returns zero if no error, the xmlParserErrors otherwise.
11671  */
11672 int
11673 xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
11674               int terminate) {
11675     int end_in_lf = 0;
11676     int remain = 0;
11677
11678     if (ctxt == NULL)
11679         return(XML_ERR_INTERNAL_ERROR);
11680     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11681         return(ctxt->errNo);
11682     if (ctxt->instate == XML_PARSER_EOF)
11683         return(-1);
11684     if (ctxt->instate == XML_PARSER_START)
11685         xmlDetectSAX2(ctxt);
11686     if ((size > 0) && (chunk != NULL) && (!terminate) &&
11687         (chunk[size - 1] == '\r')) {
11688         end_in_lf = 1;
11689         size--;
11690     }
11691
11692 xmldecl_done:
11693
11694     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
11695         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
11696         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
11697         int cur = ctxt->input->cur - ctxt->input->base;
11698         int res;
11699
11700         /*
11701          * Specific handling if we autodetected an encoding, we should not
11702          * push more than the first line ... which depend on the encoding
11703          * And only push the rest once the final encoding was detected
11704          */
11705         if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
11706             (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
11707             unsigned int len = 45;
11708
11709             if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11710                                BAD_CAST "UTF-16")) ||
11711                 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11712                                BAD_CAST "UTF16")))
11713                 len = 90;
11714             else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11715                                     BAD_CAST "UCS-4")) ||
11716                      (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
11717                                     BAD_CAST "UCS4")))
11718                 len = 180;
11719
11720             if (ctxt->input->buf->rawconsumed < len)
11721                 len -= ctxt->input->buf->rawconsumed;
11722
11723             /*
11724              * Change size for reading the initial declaration only
11725              * if size is greater than len. Otherwise, memmove in xmlBufferAdd
11726              * will blindly copy extra bytes from memory.
11727              */
11728             if (size > len) {
11729                 remain = size - len;
11730                 size = len;
11731             } else {
11732                 remain = 0;
11733             }
11734         }
11735         res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
11736         if (res < 0) {
11737             ctxt->errNo = XML_PARSER_EOF;
11738             ctxt->disableSAX = 1;
11739             return (XML_PARSER_EOF);
11740         }
11741         ctxt->input->base = ctxt->input->buf->buffer->content + base;
11742         ctxt->input->cur = ctxt->input->base + cur;
11743         ctxt->input->end =
11744             &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
11745 #ifdef DEBUG_PUSH
11746         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
11747 #endif
11748
11749     } else if (ctxt->instate != XML_PARSER_EOF) {
11750         if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
11751             xmlParserInputBufferPtr in = ctxt->input->buf;
11752             if ((in->encoder != NULL) && (in->buffer != NULL) &&
11753                     (in->raw != NULL)) {
11754                 int nbchars;
11755
11756                 nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
11757                 if (nbchars < 0) {
11758                     /* TODO 2.6.0 */
11759                     xmlGenericError(xmlGenericErrorContext,
11760                                     "xmlParseChunk: encoder error\n");
11761                     return(XML_ERR_INVALID_ENCODING);
11762                 }
11763             }
11764         }
11765     }
11766     if (remain != 0)
11767         xmlParseTryOrFinish(ctxt, 0);
11768     else
11769         xmlParseTryOrFinish(ctxt, terminate);
11770     if (ctxt->instate == XML_PARSER_EOF)
11771         return(ctxt->errNo);
11772     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11773         return(ctxt->errNo);
11774
11775     if (remain != 0) {
11776         chunk += size;
11777         size = remain;
11778         remain = 0;
11779         goto xmldecl_done;
11780     }
11781     if ((end_in_lf == 1) && (ctxt->input != NULL) &&
11782         (ctxt->input->buf != NULL)) {
11783         xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
11784     }
11785     if (terminate) {
11786         /*
11787          * Check for termination
11788          */
11789         int avail = 0;
11790
11791         if (ctxt->input != NULL) {
11792             if (ctxt->input->buf == NULL)
11793                 avail = ctxt->input->length -
11794                         (ctxt->input->cur - ctxt->input->base);
11795             else
11796                 avail = ctxt->input->buf->buffer->use -
11797                         (ctxt->input->cur - ctxt->input->base);
11798         }
11799                             
11800         if ((ctxt->instate != XML_PARSER_EOF) &&
11801             (ctxt->instate != XML_PARSER_EPILOG)) {
11802             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11803         } 
11804         if ((ctxt->instate == XML_PARSER_EPILOG) && (avail > 0)) {
11805             xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11806         }
11807         if (ctxt->instate != XML_PARSER_EOF) {
11808             if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11809                 ctxt->sax->endDocument(ctxt->userData);
11810         }
11811         ctxt->instate = XML_PARSER_EOF;
11812     }
11813     return((xmlParserErrors) ctxt->errNo);            
11814 }
11815
11816 /************************************************************************
11817  *                                                                      *
11818  *              I/O front end functions to the parser                   *
11819  *                                                                      *
11820  ************************************************************************/
11821
11822 /**
11823  * xmlCreatePushParserCtxt:
11824  * @sax:  a SAX handler
11825  * @user_data:  The user data returned on SAX callbacks
11826  * @chunk:  a pointer to an array of chars
11827  * @size:  number of chars in the array
11828  * @filename:  an optional file name or URI
11829  *
11830  * Create a parser context for using the XML parser in push mode.
11831  * If @buffer and @size are non-NULL, the data is used to detect
11832  * the encoding.  The remaining characters will be parsed so they
11833  * don't need to be fed in again through xmlParseChunk.
11834  * To allow content encoding detection, @size should be >= 4
11835  * The value of @filename is used for fetching external entities
11836  * and error/warning reports.
11837  *
11838  * Returns the new parser context or NULL
11839  */
11840
11841 xmlParserCtxtPtr
11842 xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data, 
11843                         const char *chunk, int size, const char *filename) {
11844     xmlParserCtxtPtr ctxt;
11845     xmlParserInputPtr inputStream;
11846     xmlParserInputBufferPtr buf;
11847     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
11848
11849     /*
11850      * plug some encoding conversion routines
11851      */
11852     if ((chunk != NULL) && (size >= 4))
11853         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
11854
11855     buf = xmlAllocParserInputBuffer(enc);
11856     if (buf == NULL) return(NULL);
11857
11858     ctxt = xmlNewParserCtxt();
11859     if (ctxt == NULL) {
11860         xmlErrMemory(NULL, "creating parser: out of memory\n");
11861         xmlFreeParserInputBuffer(buf);
11862         return(NULL);
11863     }
11864     ctxt->dictNames = 1;
11865     ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
11866     if (ctxt->pushTab == NULL) {
11867         xmlErrMemory(ctxt, NULL);
11868         xmlFreeParserInputBuffer(buf);
11869         xmlFreeParserCtxt(ctxt);
11870         return(NULL);
11871     }
11872     if (sax != NULL) {
11873 #ifdef LIBXML_SAX1_ENABLED
11874         if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
11875 #endif /* LIBXML_SAX1_ENABLED */
11876             xmlFree(ctxt->sax);
11877         ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
11878         if (ctxt->sax == NULL) {
11879             xmlErrMemory(ctxt, NULL);
11880             xmlFreeParserInputBuffer(buf);
11881             xmlFreeParserCtxt(ctxt);
11882             return(NULL);
11883         }
11884         memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
11885         if (sax->initialized == XML_SAX2_MAGIC)
11886             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
11887         else
11888             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
11889         if (user_data != NULL)
11890             ctxt->userData = user_data;
11891     }   
11892     if (filename == NULL) {
11893         ctxt->directory = NULL;
11894     } else {
11895         ctxt->directory = xmlParserGetDirectory(filename);
11896     }
11897
11898     inputStream = xmlNewInputStream(ctxt);
11899     if (inputStream == NULL) {
11900         xmlFreeParserCtxt(ctxt);
11901         xmlFreeParserInputBuffer(buf);
11902         return(NULL);
11903     }
11904
11905     if (filename == NULL)
11906         inputStream->filename = NULL;
11907     else {
11908         inputStream->filename = (char *)
11909             xmlCanonicPath((const xmlChar *) filename);
11910         if (inputStream->filename == NULL) {
11911             xmlFreeParserCtxt(ctxt);
11912             xmlFreeParserInputBuffer(buf);
11913             return(NULL);
11914         }
11915     }
11916     inputStream->buf = buf;
11917     inputStream->base = inputStream->buf->buffer->content;
11918     inputStream->cur = inputStream->buf->buffer->content;
11919     inputStream->end = 
11920         &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
11921
11922     inputPush(ctxt, inputStream);
11923
11924     /*
11925      * If the caller didn't provide an initial 'chunk' for determining
11926      * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
11927      * that it can be automatically determined later
11928      */
11929     if ((size == 0) || (chunk == NULL)) {
11930         ctxt->charset = XML_CHAR_ENCODING_NONE;
11931     } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
11932         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
11933         int cur = ctxt->input->cur - ctxt->input->base;
11934
11935         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);              
11936
11937         ctxt->input->base = ctxt->input->buf->buffer->content + base;
11938         ctxt->input->cur = ctxt->input->base + cur;
11939         ctxt->input->end =
11940             &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
11941 #ifdef DEBUG_PUSH
11942         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
11943 #endif
11944     }
11945
11946     if (enc != XML_CHAR_ENCODING_NONE) {
11947         xmlSwitchEncoding(ctxt, enc);
11948     }
11949
11950     return(ctxt);
11951 }
11952 #endif /* LIBXML_PUSH_ENABLED */
11953
11954 /**
11955  * xmlStopParser:
11956  * @ctxt:  an XML parser context
11957  *
11958  * Blocks further parser processing
11959  */
11960 void           
11961 xmlStopParser(xmlParserCtxtPtr ctxt) {
11962     if (ctxt == NULL)
11963         return;
11964     ctxt->instate = XML_PARSER_EOF;
11965     ctxt->errNo = XML_ERR_USER_STOP;
11966     ctxt->disableSAX = 1;
11967     if (ctxt->input != NULL) {
11968         ctxt->input->cur = BAD_CAST"";
11969         ctxt->input->base = ctxt->input->cur;
11970     }
11971 }
11972
11973 /**
11974  * xmlCreateIOParserCtxt:
11975  * @sax:  a SAX handler
11976  * @user_data:  The user data returned on SAX callbacks
11977  * @ioread:  an I/O read function
11978  * @ioclose:  an I/O close function
11979  * @ioctx:  an I/O handler
11980  * @enc:  the charset encoding if known
11981  *
11982  * Create a parser context for using the XML parser with an existing
11983  * I/O stream
11984  *
11985  * Returns the new parser context or NULL
11986  */
11987 xmlParserCtxtPtr
11988 xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
11989         xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
11990         void *ioctx, xmlCharEncoding enc) {
11991     xmlParserCtxtPtr ctxt;
11992     xmlParserInputPtr inputStream;
11993     xmlParserInputBufferPtr buf;
11994     
11995     if (ioread == NULL) return(NULL);
11996
11997     buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
11998     if (buf == NULL) return(NULL);
11999
12000     ctxt = xmlNewParserCtxt();
12001     if (ctxt == NULL) {
12002         xmlFreeParserInputBuffer(buf);
12003         return(NULL);
12004     }
12005     if (sax != NULL) {
12006 #ifdef LIBXML_SAX1_ENABLED
12007         if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12008 #endif /* LIBXML_SAX1_ENABLED */
12009             xmlFree(ctxt->sax);
12010         ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12011         if (ctxt->sax == NULL) {
12012             xmlErrMemory(ctxt, NULL);
12013             xmlFreeParserCtxt(ctxt);
12014             return(NULL);
12015         }
12016         memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12017         if (sax->initialized == XML_SAX2_MAGIC)
12018             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12019         else
12020             memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12021         if (user_data != NULL)
12022             ctxt->userData = user_data;
12023     }   
12024
12025     inputStream = xmlNewIOInputStream(ctxt, buf, enc);
12026     if (inputStream == NULL) {
12027         xmlFreeParserCtxt(ctxt);
12028         return(NULL);
12029     }
12030     inputPush(ctxt, inputStream);
12031
12032     return(ctxt);
12033 }
12034
12035 #ifdef LIBXML_VALID_ENABLED
12036 /************************************************************************
12037  *                                                                      *
12038  *              Front ends when parsing a DTD                           *
12039  *                                                                      *
12040  ************************************************************************/
12041
12042 /**
12043  * xmlIOParseDTD:
12044  * @sax:  the SAX handler block or NULL
12045  * @input:  an Input Buffer
12046  * @enc:  the charset encoding if known
12047  *
12048  * Load and parse a DTD
12049  * 
12050  * Returns the resulting xmlDtdPtr or NULL in case of error.
12051  * @input will be freed by the function in any case.
12052  */
12053
12054 xmlDtdPtr
12055 xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
12056               xmlCharEncoding enc) {
12057     xmlDtdPtr ret = NULL;
12058     xmlParserCtxtPtr ctxt;
12059     xmlParserInputPtr pinput = NULL;
12060     xmlChar start[4];
12061
12062     if (input == NULL)
12063         return(NULL);
12064
12065     ctxt = xmlNewParserCtxt();
12066     if (ctxt == NULL) {
12067         xmlFreeParserInputBuffer(input);
12068         return(NULL);
12069     }
12070
12071     /*
12072      * Set-up the SAX context
12073      */
12074     if (sax != NULL) { 
12075         if (ctxt->sax != NULL)
12076             xmlFree(ctxt->sax);
12077         ctxt->sax = sax;
12078         ctxt->userData = ctxt;
12079     }
12080     xmlDetectSAX2(ctxt);
12081
12082     /*
12083      * generate a parser input from the I/O handler
12084      */
12085
12086     pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
12087     if (pinput == NULL) {
12088         if (sax != NULL) ctxt->sax = NULL;
12089         xmlFreeParserInputBuffer(input);
12090         xmlFreeParserCtxt(ctxt);
12091         return(NULL);
12092     }
12093
12094     /*
12095      * plug some encoding conversion routines here.
12096      */
12097     if (xmlPushInput(ctxt, pinput) < 0) {
12098         if (sax != NULL) ctxt->sax = NULL;
12099         xmlFreeParserCtxt(ctxt);
12100         return(NULL);
12101     }
12102     if (enc != XML_CHAR_ENCODING_NONE) {
12103         xmlSwitchEncoding(ctxt, enc);
12104     }
12105
12106     pinput->filename = NULL;
12107     pinput->line = 1;
12108     pinput->col = 1;
12109     pinput->base = ctxt->input->cur;
12110     pinput->cur = ctxt->input->cur;
12111     pinput->free = NULL;
12112
12113     /*
12114      * let's parse that entity knowing it's an external subset.
12115      */
12116     ctxt->inSubset = 2;
12117     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12118     if (ctxt->myDoc == NULL) {
12119         xmlErrMemory(ctxt, "New Doc failed");
12120         return(NULL);
12121     }
12122     ctxt->myDoc->properties = XML_DOC_INTERNAL;
12123     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12124                                        BAD_CAST "none", BAD_CAST "none");
12125
12126     if ((enc == XML_CHAR_ENCODING_NONE) &&
12127         ((ctxt->input->end - ctxt->input->cur) >= 4)) {
12128         /* 
12129          * Get the 4 first bytes and decode the charset
12130          * if enc != XML_CHAR_ENCODING_NONE
12131          * plug some encoding conversion routines.
12132          */
12133         start[0] = RAW;
12134         start[1] = NXT(1);
12135         start[2] = NXT(2);
12136         start[3] = NXT(3);
12137         enc = xmlDetectCharEncoding(start, 4);
12138         if (enc != XML_CHAR_ENCODING_NONE) {
12139             xmlSwitchEncoding(ctxt, enc);
12140         }
12141     }
12142
12143     xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
12144
12145     if (ctxt->myDoc != NULL) {
12146         if (ctxt->wellFormed) {
12147             ret = ctxt->myDoc->extSubset;
12148             ctxt->myDoc->extSubset = NULL;
12149             if (ret != NULL) {
12150                 xmlNodePtr tmp;
12151
12152                 ret->doc = NULL;
12153                 tmp = ret->children;
12154                 while (tmp != NULL) {
12155                     tmp->doc = NULL;
12156                     tmp = tmp->next;
12157                 }
12158             }
12159         } else {
12160             ret = NULL;
12161         }
12162         xmlFreeDoc(ctxt->myDoc);
12163         ctxt->myDoc = NULL;
12164     }
12165     if (sax != NULL) ctxt->sax = NULL;
12166     xmlFreeParserCtxt(ctxt);
12167     
12168     return(ret);
12169 }
12170
12171 /**
12172  * xmlSAXParseDTD:
12173  * @sax:  the SAX handler block
12174  * @ExternalID:  a NAME* containing the External ID of the DTD
12175  * @SystemID:  a NAME* containing the URL to the DTD
12176  *
12177  * Load and parse an external subset.
12178  * 
12179  * Returns the resulting xmlDtdPtr or NULL in case of error.
12180  */
12181
12182 xmlDtdPtr
12183 xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
12184                           const xmlChar *SystemID) {
12185     xmlDtdPtr ret = NULL;
12186     xmlParserCtxtPtr ctxt;
12187     xmlParserInputPtr input = NULL;
12188     xmlCharEncoding enc;
12189     xmlChar* systemIdCanonic;
12190
12191     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
12192
12193     ctxt = xmlNewParserCtxt();
12194     if (ctxt == NULL) {
12195         return(NULL);
12196     }
12197
12198     /*
12199      * Set-up the SAX context
12200      */
12201     if (sax != NULL) { 
12202         if (ctxt->sax != NULL)
12203             xmlFree(ctxt->sax);
12204         ctxt->sax = sax;
12205         ctxt->userData = ctxt;
12206     }
12207     
12208     /*
12209      * Canonicalise the system ID
12210      */
12211     systemIdCanonic = xmlCanonicPath(SystemID);
12212     if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
12213         xmlFreeParserCtxt(ctxt);
12214         return(NULL);
12215     }
12216
12217     /*
12218      * Ask the Entity resolver to load the damn thing
12219      */
12220
12221     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
12222         input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
12223                                          systemIdCanonic);
12224     if (input == NULL) {
12225         if (sax != NULL) ctxt->sax = NULL;
12226         xmlFreeParserCtxt(ctxt);
12227         if (systemIdCanonic != NULL)
12228             xmlFree(systemIdCanonic);
12229         return(NULL);
12230     }
12231
12232     /*
12233      * plug some encoding conversion routines here.
12234      */
12235     if (xmlPushInput(ctxt, input) < 0) {
12236         if (sax != NULL) ctxt->sax = NULL;
12237         xmlFreeParserCtxt(ctxt);
12238         if (systemIdCanonic != NULL)
12239             xmlFree(systemIdCanonic);
12240         return(NULL);
12241     }
12242     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12243         enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
12244         xmlSwitchEncoding(ctxt, enc);
12245     }
12246
12247     if (input->filename == NULL)
12248         input->filename = (char *) systemIdCanonic;
12249     else
12250         xmlFree(systemIdCanonic);
12251     input->line = 1;
12252     input->col = 1;
12253     input->base = ctxt->input->cur;
12254     input->cur = ctxt->input->cur;
12255     input->free = NULL;
12256
12257     /*
12258      * let's parse that entity knowing it's an external subset.
12259      */
12260     ctxt->inSubset = 2;
12261     ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12262     if (ctxt->myDoc == NULL) {
12263         xmlErrMemory(ctxt, "New Doc failed");
12264         if (sax != NULL) ctxt->sax = NULL;
12265         xmlFreeParserCtxt(ctxt);
12266         return(NULL);
12267     }
12268     ctxt->myDoc->properties = XML_DOC_INTERNAL;
12269     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12270                                        ExternalID, SystemID);
12271     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
12272
12273     if (ctxt->myDoc != NULL) {
12274         if (ctxt->wellFormed) {
12275             ret = ctxt->myDoc->extSubset;
12276             ctxt->myDoc->extSubset = NULL;
12277             if (ret != NULL) {
12278                 xmlNodePtr tmp;
12279
12280                 ret->doc = NULL;
12281                 tmp = ret->children;
12282                 while (tmp != NULL) {
12283                     tmp->doc = NULL;
12284                     tmp = tmp->next;
12285                 }
12286             }
12287         } else {
12288             ret = NULL;
12289         }
12290         xmlFreeDoc(ctxt->myDoc);
12291         ctxt->myDoc = NULL;
12292     }
12293     if (sax != NULL) ctxt->sax = NULL;
12294     xmlFreeParserCtxt(ctxt);
12295
12296     return(ret);
12297 }
12298
12299
12300 /**
12301  * xmlParseDTD:
12302  * @ExternalID:  a NAME* containing the External ID of the DTD
12303  * @SystemID:  a NAME* containing the URL to the DTD
12304  *
12305  * Load and parse an external subset.
12306  *
12307  * Returns the resulting xmlDtdPtr or NULL in case of error.
12308  */
12309
12310 xmlDtdPtr
12311 xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
12312     return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
12313 }
12314 #endif /* LIBXML_VALID_ENABLED */
12315
12316 /************************************************************************
12317  *                                                                      *
12318  *              Front ends when parsing an Entity                       *
12319  *                                                                      *
12320  ************************************************************************/
12321
12322 /**
12323  * xmlParseCtxtExternalEntity:
12324  * @ctx:  the existing parsing context
12325  * @URL:  the URL for the entity to load
12326  * @ID:  the System ID for the entity to load
12327  * @lst:  the return value for the set of parsed nodes
12328  *
12329  * Parse an external general entity within an existing parsing context
12330  * An external general parsed entity is well-formed if it matches the
12331  * production labeled extParsedEnt.
12332  *
12333  * [78] extParsedEnt ::= TextDecl? content
12334  *
12335  * Returns 0 if the entity is well formed, -1 in case of args problem and
12336  *    the parser error code otherwise
12337  */
12338
12339 int
12340 xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
12341                        const xmlChar *ID, xmlNodePtr *lst) {
12342     xmlParserCtxtPtr ctxt;
12343     xmlDocPtr newDoc;
12344     xmlNodePtr newRoot;
12345     xmlSAXHandlerPtr oldsax = NULL;
12346     int ret = 0;
12347     xmlChar start[4];
12348     xmlCharEncoding enc;
12349
12350     if (ctx == NULL) return(-1);
12351
12352     if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
12353         (ctx->depth > 1024)) {
12354         return(XML_ERR_ENTITY_LOOP);
12355     }
12356
12357     if (lst != NULL)
12358         *lst = NULL;
12359     if ((URL == NULL) && (ID == NULL))
12360         return(-1);
12361     if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
12362         return(-1);
12363
12364     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
12365     if (ctxt == NULL) {
12366         return(-1);
12367     }
12368
12369     oldsax = ctxt->sax;
12370     ctxt->sax = ctx->sax;
12371     xmlDetectSAX2(ctxt);
12372     newDoc = xmlNewDoc(BAD_CAST "1.0");
12373     if (newDoc == NULL) {
12374         xmlFreeParserCtxt(ctxt);
12375         return(-1);
12376     }
12377     newDoc->properties = XML_DOC_INTERNAL;
12378     if (ctx->myDoc->dict) {
12379         newDoc->dict = ctx->myDoc->dict;
12380         xmlDictReference(newDoc->dict);
12381     }
12382     if (ctx->myDoc != NULL) {
12383         newDoc->intSubset = ctx->myDoc->intSubset;
12384         newDoc->extSubset = ctx->myDoc->extSubset;
12385     }
12386     if (ctx->myDoc->URL != NULL) {
12387         newDoc->URL = xmlStrdup(ctx->myDoc->URL);
12388     }
12389     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
12390     if (newRoot == NULL) {
12391         ctxt->sax = oldsax;
12392         xmlFreeParserCtxt(ctxt);
12393         newDoc->intSubset = NULL;
12394         newDoc->extSubset = NULL;
12395         xmlFreeDoc(newDoc);
12396         return(-1);
12397     }
12398     xmlAddChild((xmlNodePtr) newDoc, newRoot);
12399     nodePush(ctxt, newDoc->children);
12400     if (ctx->myDoc == NULL) {
12401         ctxt->myDoc = newDoc;
12402     } else {
12403         ctxt->myDoc = ctx->myDoc;
12404         newDoc->children->doc = ctx->myDoc;
12405     }
12406
12407     /*
12408      * Get the 4 first bytes and decode the charset
12409      * if enc != XML_CHAR_ENCODING_NONE
12410      * plug some encoding conversion routines.
12411      */
12412     GROW
12413     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12414         start[0] = RAW;
12415         start[1] = NXT(1);
12416         start[2] = NXT(2);
12417         start[3] = NXT(3);
12418         enc = xmlDetectCharEncoding(start, 4);
12419         if (enc != XML_CHAR_ENCODING_NONE) {
12420             xmlSwitchEncoding(ctxt, enc);
12421         }
12422     }
12423
12424     /*
12425      * Parse a possible text declaration first
12426      */
12427     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
12428         xmlParseTextDecl(ctxt);
12429         /*
12430          * An XML-1.0 document can't reference an entity not XML-1.0
12431          */
12432         if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
12433             (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
12434             xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH, 
12435                            "Version mismatch between document and entity\n");
12436         }
12437     }
12438
12439     /*
12440      * Doing validity checking on chunk doesn't make sense
12441      */
12442     ctxt->instate = XML_PARSER_CONTENT;
12443     ctxt->validate = ctx->validate;
12444     ctxt->valid = ctx->valid;
12445     ctxt->loadsubset = ctx->loadsubset;
12446     ctxt->depth = ctx->depth + 1;
12447     ctxt->replaceEntities = ctx->replaceEntities;
12448     if (ctxt->validate) {
12449         ctxt->vctxt.error = ctx->vctxt.error;
12450         ctxt->vctxt.warning = ctx->vctxt.warning;
12451     } else {
12452         ctxt->vctxt.error = NULL;
12453         ctxt->vctxt.warning = NULL;
12454     }
12455     ctxt->vctxt.nodeTab = NULL;
12456     ctxt->vctxt.nodeNr = 0;
12457     ctxt->vctxt.nodeMax = 0;
12458     ctxt->vctxt.node = NULL;
12459     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
12460     ctxt->dict = ctx->dict;
12461     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
12462     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
12463     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
12464     ctxt->dictNames = ctx->dictNames;
12465     ctxt->attsDefault = ctx->attsDefault;
12466     ctxt->attsSpecial = ctx->attsSpecial;
12467     ctxt->linenumbers = ctx->linenumbers;
12468
12469     xmlParseContent(ctxt);
12470
12471     ctx->validate = ctxt->validate;
12472     ctx->valid = ctxt->valid;
12473     if ((RAW == '<') && (NXT(1) == '/')) {
12474         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12475     } else if (RAW != 0) {
12476         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
12477     }
12478     if (ctxt->node != newDoc->children) {
12479         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12480     }
12481
12482     if (!ctxt->wellFormed) {
12483         if (ctxt->errNo == 0)
12484             ret = 1;
12485         else
12486             ret = ctxt->errNo;
12487     } else {
12488         if (lst != NULL) {
12489             xmlNodePtr cur;
12490
12491             /*
12492              * Return the newly created nodeset after unlinking it from
12493              * they pseudo parent.
12494              */
12495             cur = newDoc->children->children;
12496             *lst = cur;
12497             while (cur != NULL) {
12498                 cur->parent = NULL;
12499                 cur = cur->next;
12500             }
12501             newDoc->children->children = NULL;
12502         }
12503         ret = 0;
12504     }
12505     ctxt->sax = oldsax;
12506     ctxt->dict = NULL;
12507     ctxt->attsDefault = NULL;
12508     ctxt->attsSpecial = NULL;
12509     xmlFreeParserCtxt(ctxt);
12510     newDoc->intSubset = NULL;
12511     newDoc->extSubset = NULL;
12512     xmlFreeDoc(newDoc);
12513
12514     return(ret);
12515 }
12516
12517 /**
12518  * xmlParseExternalEntityPrivate:
12519  * @doc:  the document the chunk pertains to
12520  * @oldctxt:  the previous parser context if available
12521  * @sax:  the SAX handler bloc (possibly NULL)
12522  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
12523  * @depth:  Used for loop detection, use 0
12524  * @URL:  the URL for the entity to load
12525  * @ID:  the System ID for the entity to load
12526  * @list:  the return value for the set of parsed nodes
12527  *
12528  * Private version of xmlParseExternalEntity()
12529  *
12530  * Returns 0 if the entity is well formed, -1 in case of args problem and
12531  *    the parser error code otherwise
12532  */
12533
12534 static xmlParserErrors
12535 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
12536                       xmlSAXHandlerPtr sax,
12537                       void *user_data, int depth, const xmlChar *URL,
12538                       const xmlChar *ID, xmlNodePtr *list) {
12539     xmlParserCtxtPtr ctxt;
12540     xmlDocPtr newDoc;
12541     xmlNodePtr newRoot;
12542     xmlSAXHandlerPtr oldsax = NULL;
12543     xmlParserErrors ret = XML_ERR_OK;
12544     xmlChar start[4];
12545     xmlCharEncoding enc;
12546
12547     if (((depth > 40) &&
12548         ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
12549         (depth > 1024)) {
12550         return(XML_ERR_ENTITY_LOOP);
12551     }
12552
12553     if (list != NULL)
12554         *list = NULL;
12555     if ((URL == NULL) && (ID == NULL))
12556         return(XML_ERR_INTERNAL_ERROR);
12557     if (doc == NULL)
12558         return(XML_ERR_INTERNAL_ERROR);
12559
12560
12561     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
12562     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
12563     ctxt->userData = ctxt;
12564     if (oldctxt != NULL) {
12565         ctxt->_private = oldctxt->_private;
12566         ctxt->loadsubset = oldctxt->loadsubset;
12567         ctxt->validate = oldctxt->validate;
12568         ctxt->external = oldctxt->external;
12569         ctxt->record_info = oldctxt->record_info;
12570         ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
12571         ctxt->node_seq.length = oldctxt->node_seq.length;
12572         ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
12573     } else {
12574         /*
12575          * Doing validity checking on chunk without context
12576          * doesn't make sense
12577          */
12578         ctxt->_private = NULL;
12579         ctxt->validate = 0;
12580         ctxt->external = 2;
12581         ctxt->loadsubset = 0;
12582     }
12583     if (sax != NULL) {
12584         oldsax = ctxt->sax;
12585         ctxt->sax = sax;
12586         if (user_data != NULL)
12587             ctxt->userData = user_data;
12588     }
12589     xmlDetectSAX2(ctxt);
12590     newDoc = xmlNewDoc(BAD_CAST "1.0");
12591     if (newDoc == NULL) {
12592         ctxt->node_seq.maximum = 0;
12593         ctxt->node_seq.length = 0;
12594         ctxt->node_seq.buffer = NULL;
12595         xmlFreeParserCtxt(ctxt);
12596         return(XML_ERR_INTERNAL_ERROR);
12597     }
12598     newDoc->properties = XML_DOC_INTERNAL;
12599     newDoc->intSubset = doc->intSubset;
12600     newDoc->extSubset = doc->extSubset;
12601     newDoc->dict = doc->dict;
12602     xmlDictReference(newDoc->dict);
12603
12604     if (doc->URL != NULL) {
12605         newDoc->URL = xmlStrdup(doc->URL);
12606     }
12607     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
12608     if (newRoot == NULL) {
12609         if (sax != NULL)
12610             ctxt->sax = oldsax;
12611         ctxt->node_seq.maximum = 0;
12612         ctxt->node_seq.length = 0;
12613         ctxt->node_seq.buffer = NULL;
12614         xmlFreeParserCtxt(ctxt);
12615         newDoc->intSubset = NULL;
12616         newDoc->extSubset = NULL;
12617         xmlFreeDoc(newDoc);
12618         return(XML_ERR_INTERNAL_ERROR);
12619     }
12620     xmlAddChild((xmlNodePtr) newDoc, newRoot);
12621     nodePush(ctxt, newDoc->children);
12622     ctxt->myDoc = doc;
12623     newRoot->doc = doc;
12624
12625     /*
12626      * Get the 4 first bytes and decode the charset
12627      * if enc != XML_CHAR_ENCODING_NONE
12628      * plug some encoding conversion routines.
12629      */
12630     GROW;
12631     if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12632         start[0] = RAW;
12633         start[1] = NXT(1);
12634         start[2] = NXT(2);
12635         start[3] = NXT(3);
12636         enc = xmlDetectCharEncoding(start, 4);
12637         if (enc != XML_CHAR_ENCODING_NONE) {
12638             xmlSwitchEncoding(ctxt, enc);
12639         }
12640     }
12641
12642     /*
12643      * Parse a possible text declaration first
12644      */
12645     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
12646         xmlParseTextDecl(ctxt);
12647     }
12648
12649     ctxt->instate = XML_PARSER_CONTENT;
12650     ctxt->depth = depth;
12651
12652     xmlParseContent(ctxt);
12653
12654     if ((RAW == '<') && (NXT(1) == '/')) {
12655         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12656     } else if (RAW != 0) {
12657         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
12658     }
12659     if (ctxt->node != newDoc->children) {
12660         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12661     }
12662
12663     if (!ctxt->wellFormed) {
12664         if (ctxt->errNo == 0)
12665             ret = XML_ERR_INTERNAL_ERROR;
12666         else
12667             ret = (xmlParserErrors)ctxt->errNo;
12668     } else {
12669         if (list != NULL) {
12670             xmlNodePtr cur;
12671
12672             /*
12673              * Return the newly created nodeset after unlinking it from
12674              * they pseudo parent.
12675              */
12676             cur = newDoc->children->children;
12677             *list = cur;
12678             while (cur != NULL) {
12679                 cur->parent = NULL;
12680                 cur = cur->next;
12681             }
12682             newDoc->children->children = NULL;
12683         }
12684         ret = XML_ERR_OK;
12685     }
12686
12687     /*
12688      * Record in the parent context the number of entities replacement
12689      * done when parsing that reference.
12690      */
12691     if (oldctxt != NULL)
12692         oldctxt->nbentities += ctxt->nbentities;
12693
12694     /*
12695      * Also record the size of the entity parsed
12696      */
12697     if (ctxt->input != NULL) {
12698         oldctxt->sizeentities += ctxt->input->consumed;
12699         oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
12700     }
12701     /*
12702      * And record the last error if any
12703      */
12704     if (ctxt->lastError.code != XML_ERR_OK)
12705         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
12706
12707     if (sax != NULL) 
12708         ctxt->sax = oldsax;
12709     oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
12710     oldctxt->node_seq.length = ctxt->node_seq.length;
12711     oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
12712     ctxt->node_seq.maximum = 0;
12713     ctxt->node_seq.length = 0;
12714     ctxt->node_seq.buffer = NULL;
12715     xmlFreeParserCtxt(ctxt);
12716     newDoc->intSubset = NULL;
12717     newDoc->extSubset = NULL;
12718     xmlFreeDoc(newDoc);
12719
12720     return(ret);
12721 }
12722
12723 #ifdef LIBXML_SAX1_ENABLED
12724 /**
12725  * xmlParseExternalEntity:
12726  * @doc:  the document the chunk pertains to
12727  * @sax:  the SAX handler bloc (possibly NULL)
12728  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
12729  * @depth:  Used for loop detection, use 0
12730  * @URL:  the URL for the entity to load
12731  * @ID:  the System ID for the entity to load
12732  * @lst:  the return value for the set of parsed nodes
12733  *
12734  * Parse an external general entity
12735  * An external general parsed entity is well-formed if it matches the
12736  * production labeled extParsedEnt.
12737  *
12738  * [78] extParsedEnt ::= TextDecl? content
12739  *
12740  * Returns 0 if the entity is well formed, -1 in case of args problem and
12741  *    the parser error code otherwise
12742  */
12743
12744 int
12745 xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
12746           int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
12747     return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
12748                                        ID, lst));
12749 }
12750
12751 /**
12752  * xmlParseBalancedChunkMemory:
12753  * @doc:  the document the chunk pertains to
12754  * @sax:  the SAX handler bloc (possibly NULL)
12755  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
12756  * @depth:  Used for loop detection, use 0
12757  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
12758  * @lst:  the return value for the set of parsed nodes
12759  *
12760  * Parse a well-balanced chunk of an XML document
12761  * called by the parser
12762  * The allowed sequence for the Well Balanced Chunk is the one defined by
12763  * the content production in the XML grammar:
12764  *
12765  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12766  *
12767  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
12768  *    the parser error code otherwise
12769  */
12770
12771 int
12772 xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
12773      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
12774     return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
12775                                                 depth, string, lst, 0 );
12776 }
12777 #endif /* LIBXML_SAX1_ENABLED */
12778
12779 /**
12780  * xmlParseBalancedChunkMemoryInternal:
12781  * @oldctxt:  the existing parsing context
12782  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
12783  * @user_data:  the user data field for the parser context
12784  * @lst:  the return value for the set of parsed nodes
12785  *
12786  *
12787  * Parse a well-balanced chunk of an XML document
12788  * called by the parser
12789  * The allowed sequence for the Well Balanced Chunk is the one defined by
12790  * the content production in the XML grammar:
12791  *
12792  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12793  *
12794  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
12795  * error code otherwise
12796  *
12797  * In case recover is set to 1, the nodelist will not be empty even if
12798  * the parsed chunk is not well balanced.
12799  */
12800 static xmlParserErrors
12801 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
12802         const xmlChar *string, void *user_data, xmlNodePtr *lst) {
12803     xmlParserCtxtPtr ctxt;
12804     xmlDocPtr newDoc = NULL;
12805     xmlNodePtr newRoot;
12806     xmlSAXHandlerPtr oldsax = NULL;
12807     xmlNodePtr content = NULL;
12808     xmlNodePtr last = NULL;
12809     int size;
12810     xmlParserErrors ret = XML_ERR_OK;
12811 #ifdef SAX2
12812     int i;
12813 #endif
12814
12815     if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
12816         (oldctxt->depth >  1024)) {
12817         return(XML_ERR_ENTITY_LOOP);
12818     }
12819
12820
12821     if (lst != NULL)
12822         *lst = NULL;
12823     if (string == NULL)
12824         return(XML_ERR_INTERNAL_ERROR);
12825
12826     size = xmlStrlen(string);
12827
12828     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
12829     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
12830     if (user_data != NULL)
12831         ctxt->userData = user_data;
12832     else
12833         ctxt->userData = ctxt;
12834     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
12835     ctxt->dict = oldctxt->dict;
12836     ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
12837     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
12838     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
12839
12840 #ifdef SAX2
12841     /* propagate namespaces down the entity */
12842     for (i = 0;i < oldctxt->nsNr;i += 2) {
12843         nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
12844     }
12845 #endif
12846
12847     oldsax = ctxt->sax;
12848     ctxt->sax = oldctxt->sax;
12849     xmlDetectSAX2(ctxt);
12850     ctxt->replaceEntities = oldctxt->replaceEntities;
12851     ctxt->options = oldctxt->options;
12852
12853     ctxt->_private = oldctxt->_private;
12854     if (oldctxt->myDoc == NULL) {
12855         newDoc = xmlNewDoc(BAD_CAST "1.0");
12856         if (newDoc == NULL) {
12857             ctxt->sax = oldsax;
12858             ctxt->dict = NULL;
12859             xmlFreeParserCtxt(ctxt);
12860             return(XML_ERR_INTERNAL_ERROR);
12861         }
12862         newDoc->properties = XML_DOC_INTERNAL;
12863         newDoc->dict = ctxt->dict;
12864         xmlDictReference(newDoc->dict);
12865         ctxt->myDoc = newDoc;
12866     } else {
12867         ctxt->myDoc = oldctxt->myDoc;
12868         content = ctxt->myDoc->children;
12869         last = ctxt->myDoc->last;
12870     }
12871     newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
12872     if (newRoot == NULL) {
12873         ctxt->sax = oldsax;
12874         ctxt->dict = NULL;
12875         xmlFreeParserCtxt(ctxt);
12876         if (newDoc != NULL) {
12877             xmlFreeDoc(newDoc);
12878         }
12879         return(XML_ERR_INTERNAL_ERROR);
12880     }
12881     ctxt->myDoc->children = NULL;
12882     ctxt->myDoc->last = NULL;
12883     xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
12884     nodePush(ctxt, ctxt->myDoc->children);
12885     ctxt->instate = XML_PARSER_CONTENT;
12886     ctxt->depth = oldctxt->depth + 1;
12887
12888     ctxt->validate = 0;
12889     ctxt->loadsubset = oldctxt->loadsubset;
12890     if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
12891         /*
12892          * ID/IDREF registration will be done in xmlValidateElement below
12893          */
12894         ctxt->loadsubset |= XML_SKIP_IDS;
12895     }
12896     ctxt->dictNames = oldctxt->dictNames;
12897     ctxt->attsDefault = oldctxt->attsDefault;
12898     ctxt->attsSpecial = oldctxt->attsSpecial;
12899
12900     xmlParseContent(ctxt);
12901     if ((RAW == '<') && (NXT(1) == '/')) {
12902         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12903     } else if (RAW != 0) {
12904         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
12905     }
12906     if (ctxt->node != ctxt->myDoc->children) {
12907         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12908     }
12909
12910     if (!ctxt->wellFormed) {
12911         if (ctxt->errNo == 0)
12912             ret = XML_ERR_INTERNAL_ERROR;
12913         else
12914             ret = (xmlParserErrors)ctxt->errNo;
12915     } else {
12916       ret = XML_ERR_OK;
12917     }
12918
12919     if ((lst != NULL) && (ret == XML_ERR_OK)) {
12920         xmlNodePtr cur;
12921
12922         /*
12923          * Return the newly created nodeset after unlinking it from
12924          * they pseudo parent.
12925          */
12926         cur = ctxt->myDoc->children->children;
12927         *lst = cur;
12928         while (cur != NULL) {
12929 #ifdef LIBXML_VALID_ENABLED
12930             if ((oldctxt->validate) && (oldctxt->wellFormed) &&
12931                 (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
12932                 (cur->type == XML_ELEMENT_NODE)) {
12933                 oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
12934                         oldctxt->myDoc, cur);
12935             }
12936 #endif /* LIBXML_VALID_ENABLED */
12937             cur->parent = NULL;
12938             cur = cur->next;
12939         }
12940         ctxt->myDoc->children->children = NULL;
12941     }
12942     if (ctxt->myDoc != NULL) {
12943         xmlFreeNode(ctxt->myDoc->children);
12944         ctxt->myDoc->children = content;
12945         ctxt->myDoc->last = last;
12946     }
12947
12948     /*
12949      * Record in the parent context the number of entities replacement
12950      * done when parsing that reference.
12951      */
12952     if (oldctxt != NULL)
12953         oldctxt->nbentities += ctxt->nbentities;
12954
12955     /*
12956      * Also record the last error if any
12957      */
12958     if (ctxt->lastError.code != XML_ERR_OK)
12959         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
12960
12961     ctxt->sax = oldsax;
12962     ctxt->dict = NULL;
12963     ctxt->attsDefault = NULL;
12964     ctxt->attsSpecial = NULL;
12965     xmlFreeParserCtxt(ctxt);
12966     if (newDoc != NULL) {
12967         xmlFreeDoc(newDoc);
12968     }
12969
12970     return(ret);
12971 }
12972
12973 /**
12974  * xmlParseInNodeContext:
12975  * @node:  the context node
12976  * @data:  the input string
12977  * @datalen:  the input string length in bytes
12978  * @options:  a combination of xmlParserOption
12979  * @lst:  the return value for the set of parsed nodes
12980  *
12981  * Parse a well-balanced chunk of an XML document
12982  * within the context (DTD, namespaces, etc ...) of the given node.
12983  *
12984  * The allowed sequence for the data is a Well Balanced Chunk defined by
12985  * the content production in the XML grammar:
12986  *
12987  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12988  *
12989  * Returns XML_ERR_OK if the chunk is well balanced, and the parser
12990  * error code otherwise
12991  */
12992 xmlParserErrors
12993 xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
12994                       int options, xmlNodePtr *lst) {
12995 #ifdef SAX2
12996     xmlParserCtxtPtr ctxt;
12997     xmlDocPtr doc = NULL;
12998     xmlNodePtr fake, cur;
12999     int nsnr = 0;
13000
13001     xmlParserErrors ret = XML_ERR_OK;
13002
13003     /*
13004      * check all input parameters, grab the document
13005      */
13006     if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
13007         return(XML_ERR_INTERNAL_ERROR);
13008     switch (node->type) {
13009         case XML_ELEMENT_NODE:
13010         case XML_ATTRIBUTE_NODE:
13011         case XML_TEXT_NODE:
13012         case XML_CDATA_SECTION_NODE:
13013         case XML_ENTITY_REF_NODE:
13014         case XML_PI_NODE:
13015         case XML_COMMENT_NODE:
13016         case XML_DOCUMENT_NODE:
13017         case XML_HTML_DOCUMENT_NODE:
13018             break;
13019         default:
13020             return(XML_ERR_INTERNAL_ERROR);
13021
13022     }
13023     while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
13024            (node->type != XML_DOCUMENT_NODE) &&
13025            (node->type != XML_HTML_DOCUMENT_NODE))
13026         node = node->parent;
13027     if (node == NULL)
13028         return(XML_ERR_INTERNAL_ERROR);
13029     if (node->type == XML_ELEMENT_NODE)
13030         doc = node->doc;
13031     else
13032         doc = (xmlDocPtr) node;
13033     if (doc == NULL)
13034         return(XML_ERR_INTERNAL_ERROR);
13035
13036     /*
13037      * allocate a context and set-up everything not related to the
13038      * node position in the tree
13039      */
13040     if (doc->type == XML_DOCUMENT_NODE)
13041         ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
13042 #ifdef LIBXML_HTML_ENABLED
13043     else if (doc->type == XML_HTML_DOCUMENT_NODE) {
13044         ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
13045         /*
13046          * When parsing in context, it makes no sense to add implied
13047          * elements like html/body/etc...
13048          */
13049         options |= HTML_PARSE_NOIMPLIED;
13050     }
13051 #endif
13052     else
13053         return(XML_ERR_INTERNAL_ERROR);
13054
13055     if (ctxt == NULL)
13056         return(XML_ERR_NO_MEMORY);
13057
13058     /*
13059      * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
13060      * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
13061      * we must wait until the last moment to free the original one.
13062      */
13063     if (doc->dict != NULL) {
13064         if (ctxt->dict != NULL)
13065             xmlDictFree(ctxt->dict);
13066         ctxt->dict = doc->dict;
13067     } else
13068         options |= XML_PARSE_NODICT;
13069
13070     if (doc->encoding != NULL) {
13071         xmlCharEncodingHandlerPtr hdlr;
13072
13073         if (ctxt->encoding != NULL)
13074             xmlFree((xmlChar *) ctxt->encoding);
13075         ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
13076
13077         hdlr = xmlFindCharEncodingHandler(doc->encoding);
13078         if (hdlr != NULL) {
13079             xmlSwitchToEncoding(ctxt, hdlr);
13080         } else {
13081             return(XML_ERR_UNSUPPORTED_ENCODING);
13082         }
13083     }
13084
13085     xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13086     xmlDetectSAX2(ctxt);
13087     ctxt->myDoc = doc;
13088
13089     fake = xmlNewComment(NULL);
13090     if (fake == NULL) {
13091         xmlFreeParserCtxt(ctxt);
13092         return(XML_ERR_NO_MEMORY);
13093     }
13094     xmlAddChild(node, fake);
13095
13096     if (node->type == XML_ELEMENT_NODE) {
13097         nodePush(ctxt, node);
13098         /*
13099          * initialize the SAX2 namespaces stack
13100          */
13101         cur = node;
13102         while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
13103             xmlNsPtr ns = cur->nsDef;
13104             const xmlChar *iprefix, *ihref;
13105
13106             while (ns != NULL) {
13107                 if (ctxt->dict) {
13108                     iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
13109                     ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
13110                 } else {
13111                     iprefix = ns->prefix;
13112                     ihref = ns->href;
13113                 }
13114
13115                 if (xmlGetNamespace(ctxt, iprefix) == NULL) {
13116                     nsPush(ctxt, iprefix, ihref);
13117                     nsnr++;
13118                 }
13119                 ns = ns->next;
13120             }
13121             cur = cur->parent;
13122         }
13123         ctxt->instate = XML_PARSER_CONTENT;
13124     }
13125
13126     if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
13127         /*
13128          * ID/IDREF registration will be done in xmlValidateElement below
13129          */
13130         ctxt->loadsubset |= XML_SKIP_IDS;
13131     }
13132
13133 #ifdef LIBXML_HTML_ENABLED
13134     if (doc->type == XML_HTML_DOCUMENT_NODE)
13135         __htmlParseContent(ctxt);
13136     else
13137 #endif
13138         xmlParseContent(ctxt);
13139
13140     nsPop(ctxt, nsnr);
13141     if ((RAW == '<') && (NXT(1) == '/')) {
13142         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13143     } else if (RAW != 0) {
13144         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13145     }
13146     if ((ctxt->node != NULL) && (ctxt->node != node)) {
13147         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13148         ctxt->wellFormed = 0;
13149     }
13150
13151     if (!ctxt->wellFormed) {
13152         if (ctxt->errNo == 0)
13153             ret = XML_ERR_INTERNAL_ERROR;
13154         else
13155             ret = (xmlParserErrors)ctxt->errNo;
13156     } else {
13157         ret = XML_ERR_OK;
13158     }
13159
13160     /*
13161      * Return the newly created nodeset after unlinking it from
13162      * the pseudo sibling.
13163      */
13164
13165     cur = fake->next;
13166     fake->next = NULL;
13167     node->last = fake;
13168
13169     if (cur != NULL) {
13170         cur->prev = NULL;
13171     }
13172
13173     *lst = cur;
13174
13175     while (cur != NULL) {
13176         cur->parent = NULL;
13177         cur = cur->next;
13178     }
13179
13180     xmlUnlinkNode(fake);
13181     xmlFreeNode(fake);
13182
13183
13184     if (ret != XML_ERR_OK) {
13185         xmlFreeNodeList(*lst);
13186         *lst = NULL;
13187     }
13188
13189     if (doc->dict != NULL)
13190         ctxt->dict = NULL;
13191     xmlFreeParserCtxt(ctxt);
13192
13193     return(ret);
13194 #else /* !SAX2 */
13195     return(XML_ERR_INTERNAL_ERROR);
13196 #endif
13197 }
13198
13199 #ifdef LIBXML_SAX1_ENABLED
13200 /**
13201  * xmlParseBalancedChunkMemoryRecover:
13202  * @doc:  the document the chunk pertains to
13203  * @sax:  the SAX handler bloc (possibly NULL)
13204  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13205  * @depth:  Used for loop detection, use 0
13206  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13207  * @lst:  the return value for the set of parsed nodes
13208  * @recover: return nodes even if the data is broken (use 0)
13209  *
13210  *
13211  * Parse a well-balanced chunk of an XML document
13212  * called by the parser
13213  * The allowed sequence for the Well Balanced Chunk is the one defined by
13214  * the content production in the XML grammar:
13215  *
13216  * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13217  *
13218  * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13219  *    the parser error code otherwise
13220  *
13221  * In case recover is set to 1, the nodelist will not be empty even if
13222  * the parsed chunk is not well balanced, assuming the parsing succeeded to
13223  * some extent.
13224  */
13225 int
13226 xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13227      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
13228      int recover) {
13229     xmlParserCtxtPtr ctxt;
13230     xmlDocPtr newDoc;
13231     xmlSAXHandlerPtr oldsax = NULL;
13232     xmlNodePtr content, newRoot;
13233     int size;
13234     int ret = 0;
13235
13236     if (depth > 40) {
13237         return(XML_ERR_ENTITY_LOOP);
13238     }
13239
13240
13241     if (lst != NULL)
13242         *lst = NULL;
13243     if (string == NULL)
13244         return(-1);
13245
13246     size = xmlStrlen(string);
13247
13248     ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13249     if (ctxt == NULL) return(-1);
13250     ctxt->userData = ctxt;
13251     if (sax != NULL) {
13252         oldsax = ctxt->sax;
13253         ctxt->sax = sax;
13254         if (user_data != NULL)
13255             ctxt->userData = user_data;
13256     }
13257     newDoc = xmlNewDoc(BAD_CAST "1.0");
13258     if (newDoc == NULL) {
13259         xmlFreeParserCtxt(ctxt);
13260         return(-1);
13261     }
13262     newDoc->properties = XML_DOC_INTERNAL;
13263     if ((doc != NULL) && (doc->dict != NULL)) {
13264         xmlDictFree(ctxt->dict);
13265         ctxt->dict = doc->dict;
13266         xmlDictReference(ctxt->dict);
13267         ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13268         ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13269         ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13270         ctxt->dictNames = 1;
13271     } else {
13272         xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
13273     }
13274     if (doc != NULL) {
13275         newDoc->intSubset = doc->intSubset;
13276         newDoc->extSubset = doc->extSubset;
13277     }
13278     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13279     if (newRoot == NULL) {
13280         if (sax != NULL)
13281             ctxt->sax = oldsax;
13282         xmlFreeParserCtxt(ctxt);
13283         newDoc->intSubset = NULL;
13284         newDoc->extSubset = NULL;
13285         xmlFreeDoc(newDoc);
13286         return(-1);
13287     }
13288     xmlAddChild((xmlNodePtr) newDoc, newRoot);
13289     nodePush(ctxt, newRoot);
13290     if (doc == NULL) {
13291         ctxt->myDoc = newDoc;
13292     } else {
13293         ctxt->myDoc = newDoc;
13294         newDoc->children->doc = doc;
13295         /* Ensure that doc has XML spec namespace */
13296         xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
13297         newDoc->oldNs = doc->oldNs;
13298     }
13299     ctxt->instate = XML_PARSER_CONTENT;
13300     ctxt->depth = depth;
13301
13302     /*
13303      * Doing validity checking on chunk doesn't make sense
13304      */
13305     ctxt->validate = 0;
13306     ctxt->loadsubset = 0;
13307     xmlDetectSAX2(ctxt);
13308
13309     if ( doc != NULL ){
13310         content = doc->children;
13311         doc->children = NULL;
13312         xmlParseContent(ctxt);
13313         doc->children = content;
13314     }
13315     else {
13316         xmlParseContent(ctxt);
13317     }
13318     if ((RAW == '<') && (NXT(1) == '/')) {
13319         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13320     } else if (RAW != 0) {
13321         xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13322     }
13323     if (ctxt->node != newDoc->children) {
13324         xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13325     }
13326
13327     if (!ctxt->wellFormed) {
13328         if (ctxt->errNo == 0)
13329             ret = 1;
13330         else
13331             ret = ctxt->errNo;
13332     } else {
13333       ret = 0;
13334     }
13335
13336     if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
13337         xmlNodePtr cur;
13338
13339         /*
13340          * Return the newly created nodeset after unlinking it from
13341          * they pseudo parent.
13342          */
13343         cur = newDoc->children->children;
13344         *lst = cur;
13345         while (cur != NULL) {
13346             xmlSetTreeDoc(cur, doc);
13347             cur->parent = NULL;
13348             cur = cur->next;
13349         }
13350         newDoc->children->children = NULL;
13351     }
13352
13353     if (sax != NULL)
13354         ctxt->sax = oldsax;
13355     xmlFreeParserCtxt(ctxt);
13356     newDoc->intSubset = NULL;
13357     newDoc->extSubset = NULL;
13358     newDoc->oldNs = NULL;
13359     xmlFreeDoc(newDoc);
13360
13361     return(ret);
13362 }
13363
13364 /**
13365  * xmlSAXParseEntity:
13366  * @sax:  the SAX handler block
13367  * @filename:  the filename
13368  *
13369  * parse an XML external entity out of context and build a tree.
13370  * It use the given SAX function block to handle the parsing callback.
13371  * If sax is NULL, fallback to the default DOM tree building routines.
13372  *
13373  * [78] extParsedEnt ::= TextDecl? content
13374  *
13375  * This correspond to a "Well Balanced" chunk
13376  *
13377  * Returns the resulting document tree
13378  */
13379
13380 xmlDocPtr
13381 xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
13382     xmlDocPtr ret;
13383     xmlParserCtxtPtr ctxt;
13384
13385     ctxt = xmlCreateFileParserCtxt(filename);
13386     if (ctxt == NULL) {
13387         return(NULL);
13388     }
13389     if (sax != NULL) {
13390         if (ctxt->sax != NULL)
13391             xmlFree(ctxt->sax);
13392         ctxt->sax = sax;
13393         ctxt->userData = NULL;
13394     }
13395
13396     xmlParseExtParsedEnt(ctxt);
13397
13398     if (ctxt->wellFormed)
13399         ret = ctxt->myDoc;
13400     else {
13401         ret = NULL;
13402         xmlFreeDoc(ctxt->myDoc);
13403         ctxt->myDoc = NULL;
13404     }
13405     if (sax != NULL)
13406         ctxt->sax = NULL;
13407     xmlFreeParserCtxt(ctxt);
13408
13409     return(ret);
13410 }
13411
13412 /**
13413  * xmlParseEntity:
13414  * @filename:  the filename
13415  *
13416  * parse an XML external entity out of context and build a tree.
13417  *
13418  * [78] extParsedEnt ::= TextDecl? content
13419  *
13420  * This correspond to a "Well Balanced" chunk
13421  *
13422  * Returns the resulting document tree
13423  */
13424
13425 xmlDocPtr
13426 xmlParseEntity(const char *filename) {
13427     return(xmlSAXParseEntity(NULL, filename));
13428 }
13429 #endif /* LIBXML_SAX1_ENABLED */
13430
13431 /**
13432  * xmlCreateEntityParserCtxtInternal:
13433  * @URL:  the entity URL
13434  * @ID:  the entity PUBLIC ID
13435  * @base:  a possible base for the target URI
13436  * @pctx:  parser context used to set options on new context
13437  *
13438  * Create a parser context for an external entity
13439  * Automatic support for ZLIB/Compress compressed document is provided
13440  * by default if found at compile-time.
13441  *
13442  * Returns the new parser context or NULL
13443  */
13444 static xmlParserCtxtPtr
13445 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
13446                           const xmlChar *base, xmlParserCtxtPtr pctx) {
13447     xmlParserCtxtPtr ctxt;
13448     xmlParserInputPtr inputStream;
13449     char *directory = NULL;
13450     xmlChar *uri;
13451
13452     ctxt = xmlNewParserCtxt();
13453     if (ctxt == NULL) {
13454         return(NULL);
13455     }
13456
13457     if (pctx != NULL) {
13458         ctxt->options = pctx->options;
13459         ctxt->_private = pctx->_private;
13460     }
13461
13462     uri = xmlBuildURI(URL, base);
13463
13464     if (uri == NULL) {
13465         inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
13466         if (inputStream == NULL) {
13467             xmlFreeParserCtxt(ctxt);
13468             return(NULL);
13469         }
13470
13471         inputPush(ctxt, inputStream);
13472
13473         if ((ctxt->directory == NULL) && (directory == NULL))
13474             directory = xmlParserGetDirectory((char *)URL);
13475         if ((ctxt->directory == NULL) && (directory != NULL))
13476             ctxt->directory = directory;
13477     } else {
13478         inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
13479         if (inputStream == NULL) {
13480             xmlFree(uri);
13481             xmlFreeParserCtxt(ctxt);
13482             return(NULL);
13483         }
13484
13485         inputPush(ctxt, inputStream);
13486
13487         if ((ctxt->directory == NULL) && (directory == NULL))
13488             directory = xmlParserGetDirectory((char *)uri);
13489         if ((ctxt->directory == NULL) && (directory != NULL))
13490             ctxt->directory = directory;
13491         xmlFree(uri);
13492     }
13493     return(ctxt);
13494 }
13495
13496 /**
13497  * xmlCreateEntityParserCtxt:
13498  * @URL:  the entity URL
13499  * @ID:  the entity PUBLIC ID
13500  * @base:  a possible base for the target URI
13501  *
13502  * Create a parser context for an external entity
13503  * Automatic support for ZLIB/Compress compressed document is provided
13504  * by default if found at compile-time.
13505  *
13506  * Returns the new parser context or NULL
13507  */
13508 xmlParserCtxtPtr
13509 xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
13510                           const xmlChar *base) {
13511     return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
13512
13513 }
13514
13515 /************************************************************************
13516  *                                                                      *
13517  *              Front ends when parsing from a file                     *
13518  *                                                                      *
13519  ************************************************************************/
13520
13521 /**
13522  * xmlCreateURLParserCtxt:
13523  * @filename:  the filename or URL
13524  * @options:  a combination of xmlParserOption
13525  *
13526  * Create a parser context for a file or URL content. 
13527  * Automatic support for ZLIB/Compress compressed document is provided
13528  * by default if found at compile-time and for file accesses
13529  *
13530  * Returns the new parser context or NULL
13531  */
13532 xmlParserCtxtPtr
13533 xmlCreateURLParserCtxt(const char *filename, int options)
13534 {
13535     xmlParserCtxtPtr ctxt;
13536     xmlParserInputPtr inputStream;
13537     char *directory = NULL;
13538
13539     ctxt = xmlNewParserCtxt();
13540     if (ctxt == NULL) {
13541         xmlErrMemory(NULL, "cannot allocate parser context");
13542         return(NULL);
13543     }
13544
13545     if (options)
13546         xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13547     ctxt->linenumbers = 1;
13548
13549     inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
13550     if (inputStream == NULL) {
13551         xmlFreeParserCtxt(ctxt);
13552         return(NULL);
13553     }
13554
13555     inputPush(ctxt, inputStream);
13556     if ((ctxt->directory == NULL) && (directory == NULL))
13557         directory = xmlParserGetDirectory(filename);
13558     if ((ctxt->directory == NULL) && (directory != NULL))
13559         ctxt->directory = directory;
13560
13561     return(ctxt);
13562 }
13563
13564 /**
13565  * xmlCreateFileParserCtxt:
13566  * @filename:  the filename
13567  *
13568  * Create a parser context for a file content. 
13569  * Automatic support for ZLIB/Compress compressed document is provided
13570  * by default if found at compile-time.
13571  *
13572  * Returns the new parser context or NULL
13573  */
13574 xmlParserCtxtPtr
13575 xmlCreateFileParserCtxt(const char *filename)
13576 {
13577     return(xmlCreateURLParserCtxt(filename, 0));
13578 }
13579
13580 #ifdef LIBXML_SAX1_ENABLED
13581 /**
13582  * xmlSAXParseFileWithData:
13583  * @sax:  the SAX handler block
13584  * @filename:  the filename
13585  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
13586  *             documents
13587  * @data:  the userdata
13588  *
13589  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13590  * compressed document is provided by default if found at compile-time.
13591  * It use the given SAX function block to handle the parsing callback.
13592  * If sax is NULL, fallback to the default DOM tree building routines.
13593  *
13594  * User data (void *) is stored within the parser context in the
13595  * context's _private member, so it is available nearly everywhere in libxml
13596  *
13597  * Returns the resulting document tree
13598  */
13599
13600 xmlDocPtr
13601 xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
13602                         int recovery, void *data) {
13603     xmlDocPtr ret;
13604     xmlParserCtxtPtr ctxt;
13605
13606     xmlInitParser();
13607
13608     ctxt = xmlCreateFileParserCtxt(filename);
13609     if (ctxt == NULL) {
13610         return(NULL);
13611     }
13612     if (sax != NULL) {
13613         if (ctxt->sax != NULL)
13614             xmlFree(ctxt->sax);
13615         ctxt->sax = sax;
13616     }
13617     xmlDetectSAX2(ctxt);
13618     if (data!=NULL) {
13619         ctxt->_private = data;
13620     }
13621
13622     if (ctxt->directory == NULL)
13623         ctxt->directory = xmlParserGetDirectory(filename);
13624
13625     ctxt->recovery = recovery;
13626
13627     xmlParseDocument(ctxt);
13628
13629     if ((ctxt->wellFormed) || recovery) {
13630         ret = ctxt->myDoc;
13631         if (ret != NULL) {
13632             if (ctxt->input->buf->compressed > 0)
13633                 ret->compression = 9;
13634             else
13635                 ret->compression = ctxt->input->buf->compressed;
13636         }
13637     }
13638     else {
13639        ret = NULL;
13640        xmlFreeDoc(ctxt->myDoc);
13641        ctxt->myDoc = NULL;
13642     }
13643     if (sax != NULL)
13644         ctxt->sax = NULL;
13645     xmlFreeParserCtxt(ctxt);
13646     
13647     return(ret);
13648 }
13649
13650 /**
13651  * xmlSAXParseFile:
13652  * @sax:  the SAX handler block
13653  * @filename:  the filename
13654  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
13655  *             documents
13656  *
13657  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13658  * compressed document is provided by default if found at compile-time.
13659  * It use the given SAX function block to handle the parsing callback.
13660  * If sax is NULL, fallback to the default DOM tree building routines.
13661  *
13662  * Returns the resulting document tree
13663  */
13664
13665 xmlDocPtr
13666 xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
13667                           int recovery) {
13668     return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
13669 }
13670
13671 /**
13672  * xmlRecoverDoc:
13673  * @cur:  a pointer to an array of xmlChar
13674  *
13675  * parse an XML in-memory document and build a tree.
13676  * In the case the document is not Well Formed, a attempt to build a
13677  * tree is tried anyway
13678  *
13679  * Returns the resulting document tree or NULL in case of failure
13680  */
13681
13682 xmlDocPtr
13683 xmlRecoverDoc(const xmlChar *cur) {
13684     return(xmlSAXParseDoc(NULL, cur, 1));
13685 }
13686
13687 /**
13688  * xmlParseFile:
13689  * @filename:  the filename
13690  *
13691  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13692  * compressed document is provided by default if found at compile-time.
13693  *
13694  * Returns the resulting document tree if the file was wellformed,
13695  * NULL otherwise.
13696  */
13697
13698 xmlDocPtr
13699 xmlParseFile(const char *filename) {
13700     return(xmlSAXParseFile(NULL, filename, 0));
13701 }
13702
13703 /**
13704  * xmlRecoverFile:
13705  * @filename:  the filename
13706  *
13707  * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13708  * compressed document is provided by default if found at compile-time.
13709  * In the case the document is not Well Formed, it attempts to build
13710  * a tree anyway
13711  *
13712  * Returns the resulting document tree or NULL in case of failure
13713  */
13714
13715 xmlDocPtr
13716 xmlRecoverFile(const char *filename) {
13717     return(xmlSAXParseFile(NULL, filename, 1));
13718 }
13719
13720
13721 /**
13722  * xmlSetupParserForBuffer:
13723  * @ctxt:  an XML parser context
13724  * @buffer:  a xmlChar * buffer
13725  * @filename:  a file name
13726  *
13727  * Setup the parser context to parse a new buffer; Clears any prior
13728  * contents from the parser context. The buffer parameter must not be
13729  * NULL, but the filename parameter can be
13730  */
13731 void
13732 xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
13733                              const char* filename)
13734 {
13735     xmlParserInputPtr input;
13736
13737     if ((ctxt == NULL) || (buffer == NULL))
13738         return;
13739
13740     input = xmlNewInputStream(ctxt);
13741     if (input == NULL) {
13742         xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
13743         xmlClearParserCtxt(ctxt);
13744         return;
13745     }
13746   
13747     xmlClearParserCtxt(ctxt);
13748     if (filename != NULL)
13749         input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
13750     input->base = buffer;
13751     input->cur = buffer;
13752     input->end = &buffer[xmlStrlen(buffer)];
13753     inputPush(ctxt, input);
13754 }
13755
13756 /**
13757  * xmlSAXUserParseFile:
13758  * @sax:  a SAX handler
13759  * @user_data:  The user data returned on SAX callbacks
13760  * @filename:  a file name
13761  *
13762  * parse an XML file and call the given SAX handler routines.
13763  * Automatic support for ZLIB/Compress compressed document is provided
13764  * 
13765  * Returns 0 in case of success or a error number otherwise
13766  */
13767 int
13768 xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
13769                     const char *filename) {
13770     int ret = 0;
13771     xmlParserCtxtPtr ctxt;
13772     
13773     ctxt = xmlCreateFileParserCtxt(filename);
13774     if (ctxt == NULL) return -1;
13775     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
13776         xmlFree(ctxt->sax);
13777     ctxt->sax = sax;
13778     xmlDetectSAX2(ctxt);
13779
13780     if (user_data != NULL)
13781         ctxt->userData = user_data;
13782     
13783     xmlParseDocument(ctxt);
13784     
13785     if (ctxt->wellFormed)
13786         ret = 0;
13787     else {
13788         if (ctxt->errNo != 0)
13789             ret = ctxt->errNo;
13790         else
13791             ret = -1;
13792     }
13793     if (sax != NULL)
13794         ctxt->sax = NULL;
13795     if (ctxt->myDoc != NULL) {
13796         xmlFreeDoc(ctxt->myDoc);
13797         ctxt->myDoc = NULL;
13798     }
13799     xmlFreeParserCtxt(ctxt);
13800     
13801     return ret;
13802 }
13803 #endif /* LIBXML_SAX1_ENABLED */
13804
13805 /************************************************************************
13806  *                                                                      *
13807  *              Front ends when parsing from memory                     *
13808  *                                                                      *
13809  ************************************************************************/
13810
13811 /**
13812  * xmlCreateMemoryParserCtxt:
13813  * @buffer:  a pointer to a char array
13814  * @size:  the size of the array
13815  *
13816  * Create a parser context for an XML in-memory document.
13817  *
13818  * Returns the new parser context or NULL
13819  */
13820 xmlParserCtxtPtr
13821 xmlCreateMemoryParserCtxt(const char *buffer, int size) {
13822     xmlParserCtxtPtr ctxt;
13823     xmlParserInputPtr input;
13824     xmlParserInputBufferPtr buf;
13825
13826     if (buffer == NULL)
13827         return(NULL);
13828     if (size <= 0)
13829         return(NULL);
13830
13831     ctxt = xmlNewParserCtxt();
13832     if (ctxt == NULL)
13833         return(NULL);
13834
13835     /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
13836     buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
13837     if (buf == NULL) {
13838         xmlFreeParserCtxt(ctxt);
13839         return(NULL);
13840     }
13841
13842     input = xmlNewInputStream(ctxt);
13843     if (input == NULL) {
13844         xmlFreeParserInputBuffer(buf);
13845         xmlFreeParserCtxt(ctxt);
13846         return(NULL);
13847     }
13848
13849     input->filename = NULL;
13850     input->buf = buf;
13851     input->base = input->buf->buffer->content;
13852     input->cur = input->buf->buffer->content;
13853     input->end = &input->buf->buffer->content[input->buf->buffer->use];
13854
13855     inputPush(ctxt, input);
13856     return(ctxt);
13857 }
13858
13859 #ifdef LIBXML_SAX1_ENABLED
13860 /**
13861  * xmlSAXParseMemoryWithData:
13862  * @sax:  the SAX handler block
13863  * @buffer:  an pointer to a char array
13864  * @size:  the size of the array
13865  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
13866  *             documents
13867  * @data:  the userdata
13868  *
13869  * parse an XML in-memory block and use the given SAX function block
13870  * to handle the parsing callback. If sax is NULL, fallback to the default
13871  * DOM tree building routines.
13872  *
13873  * User data (void *) is stored within the parser context in the
13874  * context's _private member, so it is available nearly everywhere in libxml
13875  *
13876  * Returns the resulting document tree
13877  */
13878
13879 xmlDocPtr
13880 xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
13881                   int size, int recovery, void *data) {
13882     xmlDocPtr ret;
13883     xmlParserCtxtPtr ctxt;
13884
13885     xmlInitParser();
13886
13887     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
13888     if (ctxt == NULL) return(NULL);
13889     if (sax != NULL) {
13890         if (ctxt->sax != NULL)
13891             xmlFree(ctxt->sax);
13892         ctxt->sax = sax;
13893     }
13894     xmlDetectSAX2(ctxt);
13895     if (data!=NULL) {
13896         ctxt->_private=data;
13897     }
13898
13899     ctxt->recovery = recovery;
13900
13901     xmlParseDocument(ctxt);
13902
13903     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
13904     else {
13905        ret = NULL;
13906        xmlFreeDoc(ctxt->myDoc);
13907        ctxt->myDoc = NULL;
13908     }
13909     if (sax != NULL) 
13910         ctxt->sax = NULL;
13911     xmlFreeParserCtxt(ctxt);
13912
13913     return(ret);
13914 }
13915
13916 /**
13917  * xmlSAXParseMemory:
13918  * @sax:  the SAX handler block
13919  * @buffer:  an pointer to a char array
13920  * @size:  the size of the array
13921  * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
13922  *             documents
13923  *
13924  * parse an XML in-memory block and use the given SAX function block
13925  * to handle the parsing callback. If sax is NULL, fallback to the default
13926  * DOM tree building routines.
13927  * 
13928  * Returns the resulting document tree
13929  */
13930 xmlDocPtr
13931 xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
13932                   int size, int recovery) {
13933     return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
13934 }
13935
13936 /**
13937  * xmlParseMemory:
13938  * @buffer:  an pointer to a char array
13939  * @size:  the size of the array
13940  *
13941  * parse an XML in-memory block and build a tree.
13942  * 
13943  * Returns the resulting document tree
13944  */
13945
13946 xmlDocPtr xmlParseMemory(const char *buffer, int size) {
13947    return(xmlSAXParseMemory(NULL, buffer, size, 0));
13948 }
13949
13950 /**
13951  * xmlRecoverMemory:
13952  * @buffer:  an pointer to a char array
13953  * @size:  the size of the array
13954  *
13955  * parse an XML in-memory block and build a tree.
13956  * In the case the document is not Well Formed, an attempt to
13957  * build a tree is tried anyway
13958  *
13959  * Returns the resulting document tree or NULL in case of error
13960  */
13961
13962 xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
13963    return(xmlSAXParseMemory(NULL, buffer, size, 1));
13964 }
13965
13966 /**
13967  * xmlSAXUserParseMemory:
13968  * @sax:  a SAX handler
13969  * @user_data:  The user data returned on SAX callbacks
13970  * @buffer:  an in-memory XML document input
13971  * @size:  the length of the XML document in bytes
13972  *
13973  * A better SAX parsing routine.
13974  * parse an XML in-memory buffer and call the given SAX handler routines.
13975  *
13976  * Returns 0 in case of success or a error number otherwise
13977  */
13978 int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
13979                           const char *buffer, int size) {
13980     int ret = 0;
13981     xmlParserCtxtPtr ctxt;
13982
13983     xmlInitParser();
13984
13985     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
13986     if (ctxt == NULL) return -1;
13987     if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
13988         xmlFree(ctxt->sax);
13989     ctxt->sax = sax;
13990     xmlDetectSAX2(ctxt);
13991
13992     if (user_data != NULL)
13993         ctxt->userData = user_data;
13994
13995     xmlParseDocument(ctxt);
13996     
13997     if (ctxt->wellFormed)
13998         ret = 0;
13999     else {
14000         if (ctxt->errNo != 0)
14001             ret = ctxt->errNo;
14002         else
14003             ret = -1;
14004     }
14005     if (sax != NULL)
14006         ctxt->sax = NULL;
14007     if (ctxt->myDoc != NULL) {
14008         xmlFreeDoc(ctxt->myDoc);
14009         ctxt->myDoc = NULL;
14010     }
14011     xmlFreeParserCtxt(ctxt);
14012     
14013     return ret;
14014 }
14015 #endif /* LIBXML_SAX1_ENABLED */
14016
14017 /**
14018  * xmlCreateDocParserCtxt:
14019  * @cur:  a pointer to an array of xmlChar
14020  *
14021  * Creates a parser context for an XML in-memory document.
14022  *
14023  * Returns the new parser context or NULL
14024  */
14025 xmlParserCtxtPtr
14026 xmlCreateDocParserCtxt(const xmlChar *cur) {
14027     int len;
14028
14029     if (cur == NULL)
14030         return(NULL);
14031     len = xmlStrlen(cur);
14032     return(xmlCreateMemoryParserCtxt((const char *)cur, len));
14033 }
14034
14035 #ifdef LIBXML_SAX1_ENABLED
14036 /**
14037  * xmlSAXParseDoc:
14038  * @sax:  the SAX handler block
14039  * @cur:  a pointer to an array of xmlChar
14040  * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14041  *             documents
14042  *
14043  * parse an XML in-memory document and build a tree.
14044  * It use the given SAX function block to handle the parsing callback.
14045  * If sax is NULL, fallback to the default DOM tree building routines.
14046  * 
14047  * Returns the resulting document tree
14048  */
14049
14050 xmlDocPtr
14051 xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
14052     xmlDocPtr ret;
14053     xmlParserCtxtPtr ctxt;
14054     xmlSAXHandlerPtr oldsax = NULL;
14055
14056     if (cur == NULL) return(NULL);
14057
14058
14059     ctxt = xmlCreateDocParserCtxt(cur);
14060     if (ctxt == NULL) return(NULL);
14061     if (sax != NULL) { 
14062         oldsax = ctxt->sax;
14063         ctxt->sax = sax;
14064         ctxt->userData = NULL;
14065     }
14066     xmlDetectSAX2(ctxt);
14067
14068     xmlParseDocument(ctxt);
14069     if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14070     else {
14071        ret = NULL;
14072        xmlFreeDoc(ctxt->myDoc);
14073        ctxt->myDoc = NULL;
14074     }
14075     if (sax != NULL)
14076         ctxt->sax = oldsax;
14077     xmlFreeParserCtxt(ctxt);
14078     
14079     return(ret);
14080 }
14081
14082 /**
14083  * xmlParseDoc:
14084  * @cur:  a pointer to an array of xmlChar
14085  *
14086  * parse an XML in-memory document and build a tree.
14087  * 
14088  * Returns the resulting document tree
14089  */
14090
14091 xmlDocPtr
14092 xmlParseDoc(const xmlChar *cur) {
14093     return(xmlSAXParseDoc(NULL, cur, 0));
14094 }
14095 #endif /* LIBXML_SAX1_ENABLED */
14096
14097 #ifdef LIBXML_LEGACY_ENABLED
14098 /************************************************************************
14099  *                                                                      *
14100  *      Specific function to keep track of entities references          *
14101  *      and used by the XSLT debugger                                   *
14102  *                                                                      *
14103  ************************************************************************/
14104
14105 static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
14106
14107 /**
14108  * xmlAddEntityReference:
14109  * @ent : A valid entity
14110  * @firstNode : A valid first node for children of entity
14111  * @lastNode : A valid last node of children entity 
14112  *
14113  * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
14114  */
14115 static void
14116 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
14117                       xmlNodePtr lastNode)
14118 {
14119     if (xmlEntityRefFunc != NULL) {
14120         (*xmlEntityRefFunc) (ent, firstNode, lastNode);
14121     }
14122 }
14123
14124
14125 /**
14126  * xmlSetEntityReferenceFunc:
14127  * @func: A valid function
14128  *
14129  * Set the function to call call back when a xml reference has been made
14130  */
14131 void
14132 xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
14133 {
14134     xmlEntityRefFunc = func;
14135 }
14136 #endif /* LIBXML_LEGACY_ENABLED */
14137
14138 /************************************************************************
14139  *                                                                      *
14140  *                              Miscellaneous                           *
14141  *                                                                      *
14142  ************************************************************************/
14143
14144 #ifdef LIBXML_XPATH_ENABLED
14145 #include <libxml/xpath.h>
14146 #endif
14147
14148 extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
14149 static int xmlParserInitialized = 0;
14150
14151 /**
14152  * xmlInitParser:
14153  *
14154  * Initialization function for the XML parser.
14155  * This is not reentrant. Call once before processing in case of
14156  * use in multithreaded programs.
14157  */
14158
14159 void
14160 xmlInitParser(void) {
14161     if (xmlParserInitialized != 0)
14162         return;
14163
14164 #ifdef LIBXML_THREAD_ENABLED
14165     __xmlGlobalInitMutexLock();
14166     if (xmlParserInitialized == 0) {
14167 #endif
14168         xmlInitGlobals();
14169         xmlInitThreads();
14170         if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
14171             (xmlGenericError == NULL))
14172             initGenericErrorDefaultFunc(NULL);
14173         xmlInitMemory();
14174         xmlInitCharEncodingHandlers();
14175         xmlDefaultSAXHandlerInit();
14176         xmlRegisterDefaultInputCallbacks();
14177 #ifdef LIBXML_OUTPUT_ENABLED
14178         xmlRegisterDefaultOutputCallbacks();
14179 #endif /* LIBXML_OUTPUT_ENABLED */
14180 #ifdef LIBXML_HTML_ENABLED
14181         htmlInitAutoClose();
14182         htmlDefaultSAXHandlerInit();
14183 #endif
14184 #ifdef LIBXML_XPATH_ENABLED
14185         xmlXPathInit();
14186 #endif
14187         xmlParserInitialized = 1;
14188 #ifdef LIBXML_THREAD_ENABLED
14189     }
14190     __xmlGlobalInitMutexUnlock();
14191 #endif
14192 }
14193
14194 /**
14195  * xmlCleanupParser:
14196  *
14197  * This function name is somewhat misleading. It does not clean up
14198  * parser state, it cleans up memory allocated by the library itself.
14199  * It is a cleanup function for the XML library. It tries to reclaim all
14200  * related global memory allocated for the library processing.
14201  * It doesn't deallocate any document related memory. One should
14202  * call xmlCleanupParser() only when the process has finished using
14203  * the library and all XML/HTML documents built with it.
14204  * See also xmlInitParser() which has the opposite function of preparing
14205  * the library for operations.
14206  *
14207  * WARNING: if your application is multithreaded or has plugin support
14208  *          calling this may crash the application if another thread or
14209  *          a plugin is still using libxml2. It's sometimes very hard to
14210  *          guess if libxml2 is in use in the application, some libraries
14211  *          or plugins may use it without notice. In case of doubt abstain
14212  *          from calling this function or do it just before calling exit()
14213  *          to avoid leak reports from valgrind !
14214  */
14215
14216 void
14217 xmlCleanupParser(void) {
14218     if (!xmlParserInitialized)
14219         return;
14220
14221     xmlCleanupCharEncodingHandlers();
14222 #ifdef LIBXML_CATALOG_ENABLED
14223     xmlCatalogCleanup();
14224 #endif
14225     xmlDictCleanup();
14226     xmlCleanupInputCallbacks();
14227 #ifdef LIBXML_OUTPUT_ENABLED
14228     xmlCleanupOutputCallbacks();
14229 #endif
14230 #ifdef LIBXML_SCHEMAS_ENABLED
14231     xmlSchemaCleanupTypes();
14232     xmlRelaxNGCleanupTypes();
14233 #endif
14234     xmlCleanupGlobals();
14235     xmlResetLastError();
14236     xmlCleanupThreads(); /* must be last if called not from the main thread */
14237     xmlCleanupMemory();
14238     xmlParserInitialized = 0;
14239 }
14240
14241 /************************************************************************
14242  *                                                                      *
14243  *      New set (2.6.0) of simpler and more flexible APIs               *
14244  *                                                                      *
14245  ************************************************************************/
14246
14247 /**
14248  * DICT_FREE:
14249  * @str:  a string
14250  *
14251  * Free a string if it is not owned by the "dict" dictionnary in the
14252  * current scope
14253  */
14254 #define DICT_FREE(str)                                          \
14255         if ((str) && ((!dict) ||                                \
14256             (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
14257             xmlFree((char *)(str));
14258
14259 /**
14260  * xmlCtxtReset:
14261  * @ctxt: an XML parser context
14262  *
14263  * Reset a parser context
14264  */
14265 void
14266 xmlCtxtReset(xmlParserCtxtPtr ctxt)
14267 {
14268     xmlParserInputPtr input;
14269     xmlDictPtr dict;
14270     
14271     if (ctxt == NULL)
14272         return;
14273
14274     dict = ctxt->dict;
14275
14276     while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
14277         xmlFreeInputStream(input);
14278     }
14279     ctxt->inputNr = 0;
14280     ctxt->input = NULL;
14281
14282     ctxt->spaceNr = 0;
14283     if (ctxt->spaceTab != NULL) {
14284         ctxt->spaceTab[0] = -1;
14285         ctxt->space = &ctxt->spaceTab[0];
14286     } else {
14287         ctxt->space = NULL;
14288     }
14289
14290
14291     ctxt->nodeNr = 0;
14292     ctxt->node = NULL;
14293
14294     ctxt->nameNr = 0;
14295     ctxt->name = NULL;
14296
14297     DICT_FREE(ctxt->version);
14298     ctxt->version = NULL;
14299     DICT_FREE(ctxt->encoding);
14300     ctxt->encoding = NULL;
14301     DICT_FREE(ctxt->directory);
14302     ctxt->directory = NULL;
14303     DICT_FREE(ctxt->extSubURI);
14304     ctxt->extSubURI = NULL;
14305     DICT_FREE(ctxt->extSubSystem);
14306     ctxt->extSubSystem = NULL;
14307     if (ctxt->myDoc != NULL)
14308         xmlFreeDoc(ctxt->myDoc);
14309     ctxt->myDoc = NULL;
14310
14311     ctxt->standalone = -1;
14312     ctxt->hasExternalSubset = 0;
14313     ctxt->hasPErefs = 0;
14314     ctxt->html = 0;
14315     ctxt->external = 0;
14316     ctxt->instate = XML_PARSER_START;
14317     ctxt->token = 0;
14318
14319     ctxt->wellFormed = 1;
14320     ctxt->nsWellFormed = 1;
14321     ctxt->disableSAX = 0;
14322     ctxt->valid = 1;
14323 #if 0
14324     ctxt->vctxt.userData = ctxt;
14325     ctxt->vctxt.error = xmlParserValidityError;
14326     ctxt->vctxt.warning = xmlParserValidityWarning;
14327 #endif
14328     ctxt->record_info = 0;
14329     ctxt->nbChars = 0;
14330     ctxt->checkIndex = 0;
14331     ctxt->inSubset = 0;
14332     ctxt->errNo = XML_ERR_OK;
14333     ctxt->depth = 0;
14334     ctxt->charset = XML_CHAR_ENCODING_UTF8;
14335     ctxt->catalogs = NULL;
14336     ctxt->nbentities = 0;
14337     ctxt->sizeentities = 0;
14338     xmlInitNodeInfoSeq(&ctxt->node_seq);
14339
14340     if (ctxt->attsDefault != NULL) {
14341         xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
14342         ctxt->attsDefault = NULL;
14343     }
14344     if (ctxt->attsSpecial != NULL) {
14345         xmlHashFree(ctxt->attsSpecial, NULL);
14346         ctxt->attsSpecial = NULL;
14347     }
14348
14349 #ifdef LIBXML_CATALOG_ENABLED
14350     if (ctxt->catalogs != NULL)
14351         xmlCatalogFreeLocal(ctxt->catalogs);
14352 #endif
14353     if (ctxt->lastError.code != XML_ERR_OK)
14354         xmlResetError(&ctxt->lastError);
14355 }
14356
14357 /**
14358  * xmlCtxtResetPush:
14359  * @ctxt: an XML parser context
14360  * @chunk:  a pointer to an array of chars
14361  * @size:  number of chars in the array
14362  * @filename:  an optional file name or URI
14363  * @encoding:  the document encoding, or NULL
14364  *
14365  * Reset a push parser context
14366  *
14367  * Returns 0 in case of success and 1 in case of error
14368  */
14369 int
14370 xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
14371                  int size, const char *filename, const char *encoding)
14372 {
14373     xmlParserInputPtr inputStream;
14374     xmlParserInputBufferPtr buf;
14375     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
14376
14377     if (ctxt == NULL)
14378         return(1);
14379
14380     if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
14381         enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
14382
14383     buf = xmlAllocParserInputBuffer(enc);
14384     if (buf == NULL)
14385         return(1);
14386
14387     if (ctxt == NULL) {
14388         xmlFreeParserInputBuffer(buf);
14389         return(1);
14390     }
14391
14392     xmlCtxtReset(ctxt);
14393
14394     if (ctxt->pushTab == NULL) {
14395         ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
14396                                             sizeof(xmlChar *));
14397         if (ctxt->pushTab == NULL) {
14398             xmlErrMemory(ctxt, NULL);
14399             xmlFreeParserInputBuffer(buf);
14400             return(1);
14401         }
14402     }
14403
14404     if (filename == NULL) {
14405         ctxt->directory = NULL;
14406     } else {
14407         ctxt->directory = xmlParserGetDirectory(filename);
14408     }
14409
14410     inputStream = xmlNewInputStream(ctxt);
14411     if (inputStream == NULL) {
14412         xmlFreeParserInputBuffer(buf);
14413         return(1);
14414     }
14415
14416     if (filename == NULL)
14417         inputStream->filename = NULL;
14418     else
14419         inputStream->filename = (char *)
14420             xmlCanonicPath((const xmlChar *) filename);
14421     inputStream->buf = buf;
14422     inputStream->base = inputStream->buf->buffer->content;
14423     inputStream->cur = inputStream->buf->buffer->content;
14424     inputStream->end =
14425         &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
14426
14427     inputPush(ctxt, inputStream);
14428
14429     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
14430         (ctxt->input->buf != NULL)) {
14431         int base = ctxt->input->base - ctxt->input->buf->buffer->content;
14432         int cur = ctxt->input->cur - ctxt->input->base;
14433
14434         xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
14435
14436         ctxt->input->base = ctxt->input->buf->buffer->content + base;
14437         ctxt->input->cur = ctxt->input->base + cur;
14438         ctxt->input->end =
14439             &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->
14440                                                use];
14441 #ifdef DEBUG_PUSH
14442         xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
14443 #endif
14444     }
14445
14446     if (encoding != NULL) {
14447         xmlCharEncodingHandlerPtr hdlr;
14448
14449         if (ctxt->encoding != NULL)
14450             xmlFree((xmlChar *) ctxt->encoding);
14451         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14452
14453         hdlr = xmlFindCharEncodingHandler(encoding);
14454         if (hdlr != NULL) {
14455             xmlSwitchToEncoding(ctxt, hdlr);
14456         } else {
14457             xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
14458                               "Unsupported encoding %s\n", BAD_CAST encoding);
14459         }
14460     } else if (enc != XML_CHAR_ENCODING_NONE) {
14461         xmlSwitchEncoding(ctxt, enc);
14462     }
14463
14464     return(0);
14465 }
14466
14467
14468 /**
14469  * xmlCtxtUseOptionsInternal:
14470  * @ctxt: an XML parser context
14471  * @options:  a combination of xmlParserOption
14472  * @encoding:  the user provided encoding to use
14473  *
14474  * Applies the options to the parser context
14475  *
14476  * Returns 0 in case of success, the set of unknown or unimplemented options
14477  *         in case of error.
14478  */
14479 static int
14480 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
14481 {
14482     if (ctxt == NULL)
14483         return(-1);
14484     if (encoding != NULL) {
14485         if (ctxt->encoding != NULL)
14486             xmlFree((xmlChar *) ctxt->encoding);
14487         ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14488     }
14489     if (options & XML_PARSE_RECOVER) {
14490         ctxt->recovery = 1;
14491         options -= XML_PARSE_RECOVER;
14492         ctxt->options |= XML_PARSE_RECOVER;
14493     } else
14494         ctxt->recovery = 0;
14495     if (options & XML_PARSE_DTDLOAD) {
14496         ctxt->loadsubset = XML_DETECT_IDS;
14497         options -= XML_PARSE_DTDLOAD;
14498         ctxt->options |= XML_PARSE_DTDLOAD;
14499     } else
14500         ctxt->loadsubset = 0;
14501     if (options & XML_PARSE_DTDATTR) {
14502         ctxt->loadsubset |= XML_COMPLETE_ATTRS;
14503         options -= XML_PARSE_DTDATTR;
14504         ctxt->options |= XML_PARSE_DTDATTR;
14505     }
14506     if (options & XML_PARSE_NOENT) {
14507         ctxt->replaceEntities = 1;
14508         /* ctxt->loadsubset |= XML_DETECT_IDS; */
14509         options -= XML_PARSE_NOENT;
14510         ctxt->options |= XML_PARSE_NOENT;
14511     } else
14512         ctxt->replaceEntities = 0;
14513     if (options & XML_PARSE_PEDANTIC) {
14514         ctxt->pedantic = 1;
14515         options -= XML_PARSE_PEDANTIC;
14516         ctxt->options |= XML_PARSE_PEDANTIC;
14517     } else
14518         ctxt->pedantic = 0;
14519     if (options & XML_PARSE_NOBLANKS) {
14520         ctxt->keepBlanks = 0;
14521         ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
14522         options -= XML_PARSE_NOBLANKS;
14523         ctxt->options |= XML_PARSE_NOBLANKS;
14524     } else
14525         ctxt->keepBlanks = 1;
14526     if (options & XML_PARSE_DTDVALID) {
14527         ctxt->validate = 1;
14528         if (options & XML_PARSE_NOWARNING)
14529             ctxt->vctxt.warning = NULL;
14530         if (options & XML_PARSE_NOERROR)
14531             ctxt->vctxt.error = NULL;
14532         options -= XML_PARSE_DTDVALID;
14533         ctxt->options |= XML_PARSE_DTDVALID;
14534     } else
14535         ctxt->validate = 0;
14536     if (options & XML_PARSE_NOWARNING) {
14537         ctxt->sax->warning = NULL;
14538         options -= XML_PARSE_NOWARNING;
14539     }
14540     if (options & XML_PARSE_NOERROR) {
14541         ctxt->sax->error = NULL;
14542         ctxt->sax->fatalError = NULL;
14543         options -= XML_PARSE_NOERROR;
14544     }
14545 #ifdef LIBXML_SAX1_ENABLED
14546     if (options & XML_PARSE_SAX1) {
14547         ctxt->sax->startElement = xmlSAX2StartElement;
14548         ctxt->sax->endElement = xmlSAX2EndElement;
14549         ctxt->sax->startElementNs = NULL;
14550         ctxt->sax->endElementNs = NULL;
14551         ctxt->sax->initialized = 1;
14552         options -= XML_PARSE_SAX1;
14553         ctxt->options |= XML_PARSE_SAX1;
14554     }
14555 #endif /* LIBXML_SAX1_ENABLED */
14556     if (options & XML_PARSE_NODICT) {
14557         ctxt->dictNames = 0;
14558         options -= XML_PARSE_NODICT;
14559         ctxt->options |= XML_PARSE_NODICT;
14560     } else {
14561         ctxt->dictNames = 1;
14562     }
14563     if (options & XML_PARSE_NOCDATA) {
14564         ctxt->sax->cdataBlock = NULL;
14565         options -= XML_PARSE_NOCDATA;
14566         ctxt->options |= XML_PARSE_NOCDATA;
14567     }
14568     if (options & XML_PARSE_NSCLEAN) {
14569         ctxt->options |= XML_PARSE_NSCLEAN;
14570         options -= XML_PARSE_NSCLEAN;
14571     }
14572     if (options & XML_PARSE_NONET) {
14573         ctxt->options |= XML_PARSE_NONET;
14574         options -= XML_PARSE_NONET;
14575     }
14576     if (options & XML_PARSE_COMPACT) {
14577         ctxt->options |= XML_PARSE_COMPACT;
14578         options -= XML_PARSE_COMPACT;
14579     }
14580     if (options & XML_PARSE_OLD10) {
14581         ctxt->options |= XML_PARSE_OLD10;
14582         options -= XML_PARSE_OLD10;
14583     }
14584     if (options & XML_PARSE_NOBASEFIX) {
14585         ctxt->options |= XML_PARSE_NOBASEFIX;
14586         options -= XML_PARSE_NOBASEFIX;
14587     }
14588     if (options & XML_PARSE_HUGE) {
14589         ctxt->options |= XML_PARSE_HUGE;
14590         options -= XML_PARSE_HUGE;
14591     }
14592     if (options & XML_PARSE_OLDSAX) {
14593         ctxt->options |= XML_PARSE_OLDSAX;
14594         options -= XML_PARSE_OLDSAX;
14595     }
14596     ctxt->linenumbers = 1;
14597     return (options);
14598 }
14599
14600 /**
14601  * xmlCtxtUseOptions:
14602  * @ctxt: an XML parser context
14603  * @options:  a combination of xmlParserOption
14604  *
14605  * Applies the options to the parser context
14606  *
14607  * Returns 0 in case of success, the set of unknown or unimplemented options
14608  *         in case of error.
14609  */
14610 int
14611 xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
14612 {
14613    return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
14614 }
14615
14616 /**
14617  * xmlDoRead:
14618  * @ctxt:  an XML parser context
14619  * @URL:  the base URL to use for the document
14620  * @encoding:  the document encoding, or NULL
14621  * @options:  a combination of xmlParserOption
14622  * @reuse:  keep the context for reuse
14623  *
14624  * Common front-end for the xmlRead functions
14625  *
14626  * Returns the resulting document tree or NULL
14627  */
14628 static xmlDocPtr
14629 xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
14630           int options, int reuse)
14631 {
14632     xmlDocPtr ret;
14633
14634     xmlCtxtUseOptionsInternal(ctxt, options, encoding);
14635     if (encoding != NULL) {
14636         xmlCharEncodingHandlerPtr hdlr;
14637
14638         hdlr = xmlFindCharEncodingHandler(encoding);
14639         if (hdlr != NULL)
14640             xmlSwitchToEncoding(ctxt, hdlr);
14641     }
14642     if ((URL != NULL) && (ctxt->input != NULL) &&
14643         (ctxt->input->filename == NULL))
14644         ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
14645     xmlParseDocument(ctxt);
14646     if ((ctxt->wellFormed) || ctxt->recovery)
14647         ret = ctxt->myDoc;
14648     else {
14649         ret = NULL;
14650         if (ctxt->myDoc != NULL) {
14651             xmlFreeDoc(ctxt->myDoc);
14652         }
14653     }
14654     ctxt->myDoc = NULL;
14655     if (!reuse) {
14656         xmlFreeParserCtxt(ctxt);
14657     }
14658
14659     return (ret);
14660 }
14661
14662 /**
14663  * xmlReadDoc:
14664  * @cur:  a pointer to a zero terminated string
14665  * @URL:  the base URL to use for the document
14666  * @encoding:  the document encoding, or NULL
14667  * @options:  a combination of xmlParserOption
14668  *
14669  * parse an XML in-memory document and build a tree.
14670  * 
14671  * Returns the resulting document tree
14672  */
14673 xmlDocPtr
14674 xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
14675 {
14676     xmlParserCtxtPtr ctxt;
14677
14678     if (cur == NULL)
14679         return (NULL);
14680
14681     ctxt = xmlCreateDocParserCtxt(cur);
14682     if (ctxt == NULL)
14683         return (NULL);
14684     return (xmlDoRead(ctxt, URL, encoding, options, 0));
14685 }
14686
14687 /**
14688  * xmlReadFile:
14689  * @filename:  a file or URL
14690  * @encoding:  the document encoding, or NULL
14691  * @options:  a combination of xmlParserOption
14692  *
14693  * parse an XML file from the filesystem or the network.
14694  * 
14695  * Returns the resulting document tree
14696  */
14697 xmlDocPtr
14698 xmlReadFile(const char *filename, const char *encoding, int options)
14699 {
14700     xmlParserCtxtPtr ctxt;
14701
14702     ctxt = xmlCreateURLParserCtxt(filename, options);
14703     if (ctxt == NULL)
14704         return (NULL);
14705     return (xmlDoRead(ctxt, NULL, encoding, options, 0));
14706 }
14707
14708 /**
14709  * xmlReadMemory:
14710  * @buffer:  a pointer to a char array
14711  * @size:  the size of the array
14712  * @URL:  the base URL to use for the document
14713  * @encoding:  the document encoding, or NULL
14714  * @options:  a combination of xmlParserOption
14715  *
14716  * parse an XML in-memory document and build a tree.
14717  * 
14718  * Returns the resulting document tree
14719  */
14720 xmlDocPtr
14721 xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
14722 {
14723     xmlParserCtxtPtr ctxt;
14724
14725     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14726     if (ctxt == NULL)
14727         return (NULL);
14728     return (xmlDoRead(ctxt, URL, encoding, options, 0));
14729 }
14730
14731 /**
14732  * xmlReadFd:
14733  * @fd:  an open file descriptor
14734  * @URL:  the base URL to use for the document
14735  * @encoding:  the document encoding, or NULL
14736  * @options:  a combination of xmlParserOption
14737  *
14738  * parse an XML from a file descriptor and build a tree.
14739  * NOTE that the file descriptor will not be closed when the
14740  *      reader is closed or reset.
14741  * 
14742  * Returns the resulting document tree
14743  */
14744 xmlDocPtr
14745 xmlReadFd(int fd, const char *URL, const char *encoding, int options)
14746 {
14747     xmlParserCtxtPtr ctxt;
14748     xmlParserInputBufferPtr input;
14749     xmlParserInputPtr stream;
14750
14751     if (fd < 0)
14752         return (NULL);
14753
14754     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
14755     if (input == NULL)
14756         return (NULL);
14757     input->closecallback = NULL;
14758     ctxt = xmlNewParserCtxt();
14759     if (ctxt == NULL) {
14760         xmlFreeParserInputBuffer(input);
14761         return (NULL);
14762     }
14763     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14764     if (stream == NULL) {
14765         xmlFreeParserInputBuffer(input);
14766         xmlFreeParserCtxt(ctxt);
14767         return (NULL);
14768     }
14769     inputPush(ctxt, stream);
14770     return (xmlDoRead(ctxt, URL, encoding, options, 0));
14771 }
14772
14773 /**
14774  * xmlReadIO:
14775  * @ioread:  an I/O read function
14776  * @ioclose:  an I/O close function
14777  * @ioctx:  an I/O handler
14778  * @URL:  the base URL to use for the document
14779  * @encoding:  the document encoding, or NULL
14780  * @options:  a combination of xmlParserOption
14781  *
14782  * parse an XML document from I/O functions and source and build a tree.
14783  * 
14784  * Returns the resulting document tree
14785  */
14786 xmlDocPtr
14787 xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
14788           void *ioctx, const char *URL, const char *encoding, int options)
14789 {
14790     xmlParserCtxtPtr ctxt;
14791     xmlParserInputBufferPtr input;
14792     xmlParserInputPtr stream;
14793
14794     if (ioread == NULL)
14795         return (NULL);
14796
14797     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
14798                                          XML_CHAR_ENCODING_NONE);
14799     if (input == NULL)
14800         return (NULL);
14801     ctxt = xmlNewParserCtxt();
14802     if (ctxt == NULL) {
14803         xmlFreeParserInputBuffer(input);
14804         return (NULL);
14805     }
14806     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14807     if (stream == NULL) {
14808         xmlFreeParserInputBuffer(input);
14809         xmlFreeParserCtxt(ctxt);
14810         return (NULL);
14811     }
14812     inputPush(ctxt, stream);
14813     return (xmlDoRead(ctxt, URL, encoding, options, 0));
14814 }
14815
14816 /**
14817  * xmlCtxtReadDoc:
14818  * @ctxt:  an XML parser context
14819  * @cur:  a pointer to a zero terminated string
14820  * @URL:  the base URL to use for the document
14821  * @encoding:  the document encoding, or NULL
14822  * @options:  a combination of xmlParserOption
14823  *
14824  * parse an XML in-memory document and build a tree.
14825  * This reuses the existing @ctxt parser context
14826  * 
14827  * Returns the resulting document tree
14828  */
14829 xmlDocPtr
14830 xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
14831                const char *URL, const char *encoding, int options)
14832 {
14833     xmlParserInputPtr stream;
14834
14835     if (cur == NULL)
14836         return (NULL);
14837     if (ctxt == NULL)
14838         return (NULL);
14839
14840     xmlCtxtReset(ctxt);
14841
14842     stream = xmlNewStringInputStream(ctxt, cur);
14843     if (stream == NULL) {
14844         return (NULL);
14845     }
14846     inputPush(ctxt, stream);
14847     return (xmlDoRead(ctxt, URL, encoding, options, 1));
14848 }
14849
14850 /**
14851  * xmlCtxtReadFile:
14852  * @ctxt:  an XML parser context
14853  * @filename:  a file or URL
14854  * @encoding:  the document encoding, or NULL
14855  * @options:  a combination of xmlParserOption
14856  *
14857  * parse an XML file from the filesystem or the network.
14858  * This reuses the existing @ctxt parser context
14859  * 
14860  * Returns the resulting document tree
14861  */
14862 xmlDocPtr
14863 xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
14864                 const char *encoding, int options)
14865 {
14866     xmlParserInputPtr stream;
14867
14868     if (filename == NULL)
14869         return (NULL);
14870     if (ctxt == NULL)
14871         return (NULL);
14872
14873     xmlCtxtReset(ctxt);
14874
14875     stream = xmlLoadExternalEntity(filename, NULL, ctxt);
14876     if (stream == NULL) {
14877         return (NULL);
14878     }
14879     inputPush(ctxt, stream);
14880     return (xmlDoRead(ctxt, NULL, encoding, options, 1));
14881 }
14882
14883 /**
14884  * xmlCtxtReadMemory:
14885  * @ctxt:  an XML parser context
14886  * @buffer:  a pointer to a char array
14887  * @size:  the size of the array
14888  * @URL:  the base URL to use for the document
14889  * @encoding:  the document encoding, or NULL
14890  * @options:  a combination of xmlParserOption
14891  *
14892  * parse an XML in-memory document and build a tree.
14893  * This reuses the existing @ctxt parser context
14894  * 
14895  * Returns the resulting document tree
14896  */
14897 xmlDocPtr
14898 xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
14899                   const char *URL, const char *encoding, int options)
14900 {
14901     xmlParserInputBufferPtr input;
14902     xmlParserInputPtr stream;
14903
14904     if (ctxt == NULL)
14905         return (NULL);
14906     if (buffer == NULL)
14907         return (NULL);
14908
14909     xmlCtxtReset(ctxt);
14910
14911     input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
14912     if (input == NULL) {
14913         return(NULL);
14914     }
14915
14916     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14917     if (stream == NULL) {
14918         xmlFreeParserInputBuffer(input);
14919         return(NULL);
14920     }
14921
14922     inputPush(ctxt, stream);
14923     return (xmlDoRead(ctxt, URL, encoding, options, 1));
14924 }
14925
14926 /**
14927  * xmlCtxtReadFd:
14928  * @ctxt:  an XML parser context
14929  * @fd:  an open file descriptor
14930  * @URL:  the base URL to use for the document
14931  * @encoding:  the document encoding, or NULL
14932  * @options:  a combination of xmlParserOption
14933  *
14934  * parse an XML from a file descriptor and build a tree.
14935  * This reuses the existing @ctxt parser context
14936  * NOTE that the file descriptor will not be closed when the
14937  *      reader is closed or reset.
14938  * 
14939  * Returns the resulting document tree
14940  */
14941 xmlDocPtr
14942 xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
14943               const char *URL, const char *encoding, int options)
14944 {
14945     xmlParserInputBufferPtr input;
14946     xmlParserInputPtr stream;
14947
14948     if (fd < 0)
14949         return (NULL);
14950     if (ctxt == NULL)
14951         return (NULL);
14952
14953     xmlCtxtReset(ctxt);
14954
14955
14956     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
14957     if (input == NULL)
14958         return (NULL);
14959     input->closecallback = NULL;
14960     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14961     if (stream == NULL) {
14962         xmlFreeParserInputBuffer(input);
14963         return (NULL);
14964     }
14965     inputPush(ctxt, stream);
14966     return (xmlDoRead(ctxt, URL, encoding, options, 1));
14967 }
14968
14969 /**
14970  * xmlCtxtReadIO:
14971  * @ctxt:  an XML parser context
14972  * @ioread:  an I/O read function
14973  * @ioclose:  an I/O close function
14974  * @ioctx:  an I/O handler
14975  * @URL:  the base URL to use for the document
14976  * @encoding:  the document encoding, or NULL
14977  * @options:  a combination of xmlParserOption
14978  *
14979  * parse an XML document from I/O functions and source and build a tree.
14980  * This reuses the existing @ctxt parser context
14981  * 
14982  * Returns the resulting document tree
14983  */
14984 xmlDocPtr
14985 xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
14986               xmlInputCloseCallback ioclose, void *ioctx,
14987               const char *URL,
14988               const char *encoding, int options)
14989 {
14990     xmlParserInputBufferPtr input;
14991     xmlParserInputPtr stream;
14992
14993     if (ioread == NULL)
14994         return (NULL);
14995     if (ctxt == NULL)
14996         return (NULL);
14997
14998     xmlCtxtReset(ctxt);
14999
15000     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15001                                          XML_CHAR_ENCODING_NONE);
15002     if (input == NULL)
15003         return (NULL);
15004     stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15005     if (stream == NULL) {
15006         xmlFreeParserInputBuffer(input);
15007         return (NULL);
15008     }
15009     inputPush(ctxt, stream);
15010     return (xmlDoRead(ctxt, URL, encoding, options, 1));
15011 }
15012
15013 #define bottom_parser
15014 #include "elfgcchack.h"