source: trunk/third/libxml2/parserInternals.c @ 21532

Revision 21532, 60.3 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21531, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * parserInternals.c : Internal routines (and obsolete ones) needed for the
3 *                     XML and HTML parsers.
4 *
5 * See Copyright for the status of this software.
6 *
7 * daniel@veillard.com
8 */
9
10#define IN_LIBXML
11#include "libxml.h"
12
13#if defined(WIN32) && !defined (__CYGWIN__)
14#define XML_DIR_SEP '\\'
15#else
16#define XML_DIR_SEP '/'
17#endif
18
19#include <string.h>
20#ifdef HAVE_CTYPE_H
21#include <ctype.h>
22#endif
23#ifdef HAVE_STDLIB_H
24#include <stdlib.h>
25#endif
26#ifdef HAVE_SYS_STAT_H
27#include <sys/stat.h>
28#endif
29#ifdef HAVE_FCNTL_H
30#include <fcntl.h>
31#endif
32#ifdef HAVE_UNISTD_H
33#include <unistd.h>
34#endif
35#ifdef HAVE_ZLIB_H
36#include <zlib.h>
37#endif
38
39#include <libxml/xmlmemory.h>
40#include <libxml/tree.h>
41#include <libxml/parser.h>
42#include <libxml/parserInternals.h>
43#include <libxml/valid.h>
44#include <libxml/entities.h>
45#include <libxml/xmlerror.h>
46#include <libxml/encoding.h>
47#include <libxml/valid.h>
48#include <libxml/xmlIO.h>
49#include <libxml/uri.h>
50#include <libxml/dict.h>
51#include <libxml/SAX.h>
52#ifdef LIBXML_CATALOG_ENABLED
53#include <libxml/catalog.h>
54#endif
55#include <libxml/globals.h>
56#include <libxml/chvalid.h>
57
58/*
59 * Various global defaults for parsing
60 */
61
62/**
63 * xmlCheckVersion:
64 * @version: the include version number
65 *
66 * check the compiled lib version against the include one.
67 * This can warn or immediately kill the application
68 */
69void
70xmlCheckVersion(int version) {
71    int myversion = (int) LIBXML_VERSION;
72
73    xmlInitParser();
74
75    if ((myversion / 10000) != (version / 10000)) {
76        xmlGenericError(xmlGenericErrorContext,
77                "Fatal: program compiled against libxml %d using libxml %d\n",
78                (version / 10000), (myversion / 10000));
79        fprintf(stderr,
80                "Fatal: program compiled against libxml %d using libxml %d\n",
81                (version / 10000), (myversion / 10000));
82    }
83    if ((myversion / 100) < (version / 100)) {
84        xmlGenericError(xmlGenericErrorContext,
85                "Warning: program compiled against libxml %d using older %d\n",
86                (version / 100), (myversion / 100));
87    }
88}
89
90
91/************************************************************************
92 *                                                                      *
93 *              Some factorized error routines                          *
94 *                                                                      *
95 ************************************************************************/
96
97
98/**
99 * xmlErrMemory:
100 * @ctxt:  an XML parser context
101 * @extra:  extra informations
102 *
103 * Handle a redefinition of attribute error
104 */
105void
106xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra)
107{
108    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
109        (ctxt->instate == XML_PARSER_EOF))
110        return;
111    if (ctxt != NULL) {
112        ctxt->errNo = XML_ERR_NO_MEMORY;
113        ctxt->instate = XML_PARSER_EOF;
114        ctxt->disableSAX = 1;
115    }
116    if (extra)
117        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
118                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
119                        NULL, NULL, 0, 0,
120                        "Memory allocation failed : %s\n", extra);
121    else
122        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
123                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
124                        NULL, NULL, 0, 0, "Memory allocation failed\n");
125}
126
127/**
128 * __xmlErrEncoding:
129 * @ctxt:  an XML parser context
130 * @xmlerr:  the error number
131 * @msg:  the error message
132 * @str1:  an string info
133 * @str2:  an string info
134 *
135 * Handle an encoding error
136 */
137void
138__xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr,
139                 const char *msg, const xmlChar * str1, const xmlChar * str2)
140{
141    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
142        (ctxt->instate == XML_PARSER_EOF))
143        return;
144    if (ctxt != NULL)
145        ctxt->errNo = xmlerr;
146    __xmlRaiseError(NULL, NULL, NULL,
147                    ctxt, NULL, XML_FROM_PARSER, xmlerr, XML_ERR_FATAL,
148                    NULL, 0, (const char *) str1, (const char *) str2,
149                    NULL, 0, 0, msg, str1, str2);
150    if (ctxt != NULL) {
151        ctxt->wellFormed = 0;
152        if (ctxt->recovery == 0)
153            ctxt->disableSAX = 1;
154    }
155}
156
157/**
158 * xmlErrInternal:
159 * @ctxt:  an XML parser context
160 * @msg:  the error message
161 * @str:  error informations
162 *
163 * Handle an internal error
164 */
165static void
166xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
167{
168    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
169        (ctxt->instate == XML_PARSER_EOF))
170        return;
171    if (ctxt != NULL)
172        ctxt->errNo = XML_ERR_INTERNAL_ERROR;
173    __xmlRaiseError(NULL, NULL, NULL,
174                    ctxt, NULL, XML_FROM_PARSER, XML_ERR_INTERNAL_ERROR,
175                    XML_ERR_FATAL, NULL, 0, (const char *) str, NULL, NULL,
176                    0, 0, msg, str);
177    if (ctxt != NULL) {
178        ctxt->wellFormed = 0;
179        if (ctxt->recovery == 0)
180            ctxt->disableSAX = 1;
181    }
182}
183
184/**
185 * xmlErrEncodingInt:
186 * @ctxt:  an XML parser context
187 * @error:  the error number
188 * @msg:  the error message
189 * @val:  an integer value
190 *
191 * n encoding error
192 */
193static void
194xmlErrEncodingInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
195                  const char *msg, int val)
196{
197    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
198        (ctxt->instate == XML_PARSER_EOF))
199        return;
200    if (ctxt != NULL)
201        ctxt->errNo = error;
202    __xmlRaiseError(NULL, NULL, NULL,
203                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
204                    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
205    if (ctxt != NULL) {
206        ctxt->wellFormed = 0;
207        if (ctxt->recovery == 0)
208            ctxt->disableSAX = 1;
209    }
210}
211
212/**
213 * xmlIsLetter:
214 * @c:  an unicode character (int)
215 *
216 * Check whether the character is allowed by the production
217 * [84] Letter ::= BaseChar | Ideographic
218 *
219 * Returns 0 if not, non-zero otherwise
220 */
221int
222xmlIsLetter(int c) {
223    return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
224}
225
226/************************************************************************
227 *                                                                      *
228 *              Input handling functions for progressive parsing        *
229 *                                                                      *
230 ************************************************************************/
231
232/* #define DEBUG_INPUT */
233/* #define DEBUG_STACK */
234/* #define DEBUG_PUSH */
235
236
237/* we need to keep enough input to show errors in context */
238#define LINE_LEN        80
239
240#ifdef DEBUG_INPUT
241#define CHECK_BUFFER(in) check_buffer(in)
242
243static
244void check_buffer(xmlParserInputPtr in) {
245    if (in->base != in->buf->buffer->content) {
246        xmlGenericError(xmlGenericErrorContext,
247                "xmlParserInput: base mismatch problem\n");
248    }
249    if (in->cur < in->base) {
250        xmlGenericError(xmlGenericErrorContext,
251                "xmlParserInput: cur < base problem\n");
252    }
253    if (in->cur > in->base + in->buf->buffer->use) {
254        xmlGenericError(xmlGenericErrorContext,
255                "xmlParserInput: cur > base + use problem\n");
256    }
257    xmlGenericError(xmlGenericErrorContext,"buffer %x : content %x, cur %d, use %d, size %d\n",
258            (int) in, (int) in->buf->buffer->content, in->cur - in->base,
259            in->buf->buffer->use, in->buf->buffer->size);
260}
261
262#else
263#define CHECK_BUFFER(in)
264#endif
265
266
267/**
268 * xmlParserInputRead:
269 * @in:  an XML parser input
270 * @len:  an indicative size for the lookahead
271 *
272 * This function refresh the input for the parser. It doesn't try to
273 * preserve pointers to the input buffer, and discard already read data
274 *
275 * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
276 * end of this entity
277 */
278int
279xmlParserInputRead(xmlParserInputPtr in, int len) {
280    int ret;
281    int used;
282    int indx;
283
284    if (in == NULL) return(-1);
285#ifdef DEBUG_INPUT
286    xmlGenericError(xmlGenericErrorContext, "Read\n");
287#endif
288    if (in->buf == NULL) return(-1);
289    if (in->base == NULL) return(-1);
290    if (in->cur == NULL) return(-1);
291    if (in->buf->buffer == NULL) return(-1);
292    if (in->buf->readcallback == NULL) return(-1);
293
294    CHECK_BUFFER(in);
295
296    used = in->cur - in->buf->buffer->content;
297    ret = xmlBufferShrink(in->buf->buffer, used);
298    if (ret > 0) {
299        in->cur -= ret;
300        in->consumed += ret;
301    }
302    ret = xmlParserInputBufferRead(in->buf, len);
303    if (in->base != in->buf->buffer->content) {
304        /*
305         * the buffer has been reallocated
306         */
307        indx = in->cur - in->base;
308        in->base = in->buf->buffer->content;
309        in->cur = &in->buf->buffer->content[indx];
310    }
311    in->end = &in->buf->buffer->content[in->buf->buffer->use];
312
313    CHECK_BUFFER(in);
314
315    return(ret);
316}
317
318/**
319 * xmlParserInputGrow:
320 * @in:  an XML parser input
321 * @len:  an indicative size for the lookahead
322 *
323 * This function increase the input for the parser. It tries to
324 * preserve pointers to the input buffer, and keep already read data
325 *
326 * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
327 * end of this entity
328 */
329int
330xmlParserInputGrow(xmlParserInputPtr in, int len) {
331    int ret;
332    int indx;
333
334    if (in == NULL) return(-1);
335#ifdef DEBUG_INPUT
336    xmlGenericError(xmlGenericErrorContext, "Grow\n");
337#endif
338    if (in->buf == NULL) return(-1);
339    if (in->base == NULL) return(-1);
340    if (in->cur == NULL) return(-1);
341    if (in->buf->buffer == NULL) return(-1);
342
343    CHECK_BUFFER(in);
344
345    indx = in->cur - in->base;
346    if (in->buf->buffer->use > (unsigned int) indx + INPUT_CHUNK) {
347
348        CHECK_BUFFER(in);
349
350        return(0);
351    }
352    if (in->buf->readcallback != NULL)
353        ret = xmlParserInputBufferGrow(in->buf, len);
354    else       
355        return(0);
356
357    /*
358     * NOTE : in->base may be a "dangling" i.e. freed pointer in this
359     *        block, but we use it really as an integer to do some
360     *        pointer arithmetic. Insure will raise it as a bug but in
361     *        that specific case, that's not !
362     */
363    if (in->base != in->buf->buffer->content) {
364        /*
365         * the buffer has been reallocated
366         */
367        indx = in->cur - in->base;
368        in->base = in->buf->buffer->content;
369        in->cur = &in->buf->buffer->content[indx];
370    }
371    in->end = &in->buf->buffer->content[in->buf->buffer->use];
372
373    CHECK_BUFFER(in);
374
375    return(ret);
376}
377
378/**
379 * xmlParserInputShrink:
380 * @in:  an XML parser input
381 *
382 * This function removes used input for the parser.
383 */
384void
385xmlParserInputShrink(xmlParserInputPtr in) {
386    int used;
387    int ret;
388    int indx;
389
390#ifdef DEBUG_INPUT
391    xmlGenericError(xmlGenericErrorContext, "Shrink\n");
392#endif
393    if (in == NULL) return;
394    if (in->buf == NULL) return;
395    if (in->base == NULL) return;
396    if (in->cur == NULL) return;
397    if (in->buf->buffer == NULL) return;
398
399    CHECK_BUFFER(in);
400
401    used = in->cur - in->buf->buffer->content;
402    /*
403     * Do not shrink on large buffers whose only a tiny fraction
404     * was consumed
405     */
406    if (used > INPUT_CHUNK) {
407        ret = xmlBufferShrink(in->buf->buffer, used - LINE_LEN);
408        if (ret > 0) {
409            in->cur -= ret;
410            in->consumed += ret;
411        }
412        in->end = &in->buf->buffer->content[in->buf->buffer->use];
413    }
414
415    CHECK_BUFFER(in);
416
417    if (in->buf->buffer->use > INPUT_CHUNK) {
418        return;
419    }
420    xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
421    if (in->base != in->buf->buffer->content) {
422        /*
423         * the buffer has been reallocated
424         */
425        indx = in->cur - in->base;
426        in->base = in->buf->buffer->content;
427        in->cur = &in->buf->buffer->content[indx];
428    }
429    in->end = &in->buf->buffer->content[in->buf->buffer->use];
430
431    CHECK_BUFFER(in);
432}
433
434/************************************************************************
435 *                                                                      *
436 *              UTF8 character input and related functions              *
437 *                                                                      *
438 ************************************************************************/
439
440/**
441 * xmlNextChar:
442 * @ctxt:  the XML parser context
443 *
444 * Skip to the next char input char.
445 */
446
447void
448xmlNextChar(xmlParserCtxtPtr ctxt)
449{
450    if ((ctxt == NULL) || (ctxt->instate == XML_PARSER_EOF) ||
451        (ctxt->input == NULL))
452        return;
453
454    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
455        if ((*ctxt->input->cur == 0) &&
456            (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
457            (ctxt->instate != XML_PARSER_COMMENT)) {
458            /*
459             * If we are at the end of the current entity and
460             * the context allows it, we pop consumed entities
461             * automatically.
462             * the auto closing should be blocked in other cases
463             */
464            xmlPopInput(ctxt);
465        } else {
466            const unsigned char *cur;
467            unsigned char c;
468
469            /*
470             *   2.11 End-of-Line Handling
471             *   the literal two-character sequence "#xD#xA" or a standalone
472             *   literal #xD, an XML processor must pass to the application
473             *   the single character #xA.
474             */
475            if (*(ctxt->input->cur) == '\n') {
476                ctxt->input->line++; ctxt->input->col = 1;
477            } else
478                ctxt->input->col++;
479
480            /*
481             * We are supposed to handle UTF8, check it's valid
482             * From rfc2044: encoding of the Unicode values on UTF-8:
483             *
484             * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
485             * 0000 0000-0000 007F   0xxxxxxx
486             * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
487             * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
488             *
489             * Check for the 0x110000 limit too
490             */
491            cur = ctxt->input->cur;
492
493            c = *cur;
494            if (c & 0x80) {
495                if (c == 0xC0)
496                    goto encoding_error;
497                if (cur[1] == 0)
498                    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
499                if ((cur[1] & 0xc0) != 0x80)
500                    goto encoding_error;
501                if ((c & 0xe0) == 0xe0) {
502                    unsigned int val;
503
504                    if (cur[2] == 0)
505                        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
506                    if ((cur[2] & 0xc0) != 0x80)
507                        goto encoding_error;
508                    if ((c & 0xf0) == 0xf0) {
509                        if (cur[3] == 0)
510                            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
511                        if (((c & 0xf8) != 0xf0) ||
512                            ((cur[3] & 0xc0) != 0x80))
513                            goto encoding_error;
514                        /* 4-byte code */
515                        ctxt->input->cur += 4;
516                        val = (cur[0] & 0x7) << 18;
517                        val |= (cur[1] & 0x3f) << 12;
518                        val |= (cur[2] & 0x3f) << 6;
519                        val |= cur[3] & 0x3f;
520                    } else {
521                        /* 3-byte code */
522                        ctxt->input->cur += 3;
523                        val = (cur[0] & 0xf) << 12;
524                        val |= (cur[1] & 0x3f) << 6;
525                        val |= cur[2] & 0x3f;
526                    }
527                    if (((val > 0xd7ff) && (val < 0xe000)) ||
528                        ((val > 0xfffd) && (val < 0x10000)) ||
529                        (val >= 0x110000)) {
530                        xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
531                                          "Char 0x%X out of allowed range\n",
532                                          val);
533                    }
534                } else
535                    /* 2-byte code */
536                    ctxt->input->cur += 2;
537            } else
538                /* 1-byte code */
539                ctxt->input->cur++;
540
541            ctxt->nbChars++;
542            if (*ctxt->input->cur == 0)
543                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
544        }
545    } else {
546        /*
547         * Assume it's a fixed length encoding (1) with
548         * a compatible encoding for the ASCII set, since
549         * XML constructs only use < 128 chars
550         */
551
552        if (*(ctxt->input->cur) == '\n') {
553            ctxt->input->line++; ctxt->input->col = 1;
554        } else
555            ctxt->input->col++;
556        ctxt->input->cur++;
557        ctxt->nbChars++;
558        if (*ctxt->input->cur == 0)
559            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
560    }
561    if ((*ctxt->input->cur == '%') && (!ctxt->html))
562        xmlParserHandlePEReference(ctxt);
563    if ((*ctxt->input->cur == 0) &&
564        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
565        xmlPopInput(ctxt);
566    return;
567encoding_error:
568    /*
569     * If we detect an UTF8 error that probably mean that the
570     * input encoding didn't get properly advertised in the
571     * declaration header. Report the error and switch the encoding
572     * to ISO-Latin-1 (if you don't like this policy, just declare the
573     * encoding !)
574     */
575    if ((ctxt == NULL) || (ctxt->input == NULL) ||
576        (ctxt->input->end - ctxt->input->cur < 4)) {
577        __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
578                     "Input is not proper UTF-8, indicate encoding !\n",
579                     NULL, NULL);
580    } else {
581        char buffer[150];
582
583        snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
584                        ctxt->input->cur[0], ctxt->input->cur[1],
585                        ctxt->input->cur[2], ctxt->input->cur[3]);
586        __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
587                     "Input is not proper UTF-8, indicate encoding !\n%s",
588                     BAD_CAST buffer, NULL);
589    }
590    ctxt->charset = XML_CHAR_ENCODING_8859_1;
591    ctxt->input->cur++;
592    return;
593}
594
595/**
596 * xmlCurrentChar:
597 * @ctxt:  the XML parser context
598 * @len:  pointer to the length of the char read
599 *
600 * The current char value, if using UTF-8 this may actually span multiple
601 * bytes in the input buffer. Implement the end of line normalization:
602 * 2.11 End-of-Line Handling
603 * Wherever an external parsed entity or the literal entity value
604 * of an internal parsed entity contains either the literal two-character
605 * sequence "#xD#xA" or a standalone literal #xD, an XML processor
606 * must pass to the application the single character #xA.
607 * This behavior can conveniently be produced by normalizing all
608 * line breaks to #xA on input, before parsing.)
609 *
610 * Returns the current char value and its length
611 */
612
613int
614xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
615    if ((ctxt == NULL) || (len == NULL) || (ctxt->input == NULL)) return(0);
616    if (ctxt->instate == XML_PARSER_EOF)
617        return(0);
618
619    if ((*ctxt->input->cur >= 0x20) && (*ctxt->input->cur <= 0x7F)) {
620            *len = 1;
621            return((int) *ctxt->input->cur);
622    }
623    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
624        /*
625         * We are supposed to handle UTF8, check it's valid
626         * From rfc2044: encoding of the Unicode values on UTF-8:
627         *
628         * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
629         * 0000 0000-0000 007F   0xxxxxxx
630         * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
631         * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
632         *
633         * Check for the 0x110000 limit too
634         */
635        const unsigned char *cur = ctxt->input->cur;
636        unsigned char c;
637        unsigned int val;
638
639        c = *cur;
640        if (c & 0x80) {
641            if (c == 0xC0)
642                goto encoding_error;
643            if (cur[1] == 0)
644                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
645            if ((cur[1] & 0xc0) != 0x80)
646                goto encoding_error;
647            if ((c & 0xe0) == 0xe0) {
648
649                if (cur[2] == 0)
650                    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
651                if ((cur[2] & 0xc0) != 0x80)
652                    goto encoding_error;
653                if ((c & 0xf0) == 0xf0) {
654                    if (cur[3] == 0)
655                        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
656                    if (((c & 0xf8) != 0xf0) ||
657                        ((cur[3] & 0xc0) != 0x80))
658                        goto encoding_error;
659                    /* 4-byte code */
660                    *len = 4;
661                    val = (cur[0] & 0x7) << 18;
662                    val |= (cur[1] & 0x3f) << 12;
663                    val |= (cur[2] & 0x3f) << 6;
664                    val |= cur[3] & 0x3f;
665                } else {
666                  /* 3-byte code */
667                    *len = 3;
668                    val = (cur[0] & 0xf) << 12;
669                    val |= (cur[1] & 0x3f) << 6;
670                    val |= cur[2] & 0x3f;
671                }
672            } else {
673              /* 2-byte code */
674                *len = 2;
675                val = (cur[0] & 0x1f) << 6;
676                val |= cur[1] & 0x3f;
677            }
678            if (!IS_CHAR(val)) {
679                xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
680                                  "Char 0x%X out of allowed range\n", val);
681            }   
682            return(val);
683        } else {
684            /* 1-byte code */
685            *len = 1;
686            if (*ctxt->input->cur == 0xD) {
687                if (ctxt->input->cur[1] == 0xA) {
688                    ctxt->nbChars++;
689                    ctxt->input->cur++;
690                }
691                return(0xA);
692            }
693            return((int) *ctxt->input->cur);
694        }
695    }
696    /*
697     * Assume it's a fixed length encoding (1) with
698     * a compatible encoding for the ASCII set, since
699     * XML constructs only use < 128 chars
700     */
701    *len = 1;
702    if (*ctxt->input->cur == 0xD) {
703        if (ctxt->input->cur[1] == 0xA) {
704            ctxt->nbChars++;
705            ctxt->input->cur++;
706        }
707        return(0xA);
708    }
709    return((int) *ctxt->input->cur);
710encoding_error:
711    /*
712     * An encoding problem may arise from a truncated input buffer
713     * splitting a character in the middle. In that case do not raise
714     * an error but return 0 to endicate an end of stream problem
715     */
716    if (ctxt->input->end - ctxt->input->cur < 4) {
717        *len = 0;
718        return(0);
719    }
720
721    /*
722     * If we detect an UTF8 error that probably mean that the
723     * input encoding didn't get properly advertised in the
724     * declaration header. Report the error and switch the encoding
725     * to ISO-Latin-1 (if you don't like this policy, just declare the
726     * encoding !)
727     */
728    {
729        char buffer[150];
730
731        snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
732                        ctxt->input->cur[0], ctxt->input->cur[1],
733                        ctxt->input->cur[2], ctxt->input->cur[3]);
734        __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
735                     "Input is not proper UTF-8, indicate encoding !\n%s",
736                     BAD_CAST buffer, NULL);
737    }
738    ctxt->charset = XML_CHAR_ENCODING_8859_1;
739    *len = 1;
740    return((int) *ctxt->input->cur);
741}
742
743/**
744 * xmlStringCurrentChar:
745 * @ctxt:  the XML parser context
746 * @cur:  pointer to the beginning of the char
747 * @len:  pointer to the length of the char read
748 *
749 * The current char value, if using UTF-8 this may actually span multiple
750 * bytes in the input buffer.
751 *
752 * Returns the current char value and its length
753 */
754
755int
756xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar * cur, int *len)
757{
758    if ((len == NULL) || (cur == NULL)) return(0);
759    if ((ctxt == NULL) || (ctxt->charset == XML_CHAR_ENCODING_UTF8)) {
760        /*
761         * We are supposed to handle UTF8, check it's valid
762         * From rfc2044: encoding of the Unicode values on UTF-8:
763         *
764         * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
765         * 0000 0000-0000 007F   0xxxxxxx
766         * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
767         * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
768         *
769         * Check for the 0x110000 limit too
770         */
771        unsigned char c;
772        unsigned int val;
773
774        c = *cur;
775        if (c & 0x80) {
776            if ((cur[1] & 0xc0) != 0x80)
777                goto encoding_error;
778            if ((c & 0xe0) == 0xe0) {
779
780                if ((cur[2] & 0xc0) != 0x80)
781                    goto encoding_error;
782                if ((c & 0xf0) == 0xf0) {
783                    if (((c & 0xf8) != 0xf0) || ((cur[3] & 0xc0) != 0x80))
784                        goto encoding_error;
785                    /* 4-byte code */
786                    *len = 4;
787                    val = (cur[0] & 0x7) << 18;
788                    val |= (cur[1] & 0x3f) << 12;
789                    val |= (cur[2] & 0x3f) << 6;
790                    val |= cur[3] & 0x3f;
791                } else {
792                    /* 3-byte code */
793                    *len = 3;
794                    val = (cur[0] & 0xf) << 12;
795                    val |= (cur[1] & 0x3f) << 6;
796                    val |= cur[2] & 0x3f;
797                }
798            } else {
799                /* 2-byte code */
800                *len = 2;
801                val = (cur[0] & 0x1f) << 6;
802                val |= cur[1] & 0x3f;
803            }
804            if (!IS_CHAR(val)) {
805                xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
806                                  "Char 0x%X out of allowed range\n", val);
807            }
808            return (val);
809        } else {
810            /* 1-byte code */
811            *len = 1;
812            return ((int) *cur);
813        }
814    }
815    /*
816     * Assume it's a fixed length encoding (1) with
817     * a compatible encoding for the ASCII set, since
818     * XML constructs only use < 128 chars
819     */
820    *len = 1;
821    return ((int) *cur);
822encoding_error:
823
824    /*
825     * An encoding problem may arise from a truncated input buffer
826     * splitting a character in the middle. In that case do not raise
827     * an error but return 0 to endicate an end of stream problem
828     */
829    if ((ctxt == NULL) || (ctxt->input == NULL) ||
830        (ctxt->input->end - ctxt->input->cur < 4)) {
831        *len = 0;
832        return(0);
833    }
834    /*
835     * If we detect an UTF8 error that probably mean that the
836     * input encoding didn't get properly advertised in the
837     * declaration header. Report the error and switch the encoding
838     * to ISO-Latin-1 (if you don't like this policy, just declare the
839     * encoding !)
840     */
841    {
842        char buffer[150];
843
844        snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
845                        ctxt->input->cur[0], ctxt->input->cur[1],
846                        ctxt->input->cur[2], ctxt->input->cur[3]);
847        __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
848                     "Input is not proper UTF-8, indicate encoding !\n%s",
849                     BAD_CAST buffer, NULL);
850    }
851    *len = 1;
852    return ((int) *cur);
853}
854
855/**
856 * xmlCopyCharMultiByte:
857 * @out:  pointer to an array of xmlChar
858 * @val:  the char value
859 *
860 * append the char value in the array
861 *
862 * Returns the number of xmlChar written
863 */
864int
865xmlCopyCharMultiByte(xmlChar *out, int val) {
866    if (out == NULL) return(0);
867    /*
868     * We are supposed to handle UTF8, check it's valid
869     * From rfc2044: encoding of the Unicode values on UTF-8:
870     *
871     * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
872     * 0000 0000-0000 007F   0xxxxxxx
873     * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
874     * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
875     */
876    if  (val >= 0x80) {
877        xmlChar *savedout = out;
878        int bits;
879        if (val <   0x800) { *out++= (val >>  6) | 0xC0;  bits=  0; }
880        else if (val < 0x10000) { *out++= (val >> 12) | 0xE0;  bits=  6;}
881        else if (val < 0x110000)  { *out++= (val >> 18) | 0xF0;  bits=  12; }
882        else {
883            xmlErrEncodingInt(NULL, XML_ERR_INVALID_CHAR,
884                    "Internal error, xmlCopyCharMultiByte 0x%X out of bound\n",
885                              val);
886            return(0);
887        }
888        for ( ; bits >= 0; bits-= 6)
889            *out++= ((val >> bits) & 0x3F) | 0x80 ;
890        return (out - savedout);
891    }
892    *out = (xmlChar) val;
893    return 1;
894}
895
896/**
897 * xmlCopyChar:
898 * @len:  Ignored, compatibility
899 * @out:  pointer to an array of xmlChar
900 * @val:  the char value
901 *
902 * append the char value in the array
903 *
904 * Returns the number of xmlChar written
905 */
906
907int
908xmlCopyChar(int len ATTRIBUTE_UNUSED, xmlChar *out, int val) {
909    if (out == NULL) return(0);
910    /* the len parameter is ignored */
911    if  (val >= 0x80) {
912        return(xmlCopyCharMultiByte (out, val));
913    }
914    *out = (xmlChar) val;
915    return 1;
916}
917
918/************************************************************************
919 *                                                                      *
920 *              Commodity functions to switch encodings                 *
921 *                                                                      *
922 ************************************************************************/
923
924/**
925 * xmlSwitchEncoding:
926 * @ctxt:  the parser context
927 * @enc:  the encoding value (number)
928 *
929 * change the input functions when discovering the character encoding
930 * of a given entity.
931 *
932 * Returns 0 in case of success, -1 otherwise
933 */
934int
935xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
936{
937    xmlCharEncodingHandlerPtr handler;
938
939    if (ctxt == NULL) return(-1);
940    switch (enc) {
941        case XML_CHAR_ENCODING_ERROR:
942            __xmlErrEncoding(ctxt, XML_ERR_UNKNOWN_ENCODING,
943                           "encoding unknown\n", NULL, NULL);
944            break;
945        case XML_CHAR_ENCODING_NONE:
946            /* let's assume it's UTF-8 without the XML decl */
947            ctxt->charset = XML_CHAR_ENCODING_UTF8;
948            return(0);
949        case XML_CHAR_ENCODING_UTF8:
950            /* default encoding, no conversion should be needed */
951            ctxt->charset = XML_CHAR_ENCODING_UTF8;
952
953            /*
954             * Errata on XML-1.0 June 20 2001
955             * Specific handling of the Byte Order Mark for
956             * UTF-8
957             */
958            if ((ctxt->input != NULL) &&
959                (ctxt->input->cur[0] == 0xEF) &&
960                (ctxt->input->cur[1] == 0xBB) &&
961                (ctxt->input->cur[2] == 0xBF)) {
962                ctxt->input->cur += 3;
963            }
964            return(0);
965    case XML_CHAR_ENCODING_UTF16LE:
966    case XML_CHAR_ENCODING_UTF16BE:
967        /*The raw input characters are encoded
968         *in UTF-16. As we expect this function
969         *to be called after xmlCharEncInFunc, we expect
970         *ctxt->input->cur to contain UTF-8 encoded characters.
971         *So the raw UTF16 Byte Order Mark
972         *has also been converted into
973         *an UTF-8 BOM. Let's skip that BOM.
974         */
975        if ((ctxt->input != NULL) &&
976            (ctxt->input->cur[0] == 0xEF) &&
977            (ctxt->input->cur[1] == 0xBB) &&
978            (ctxt->input->cur[2] == 0xBF)) {
979            ctxt->input->cur += 3;
980        }
981        break ;
982        default:
983            break;
984    }
985    handler = xmlGetCharEncodingHandler(enc);
986    if (handler == NULL) {
987        /*
988         * Default handlers.
989         */
990        switch (enc) {
991            case XML_CHAR_ENCODING_ERROR:
992                __xmlErrEncoding(ctxt, XML_ERR_UNKNOWN_ENCODING,
993                               "encoding unknown\n", NULL, NULL);
994                break;
995            case XML_CHAR_ENCODING_NONE:
996                /* let's assume it's UTF-8 without the XML decl */
997                ctxt->charset = XML_CHAR_ENCODING_UTF8;
998                return(0);
999            case XML_CHAR_ENCODING_UTF8:
1000            case XML_CHAR_ENCODING_ASCII:
1001                /* default encoding, no conversion should be needed */
1002                ctxt->charset = XML_CHAR_ENCODING_UTF8;
1003                return(0);
1004            case XML_CHAR_ENCODING_UTF16LE:
1005                break;
1006            case XML_CHAR_ENCODING_UTF16BE:
1007                break;
1008            case XML_CHAR_ENCODING_UCS4LE:
1009                __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1010                               "encoding not supported %s\n",
1011                               BAD_CAST "USC4 little endian", NULL);
1012                break;
1013            case XML_CHAR_ENCODING_UCS4BE:
1014                __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1015                               "encoding not supported %s\n",
1016                               BAD_CAST "USC4 big endian", NULL);
1017                break;
1018            case XML_CHAR_ENCODING_EBCDIC:
1019                __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1020                               "encoding not supported %s\n",
1021                               BAD_CAST "EBCDIC", NULL);
1022                break;
1023            case XML_CHAR_ENCODING_UCS4_2143:
1024                __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1025                               "encoding not supported %s\n",
1026                               BAD_CAST "UCS4 2143", NULL);
1027                break;
1028            case XML_CHAR_ENCODING_UCS4_3412:
1029                __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1030                               "encoding not supported %s\n",
1031                               BAD_CAST "UCS4 3412", NULL);
1032                break;
1033            case XML_CHAR_ENCODING_UCS2:
1034                __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1035                               "encoding not supported %s\n",
1036                               BAD_CAST "UCS2", NULL);
1037                break;
1038            case XML_CHAR_ENCODING_8859_1:
1039            case XML_CHAR_ENCODING_8859_2:
1040            case XML_CHAR_ENCODING_8859_3:
1041            case XML_CHAR_ENCODING_8859_4:
1042            case XML_CHAR_ENCODING_8859_5:
1043            case XML_CHAR_ENCODING_8859_6:
1044            case XML_CHAR_ENCODING_8859_7:
1045            case XML_CHAR_ENCODING_8859_8:
1046            case XML_CHAR_ENCODING_8859_9:
1047                /*
1048                 * We used to keep the internal content in the
1049                 * document encoding however this turns being unmaintainable
1050                 * So xmlGetCharEncodingHandler() will return non-null
1051                 * values for this now.
1052                 */
1053                if ((ctxt->inputNr == 1) &&
1054                    (ctxt->encoding == NULL) &&
1055                    (ctxt->input->encoding != NULL)) {
1056                    ctxt->encoding = xmlStrdup(ctxt->input->encoding);
1057                }
1058                ctxt->charset = enc;
1059                return(0);
1060            case XML_CHAR_ENCODING_2022_JP:
1061                __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1062                               "encoding not supported %s\n",
1063                               BAD_CAST "ISO-2022-JP", NULL);
1064                break;
1065            case XML_CHAR_ENCODING_SHIFT_JIS:
1066                __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1067                               "encoding not supported %s\n",
1068                               BAD_CAST "Shift_JIS", NULL);
1069                break;
1070            case XML_CHAR_ENCODING_EUC_JP:
1071                __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1072                               "encoding not supported %s\n",
1073                               BAD_CAST "EUC-JP", NULL);
1074                break;
1075        }
1076    }
1077    if (handler == NULL)
1078        return(-1);
1079    ctxt->charset = XML_CHAR_ENCODING_UTF8;
1080    return(xmlSwitchToEncoding(ctxt, handler));
1081}
1082
1083/**
1084 * xmlSwitchInputEncoding:
1085 * @ctxt:  the parser context
1086 * @input:  the input stream
1087 * @handler:  the encoding handler
1088 *
1089 * change the input functions when discovering the character encoding
1090 * of a given entity.
1091 *
1092 * Returns 0 in case of success, -1 otherwise
1093 */
1094int
1095xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
1096                       xmlCharEncodingHandlerPtr handler)
1097{
1098    int nbchars;
1099
1100    if (handler == NULL)
1101        return (-1);
1102    if (input == NULL)
1103        return (-1);
1104    if (input->buf != NULL) {
1105        if (input->buf->encoder != NULL) {
1106            /*
1107             * Check in case the auto encoding detetection triggered
1108             * in already.
1109             */
1110            if (input->buf->encoder == handler)
1111                return (0);
1112
1113            /*
1114             * "UTF-16" can be used for both LE and BE
1115             if ((!xmlStrncmp(BAD_CAST input->buf->encoder->name,
1116             BAD_CAST "UTF-16", 6)) &&
1117             (!xmlStrncmp(BAD_CAST handler->name,
1118             BAD_CAST "UTF-16", 6))) {
1119             return(0);
1120             }
1121             */
1122
1123            /*
1124             * Note: this is a bit dangerous, but that's what it
1125             * takes to use nearly compatible signature for different
1126             * encodings.
1127             */
1128            xmlCharEncCloseFunc(input->buf->encoder);
1129            input->buf->encoder = handler;
1130            return (0);
1131        }
1132        input->buf->encoder = handler;
1133
1134        /*
1135         * Is there already some content down the pipe to convert ?
1136         */
1137        if ((input->buf->buffer != NULL) && (input->buf->buffer->use > 0)) {
1138            int processed;
1139            unsigned int use;
1140
1141            /*
1142             * Specific handling of the Byte Order Mark for
1143             * UTF-16
1144             */
1145            if ((handler->name != NULL) &&
1146                (!strcmp(handler->name, "UTF-16LE") ||
1147                 !strcmp(handler->name, "UTF-16")) &&
1148                (input->cur[0] == 0xFF) && (input->cur[1] == 0xFE)) {
1149                input->cur += 2;
1150            }
1151            if ((handler->name != NULL) &&
1152                (!strcmp(handler->name, "UTF-16BE")) &&
1153                (input->cur[0] == 0xFE) && (input->cur[1] == 0xFF)) {
1154                input->cur += 2;
1155            }
1156            /*
1157             * Errata on XML-1.0 June 20 2001
1158             * Specific handling of the Byte Order Mark for
1159             * UTF-8
1160             */
1161            if ((handler->name != NULL) &&
1162                (!strcmp(handler->name, "UTF-8")) &&
1163                (input->cur[0] == 0xEF) &&
1164                (input->cur[1] == 0xBB) && (input->cur[2] == 0xBF)) {
1165                input->cur += 3;
1166            }
1167
1168            /*
1169             * Shrink the current input buffer.
1170             * Move it as the raw buffer and create a new input buffer
1171             */
1172            processed = input->cur - input->base;
1173            xmlBufferShrink(input->buf->buffer, processed);
1174            input->buf->raw = input->buf->buffer;
1175            input->buf->buffer = xmlBufferCreate();
1176            input->buf->rawconsumed = processed;
1177            use = input->buf->raw->use;
1178
1179            if (ctxt->html) {
1180                /*
1181                 * convert as much as possible of the buffer
1182                 */
1183                nbchars = xmlCharEncInFunc(input->buf->encoder,
1184                                           input->buf->buffer,
1185                                           input->buf->raw);
1186            } else {
1187                /*
1188                 * convert just enough to get
1189                 * '<?xml version="1.0" encoding="xxx"?>'
1190                 * parsed with the autodetected encoding
1191                 * into the parser reading buffer.
1192                 */
1193                nbchars = xmlCharEncFirstLine(input->buf->encoder,
1194                                              input->buf->buffer,
1195                                              input->buf->raw);
1196            }
1197            if (nbchars < 0) {
1198                xmlErrInternal(ctxt,
1199                               "switching encoding: encoder error\n",
1200                               NULL);
1201                return (-1);
1202            }
1203            input->buf->rawconsumed += use - input->buf->raw->use;
1204            input->base = input->cur = input->buf->buffer->content;
1205            input->end = &input->base[input->buf->buffer->use];
1206
1207        }
1208        return (0);
1209    } else {
1210        if ((input->length == 0) || (input->buf == NULL)) {
1211            /*
1212             * When parsing a static memory array one must know the
1213             * size to be able to convert the buffer.
1214             */
1215            xmlErrInternal(ctxt, "switching encoding : no input\n", NULL);
1216            return (-1);
1217        } else {
1218            int processed;
1219
1220            /*
1221             * Shrink the current input buffer.
1222             * Move it as the raw buffer and create a new input buffer
1223             */
1224            processed = input->cur - input->base;
1225
1226            input->buf->raw = xmlBufferCreate();
1227            xmlBufferAdd(input->buf->raw, input->cur,
1228                         input->length - processed);
1229            input->buf->buffer = xmlBufferCreate();
1230
1231            /*
1232             * convert as much as possible of the raw input
1233             * to the parser reading buffer.
1234             */
1235            nbchars = xmlCharEncInFunc(input->buf->encoder,
1236                                       input->buf->buffer,
1237                                       input->buf->raw);
1238            if (nbchars < 0) {
1239                xmlErrInternal(ctxt,
1240                               "switching encoding: encoder error\n",
1241                               NULL);
1242                return (-1);
1243            }
1244
1245            /*
1246             * Conversion succeeded, get rid of the old buffer
1247             */
1248            if ((input->free != NULL) && (input->base != NULL))
1249                input->free((xmlChar *) input->base);
1250            input->base = input->cur = input->buf->buffer->content;
1251            input->end = &input->base[input->buf->buffer->use];
1252        }
1253    }
1254    return (0);
1255}
1256
1257/**
1258 * xmlSwitchToEncoding:
1259 * @ctxt:  the parser context
1260 * @handler:  the encoding handler
1261 *
1262 * change the input functions when discovering the character encoding
1263 * of a given entity.
1264 *
1265 * Returns 0 in case of success, -1 otherwise
1266 */
1267int
1268xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
1269{
1270    if (handler != NULL) {
1271        if (ctxt->input != NULL) {
1272            xmlSwitchInputEncoding(ctxt, ctxt->input, handler);
1273        } else {
1274            xmlErrInternal(ctxt, "xmlSwitchToEncoding : no input\n",
1275                           NULL);
1276            return(-1);
1277        }
1278        /*
1279         * The parsing is now done in UTF8 natively
1280         */
1281        ctxt->charset = XML_CHAR_ENCODING_UTF8;
1282    } else
1283        return(-1);
1284    return(0);
1285}
1286
1287/************************************************************************
1288 *                                                                      *
1289 *      Commodity functions to handle entities processing               *
1290 *                                                                      *
1291 ************************************************************************/
1292
1293/**
1294 * xmlFreeInputStream:
1295 * @input:  an xmlParserInputPtr
1296 *
1297 * Free up an input stream.
1298 */
1299void
1300xmlFreeInputStream(xmlParserInputPtr input) {
1301    if (input == NULL) return;
1302
1303    if (input->filename != NULL) xmlFree((char *) input->filename);
1304    if (input->directory != NULL) xmlFree((char *) input->directory);
1305    if (input->encoding != NULL) xmlFree((char *) input->encoding);
1306    if (input->version != NULL) xmlFree((char *) input->version);
1307    if ((input->free != NULL) && (input->base != NULL))
1308        input->free((xmlChar *) input->base);
1309    if (input->buf != NULL)
1310        xmlFreeParserInputBuffer(input->buf);
1311    xmlFree(input);
1312}
1313
1314/**
1315 * xmlNewInputStream:
1316 * @ctxt:  an XML parser context
1317 *
1318 * Create a new input stream structure
1319 * Returns the new input stream or NULL
1320 */
1321xmlParserInputPtr
1322xmlNewInputStream(xmlParserCtxtPtr ctxt) {
1323    xmlParserInputPtr input;
1324    static int id = 0;
1325
1326    input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
1327    if (input == NULL) {
1328        xmlErrMemory(ctxt,  "couldn't allocate a new input stream\n");
1329        return(NULL);
1330    }
1331    memset(input, 0, sizeof(xmlParserInput));
1332    input->line = 1;
1333    input->col = 1;
1334    input->standalone = -1;
1335    /*
1336     * we don't care about thread reentrancy unicity for a single
1337     * parser context (and hence thread) is sufficient.
1338     */
1339    input->id = id++;
1340    return(input);
1341}
1342
1343/**
1344 * xmlNewIOInputStream:
1345 * @ctxt:  an XML parser context
1346 * @input:  an I/O Input
1347 * @enc:  the charset encoding if known
1348 *
1349 * Create a new input stream structure encapsulating the @input into
1350 * a stream suitable for the parser.
1351 *
1352 * Returns the new input stream or NULL
1353 */
1354xmlParserInputPtr
1355xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
1356                    xmlCharEncoding enc) {
1357    xmlParserInputPtr inputStream;
1358
1359    if (input == NULL) return(NULL);
1360    if (xmlParserDebugEntities)
1361        xmlGenericError(xmlGenericErrorContext, "new input from I/O\n");
1362    inputStream = xmlNewInputStream(ctxt);
1363    if (inputStream == NULL) {
1364        return(NULL);
1365    }
1366    inputStream->filename = NULL;
1367    inputStream->buf = input;
1368    inputStream->base = inputStream->buf->buffer->content;
1369    inputStream->cur = inputStream->buf->buffer->content;
1370    inputStream->end = &inputStream->base[inputStream->buf->buffer->use];
1371    if (enc != XML_CHAR_ENCODING_NONE) {
1372        xmlSwitchEncoding(ctxt, enc);
1373    }
1374
1375    return(inputStream);
1376}
1377
1378/**
1379 * xmlNewEntityInputStream:
1380 * @ctxt:  an XML parser context
1381 * @entity:  an Entity pointer
1382 *
1383 * Create a new input stream based on an xmlEntityPtr
1384 *
1385 * Returns the new input stream or NULL
1386 */
1387xmlParserInputPtr
1388xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
1389    xmlParserInputPtr input;
1390
1391    if (entity == NULL) {
1392        xmlErrInternal(ctxt, "xmlNewEntityInputStream entity = NULL\n",
1393                       NULL);
1394        return(NULL);
1395    }
1396    if (xmlParserDebugEntities)
1397        xmlGenericError(xmlGenericErrorContext,
1398                "new input from entity: %s\n", entity->name);
1399    if (entity->content == NULL) {
1400        switch (entity->etype) {
1401            case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
1402                xmlErrInternal(ctxt, "Cannot parse entity %s\n",
1403                               entity->name);
1404                break;
1405            case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
1406            case XML_EXTERNAL_PARAMETER_ENTITY:
1407                return(xmlLoadExternalEntity((char *) entity->URI,
1408                       (char *) entity->ExternalID, ctxt));
1409            case XML_INTERNAL_GENERAL_ENTITY:
1410                xmlErrInternal(ctxt,
1411                      "Internal entity %s without content !\n",
1412                               entity->name);
1413                break;
1414            case XML_INTERNAL_PARAMETER_ENTITY:
1415                xmlErrInternal(ctxt,
1416                      "Internal parameter entity %s without content !\n",
1417                               entity->name);
1418                break;
1419            case XML_INTERNAL_PREDEFINED_ENTITY:
1420                xmlErrInternal(ctxt,
1421                      "Predefined entity %s without content !\n",
1422                               entity->name);
1423                break;
1424        }
1425        return(NULL);
1426    }
1427    input = xmlNewInputStream(ctxt);
1428    if (input == NULL) {
1429        return(NULL);
1430    }
1431    input->filename = (char *) entity->URI;
1432    input->base = entity->content;
1433    input->cur = entity->content;
1434    input->length = entity->length;
1435    input->end = &entity->content[input->length];
1436    return(input);
1437}
1438
1439/**
1440 * xmlNewStringInputStream:
1441 * @ctxt:  an XML parser context
1442 * @buffer:  an memory buffer
1443 *
1444 * Create a new input stream based on a memory buffer.
1445 * Returns the new input stream
1446 */
1447xmlParserInputPtr
1448xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
1449    xmlParserInputPtr input;
1450
1451    if (buffer == NULL) {
1452        xmlErrInternal(ctxt, "xmlNewStringInputStream string = NULL\n",
1453                       NULL);
1454        return(NULL);
1455    }
1456    if (xmlParserDebugEntities)
1457        xmlGenericError(xmlGenericErrorContext,
1458                "new fixed input: %.30s\n", buffer);
1459    input = xmlNewInputStream(ctxt);
1460    if (input == NULL) {
1461        xmlErrMemory(ctxt,  "couldn't allocate a new input stream\n");
1462        return(NULL);
1463    }
1464    input->base = buffer;
1465    input->cur = buffer;
1466    input->length = xmlStrlen(buffer);
1467    input->end = &buffer[input->length];
1468    return(input);
1469}
1470
1471/**
1472 * xmlNewInputFromFile:
1473 * @ctxt:  an XML parser context
1474 * @filename:  the filename to use as entity
1475 *
1476 * Create a new input stream based on a file or an URL.
1477 *
1478 * Returns the new input stream or NULL in case of error
1479 */
1480xmlParserInputPtr
1481xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
1482    xmlParserInputBufferPtr buf;
1483    xmlParserInputPtr inputStream;
1484    char *directory = NULL;
1485    xmlChar *URI = NULL;
1486
1487    if (xmlParserDebugEntities)
1488        xmlGenericError(xmlGenericErrorContext,
1489                "new input from file: %s\n", filename);
1490    if (ctxt == NULL) return(NULL);
1491    buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1492    if (buf == NULL) {
1493        __xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n",
1494                     (const char *) filename);
1495        return(NULL);
1496    }
1497
1498    inputStream = xmlNewInputStream(ctxt);
1499    if (inputStream == NULL) {
1500        if (directory != NULL) xmlFree((char *) directory);
1501        if (URI != NULL) xmlFree((char *) URI);
1502        return(NULL);
1503    }
1504    inputStream->buf = buf;
1505    inputStream = xmlCheckHTTPInput(ctxt, inputStream);
1506    if (inputStream == NULL)
1507        return(NULL);
1508   
1509    if (inputStream->filename == NULL)
1510        URI = xmlStrdup((xmlChar *) filename);
1511    else
1512        URI = xmlStrdup((xmlChar *) inputStream->filename);
1513    directory = xmlParserGetDirectory((const char *) URI);
1514    inputStream->filename = (char *) xmlCanonicPath((const xmlChar *) URI);
1515    if (URI != NULL) xmlFree((char *) URI);
1516    inputStream->directory = directory;
1517
1518    inputStream->base = inputStream->buf->buffer->content;
1519    inputStream->cur = inputStream->buf->buffer->content;
1520    inputStream->end = &inputStream->base[inputStream->buf->buffer->use];
1521    if ((ctxt->directory == NULL) && (directory != NULL))
1522        ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
1523    return(inputStream);
1524}
1525
1526/************************************************************************
1527 *                                                                      *
1528 *              Commodity functions to handle parser contexts           *
1529 *                                                                      *
1530 ************************************************************************/
1531
1532/**
1533 * xmlInitParserCtxt:
1534 * @ctxt:  an XML parser context
1535 *
1536 * Initialize a parser context
1537 *
1538 * Returns 0 in case of success and -1 in case of error
1539 */
1540
1541int
1542xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
1543{
1544    xmlParserInputPtr input;
1545
1546    if(ctxt==NULL) {
1547        xmlErrInternal(NULL, "Got NULL parser context\n", NULL);
1548        return(-1);
1549    }
1550
1551    xmlDefaultSAXHandlerInit();
1552
1553    if (ctxt->dict == NULL)
1554        ctxt->dict = xmlDictCreate();
1555    if (ctxt->dict == NULL) {
1556        xmlErrMemory(NULL, "cannot initialize parser context\n");
1557        return(-1);
1558    }
1559    if (ctxt->sax == NULL)
1560        ctxt->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
1561    if (ctxt->sax == NULL) {
1562        xmlErrMemory(NULL, "cannot initialize parser context\n");
1563        return(-1);
1564    }
1565    else
1566        xmlSAXVersion(ctxt->sax, 2);
1567
1568    ctxt->maxatts = 0;
1569    ctxt->atts = NULL;
1570    /* Allocate the Input stack */
1571    if (ctxt->inputTab == NULL) {
1572        ctxt->inputTab = (xmlParserInputPtr *)
1573                    xmlMalloc(5 * sizeof(xmlParserInputPtr));
1574        ctxt->inputMax = 5;
1575    }
1576    if (ctxt->inputTab == NULL) {
1577        xmlErrMemory(NULL, "cannot initialize parser context\n");
1578        ctxt->inputNr = 0;
1579        ctxt->inputMax = 0;
1580        ctxt->input = NULL;
1581        return(-1);
1582    }
1583    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
1584        xmlFreeInputStream(input);
1585    }
1586    ctxt->inputNr = 0;
1587    ctxt->input = NULL;
1588
1589    ctxt->version = NULL;
1590    ctxt->encoding = NULL;
1591    ctxt->standalone = -1;
1592    ctxt->hasExternalSubset = 0;
1593    ctxt->hasPErefs = 0;
1594    ctxt->html = 0;
1595    ctxt->external = 0;
1596    ctxt->instate = XML_PARSER_START;
1597    ctxt->token = 0;
1598    ctxt->directory = NULL;
1599
1600    /* Allocate the Node stack */
1601    if (ctxt->nodeTab == NULL) {
1602        ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
1603        ctxt->nodeMax = 10;
1604    }
1605    if (ctxt->nodeTab == NULL) {
1606        xmlErrMemory(NULL, "cannot initialize parser context\n");
1607        ctxt->nodeNr = 0;
1608        ctxt->nodeMax = 0;
1609        ctxt->node = NULL;
1610        ctxt->inputNr = 0;
1611        ctxt->inputMax = 0;
1612        ctxt->input = NULL;
1613        return(-1);
1614    }
1615    ctxt->nodeNr = 0;
1616    ctxt->node = NULL;
1617
1618    /* Allocate the Name stack */
1619    if (ctxt->nameTab == NULL) {
1620        ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
1621        ctxt->nameMax = 10;
1622    }
1623    if (ctxt->nameTab == NULL) {
1624        xmlErrMemory(NULL, "cannot initialize parser context\n");
1625        ctxt->nodeNr = 0;
1626        ctxt->nodeMax = 0;
1627        ctxt->node = NULL;
1628        ctxt->inputNr = 0;
1629        ctxt->inputMax = 0;
1630        ctxt->input = NULL;
1631        ctxt->nameNr = 0;
1632        ctxt->nameMax = 0;
1633        ctxt->name = NULL;
1634        return(-1);
1635    }
1636    ctxt->nameNr = 0;
1637    ctxt->name = NULL;
1638
1639    /* Allocate the space stack */
1640    if (ctxt->spaceTab == NULL) {
1641        ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
1642        ctxt->spaceMax = 10;
1643    }
1644    if (ctxt->spaceTab == NULL) {
1645        xmlErrMemory(NULL, "cannot initialize parser context\n");
1646        ctxt->nodeNr = 0;
1647        ctxt->nodeMax = 0;
1648        ctxt->node = NULL;
1649        ctxt->inputNr = 0;
1650        ctxt->inputMax = 0;
1651        ctxt->input = NULL;
1652        ctxt->nameNr = 0;
1653        ctxt->nameMax = 0;
1654        ctxt->name = NULL;
1655        ctxt->spaceNr = 0;
1656        ctxt->spaceMax = 0;
1657        ctxt->space = NULL;
1658        return(-1);
1659    }
1660    ctxt->spaceNr = 1;
1661    ctxt->spaceMax = 10;
1662    ctxt->spaceTab[0] = -1;
1663    ctxt->space = &ctxt->spaceTab[0];
1664    ctxt->userData = ctxt;
1665    ctxt->myDoc = NULL;
1666    ctxt->wellFormed = 1;
1667    ctxt->nsWellFormed = 1;
1668    ctxt->valid = 1;
1669    ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
1670    ctxt->validate = xmlDoValidityCheckingDefaultValue;
1671    ctxt->pedantic = xmlPedanticParserDefaultValue;
1672    ctxt->linenumbers = xmlLineNumbersDefaultValue;
1673    ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
1674    if (ctxt->keepBlanks == 0)
1675        ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
1676
1677    ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0;
1678    ctxt->vctxt.userData = ctxt;
1679    ctxt->vctxt.error = xmlParserValidityError;
1680    ctxt->vctxt.warning = xmlParserValidityWarning;
1681    if (ctxt->validate) {
1682        if (xmlGetWarningsDefaultValue == 0)
1683            ctxt->vctxt.warning = NULL;
1684        else
1685            ctxt->vctxt.warning = xmlParserValidityWarning;
1686        ctxt->vctxt.nodeMax = 0;
1687    }
1688    ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
1689    ctxt->record_info = 0;
1690    ctxt->nbChars = 0;
1691    ctxt->checkIndex = 0;
1692    ctxt->inSubset = 0;
1693    ctxt->errNo = XML_ERR_OK;
1694    ctxt->depth = 0;
1695    ctxt->charset = XML_CHAR_ENCODING_UTF8;
1696    ctxt->catalogs = NULL;
1697    xmlInitNodeInfoSeq(&ctxt->node_seq);
1698    return(0);
1699}
1700
1701/**
1702 * xmlFreeParserCtxt:
1703 * @ctxt:  an XML parser context
1704 *
1705 * Free all the memory used by a parser context. However the parsed
1706 * document in ctxt->myDoc is not freed.
1707 */
1708
1709void
1710xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
1711{
1712    xmlParserInputPtr input;
1713
1714    if (ctxt == NULL) return;
1715
1716    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
1717        xmlFreeInputStream(input);
1718    }
1719    if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
1720    if (ctxt->nameTab != NULL) xmlFree((xmlChar * *)ctxt->nameTab);
1721    if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
1722    if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
1723    if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
1724    if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
1725    if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
1726    if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
1727#ifdef LIBXML_SAX1_ENABLED
1728    if ((ctxt->sax != NULL) &&
1729        (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler))
1730#else
1731    if (ctxt->sax != NULL)
1732#endif /* LIBXML_SAX1_ENABLED */
1733        xmlFree(ctxt->sax);
1734    if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
1735    if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
1736    if (ctxt->atts != NULL) xmlFree((xmlChar * *)ctxt->atts);
1737    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
1738    if (ctxt->nsTab != NULL) xmlFree((char *) ctxt->nsTab);
1739    if (ctxt->pushTab != NULL) xmlFree(ctxt->pushTab);
1740    if (ctxt->attallocs != NULL) xmlFree(ctxt->attallocs);
1741    if (ctxt->attsDefault != NULL)
1742        xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
1743    if (ctxt->attsSpecial != NULL)
1744        xmlHashFree(ctxt->attsSpecial, NULL);
1745    if (ctxt->freeElems != NULL) {
1746        xmlNodePtr cur, next;
1747
1748        cur = ctxt->freeElems;
1749        while (cur != NULL) {
1750            next = cur->next;
1751            xmlFree(cur);
1752            cur = next;
1753        }
1754    }
1755    if (ctxt->freeAttrs != NULL) {
1756        xmlAttrPtr cur, next;
1757
1758        cur = ctxt->freeAttrs;
1759        while (cur != NULL) {
1760            next = cur->next;
1761            xmlFree(cur);
1762            cur = next;
1763        }
1764    }
1765    /*
1766     * cleanup the error strings
1767     */
1768    if (ctxt->lastError.message != NULL)
1769        xmlFree(ctxt->lastError.message);
1770    if (ctxt->lastError.file != NULL)
1771        xmlFree(ctxt->lastError.file);
1772    if (ctxt->lastError.str1 != NULL)
1773        xmlFree(ctxt->lastError.str1);
1774    if (ctxt->lastError.str2 != NULL)
1775        xmlFree(ctxt->lastError.str2);
1776    if (ctxt->lastError.str3 != NULL)
1777        xmlFree(ctxt->lastError.str3);
1778
1779#ifdef LIBXML_CATALOG_ENABLED
1780    if (ctxt->catalogs != NULL)
1781        xmlCatalogFreeLocal(ctxt->catalogs);
1782#endif
1783    xmlFree(ctxt);
1784}
1785
1786/**
1787 * xmlNewParserCtxt:
1788 *
1789 * Allocate and initialize a new parser context.
1790 *
1791 * Returns the xmlParserCtxtPtr or NULL
1792 */
1793
1794xmlParserCtxtPtr
1795xmlNewParserCtxt()
1796{
1797    xmlParserCtxtPtr ctxt;
1798
1799    ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
1800    if (ctxt == NULL) {
1801        xmlErrMemory(NULL, "cannot allocate parser context\n");
1802        return(NULL);
1803    }
1804    memset(ctxt, 0, sizeof(xmlParserCtxt));
1805    if (xmlInitParserCtxt(ctxt) < 0) {
1806        xmlFreeParserCtxt(ctxt);
1807        return(NULL);
1808    }
1809    return(ctxt);
1810}
1811
1812/************************************************************************
1813 *                                                                      *
1814 *              Handling of node informations                           *
1815 *                                                                      *
1816 ************************************************************************/
1817
1818/**
1819 * xmlClearParserCtxt:
1820 * @ctxt:  an XML parser context
1821 *
1822 * Clear (release owned resources) and reinitialize a parser context
1823 */
1824
1825void
1826xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
1827{
1828  if (ctxt==NULL)
1829    return;
1830  xmlClearNodeInfoSeq(&ctxt->node_seq);
1831  xmlCtxtReset(ctxt);
1832}
1833
1834
1835/**
1836 * xmlParserFindNodeInfo:
1837 * @ctx:  an XML parser context
1838 * @node:  an XML node within the tree
1839 *
1840 * Find the parser node info struct for a given node
1841 *
1842 * Returns an xmlParserNodeInfo block pointer or NULL
1843 */
1844const xmlParserNodeInfo *
1845xmlParserFindNodeInfo(const xmlParserCtxtPtr ctx, const xmlNodePtr node)
1846{
1847    unsigned long pos;
1848
1849    if ((ctx == NULL) || (node == NULL))
1850        return (NULL);
1851    /* Find position where node should be at */
1852    pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
1853    if (pos < ctx->node_seq.length
1854        && ctx->node_seq.buffer[pos].node == node)
1855        return &ctx->node_seq.buffer[pos];
1856    else
1857        return NULL;
1858}
1859
1860
1861/**
1862 * xmlInitNodeInfoSeq:
1863 * @seq:  a node info sequence pointer
1864 *
1865 * -- Initialize (set to initial state) node info sequence
1866 */
1867void
1868xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
1869{
1870    if (seq == NULL)
1871        return;
1872    seq->length = 0;
1873    seq->maximum = 0;
1874    seq->buffer = NULL;
1875}
1876
1877/**
1878 * xmlClearNodeInfoSeq:
1879 * @seq:  a node info sequence pointer
1880 *
1881 * -- Clear (release memory and reinitialize) node
1882 *   info sequence
1883 */
1884void
1885xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
1886{
1887    if (seq == NULL)
1888        return;
1889    if (seq->buffer != NULL)
1890        xmlFree(seq->buffer);
1891    xmlInitNodeInfoSeq(seq);
1892}
1893
1894/**
1895 * xmlParserFindNodeInfoIndex:
1896 * @seq:  a node info sequence pointer
1897 * @node:  an XML node pointer
1898 *
1899 *
1900 * xmlParserFindNodeInfoIndex : Find the index that the info record for
1901 *   the given node is or should be at in a sorted sequence
1902 *
1903 * Returns a long indicating the position of the record
1904 */
1905unsigned long
1906xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
1907                           const xmlNodePtr node)
1908{
1909    unsigned long upper, lower, middle;
1910    int found = 0;
1911
1912    if ((seq == NULL) || (node == NULL))
1913        return (-1);
1914
1915    /* Do a binary search for the key */
1916    lower = 1;
1917    upper = seq->length;
1918    middle = 0;
1919    while (lower <= upper && !found) {
1920        middle = lower + (upper - lower) / 2;
1921        if (node == seq->buffer[middle - 1].node)
1922            found = 1;
1923        else if (node < seq->buffer[middle - 1].node)
1924            upper = middle - 1;
1925        else
1926            lower = middle + 1;
1927    }
1928
1929    /* Return position */
1930    if (middle == 0 || seq->buffer[middle - 1].node < node)
1931        return middle;
1932    else
1933        return middle - 1;
1934}
1935
1936
1937/**
1938 * xmlParserAddNodeInfo:
1939 * @ctxt:  an XML parser context
1940 * @info:  a node info sequence pointer
1941 *
1942 * Insert node info record into the sorted sequence
1943 */
1944void
1945xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
1946                     const xmlParserNodeInfoPtr info)
1947{
1948    unsigned long pos;
1949
1950    if ((ctxt == NULL) || (info == NULL)) return;
1951
1952    /* Find pos and check to see if node is already in the sequence */
1953    pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, (xmlNodePtr)
1954                                     info->node);
1955    if (pos < ctxt->node_seq.length
1956        && ctxt->node_seq.buffer[pos].node == info->node) {
1957        ctxt->node_seq.buffer[pos] = *info;
1958    }
1959
1960    /* Otherwise, we need to add new node to buffer */
1961    else {
1962        if (ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) {
1963            xmlParserNodeInfo *tmp_buffer;
1964            unsigned int byte_size;
1965
1966            if (ctxt->node_seq.maximum == 0)
1967                ctxt->node_seq.maximum = 2;
1968            byte_size = (sizeof(*ctxt->node_seq.buffer) *
1969                        (2 * ctxt->node_seq.maximum));
1970
1971            if (ctxt->node_seq.buffer == NULL)
1972                tmp_buffer = (xmlParserNodeInfo *) xmlMalloc(byte_size);
1973            else
1974                tmp_buffer =
1975                    (xmlParserNodeInfo *) xmlRealloc(ctxt->node_seq.buffer,
1976                                                     byte_size);
1977
1978            if (tmp_buffer == NULL) {
1979                xmlErrMemory(ctxt, "failed to allocate buffer\n");
1980                return;
1981            }
1982            ctxt->node_seq.buffer = tmp_buffer;
1983            ctxt->node_seq.maximum *= 2;
1984        }
1985
1986        /* If position is not at end, move elements out of the way */
1987        if (pos != ctxt->node_seq.length) {
1988            unsigned long i;
1989
1990            for (i = ctxt->node_seq.length; i > pos; i--)
1991                ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
1992        }
1993
1994        /* Copy element and increase length */
1995        ctxt->node_seq.buffer[pos] = *info;
1996        ctxt->node_seq.length++;
1997    }
1998}
1999
2000/************************************************************************
2001 *                                                                      *
2002 *              Defaults settings                                       *
2003 *                                                                      *
2004 ************************************************************************/
2005/**
2006 * xmlPedanticParserDefault:
2007 * @val:  int 0 or 1
2008 *
2009 * Set and return the previous value for enabling pedantic warnings.
2010 *
2011 * Returns the last value for 0 for no substitution, 1 for substitution.
2012 */
2013
2014int
2015xmlPedanticParserDefault(int val) {
2016    int old = xmlPedanticParserDefaultValue;
2017
2018    xmlPedanticParserDefaultValue = val;
2019    return(old);
2020}
2021
2022/**
2023 * xmlLineNumbersDefault:
2024 * @val:  int 0 or 1
2025 *
2026 * Set and return the previous value for enabling line numbers in elements
2027 * contents. This may break on old application and is turned off by default.
2028 *
2029 * Returns the last value for 0 for no substitution, 1 for substitution.
2030 */
2031
2032int
2033xmlLineNumbersDefault(int val) {
2034    int old = xmlLineNumbersDefaultValue;
2035
2036    xmlLineNumbersDefaultValue = val;
2037    return(old);
2038}
2039
2040/**
2041 * xmlSubstituteEntitiesDefault:
2042 * @val:  int 0 or 1
2043 *
2044 * Set and return the previous value for default entity support.
2045 * Initially the parser always keep entity references instead of substituting
2046 * entity values in the output. This function has to be used to change the
2047 * default parser behavior
2048 * SAX::substituteEntities() has to be used for changing that on a file by
2049 * file basis.
2050 *
2051 * Returns the last value for 0 for no substitution, 1 for substitution.
2052 */
2053
2054int
2055xmlSubstituteEntitiesDefault(int val) {
2056    int old = xmlSubstituteEntitiesDefaultValue;
2057
2058    xmlSubstituteEntitiesDefaultValue = val;
2059    return(old);
2060}
2061
2062/**
2063 * xmlKeepBlanksDefault:
2064 * @val:  int 0 or 1
2065 *
2066 * Set and return the previous value for default blanks text nodes support.
2067 * The 1.x version of the parser used an heuristic to try to detect
2068 * ignorable white spaces. As a result the SAX callback was generating
2069 * xmlSAX2IgnorableWhitespace() callbacks instead of characters() one, and when
2070 * using the DOM output text nodes containing those blanks were not generated.
2071 * The 2.x and later version will switch to the XML standard way and
2072 * ignorableWhitespace() are only generated when running the parser in
2073 * validating mode and when the current element doesn't allow CDATA or
2074 * mixed content.
2075 * This function is provided as a way to force the standard behavior
2076 * on 1.X libs and to switch back to the old mode for compatibility when
2077 * running 1.X client code on 2.X . Upgrade of 1.X code should be done
2078 * by using xmlIsBlankNode() commodity function to detect the "empty"
2079 * nodes generated.
2080 * This value also affect autogeneration of indentation when saving code
2081 * if blanks sections are kept, indentation is not generated.
2082 *
2083 * Returns the last value for 0 for no substitution, 1 for substitution.
2084 */
2085
2086int
2087xmlKeepBlanksDefault(int val) {
2088    int old = xmlKeepBlanksDefaultValue;
2089
2090    xmlKeepBlanksDefaultValue = val;
2091    xmlIndentTreeOutput = !val;
2092    return(old);
2093}
2094
Note: See TracBrowser for help on using the repository browser.